Merge "Test Recents Transition sleep re-entry" into udc-dev
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index b732da2..19a4766 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -24,11 +24,9 @@
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.IStopUserCallback;
-import android.app.WaitResult;
 import android.app.WallpaperManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -69,6 +67,7 @@
 import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * Perf tests for user life cycle events.
@@ -101,7 +100,6 @@
     private static final long TIMEOUT_MAX_TEST_TIME_MS = 24 * 60_000;
 
     private static final int TIMEOUT_IN_SECOND = 30;
-    private static final int CHECK_USER_REMOVED_INTERVAL_MS = 200;
 
     /** Name of users/profiles in the test. Users with this name may be freely removed. */
     private static final String TEST_USER_NAME = "UserLifecycleTests_test_user";
@@ -1261,15 +1259,13 @@
      * <p> This should always be used for profiles since profiles cannot be started in foreground.
      */
     private void startUserInBackgroundAndWaitForUnlock(int userId) {
-        final ProgressWaiter waiter = new ProgressWaiter();
-        boolean success = false;
         try {
-            mIam.startUserInBackgroundWithListener(userId, waiter);
-            success = waiter.waitForFinish(TIMEOUT_IN_SECOND);
-        } catch (RemoteException e) {
-            Log.e(TAG, "startUserInBackgroundAndWaitForUnlock failed", e);
+            attestTrue("Failed to start user " + userId + " in background.",
+                    ShellHelper.runShellCommandWithTimeout("am start-user -w " + userId,
+                            TIMEOUT_IN_SECOND).startsWith("Success:"));
+        } catch (TimeoutException e) {
+            fail("Could not start user " + userId + " in " + TIMEOUT_IN_SECOND + " seconds");
         }
-        attestTrue("Failed to start user " + userId + " in background.", success);
     }
 
     /** Starts the given user in the foreground. */
@@ -1389,14 +1385,20 @@
      * Launches the given package in the given user.
      * Make sure the keyguard has been dismissed prior to calling.
      */
-    private void startApp(int userId, String packageName) throws RemoteException {
-        final Context context = InstrumentationRegistry.getContext();
-        final WaitResult result = ActivityTaskManager.getService().startActivityAndWait(null,
-                context.getPackageName(), context.getAttributionTag(),
-                context.getPackageManager().getLaunchIntentForPackage(packageName), null, null,
-                null, 0, 0, null, null, userId);
-        attestTrue("User " + userId + " failed to start " + packageName,
-                result.result == ActivityManager.START_SUCCESS);
+    private void startApp(int userId, String packageName) {
+        final String failMessage = "User " + userId + " failed to start " + packageName;
+        final String component = InstrumentationRegistry.getContext().getPackageManager()
+                .getLaunchIntentForPackage(packageName).getComponent().flattenToShortString();
+        try {
+            final String result = ShellHelper.runShellCommandWithTimeout(
+                    "am start -W -n " + component + " --user " + userId, TIMEOUT_IN_SECOND);
+            assertTrue(failMessage + ", component=" + component + ", result=" + result,
+                    result.contains("Status: ok")
+                    && !result.contains("Warning:")
+                    && !result.contains("Error:"));
+        } catch (TimeoutException e) {
+            fail(failMessage + " in " + TIMEOUT_IN_SECOND + " seconds");
+        }
     }
 
     private class ProgressWaiter extends IProgressListener.Stub {
@@ -1471,17 +1473,11 @@
     private void removeUser(int userId) throws RemoteException {
         stopUserAfterWaitingForBroadcastIdle(userId, true);
         try {
-            mUm.removeUser(userId);
-            final long startTime = System.currentTimeMillis();
-            final long timeoutInMs = TIMEOUT_IN_SECOND * 1000;
-            while (mUm.getUserInfo(userId) != null &&
-                    System.currentTimeMillis() - startTime < timeoutInMs) {
-                TimeUnit.MILLISECONDS.sleep(CHECK_USER_REMOVED_INTERVAL_MS);
-            }
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        } catch (Exception e) {
-            // Ignore
+            ShellHelper.runShellCommandWithTimeout("pm remove-user -w " + userId,
+                    TIMEOUT_IN_SECOND);
+        } catch (TimeoutException e) {
+            Log.e(TAG, String.format("Could not remove user %d in %d seconds",
+                    userId, TIMEOUT_IN_SECOND), e);
         }
         if (mUm.getUserInfo(userId) != null) {
             mUsersToRemove.add(userId);
@@ -1544,7 +1540,11 @@
     }
 
     private void waitForBroadcastIdle() {
-        ShellHelper.runShellCommand("am wait-for-broadcast-idle");
+        try {
+            ShellHelper.runShellCommandWithTimeout("am wait-for-broadcast-idle", TIMEOUT_IN_SECOND);
+        } catch (TimeoutException e) {
+            Log.e(TAG, "Ending waitForBroadcastIdle because it is taking too long", e);
+        }
     }
 
     private void sleep(long ms) {
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/ShellHelper.java b/apct-tests/perftests/utils/src/android/perftests/utils/ShellHelper.java
index 7b52576..a35899a 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/ShellHelper.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/ShellHelper.java
@@ -24,6 +24,10 @@
 import androidx.test.InstrumentationRegistry;
 
 import java.io.FileInputStream;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Provides Shell-based utilities such as running a command.
@@ -31,6 +35,43 @@
 public final class ShellHelper {
 
     /**
+     * Runs a Shell command with a timeout, returning a trimmed response.
+     */
+    @NonNull
+    public static String runShellCommandWithTimeout(@NonNull String command, long timeoutInSecond)
+            throws TimeoutException {
+        AtomicReference<Exception> exception = new AtomicReference<>(null);
+        AtomicReference<String> result = new AtomicReference<>(null);
+
+        CountDownLatch latch = new CountDownLatch(1);
+
+        new Thread(() -> {
+            try {
+                result.set(runShellCommandRaw(command));
+            } catch (Exception e) {
+                exception.set(e);
+            } finally {
+                latch.countDown();
+            }
+        }).start();
+
+        try {
+            if (!latch.await(timeoutInSecond, TimeUnit.SECONDS)) {
+                throw new TimeoutException("Command: '" + command + "' could not run in "
+                        + timeoutInSecond + " seconds");
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+
+        if (exception.get() != null) {
+            throw new AndroidRuntimeException(exception.get());
+        }
+
+        return result.get();
+    }
+
+    /**
      * Runs a Shell command, returning a trimmed response.
      */
     @NonNull
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index f779b4d..b0b3b1f 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -319,6 +319,8 @@
     private SensorManager mSensorManager;
     private final boolean mUseMotionSensor;
     private Sensor mMotionSensor;
+    private final boolean mIsLocationPrefetchEnabled;
+    @Nullable
     private LocationRequest mLocationRequest;
     private Intent mIdleIntent;
     private Bundle mIdleIntentOptions;
@@ -2460,6 +2462,11 @@
             return null;
         }
 
+        boolean isLocationPrefetchEnabled() {
+            return mContext.getResources().getBoolean(
+                   com.android.internal.R.bool.config_autoPowerModePrefetchLocation);
+        }
+
         boolean useMotionSensor() {
             return mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_autoPowerModeUseMotionSensor);
@@ -2489,6 +2496,7 @@
         mAppStateTracker = mInjector.getAppStateTracker(context,
                 AppSchedulingModuleThread.get().getLooper());
         LocalServices.addService(AppStateTracker.class, mAppStateTracker);
+        mIsLocationPrefetchEnabled = mInjector.isLocationPrefetchEnabled();
         mUseMotionSensor = mInjector.useMotionSensor();
     }
 
@@ -2602,8 +2610,7 @@
                     mMotionSensor = mInjector.getMotionSensor();
                 }
 
-                if (getContext().getResources().getBoolean(
-                        com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
+                if (mIsLocationPrefetchEnabled) {
                     mLocationRequest = new LocationRequest.Builder(/*intervalMillis=*/ 0)
                         .setQuality(LocationRequest.QUALITY_HIGH_ACCURACY)
                         .setMaxUpdates(1)
@@ -3779,34 +3786,40 @@
             case STATE_SENSING:
                 cancelSensingTimeoutAlarmLocked();
                 moveToStateLocked(STATE_LOCATING, reason);
-                scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT);
-                LocationManager locationManager = mInjector.getLocationManager();
-                if (locationManager != null
-                        && locationManager.getProvider(LocationManager.FUSED_PROVIDER) != null) {
-                    locationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER,
-                            mLocationRequest,
-                            AppSchedulingModuleThread.getExecutor(),
-                            mGenericLocationListener);
-                    mLocating = true;
+                if (mIsLocationPrefetchEnabled) {
+                    scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT);
+                    LocationManager locationManager = mInjector.getLocationManager();
+                    if (locationManager != null
+                            && locationManager.getProvider(LocationManager.FUSED_PROVIDER)
+                                    != null) {
+                        locationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER,
+                                mLocationRequest,
+                                AppSchedulingModuleThread.getExecutor(),
+                                mGenericLocationListener);
+                        mLocating = true;
+                    } else {
+                        mHasFusedLocation = false;
+                    }
+                    if (locationManager != null
+                            && locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
+                        mHasGps = true;
+                        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+                                1000, 5, mGpsLocationListener, mHandler.getLooper());
+                        mLocating = true;
+                    } else {
+                        mHasGps = false;
+                    }
+                    // If we have a location provider, we're all set, the listeners will move state
+                    // forward.
+                    if (mLocating) {
+                        break;
+                    }
+                    // Otherwise, we have to move from locating into idle maintenance.
                 } else {
-                    mHasFusedLocation = false;
-                }
-                if (locationManager != null
-                        && locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
-                    mHasGps = true;
-                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
-                            mGpsLocationListener, mHandler.getLooper());
-                    mLocating = true;
-                } else {
-                    mHasGps = false;
-                }
-                // If we have a location provider, we're all set, the listeners will move state
-                // forward.
-                if (mLocating) {
-                    break;
+                    mLocating = false;
                 }
 
-                // Otherwise, we have to move from locating into idle maintenance.
+                // We're not doing any locating work, so move on to the next state.
             case STATE_LOCATING:
                 cancelAlarmLocked();
                 cancelLocatingLocked();
@@ -5303,15 +5316,19 @@
                 pw.print("  "); pw.print(mStationaryListeners.size());
                 pw.println(" stationary listeners registered");
             }
-            pw.print("  mLocating="); pw.print(mLocating);
-            pw.print(" mHasGps="); pw.print(mHasGps);
-            pw.print(" mHasFused="); pw.print(mHasFusedLocation);
-            pw.print(" mLocated="); pw.println(mLocated);
-            if (mLastGenericLocation != null) {
-                pw.print("  mLastGenericLocation="); pw.println(mLastGenericLocation);
-            }
-            if (mLastGpsLocation != null) {
-                pw.print("  mLastGpsLocation="); pw.println(mLastGpsLocation);
+            if (mIsLocationPrefetchEnabled) {
+                pw.print("  mLocating="); pw.print(mLocating);
+                pw.print(" mHasGps="); pw.print(mHasGps);
+                pw.print(" mHasFused="); pw.print(mHasFusedLocation);
+                pw.print(" mLocated="); pw.println(mLocated);
+                if (mLastGenericLocation != null) {
+                    pw.print("  mLastGenericLocation="); pw.println(mLastGenericLocation);
+                }
+                if (mLastGpsLocation != null) {
+                    pw.print("  mLastGpsLocation="); pw.println(mLastGpsLocation);
+                }
+            } else {
+                pw.println("  Location prefetching disabled");
             }
             pw.print("  mState="); pw.print(stateToString(mState));
             pw.print(" mLightState=");
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
index 430a1e2..4d646de 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
@@ -292,6 +292,10 @@
                 return "permission";
             case EXACT_ALLOW_REASON_POLICY_PERMISSION:
                 return "policy_permission";
+            case EXACT_ALLOW_REASON_LISTENER:
+                return "listener";
+            case EXACT_ALLOW_REASON_PRIORITIZED:
+                return "prioritized";
             case EXACT_ALLOW_REASON_NOT_APPLICABLE:
                 return "N/A";
             default:
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 577260e..8a4b464 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1560,7 +1560,8 @@
                     jobStatus.getJob().getMinLatencyMillis(),
                     jobStatus.getEstimatedNetworkDownloadBytes(),
                     jobStatus.getEstimatedNetworkUploadBytes(),
-                    jobStatus.getWorkCount());
+                    jobStatus.getWorkCount(),
+                    ActivityManager.processStateAmToProto(mUidProcStates.get(jobStatus.getUid())));
 
             // If the job is immediately ready to run, then we can just immediately
             // put it in the pending list and try to schedule it.  This is especially
@@ -1935,6 +1936,7 @@
      * {@code incomingJob} is non-null, it replaces {@code cancelled} in the store of
      * currently scheduled jobs.
      */
+    @GuardedBy("mLock")
     private void cancelJobImplLocked(JobStatus cancelled, JobStatus incomingJob,
             @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
         if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
@@ -1986,7 +1988,8 @@
                     cancelled.getJob().getMinLatencyMillis(),
                     cancelled.getEstimatedNetworkDownloadBytes(),
                     cancelled.getEstimatedNetworkUploadBytes(),
-                    cancelled.getWorkCount());
+                    cancelled.getWorkCount(),
+                    ActivityManager.processStateAmToProto(mUidProcStates.get(cancelled.getUid())));
         }
         // If this is a replacement, bring in the new version of the job
         if (incomingJob != null) {
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 fb36cde..f95df44 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -25,6 +25,7 @@
 import android.annotation.BytesLong;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.Notification;
 import android.app.compat.CompatChanges;
@@ -476,7 +477,8 @@
                     job.getJob().getMinLatencyMillis(),
                     job.getEstimatedNetworkDownloadBytes(),
                     job.getEstimatedNetworkUploadBytes(),
-                    job.getWorkCount());
+                    job.getWorkCount(),
+                    ActivityManager.processStateAmToProto(mService.getUidProcState(job.getUid())));
             final String sourcePackage = job.getSourcePackageName();
             if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
                 final String componentPackage = job.getServiceComponent().getPackageName();
@@ -1447,7 +1449,9 @@
                 completedJob.getJob().getMinLatencyMillis(),
                 completedJob.getEstimatedNetworkDownloadBytes(),
                 completedJob.getEstimatedNetworkUploadBytes(),
-                completedJob.getWorkCount());
+                completedJob.getWorkCount(),
+                ActivityManager
+                        .processStateAmToProto(mService.getUidProcState(completedJob.getUid())));
         if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
             Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_SYSTEM_SERVER, "JobScheduler",
                     getId());
diff --git a/config/dirty-image-objects b/config/dirty-image-objects
index dfd091c..2584610e 100644
--- a/config/dirty-image-objects
+++ b/config/dirty-image-objects
@@ -28,359 +28,270 @@
 # Then, grep for lines containing "Private dirty object" from the output.
 # This particular file was generated by dumping systemserver and systemui.
 #
-Landroid/accounts/Account;
-Landroid/accounts/OnAccountsUpdateListener;
 Landroid/animation/LayoutTransition;
 Landroid/app/ActivityManager;
-Landroid/app/ActivityManager$OnUidImportanceListener;
 Landroid/app/ActivityTaskManager;
 Landroid/app/ActivityThread;
-Landroid/app/admin/DevicePolicyManager;
 Landroid/app/AlarmManager;
-Landroid/app/Application;
 Landroid/app/AppOpsManager;
-Landroid/app/backup/BackupManager;
 Landroid/app/ContextImpl;
-Landroid/app/INotificationManager;
-Landroid/app/Notification$BigPictureStyle;
-Landroid/app/Notification$BigTextStyle;
-Landroid/app/Notification$InboxStyle;
-Landroid/app/NotificationChannel;
-Landroid/app/NotificationChannelGroup;
+Landroid/app/Notification;
 Landroid/app/NotificationManager;
-Landroid/app/PendingIntent;
-Landroid/app/PendingIntent$OnFinished;
+Landroid/app/PendingIntent$FinishedDispatcher;
+Landroid/app/PropertyInvalidatedCache$NoPreloadHolder;
 Landroid/app/QueuedWork;
 Landroid/app/ResourcesManager;
+Landroid/app/SystemServiceRegistry;
 Landroid/app/WallpaperManager;
-Landroid/app/WindowConfiguration;
-Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/BluetoothProfile;
-Landroid/bluetooth/IBluetoothA2dp;
-Landroid/bluetooth/IBluetoothHeadsetPhone;
-Landroid/bluetooth/IBluetoothHidDevice;
-Landroid/bluetooth/IBluetoothHidHost;
-Landroid/bluetooth/IBluetoothMap;
-Landroid/bluetooth/IBluetoothPan;
-Landroid/bluetooth/IBluetoothPbap;
-Landroid/bluetooth/IBluetoothSap;
-Landroid/content/ClipboardManager$OnPrimaryClipChangedListener;
-Landroid/content/ComponentName;
-Landroid/content/ContentProvider$PipeDataWriter;
+Landroid/app/backup/BackupManager;
+Landroid/compat/Compatibility;
+Landroid/content/AsyncQueryHandler;
+Landroid/content/ContentProviderClient;
 Landroid/content/ContentResolver;
 Landroid/content/Context;
-Landroid/content/Intent;
-Landroid/content/pm/PackageManager$OnPermissionsChangedListener;
-Landroid/content/pm/VersionedPackage;
-Landroid/content/res/Configuration;
-Landroid/content/SharedPreferences$OnSharedPreferenceChangeListener;
+Landroid/content/pm/PackageItemInfo;
+Landroid/content/pm/UserPackage;
+Landroid/content/res/ResourceTimer;
 Landroid/database/CursorWindow;
 Landroid/database/sqlite/SQLiteCompatibilityWalFlags;
-Landroid/database/sqlite/SQLiteDatabase$CursorFactory;
+Landroid/database/sqlite/SQLiteDebug$NoPreloadHolder;
 Landroid/database/sqlite/SQLiteGlobal;
-Landroid/database/sqlite/SQLiteTransactionListener;
 Landroid/ddm/DdmHandleAppName;
 Landroid/graphics/Bitmap;
 Landroid/graphics/Canvas;
-Landroid/graphics/drawable/AdaptiveIconDrawable;
-Landroid/graphics/drawable/ColorDrawable;
-Landroid/graphics/drawable/GradientDrawable;
-Landroid/graphics/drawable/Icon;
-Landroid/graphics/drawable/InsetDrawable;
-Landroid/graphics/drawable/RippleDrawable;
-Landroid/graphics/drawable/VectorDrawable$VGroup;
-Landroid/graphics/ImageDecoder;
-Landroid/graphics/Rect;
+Landroid/graphics/Compatibility;
+Landroid/graphics/HardwareRenderer;
 Landroid/graphics/TemporaryBuffer;
-Landroid/hardware/biometrics/BiometricSourceType;
-Landroid/hardware/display/ColorDisplayManager$ColorDisplayManagerInternal;
-Landroid/hardware/display/DisplayManagerGlobal;
-Landroid/hardware/display/NightDisplayListener$Callback;
-Landroid/hardware/input/InputManager;
-Landroid/hardware/input/InputManager$InputDeviceListener;
+Landroid/graphics/Typeface;
+Landroid/graphics/drawable/AdaptiveIconDrawable;
 Landroid/hardware/SensorPrivacyManager;
 Landroid/hardware/SystemSensorManager;
-Landroid/icu/impl/OlsonTimeZone;
-Landroid/icu/text/BreakIterator;
+Landroid/hardware/devicestate/DeviceStateManagerGlobal;
+Landroid/hardware/display/ColorDisplayManager$ColorDisplayManagerInternal;
+Landroid/hardware/display/DisplayManagerGlobal;
+Landroid/hardware/input/InputManagerGlobal;
+Landroid/hardware/location/GeofenceHardwareImpl;
+Landroid/icu/impl/number/range/StandardPluralRanges;
 Landroid/icu/text/Collator;
-Landroid/icu/text/DateFormat$BooleanAttribute;
-Landroid/icu/text/DateTimePatternGenerator$DTPGflags;
-Landroid/icu/text/PluralRules$Operand;
 Landroid/icu/util/TimeZone;
-Landroid/location/GpsStatus$Listener;
-Landroid/location/LocationListener;
+Landroid/location/LocationManager;
 Landroid/media/AudioManager;
+Landroid/media/AudioPlaybackConfiguration;
+Landroid/media/AudioSystem;
+Landroid/media/MediaCodec;
+Landroid/media/MediaCodecList;
+Landroid/media/MediaFrameworkPlatformInitializer;
+Landroid/media/MediaRouter2Manager;
 Landroid/media/MediaRouter;
 Landroid/media/PlayerBase;
-Landroid/media/session/MediaSessionManager;
-Landroid/net/apf/ApfCapabilities;
-Landroid/net/ConnectivityManager;
-Landroid/net/ConnectivityManager$OnNetworkActiveListener;
-Landroid/net/ConnectivityThread$Singleton;
-Landroid/net/IpConfiguration$IpAssignment;
-Landroid/net/IpConfiguration$ProxySettings;
-Landroid/net/IpPrefix;
-Landroid/net/LinkAddress;
-Landroid/net/LinkProperties;
-Landroid/net/Network;
-Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkInfo;
-Landroid/net/NetworkInfo$State;
-Landroid/net/NetworkRequest;
-Landroid/net/NetworkRequest$Type;
-Landroid/net/RouteInfo;
-Landroid/net/StringNetworkSpecifier;
-Landroid/net/TrafficStats;
-Landroid/net/UidRange;
-Landroid/net/Uri$HierarchicalUri;
-Landroid/net/Uri$StringUri;
-Landroid/net/wifi/WifiManager;
-Landroid/net/wifi/WifiManager$SoftApCallback;
-Landroid/os/AsyncResult;
+Landroid/media/audiopolicy/AudioProductStrategy;
+Landroid/media/audiopolicy/AudioVolumeGroup;
+Landroid/nfc/NfcAdapter;
+Landroid/nfc/NfcFrameworkInitializer;
+Landroid/nfc/cardemulation/CardEmulation;
 Landroid/os/AsyncTask;
+Landroid/os/BaseBundle;
+Landroid/os/Binder;
 Landroid/os/BinderProxy;
-Landroid/os/Bundle;
-Landroid/os/DeadObjectException;
 Landroid/os/Environment;
 Landroid/os/FileObserver;
 Landroid/os/Handler;
-Landroid/os/IDeviceIdleController;
 Landroid/os/LocaleList;
 Landroid/os/Looper;
 Landroid/os/Message;
-Landroid/os/ParcelUuid;
+Landroid/os/NullVibrator;
+Landroid/os/Parcel;
 Landroid/os/Process;
-Landroid/os/RecoverySystem;
 Landroid/os/ServiceManager;
-Landroid/os/storage/StorageManager;
 Landroid/os/StrictMode;
-Landroid/os/Trace;
+Landroid/os/UEventObserver;
+Landroid/os/UserManager;
 Landroid/os/WorkSource;
-Landroid/os/WorkSource$WorkChain;
+Landroid/os/storage/StorageManager;
 Landroid/permission/PermissionManager;
+Landroid/provider/DeviceConfigInitializer;
 Landroid/provider/FontsContract;
-Landroid/provider/Settings$SettingNotFoundException;
+Landroid/provider/Settings;
+Landroid/renderscript/RenderScript;
 Landroid/renderscript/RenderScriptCacheDir;
-Landroid/security/IKeyChainService;
-Landroid/security/keystore/AndroidKeyStoreProvider;
+Landroid/security/keystore2/KeyStoreCryptoOperationUtils;
 Landroid/security/net/config/ApplicationConfig;
 Landroid/security/net/config/SystemCertificateSource$NoPreloadHolder;
-Landroid/telecom/PhoneAccountHandle;
+Landroid/security/net/config/UserCertificateSource$NoPreloadHolder;
+Landroid/telecom/Log;
+Landroid/telecom/TelecomManager;
 Landroid/telephony/AnomalyReporter;
-Landroid/telephony/CellSignalStrengthCdma;
-Landroid/telephony/CellSignalStrengthGsm;
-Landroid/telephony/CellSignalStrengthLte;
-Landroid/telephony/CellSignalStrengthNr;
-Landroid/telephony/CellSignalStrengthTdscdma;
-Landroid/telephony/CellSignalStrengthWcdma;
-Landroid/telephony/DataSpecificRegistrationInfo;
-Landroid/telephony/emergency/EmergencyNumber;
-Landroid/telephony/ims/ImsMmTelManager$CapabilityCallback$CapabilityBinder;
-Landroid/telephony/ims/ImsMmTelManager$RegistrationCallback$RegistrationBinder;
-Landroid/telephony/ims/ImsReasonInfo;
-Landroid/telephony/ims/ProvisioningManager$Callback$CallbackBinder;
-Landroid/telephony/ModemActivityInfo;
-Landroid/telephony/ModemInfo;
-Landroid/telephony/NetworkRegistrationInfo;
-Landroid/telephony/NetworkService;
+Landroid/telephony/TelephonyFrameworkInitializer;
+Landroid/telephony/TelephonyLocalConnection;
 Landroid/telephony/TelephonyManager;
-Landroid/telephony/VoiceSpecificRegistrationInfo;
-Landroid/text/format/DateFormat;
-Landroid/text/method/SingleLineTransformationMethod;
-Landroid/text/Selection$MemoryTextWatcher;
-Landroid/text/SpanWatcher;
-Landroid/text/style/AlignmentSpan;
-Landroid/text/style/CharacterStyle;
-Landroid/text/style/LeadingMarginSpan;
-Landroid/text/style/LineBackgroundSpan;
-Landroid/text/style/LineHeightSpan;
-Landroid/text/style/MetricAffectingSpan;
-Landroid/text/style/ReplacementSpan;
-Landroid/text/style/SuggestionSpan;
-Landroid/text/style/TabStopSpan;
+Landroid/telephony/TelephonyRegistryManager;
+Landroid/text/DynamicLayout;
 Landroid/text/TextUtils;
-Landroid/text/TextWatcher;
-Landroid/transition/ChangeClipBounds;
-Landroid/transition/ChangeImageTransform;
-Landroid/transition/ChangeTransform;
+Landroid/text/format/DateFormat;
+Landroid/text/format/DateUtils;
+Landroid/text/method/ArrowKeyMovementMethod;
+Landroid/text/method/LinkMovementMethod;
+Landroid/text/method/SingleLineTransformationMethod;
+Landroid/text/style/ClickableSpan;
+Landroid/timezone/TelephonyLookup;
+Landroid/timezone/TimeZoneFinder;
 Landroid/util/ArrayMap;
 Landroid/util/ArraySet;
-Landroid/util/DisplayMetrics;
 Landroid/util/EventLog;
-Landroid/util/Log;
-Landroid/util/Patterns;
-Landroid/view/AbsSavedState$1;
-Landroid/view/accessibility/AccessibilityManager;
-Landroid/view/accessibility/AccessibilityManager$AccessibilityServicesStateChangeListener;
-Landroid/view/accessibility/AccessibilityManager$TouchExplorationStateChangeListener;
-Landroid/view/accessibility/AccessibilityNodeIdManager;
-Landroid/view/autofill/AutofillManager;
-Landroid/view/autofill/Helper;
+Landroid/util/NtpTrustedTime;
 Landroid/view/Choreographer;
-Landroid/view/inputmethod/InputMethodManager;
-Landroid/view/IWindowManager;
+Landroid/view/CrossWindowBlurListeners;
+Landroid/view/DisplayCutout;
+Landroid/view/KeyEvent;
+Landroid/view/MotionEvent;
 Landroid/view/PointerIcon;
-Landroid/view/RemoteAnimationAdapter;
-Landroid/view/ThreadedRenderer;
+Landroid/view/RoundedCorners;
+Landroid/view/SurfaceControl;
 Landroid/view/View;
-Landroid/view/View$OnHoverListener;
+Landroid/view/ViewGroup$TouchTarget;
 Landroid/view/ViewRootImpl;
-Landroid/view/ViewStub;
-Landroid/view/ViewStub$OnInflateListener;
 Landroid/view/ViewTreeObserver;
-Landroid/view/WindowManager$LayoutParams;
 Landroid/view/WindowManagerGlobal;
-Landroid/widget/ActionMenuPresenter$OverflowMenuButton;
-Landroid/widget/ActionMenuView;
-Landroid/widget/Button;
-Landroid/widget/CheckBox;
-Landroid/widget/FrameLayout;
-Landroid/widget/ImageButton;
+Landroid/view/accessibility/AccessibilityManager;
+Landroid/view/accessibility/AccessibilityNodeIdManager;
+Landroid/view/autofill/Helper;
+Landroid/view/inputmethod/IInputMethodManagerGlobalInvoker;
+Landroid/view/inputmethod/InputMethodManager;
+Landroid/webkit/CookieSyncManager;
+Landroid/webkit/WebView;
+Landroid/webkit/WebViewFactory;
+Landroid/webkit/WebViewZygote;
+Landroid/widget/AbsListView;
 Landroid/widget/ImageView;
 Landroid/widget/LinearLayout;
-Landroid/widget/RelativeLayout;
-Landroid/widget/SeekBar;
-Landroid/widget/Space;
-Landroid/widget/TextView;
-Landroid/widget/Toolbar;
-[B
-Lcom/android/ims/ImsManager;
+Landroid/widget/Toast;
+Landroid/window/SurfaceSyncGroup;
+Lcom/android/i18n/timezone/TelephonyLookup;
+Lcom/android/i18n/timezone/TimeZoneFinder;
+Lcom/android/internal/config/appcloning/AppCloningDeviceConfigHelper;
+Lcom/android/internal/content/om/OverlayConfig;
+Lcom/android/internal/display/BrightnessSynchronizer;
+Lcom/android/internal/infra/AndroidFuture;
+Lcom/android/internal/inputmethod/ImeTracing;
+Lcom/android/internal/inputmethod/InputMethodPrivilegedOperationsRegistry;
+Lcom/android/internal/jank/InteractionJankMonitor$InstanceHolder;
+Lcom/android/internal/jank/InteractionJankMonitor;
 Lcom/android/internal/logging/MetricsLogger;
 Lcom/android/internal/os/BackgroundThread;
 Lcom/android/internal/os/BinderInternal;
-Lcom/android/internal/os/BinderInternal$BinderProxyLimitListener;
+Lcom/android/internal/os/KernelCpuBpfTracking;
 Lcom/android/internal/os/RuntimeInit;
 Lcom/android/internal/os/SomeArgs;
-Lcom/android/internal/policy/DecorView;
-Lcom/android/internal/statusbar/IStatusBarService;
-Lcom/android/internal/telephony/AppSmsManager;
-Landroid/telephony/CallerInfoAsyncQuery$OnQueryCompleteListener;
-Lcom/android/internal/telephony/CarrierActionAgent;
-Lcom/android/internal/telephony/cat/CatService;
-Lcom/android/internal/telephony/cat/IconLoader;
-Lcom/android/internal/telephony/cat/RilMessageDecoder;
-Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager;
-Lcom/android/internal/telephony/cdma/EriManager;
-Lcom/android/internal/telephony/CellularNetworkValidator;
-Lcom/android/internal/telephony/CommandException;
-Lcom/android/internal/telephony/dataconnection/DataConnection$DcActivatingState;
-Lcom/android/internal/telephony/dataconnection/DataConnection$DcActiveState;
-Lcom/android/internal/telephony/dataconnection/DataConnection$DcInactiveState;
-Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;
-Lcom/android/internal/telephony/dataconnection/DcTracker;
-Lcom/android/internal/telephony/euicc/EuiccCardController;
-Lcom/android/internal/telephony/euicc/EuiccController;
-Lcom/android/internal/telephony/GsmAlphabet;
-Lcom/android/internal/telephony/GsmCdmaCallTracker;
-Lcom/android/internal/telephony/GsmCdmaPhone;
-Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;
-Lcom/android/internal/telephony/IccSmsInterfaceManager;
-Lcom/android/internal/telephony/ims/ImsResolver;
-Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker;
-Lcom/android/internal/telephony/imsphone/ImsPhone;
-Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;
-Lcom/android/internal/telephony/ims/RcsMessageStoreController;
+Lcom/android/internal/os/ZygoteInit;
+Lcom/android/internal/policy/AttributeCache;
+Lcom/android/internal/protolog/BaseProtoLogImpl;
+Lcom/android/internal/protolog/ProtoLogImpl;
+Lcom/android/internal/statusbar/NotificationVisibility;
+Lcom/android/internal/telephony/CellBroadcastServiceManager;
 Lcom/android/internal/telephony/IntentBroadcaster;
-Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;
-Lcom/android/internal/telephony/metrics/TelephonyMetrics;
+Lcom/android/internal/telephony/MccTable;
 Lcom/android/internal/telephony/MultiSimSettingController;
-Lcom/android/internal/telephony/nano/CarrierIdProto$CarrierAttribute;
-Lcom/android/internal/telephony/nano/CarrierIdProto$CarrierId;
-Lcom/android/internal/telephony/nano/TelephonyProto$RilDataCall;
-Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;
-Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event$RilCall;
-Lcom/android/internal/telephony/NitzStateMachine;
+Lcom/android/internal/telephony/PackageChangeReceiver;
 Lcom/android/internal/telephony/PhoneConfigurationManager;
 Lcom/android/internal/telephony/PhoneFactory;
-Lcom/android/internal/telephony/PhoneSwitcher;
 Lcom/android/internal/telephony/ProxyController;
-Lcom/android/internal/telephony/RadioConfig;
-Lcom/android/internal/telephony/RIL;
 Lcom/android/internal/telephony/RILRequest;
-Lcom/android/internal/telephony/RilWakelockInfo;
-Lcom/android/internal/telephony/ServiceStateTracker;
-Lcom/android/internal/telephony/SimActivationTracker;
+Lcom/android/internal/telephony/RadioConfig;
+Lcom/android/internal/telephony/RadioInterfaceCapabilityController;
 Lcom/android/internal/telephony/SmsApplication;
 Lcom/android/internal/telephony/SmsBroadcastUndelivered;
-Lcom/android/internal/telephony/SmsStorageMonitor;
-Lcom/android/internal/telephony/SmsUsageMonitor;
-Lcom/android/internal/telephony/SubscriptionController;
-Lcom/android/internal/telephony/SubscriptionInfoUpdater;
+Lcom/android/internal/telephony/SomeArgs;
 Lcom/android/internal/telephony/TelephonyComponentFactory;
 Lcom/android/internal/telephony/TelephonyDevController;
-Lcom/android/internal/telephony/TelephonyTester;
-Lcom/android/internal/telephony/uicc/AdnRecordCache;
-Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/cat/CatService;
+Lcom/android/internal/telephony/cdma/CdmaInboundSmsHandler;
+Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager;
+Lcom/android/internal/telephony/euicc/EuiccCardController;
+Lcom/android/internal/telephony/euicc/EuiccController;
+Lcom/android/internal/telephony/ims/ImsResolver;
+Lcom/android/internal/telephony/metrics/TelephonyMetrics;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$CarrierIdMismatch;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularDataServiceSwitch;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularServiceState;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$DataCallSession;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$EmergencyNumbersInfo;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$GbaEvent;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsDedicatedBearerEvent;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsDedicatedBearerListenerEvent;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsRegistrationFeatureTagStats;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsRegistrationServiceDescStats;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsRegistrationStats;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsRegistrationTermination;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$IncomingSms;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$NetworkRequests;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$NetworkRequestsV2;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$OutgoingShortCodeSms;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$OutgoingSms;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$PresenceNotifyEvent;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$RcsAcsProvisioningStats;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$RcsClientProvisioningStats;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SatelliteController;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SatelliteIncomingDatagram;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SatelliteOutgoingDatagram;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SatelliteProvision;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SatelliteSession;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SatelliteSosMessageRecommender;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SipDelegateStats;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SipMessageResponse;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SipTransportFeatureTagStats;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$SipTransportSession;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$UceEventStats;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$UnmeteredNetworks;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$VoiceCallRatUsage;
+Lcom/android/internal/telephony/nano/PersistAtomsProto$VoiceCallSession;
+Lcom/android/internal/telephony/nano/TelephonyProto$RilDataCall;
+Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event$RilCall;
+Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyServiceState$NetworkRegistrationInfo;
+Lcom/android/internal/telephony/satellite/PointingAppController;
+Lcom/android/internal/telephony/satellite/SatelliteModemInterface;
 Lcom/android/internal/telephony/uicc/UiccController;
-Lcom/android/internal/telephony/uicc/UiccProfile;
 Lcom/android/internal/telephony/uicc/UiccStateChangedLauncher;
-Lcom/android/internal/telephony/uicc/UsimFileHandler;
-Lcom/android/internal/telephony/uicc/VoiceMailConstants;
-Lcom/android/internal/util/LatencyTracker;
-Lcom/android/internal/util/StateMachine$SmHandler;
-Lcom/android/okhttp/OkHttpClient;
-Lcom/android/okhttp/okio/AsyncTimeout;
-Lcom/android/okhttp/okio/SegmentPool;
+Lcom/android/internal/util/ContrastColorUtil;
+Lcom/android/internal/view/WindowManagerPolicyThread;
+Lcom/android/org/bouncycastle/crypto/CryptoServicesRegistrar;
 Lcom/android/phone/ecc/nano/ProtobufEccData$CountryInfo;
 Lcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;
-Lcom/android/server/sip/SipWakeupTimer;
-Lcom/android/server/SystemConfig;
+Lcom/android/server/AppWidgetBackupBridge;
 Ldalvik/system/BaseDexClassLoader;
 Ldalvik/system/BlockGuard;
 Ldalvik/system/CloseGuard;
 Ldalvik/system/RuntimeHooks;
 Ldalvik/system/SocketTagger;
-Ljava/io/BufferedReader;
-Ljava/lang/AssertionError;
-Ljava/lang/Boolean;
-Ljava/lang/Byte;
-Ljava/lang/Character;
-Ljava/lang/CharSequence;
-Ljava/lang/Class;
-Ljava/lang/IllegalAccessException;
-Ljava/lang/IllegalStateException;
-Ljava/lang/NoSuchMethodException;
-Ljava/lang/NullPointerException;
-Ljava/lang/Object;
-[Ljava/lang/Object;
-Ljava/lang/ref/FinalizerReference;
-Ljava/lang/Runnable;
-Ljava/lang/SecurityException;
-Ljava/lang/Short;
-[Ljava/lang/String;
+Ldalvik/system/VMRuntime;
+Ldalvik/system/ZipPathValidator;
+Ldalvik/system/ZygoteHooks;
 Ljava/lang/System;
 Ljava/lang/Thread;
 Ljava/lang/Throwable;
-Ljava/lang/UnsatisfiedLinkError;
-Ljava/net/Inet6Address;
-Ljava/net/Socket;
-Ljava/net/SocketException;
+Ljava/lang/ref/FinalizerReference;
+Ljava/lang/ref/ReferenceQueue;
+Ljava/net/ResponseCache;
 Ljava/nio/Bits;
 Ljava/nio/charset/Charset;
-Ljava/security/interfaces/RSAPrivateKey;
 Ljava/security/Provider;
 Ljava/util/Collections;
-Ljava/util/concurrent/Executor;
 Ljava/util/GregorianCalendar;
-Ljava/util/Locale;
 Ljava/util/Locale$NoImagePreloadHolder;
+Ljava/util/Locale;
 Ljava/util/Scanner;
-Ljava/util/Set;
 Ljava/util/TimeZone;
+Ljava/util/concurrent/ForkJoinPool;
+Ljava/util/concurrent/ThreadLocalRandom;
+Ljavax/net/ServerSocketFactory;
 Ljavax/net/SocketFactory;
-Ljavax/net/ssl/HttpsURLConnection;
 Ljavax/net/ssl/HttpsURLConnection$NoPreloadHolder;
+Ljavax/net/ssl/HttpsURLConnection;
 Ljavax/net/ssl/SSLContext;
-Ljavax/net/ssl/SSLSessionContext;
+Ljavax/net/ssl/SSLServerSocketFactory;
 Ljavax/net/ssl/SSLSocketFactory;
 Llibcore/io/Libcore;
-Llibcore/io/Memory;
 Llibcore/net/NetworkSecurityPolicy;
-Llibcore/timezone/TimeZoneFinder;
-Lorg/apache/http/params/HttpParams;
 Lsun/misc/Cleaner;
-Lsun/nio/ch/FileChannelImpl;
 Lsun/nio/ch/FileChannelImpl$Unmapper;
-Lsun/nio/fs/UnixChannelFactory;
+Lsun/nio/ch/FileChannelImpl;
 Lsun/security/jca/Providers;
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index ae63816..d97f718 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -536,6 +536,12 @@
     field @NonNull public static final android.app.admin.DeviceAdminAuthority DEVICE_ADMIN_AUTHORITY;
   }
 
+  public final class DevicePolicyIdentifiers {
+    field public static final String PERMITTED_INPUT_METHODS_POLICY = "permittedInputMethods";
+    field public static final String PERSONAL_APPS_SUSPENDED_POLICY = "personalAppsSuspended";
+    field public static final String SCREEN_CAPTURE_DISABLED_POLICY = "screenCaptureDisabled";
+  }
+
   public class DevicePolicyManager {
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public void acknowledgeNewUserDisclaimer();
     method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void calculateHasIncompatibleAccounts();
@@ -3626,18 +3632,12 @@
   }
 
   public final class AutofillManager {
-    method public void clearAutofillRequestCallback();
-    method @RequiresPermission(android.Manifest.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS) public void setAutofillRequestCallback(@NonNull java.util.concurrent.Executor, @NonNull android.view.autofill.AutofillRequestCallback);
     field public static final String ANY_HINT = "any";
     field public static final int FLAG_SMART_SUGGESTION_OFF = 0; // 0x0
     field public static final int FLAG_SMART_SUGGESTION_SYSTEM = 1; // 0x1
     field public static final int MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS = 120000; // 0x1d4c0
   }
 
-  public interface AutofillRequestCallback {
-    method public void onFillRequest(@Nullable android.view.inputmethod.InlineSuggestionsRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.FillCallback);
-  }
-
 }
 
 package android.view.contentcapture {
@@ -3761,11 +3761,6 @@
     method @NonNull public static android.view.inputmethod.InlineSuggestionInfo newInlineSuggestionInfo(@NonNull android.widget.inline.InlinePresentationSpec, @NonNull String, @Nullable String[], @NonNull String, boolean);
   }
 
-  public static final class InlineSuggestionsRequest.Builder {
-    method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder setClientSupported(boolean);
-    method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder setServiceSupported(boolean);
-  }
-
   public final class InlineSuggestionsResponse implements android.os.Parcelable {
     method @NonNull public static android.view.inputmethod.InlineSuggestionsResponse newInlineSuggestionsResponse(@NonNull java.util.List<android.view.inputmethod.InlineSuggestion>);
   }
@@ -3783,6 +3778,7 @@
     method @NonNull @RequiresPermission(value=android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional=true) public java.util.List<android.view.inputmethod.InputMethodInfo> getInputMethodListAsUser(int);
     method public boolean hasActiveInputConnection(@Nullable android.view.View);
     method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean hasPendingImeVisibilityRequests();
+    method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean isCurrentRootView(@NonNull android.view.View);
     method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean isInputMethodPickerShown();
     method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public void setStylusWindowIdleTimeoutForTest(long);
     field public static final long CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING = 214016041L; // 0xcc1a029L
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 61d6787..2ae7216 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -403,8 +403,11 @@
     private static final String KEY_SPLASH_SCREEN_STYLE =
             "android.activity.splashScreenStyle";
 
-    /** See {@link #setTransientLaunch()}. */
-    private static final String KEY_TRANSIENT_LAUNCH = "android.activity.transientLaunch";
+    /**
+     * See {@link #setTransientLaunch()}.
+     * @hide
+     */
+    public static final String KEY_TRANSIENT_LAUNCH = "android.activity.transientLaunch";
 
     /** see {@link #makeLaunchIntoPip(PictureInPictureParams)}. */
     private static final String KEY_LAUNCH_INTO_PIP_PARAMS =
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 3312294..9e59ee4 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2547,7 +2547,7 @@
             .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
         new AppOpInfo.Builder(OP_TURN_SCREEN_ON, OPSTR_TURN_SCREEN_ON, "TURN_SCREEN_ON")
             .setPermission(Manifest.permission.TURN_SCREEN_ON)
-            .setDefaultMode(AppOpsManager.MODE_ERRORED).build(),
+            .setDefaultMode(AppOpsManager.MODE_DEFAULT).build(),
         new AppOpInfo.Builder(OP_GET_ACCOUNTS, OPSTR_GET_ACCOUNTS, "GET_ACCOUNTS")
             .setPermission(Manifest.permission.GET_ACCOUNTS)
             .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 36e5762..3c6ff28 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -137,7 +137,7 @@
      * activities inside it belong to a managed profile user, and that user has just
      * been locked.
      */
-    void onTaskProfileLocked(in ActivityManager.RunningTaskInfo taskInfo);
+    void onTaskProfileLocked(in ActivityManager.RunningTaskInfo taskInfo, int userId);
 
     /**
      * Called when a task snapshot got updated.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index d375760..67226d0 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6994,7 +6994,7 @@
      */
     public boolean isColorized() {
         return extras.getBoolean(EXTRA_COLORIZED)
-                && (hasColorizedPermission() || isForegroundService());
+                && (hasColorizedPermission() || isFgsOrUij());
     }
 
     /**
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 746dcb6..d8cedb8 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -44,6 +44,7 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlSerializer;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -246,6 +247,7 @@
     private boolean mBypassDnd;
     private int mLockscreenVisibility = DEFAULT_VISIBILITY;
     private Uri mSound = Settings.System.DEFAULT_NOTIFICATION_URI;
+    private boolean mSoundRestored = false;
     private boolean mLights;
     private int mLightColor = DEFAULT_LIGHT_COLOR;
     private long[] mVibration;
@@ -929,8 +931,9 @@
     /**
      * @hide
      */
-    public void populateFromXmlForRestore(XmlPullParser parser, Context context) {
-        populateFromXml(XmlUtils.makeTyped(parser), true, context);
+    public void populateFromXmlForRestore(XmlPullParser parser, boolean pkgInstalled,
+            Context context) {
+        populateFromXml(XmlUtils.makeTyped(parser), true, pkgInstalled, context);
     }
 
     /**
@@ -938,14 +941,14 @@
      */
     @SystemApi
     public void populateFromXml(XmlPullParser parser) {
-        populateFromXml(XmlUtils.makeTyped(parser), false, null);
+        populateFromXml(XmlUtils.makeTyped(parser), false, true, null);
     }
 
     /**
      * If {@param forRestore} is true, {@param Context} MUST be non-null.
      */
     private void populateFromXml(TypedXmlPullParser parser, boolean forRestore,
-            @Nullable Context context) {
+            boolean pkgInstalled, @Nullable Context context) {
         Preconditions.checkArgument(!forRestore || context != null,
                 "forRestore is true but got null context");
 
@@ -956,7 +959,8 @@
         setLockscreenVisibility(safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY));
 
         Uri sound = safeUri(parser, ATT_SOUND);
-        setSound(forRestore ? restoreSoundUri(context, sound) : sound, safeAudioAttributes(parser));
+        setSound(forRestore ? restoreSoundUri(context, sound, pkgInstalled) : sound,
+                safeAudioAttributes(parser));
 
         enableLights(safeBool(parser, ATT_LIGHTS, false));
         setLightColor(safeInt(parser, ATT_LIGHT_COLOR, DEFAULT_LIGHT_COLOR));
@@ -978,8 +982,58 @@
         setImportantConversation(safeBool(parser, ATT_IMP_CONVERSATION, false));
     }
 
+    /**
+     * Returns whether the sound for this channel was successfully restored
+     *  from backup.
+     * @return false if the sound was not restored successfully. true otherwise (default value)
+     * @hide
+     */
+    public boolean isSoundRestored() {
+        return mSoundRestored;
+    }
+
     @Nullable
-    private Uri restoreSoundUri(Context context, @Nullable Uri uri) {
+    private Uri getCanonicalizedSoundUri(ContentResolver contentResolver, @NonNull Uri uri) {
+        if (Settings.System.DEFAULT_NOTIFICATION_URI.equals(uri)) {
+            return uri;
+        }
+
+        if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
+            try {
+                contentResolver.getResourceId(uri);
+                return uri;
+            } catch (FileNotFoundException e) {
+                return null;
+            }
+        }
+
+        if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
+            return uri;
+        }
+
+        return contentResolver.canonicalize(uri);
+    }
+
+    @Nullable
+    private Uri getUncanonicalizedSoundUri(ContentResolver contentResolver, @NonNull Uri uri) {
+        if (Settings.System.DEFAULT_NOTIFICATION_URI.equals(uri)
+                || ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())
+                || ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
+            return uri;
+        }
+        return contentResolver.uncanonicalize(uri);
+    }
+
+    /**
+     * Restore/validate sound Uri from backup
+     * @param context The Context
+     * @param uri The sound Uri to restore
+     * @param pkgInstalled If the parent package is installed
+     * @return restored and validated Uri
+     * @hide
+     */
+    @Nullable
+    public Uri restoreSoundUri(Context context, @Nullable Uri uri, boolean pkgInstalled) {
         if (uri == null || Uri.EMPTY.equals(uri)) {
             return null;
         }
@@ -991,12 +1045,22 @@
         // the uri and in the case of not having the resource we end up with the default - better
         // than broken. As a side effect we'll canonicalize already canonicalized uris, this is fine
         // according to the docs because canonicalize method has to handle canonical uris as well.
-        Uri canonicalizedUri = contentResolver.canonicalize(uri);
+        Uri canonicalizedUri = getCanonicalizedSoundUri(contentResolver, uri);
         if (canonicalizedUri == null) {
-            // We got a null because the uri in the backup does not exist here, so we return default
-            return Settings.System.DEFAULT_NOTIFICATION_URI;
+            // Uri failed to restore with package installed
+            if (!mSoundRestored && pkgInstalled) {
+                mSoundRestored = true;
+                // We got a null because the uri in the backup does not exist here, so we return
+                // default
+                return Settings.System.DEFAULT_NOTIFICATION_URI;
+            } else {
+                // Flag as unrestored and try again later (on package install)
+                mSoundRestored = false;
+                return uri;
+            }
         }
-        return contentResolver.uncanonicalize(canonicalizedUri);
+        mSoundRestored = true;
+        return getUncanonicalizedSoundUri(contentResolver, canonicalizedUri);
     }
 
     /**
@@ -1019,7 +1083,7 @@
         if (sound == null || Uri.EMPTY.equals(sound)) {
             return null;
         }
-        Uri canonicalSound = context.getContentResolver().canonicalize(sound);
+        Uri canonicalSound = getCanonicalizedSoundUri(context.getContentResolver(), sound);
         if (canonicalSound == null) {
             // The content provider does not support canonical uris so we backup the default
             return Settings.System.DEFAULT_NOTIFICATION_URI;
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 99a7fa2..705b5ee 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -407,7 +407,7 @@
     }
 
     private static void checkPendingIntent(int flags, @NonNull Intent intent,
-            @NonNull Context context) {
+            @NonNull Context context, boolean isActivityResultType) {
         final boolean isFlagImmutableSet = (flags & PendingIntent.FLAG_IMMUTABLE) != 0;
         final boolean isFlagMutableSet = (flags & PendingIntent.FLAG_MUTABLE) != 0;
         final String packageName = context.getPackageName();
@@ -428,11 +428,12 @@
                 throw new IllegalArgumentException(msg);
         }
 
-        // For apps with target SDK < U, warn that creation or retrieval of a mutable
-        // implicit PendingIntent will be blocked from target SDK U onwards for security
-        // reasons. The block itself happens on the server side, but this warning has to
-        // stay here to preserve the client side stack trace for app developers.
-        if (isNewMutableDisallowedImplicitPendingIntent(flags, intent)
+        // For apps with target SDK < U, warn that creation or retrieval of a mutable implicit
+        // PendingIntent that is not of type {@link ActivityManager#INTENT_SENDER_ACTIVITY_RESULT}
+        // will be blocked from target SDK U onwards for security reasons. The block itself
+        // happens on the server side, but this warning has to stay here to preserve the client
+        // side stack trace for app developers.
+        if (isNewMutableDisallowedImplicitPendingIntent(flags, intent, isActivityResultType)
                 && !Compatibility.isChangeEnabled(BLOCK_MUTABLE_IMPLICIT_PENDING_INTENT)) {
             String msg = "New mutable implicit PendingIntent: pkg=" + packageName
                     + ", action=" + intent.getAction()
@@ -445,7 +446,13 @@
 
     /** @hide */
     public static boolean isNewMutableDisallowedImplicitPendingIntent(int flags,
-            @NonNull Intent intent) {
+            @NonNull Intent intent, boolean isActivityResultType) {
+        if (isActivityResultType) {
+            // Pending intents of type {@link ActivityManager#INTENT_SENDER_ACTIVITY_RESULT}
+            // should be ignored as they are intrinsically tied to a target which means they
+            // are already explicit.
+            return false;
+        }
         boolean isFlagNoCreateSet = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
         boolean isFlagMutableSet = (flags & PendingIntent.FLAG_MUTABLE) != 0;
         boolean isImplicit = (intent.getComponent() == null) && (intent.getPackage() == null);
@@ -534,7 +541,7 @@
             @NonNull Intent intent, int flags, Bundle options, UserHandle user) {
         String packageName = context.getPackageName();
         String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver());
-        checkPendingIntent(flags, intent, context);
+        checkPendingIntent(flags, intent, context, /* isActivityResultType */ false);
         try {
             intent.migrateExtraStreamToClipData(context);
             intent.prepareToLeaveProcess(context);
@@ -668,7 +675,7 @@
             intents[i].migrateExtraStreamToClipData(context);
             intents[i].prepareToLeaveProcess(context);
             resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
-            checkPendingIntent(flags, intents[i], context);
+            checkPendingIntent(flags, intents[i], context, /* isActivityResultType */ false);
         }
         try {
             IIntentSender target =
@@ -721,7 +728,7 @@
             Intent intent, int flags, UserHandle userHandle) {
         String packageName = context.getPackageName();
         String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver());
-        checkPendingIntent(flags, intent, context);
+        checkPendingIntent(flags, intent, context, /* isActivityResultType */ false);
         try {
             intent.prepareToLeaveProcess(context);
             IIntentSender target =
@@ -800,7 +807,7 @@
             Intent intent, int flags, int serviceKind) {
         String packageName = context.getPackageName();
         String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver());
-        checkPendingIntent(flags, intent, context);
+        checkPendingIntent(flags, intent, context, /* isActivityResultType */ false);
         try {
             intent.prepareToLeaveProcess(context);
             IIntentSender target =
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 774bc06..0290cee 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -154,8 +154,18 @@
     }
 
     @Override
+    public void onTaskProfileLocked(RunningTaskInfo taskInfo, int userId)
+            throws RemoteException {
+        onTaskProfileLocked(taskInfo);
+    }
+
+    /**
+     * @deprecated see {@link #onTaskProfileLocked(RunningTaskInfo, int)}
+     */
+    @Deprecated
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public void onTaskProfileLocked(RunningTaskInfo taskInfo) throws RemoteException {
+    public void onTaskProfileLocked(RunningTaskInfo taskInfo)
+            throws RemoteException {
     }
 
     @Override
diff --git a/core/java/android/app/admin/DevicePolicyCache.java b/core/java/android/app/admin/DevicePolicyCache.java
index b6e83c8..29f657e 100644
--- a/core/java/android/app/admin/DevicePolicyCache.java
+++ b/core/java/android/app/admin/DevicePolicyCache.java
@@ -19,8 +19,8 @@
 
 import com.android.server.LocalServices;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Collections;
+import java.util.Map;
 
 /**
  * Stores a copy of the set of device policies maintained by {@link DevicePolicyManager} that
@@ -64,10 +64,11 @@
     public abstract boolean canAdminGrantSensorsPermissions();
 
     /**
-     * Returns a list of package names for which all launcher shortcuts should be modified to be
-     * launched in the managed profile and badged accordingly.
+     * Returns a map of package names to package names, for which all launcher shortcuts which
+     * match a key package name should be modified to launch the corresponding value package
+     * name in the managed profile. The overridden shortcut should be badged accordingly.
      */
-    public abstract List<String> getLauncherShortcutOverrides();
+    public abstract Map<String, String> getLauncherShortcutOverrides();
 
     /**
      * Empty implementation.
@@ -95,8 +96,8 @@
             return false;
         }
         @Override
-        public List<String> getLauncherShortcutOverrides() {
-            return new ArrayList<>();
+        public Map<String, String>  getLauncherShortcutOverrides() {
+            return Collections.EMPTY_MAP;
         }
     }
 }
diff --git a/core/java/android/app/admin/DevicePolicyIdentifiers.java b/core/java/android/app/admin/DevicePolicyIdentifiers.java
index 9b0a70d..aeac59b 100644
--- a/core/java/android/app/admin/DevicePolicyIdentifiers.java
+++ b/core/java/android/app/admin/DevicePolicyIdentifiers.java
@@ -17,6 +17,7 @@
 package android.app.admin;
 
 import android.annotation.NonNull;
+import android.annotation.TestApi;
 import android.os.UserManager;
 
 import java.util.Objects;
@@ -118,6 +119,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final String PERMITTED_INPUT_METHODS_POLICY = "permittedInputMethods";
 
     /**
@@ -125,6 +127,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final String PERSONAL_APPS_SUSPENDED_POLICY = "personalAppsSuspended";
 
     /**
@@ -132,6 +135,7 @@
      *
      * @hide
      */
+    @TestApi
     public static final String SCREEN_CAPTURE_DISABLED_POLICY = "screenCaptureDisabled";
 
     /**
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index a8a2ad1..e0364cb 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -8394,8 +8394,7 @@
      * <p>
      * The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA} to be able to call this method; if it has
-     * not, a security exception will be thrown, or the caller must hold the permission
-     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CAMERA}.
+     * not, a security exception will be thrown.
      * <p>
      * <b>Note</b>, this policy type is deprecated for legacy device admins since
      * {@link android.os.Build.VERSION_CODES#Q}. On Android
@@ -8411,8 +8410,7 @@
                      the caller is not a device admin
      * @param disabled Whether or not the camera should be disabled.
      * @throws SecurityException if {@code admin} is not an active administrator or does not use
-     *             {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA} and the caller does not hold
-     *             the permisisons {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CAMERA}.
+     *             {@link DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA}.
      */
     @RequiresPermission(value = MANAGE_DEVICE_POLICY_CAMERA, conditional = true)
     public void setCameraDisabled(@Nullable ComponentName admin, boolean disabled) {
@@ -9601,6 +9599,7 @@
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             } catch (IllegalArgumentException ex) {
+                Log.e(TAG, "IllegalArgumentException checking isPackageSuspended", ex);
                 throw new NameNotFoundException(packageName);
             }
         }
@@ -13402,11 +13401,10 @@
     /**
      * Called by a device admin or holder of the permission
      * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SUPPORT_MESSAGE} to set the short
-     * support message. This will be displayed to the user
-     * in settings screens where funtionality has been disabled by the admin. The message should be
-     * limited to a short statement such as "This setting is disabled by your administrator. Contact
-     * someone@example.com for support." If the message is longer than 200 characters it may be
-     * truncated.
+     * support message. This will be displayed to the user in settings screens where functionality
+     * has been disabled by the admin. The message should be limited to a short statement such as
+     * "This setting is disabled by your administrator. Contact someone@example.com for support."
+     * If the message is longer than 200 characters it may be truncated.
      * <p>
      * If the short support message needs to be localized, it is the responsibility of the
      * {@link DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast
@@ -13461,7 +13459,8 @@
 
     /**
      * Called by a device admin to set the long support message. This will be displayed to the user
-     * in the device administators settings screen.
+     * in the device administrators settings screen. If the message is longer than 20000 characters
+     * it may be truncated.
      * <p>
      * If the long support message needs to be localized, it is the responsibility of the
      * {@link DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast
diff --git a/core/java/android/app/admin/DevicePolicyResources.java b/core/java/android/app/admin/DevicePolicyResources.java
index 052f670..77ba560 100644
--- a/core/java/android/app/admin/DevicePolicyResources.java
+++ b/core/java/android/app/admin/DevicePolicyResources.java
@@ -1662,14 +1662,16 @@
             /**
              * Label returned from
              * {@link android.content.pm.CrossProfileApps#getProfileSwitchingLabel(UserHandle)}
-             * that calling app can show to user for the semantic of switching to work profile.
+             * that calling app can show to user for the semantic of switching to work profile, and
+             * accepts the app name as a param.
              */
             public static final String SWITCH_TO_WORK_LABEL = PREFIX + "SWITCH_TO_WORK_LABEL";
 
             /**
              * Label returned from
              * {@link android.content.pm.CrossProfileApps#getProfileSwitchingLabel(UserHandle)}
-             * that calling app can show to user for the semantic of switching to personal profile.
+             * that calling app can show to user for the semantic of switching to personal profile,
+             * and accepts the app name as a param.
              */
             public static final String SWITCH_TO_PERSONAL_LABEL =
                     PREFIX + "SWITCH_TO_PERSONAL_LABEL";
diff --git a/core/java/android/app/admin/LockTaskPolicy.java b/core/java/android/app/admin/LockTaskPolicy.java
index f5d1cb4..b671d57 100644
--- a/core/java/android/app/admin/LockTaskPolicy.java
+++ b/core/java/android/app/admin/LockTaskPolicy.java
@@ -38,6 +38,7 @@
     /**
      * @hide
      */
+    // We default on the power button menu, in order to be consistent with pre-P behaviour
     public static final int DEFAULT_LOCK_TASK_FLAG =
             DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
 
@@ -72,18 +73,28 @@
     /**
      * @hide
      */
-    public LockTaskPolicy(@NonNull Set<String> packages) {
-        Objects.requireNonNull(packages);
-        mPackages.addAll(packages);
+    public LockTaskPolicy(@Nullable Set<String> packages) {
+        if (packages != null) {
+            mPackages.addAll(packages);
+        }
         setValue(this);
     }
 
     /**
      * @hide
      */
-    public LockTaskPolicy(@NonNull Set<String> packages, int flags) {
-        Objects.requireNonNull(packages);
-        mPackages = new HashSet<>(packages);
+    public LockTaskPolicy(int flags) {
+        mFlags = flags;
+        setValue(this);
+    }
+
+    /**
+     * @hide
+     */
+    public LockTaskPolicy(@Nullable Set<String> packages, int flags) {
+        if (packages != null) {
+            mPackages.addAll(packages);
+        }
         mFlags = flags;
         setValue(this);
     }
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index d6951ee..7ac8f37 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -18,6 +18,7 @@
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.app.admin.DevicePolicyResources.Strings.Core.SWITCH_TO_PERSONAL_LABEL;
 import static android.app.admin.DevicePolicyResources.Strings.Core.SWITCH_TO_WORK_LABEL;
+import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -40,6 +41,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.text.TextUtils;
 
 import com.android.internal.R;
 import com.android.internal.util.UserIcons;
@@ -329,19 +331,40 @@
 
         final boolean isManagedProfile = mUserManager.isManagedProfile(userHandle.getIdentifier());
         final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+        final String callingAppLabel = getCallingApplicationLabel().toString();
         return dpm.getResources().getString(
                 getUpdatableProfileSwitchingLabelId(isManagedProfile),
-                () -> getDefaultProfileSwitchingLabel(isManagedProfile));
+                () -> getDefaultProfileSwitchingLabel(isManagedProfile, callingAppLabel),
+                callingAppLabel);
+    }
+
+    private CharSequence getCallingApplicationLabel() {
+        PackageManager pm = mContext.getPackageManager();
+        // If there is a label for the launcher intent, then use that as it is typically shorter.
+        // Otherwise, just use the top-level application name.
+        Intent launchIntent = pm.getLaunchIntentForPackage(mContext.getPackageName());
+        List<ResolveInfo> infos =
+                pm.queryIntentActivities(
+                        launchIntent, PackageManager.ResolveInfoFlags.of(MATCH_DEFAULT_ONLY));
+        if (infos.size() > 0) {
+            return infos.get(0).loadLabel(pm);
+        }
+        return mContext.getApplicationInfo()
+                .loadSafeLabel(
+                        pm,
+                        /* ellipsizeDip= */ 0,
+                        TextUtils.SAFE_STRING_FLAG_SINGLE_LINE
+                                | TextUtils.SAFE_STRING_FLAG_TRIM);
     }
 
     private String getUpdatableProfileSwitchingLabelId(boolean isManagedProfile) {
         return isManagedProfile ? SWITCH_TO_WORK_LABEL : SWITCH_TO_PERSONAL_LABEL;
     }
 
-    private String getDefaultProfileSwitchingLabel(boolean isManagedProfile) {
+    private String getDefaultProfileSwitchingLabel(boolean isManagedProfile, String label) {
         final int stringRes = isManagedProfile
-                ? R.string.managed_profile_label : R.string.user_owner_label;
-        return mResources.getString(stringRes);
+                ? R.string.managed_profile_app_label : R.string.user_owner_app_label;
+        return mResources.getString(stringRes, label);
     }
 
 
@@ -366,10 +389,18 @@
         if (isManagedProfile) {
             return mContext.getPackageManager().getUserBadgeForDensityNoBackground(
                     userHandle, /* density= */ 0);
-        } else {
-            return UserIcons.getDefaultUserIcon(
-                    mResources, UserHandle.USER_SYSTEM, true /* light */);
         }
+        Drawable personalProfileIcon = UserIcons.getDefaultUserIcon(
+                mResources, UserHandle.USER_SYSTEM,  /* light= */ true);
+        // Using the same colors as the managed profile icon.
+        int colorId = mContext.getResources().getConfiguration().isNightModeActive()
+                ? R.color.profile_badge_1_dark
+                : R.color.profile_badge_1;
+        // First set the color filter to null so that it does not override
+        // the tint.
+        personalProfileIcon.setColorFilter(null);
+        personalProfileIcon.setTint(mResources.getColor(colorId, /* theme= */ null));
+        return personalProfileIcon;
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 30fd77c..de66f05 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -3554,6 +3554,18 @@
         }
 
         /**
+         * @return the path to the validated base APK for this session, which may point at an
+         * APK inside the session (when the session defines the base), or it may
+         * point at the existing base APK (when adding splits to an existing app).
+         *
+         * @hide
+         */
+        @RequiresPermission(Manifest.permission.READ_INSTALLED_SESSION_PATHS)
+        public @Nullable String getResolvedBaseApkPath() {
+            return resolvedBaseCodePath;
+        }
+
+        /**
          * Get the value set in {@link SessionParams#setGrantedRuntimePermissions(String[])}.
          *
          * @hide
diff --git a/core/java/android/credentials/ui/RequestInfo.java b/core/java/android/credentials/ui/RequestInfo.java
index 09d2db8..9ebb058 100644
--- a/core/java/android/credentials/ui/RequestInfo.java
+++ b/core/java/android/credentials/ui/RequestInfo.java
@@ -30,6 +30,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Contains information about the request that initiated this UX flow.
@@ -64,6 +66,9 @@
     @Nullable
     private final CreateCredentialRequest mCreateCredentialRequest;
 
+    @NonNull
+    private final List<String> mDefaultProviderIds;
+
     @Nullable
     private final GetCredentialRequest mGetCredentialRequest;
 
@@ -83,7 +88,8 @@
             @NonNull String appPackageName) {
         return new RequestInfo(
                 token, TYPE_CREATE, appPackageName, createCredentialRequest, null,
-                /*hasPermissionToOverrideDefault=*/ false);
+                /*hasPermissionToOverrideDefault=*/ false,
+                /*defaultProviderIds=*/ new ArrayList<>());
     }
 
     /**
@@ -94,10 +100,11 @@
     @NonNull
     public static RequestInfo newCreateRequestInfo(
             @NonNull IBinder token, @NonNull CreateCredentialRequest createCredentialRequest,
-            @NonNull String appPackageName, boolean hasPermissionToOverrideDefault) {
+            @NonNull String appPackageName, boolean hasPermissionToOverrideDefault,
+            @NonNull List<String> defaultProviderIds) {
         return new RequestInfo(
                 token, TYPE_CREATE, appPackageName, createCredentialRequest, null,
-                hasPermissionToOverrideDefault);
+                hasPermissionToOverrideDefault, defaultProviderIds);
     }
 
     /** Creates new {@code RequestInfo} for a get-credential flow. */
@@ -107,7 +114,8 @@
             @NonNull String appPackageName) {
         return new RequestInfo(
                 token, TYPE_GET, appPackageName, null, getCredentialRequest,
-                /*hasPermissionToOverrideDefault=*/ false);
+                /*hasPermissionToOverrideDefault=*/ false,
+                /*defaultProviderIds=*/ new ArrayList<>());
     }
 
 
@@ -149,6 +157,20 @@
     }
 
     /**
+     * Returns default provider identifier (flattened component name) configured from the user
+     * settings.
+     *
+     * Will only be possibly non-empty for the create use case. Not meaningful for the sign-in use
+     * case.
+     *
+     * @hide
+     */
+    @NonNull
+    public List<String> getDefaultProviderIds() {
+        return mDefaultProviderIds;
+    }
+
+    /**
      * Returns the non-null GetCredentialRequest when the type of the request is {@link
      * #TYPE_GET}, or null otherwise.
      */
@@ -161,13 +183,15 @@
             @NonNull String appPackageName,
             @Nullable CreateCredentialRequest createCredentialRequest,
             @Nullable GetCredentialRequest getCredentialRequest,
-            boolean hasPermissionToOverrideDefault) {
+            boolean hasPermissionToOverrideDefault,
+            @NonNull List<String> defaultProviderIds) {
         mToken = token;
         mType = type;
         mAppPackageName = appPackageName;
         mCreateCredentialRequest = createCredentialRequest;
         mGetCredentialRequest = getCredentialRequest;
         mHasPermissionToOverrideDefault = hasPermissionToOverrideDefault;
+        mDefaultProviderIds = defaultProviderIds == null ? new ArrayList<>() : defaultProviderIds;
     }
 
     private RequestInfo(@NonNull Parcel in) {
@@ -188,6 +212,7 @@
         mCreateCredentialRequest = createCredentialRequest;
         mGetCredentialRequest = getCredentialRequest;
         mHasPermissionToOverrideDefault = in.readBoolean();
+        mDefaultProviderIds = in.createStringArrayList();
     }
 
     @Override
@@ -198,6 +223,7 @@
         dest.writeTypedObject(mCreateCredentialRequest, flags);
         dest.writeTypedObject(mGetCredentialRequest, flags);
         dest.writeBoolean(mHasPermissionToOverrideDefault);
+        dest.writeStringList(mDefaultProviderIds);
     }
 
     @Override
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
index a1d74df..37c5213 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -61,36 +61,42 @@
      * This variant is intended for use when the caller is acting an originator, rather than on
      * behalf of a different entity, as far as authorization goes.
      */
-    SoundTriggerModule(@NonNull ISoundTriggerMiddlewareService service,
+    public SoundTriggerModule(@NonNull ISoundTriggerMiddlewareService service,
             int moduleId, @NonNull SoundTrigger.StatusListener listener, @NonNull Looper looper,
-            @NonNull Identity originatorIdentity)
-            throws RemoteException {
+            @NonNull Identity originatorIdentity) {
         mId = moduleId;
         mEventHandlerDelegate = new EventHandlerDelegate(listener, looper);
-
-        try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
-            mService = service.attachAsOriginator(moduleId, originatorIdentity,
-                    mEventHandlerDelegate);
+        try {
+            try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+                mService = service.attachAsOriginator(moduleId, originatorIdentity,
+                        mEventHandlerDelegate);
+            }
+            mService.asBinder().linkToDeath(mEventHandlerDelegate, 0);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
-        mService.asBinder().linkToDeath(mEventHandlerDelegate, 0);
     }
 
     /**
      * This variant is intended for use when the caller is acting as a middleman, i.e. on behalf of
      * a different entity, as far as authorization goes.
      */
-    SoundTriggerModule(@NonNull ISoundTriggerMiddlewareService service,
+    public SoundTriggerModule(@NonNull ISoundTriggerMiddlewareService service,
             int moduleId, @NonNull SoundTrigger.StatusListener listener, @NonNull Looper looper,
-            @NonNull Identity middlemanIdentity, @NonNull Identity originatorIdentity)
-            throws RemoteException {
+            @NonNull Identity middlemanIdentity, @NonNull Identity originatorIdentity) {
         mId = moduleId;
         mEventHandlerDelegate = new EventHandlerDelegate(listener, looper);
 
-        try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
-            mService = service.attachAsMiddleman(moduleId, middlemanIdentity, originatorIdentity,
-                    mEventHandlerDelegate);
+        try {
+            try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+                mService = service.attachAsMiddleman(moduleId, middlemanIdentity,
+                        originatorIdentity,
+                        mEventHandlerDelegate);
+            }
+            mService.asBinder().linkToDeath(mEventHandlerDelegate, 0);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
-        mService.asBinder().linkToDeath(mEventHandlerDelegate, 0);
     }
 
     @Override
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index ed6a88f..70b72c8 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -304,7 +304,9 @@
                 return;
             }
             case DO_SET_STYLUS_WINDOW_IDLE_TIMEOUT: {
-                inputMethod.setStylusWindowIdleTimeoutForTest((long) msg.obj);
+                if (isValid(inputMethod, target, "DO_SET_STYLUS_WINDOW_IDLE_TIMEOUT")) {
+                    inputMethod.setStylusWindowIdleTimeoutForTest((long) msg.obj);
+                }
                 return;
             }
         }
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index efed688..365f913 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -16,6 +16,7 @@
 
 package android.net;
 
+import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
 import static android.app.ActivityManager.procStateToString;
 import static android.content.pm.PackageManager.GET_SIGNATURES;
 
@@ -805,6 +806,9 @@
     /** @hide */
     public static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(
             int procState, @ProcessCapability int capability) {
+        if (procState == PROCESS_STATE_UNKNOWN) {
+            return false;
+        }
         return procState <= FOREGROUND_THRESHOLD_STATE
                 || (capability & ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0;
     }
@@ -832,6 +836,9 @@
     /** @hide */
     public static boolean isProcStateAllowedWhileOnRestrictBackground(int procState,
             @ProcessCapability int capabilities) {
+        if (procState == PROCESS_STATE_UNKNOWN) {
+            return false;
+        }
         return procState <= FOREGROUND_THRESHOLD_STATE
                 // This is meant to be a user-initiated job, and therefore gets similar network
                 // access to FGS.
diff --git a/core/java/android/net/metrics/WakeupStats.java b/core/java/android/net/metrics/WakeupStats.java
index bb36536..fac747c 100644
--- a/core/java/android/net/metrics/WakeupStats.java
+++ b/core/java/android/net/metrics/WakeupStats.java
@@ -80,18 +80,20 @@
                 break;
         }
 
-        switch (ev.dstHwAddr.getAddressType()) {
-            case MacAddress.TYPE_UNICAST:
-                l2UnicastCount++;
-                break;
-            case MacAddress.TYPE_MULTICAST:
-                l2MulticastCount++;
-                break;
-            case MacAddress.TYPE_BROADCAST:
-                l2BroadcastCount++;
-                break;
-            default:
-                break;
+        if (ev.dstHwAddr != null) {
+            switch (ev.dstHwAddr.getAddressType()) {
+                case MacAddress.TYPE_UNICAST:
+                    l2UnicastCount++;
+                    break;
+                case MacAddress.TYPE_MULTICAST:
+                    l2MulticastCount++;
+                    break;
+                case MacAddress.TYPE_BROADCAST:
+                    l2BroadcastCount++;
+                    break;
+                default:
+                    break;
+            }
         }
 
         increment(ethertypes, ev.ethertype);
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 7383e63..9f9c222 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -493,7 +493,7 @@
          * @hide
          */
         @TestApi
-        public static final int RESOURCES_SDK_INT = SDK_INT;
+        public static final int RESOURCES_SDK_INT = SDK_INT + ACTIVE_CODENAMES.length;
 
         /**
          * The current lowest supported value of app target SDK. Applications targeting
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 65528e3..bc80c8b 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -12,11 +12,11 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Describes the source of some work that may be done by someone else.
@@ -29,9 +29,13 @@
 
     @UnsupportedAppUsage
     int mNum;
+
     @UnsupportedAppUsage
-    int[] mUids;
+    @NonNull
+    int[] mUids = new int[0];
+
     @UnsupportedAppUsage
+    @Nullable
     String[] mNames;
 
     private ArrayList<WorkChain> mChains;
@@ -73,13 +77,8 @@
             return;
         }
         mNum = orig.mNum;
-        if (orig.mUids != null) {
-            mUids = orig.mUids.clone();
-            mNames = orig.mNames != null ? orig.mNames.clone() : null;
-        } else {
-            mUids = null;
-            mNames = null;
-        }
+        mUids = orig.mUids.clone();
+        mNames = orig.mNames != null ? orig.mNames.clone() : null;
 
         if (orig.mChains != null) {
             // Make a copy of all WorkChains that exist on |orig| since they are mutable.
@@ -114,7 +113,7 @@
      */
     @SystemApi
     public WorkSource(int uid, @NonNull String packageName) {
-        Preconditions.checkNotNull(packageName, "packageName can't be null");
+        Objects.requireNonNull(packageName, "packageName can't be null");
         mNum = 1;
         mUids = new int[] { uid, 0 };
         mNames = new String[] { packageName, null };
@@ -124,7 +123,7 @@
     @UnsupportedAppUsage
     WorkSource(Parcel in) {
         mNum = in.readInt();
-        mUids = in.createIntArray();
+        mUids = Objects.requireNonNullElse(in.createIntArray(), new int[0]);
         mNames = in.createStringArray();
 
         int numChains = in.readInt();
@@ -318,30 +317,22 @@
      */
     public void set(WorkSource other) {
         if (other == null) {
-            mNum = 0;
-            if (mChains != null) {
-                mChains.clear();
-            }
+            clear();
             return;
         }
         mNum = other.mNum;
-        if (other.mUids != null) {
-            if (mUids != null && mUids.length >= mNum) {
-                System.arraycopy(other.mUids, 0, mUids, 0, mNum);
+        if (mUids.length >= mNum) { // this has more data than other
+            System.arraycopy(other.mUids, 0, mUids, 0, mNum);
+        } else {
+            mUids = other.mUids.clone();
+        }
+        if (other.mNames != null) {
+            if (mNames != null && mNames.length >= mNum) {
+                System.arraycopy(other.mNames, 0, mNames, 0, mNum);
             } else {
-                mUids = other.mUids.clone();
-            }
-            if (other.mNames != null) {
-                if (mNames != null && mNames.length >= mNum) {
-                    System.arraycopy(other.mNames, 0, mNames, 0, mNum);
-                } else {
-                    mNames = other.mNames.clone();
-                }
-            } else {
-                mNames = null;
+                mNames = other.mNames.clone();
             }
         } else {
-            mUids = null;
             mNames = null;
         }
 
@@ -361,7 +352,7 @@
     /** @hide */
     public void set(int uid) {
         mNum = 1;
-        if (mUids == null) mUids = new int[2];
+        if (mUids.length == 0) mUids = new int[2];
         mUids[0] = uid;
         mNames = null;
         if (mChains != null) {
@@ -375,7 +366,7 @@
             throw new NullPointerException("Name can't be null");
         }
         mNum = 1;
-        if (mUids == null) {
+        if (mUids.length == 0) {
             mUids = new int[2];
             mNames = new String[2];
         }
@@ -727,7 +718,7 @@
                 if (DEBUG) Log.d(TAG, "i1=" + i1 + " i2=" + i2 + " N1=" + N1
                         + ": insert " + uids2[i2]);
                 changed = true;
-                if (uids1 == null) {
+                if (uids1.length == 0) {
                     uids1 = new int[4];
                     uids1[0] = uids2[i2];
                 } else if (N1 >= uids1.length) {
@@ -866,7 +857,7 @@
 
     private void insert(int index, int uid)  {
         if (DEBUG) Log.d(TAG, "Insert in " + this + " @ " + index + " uid " + uid);
-        if (mUids == null) {
+        if (mUids.length == 0) {
             mUids = new int[4];
             mUids[0] = uid;
             mNum = 1;
@@ -891,7 +882,7 @@
     }
 
     private void insert(int index, int uid, String name)  {
-        if (mUids == null) {
+        if (mNum == 0) {
             mUids = new int[4];
             mUids[0] = uid;
             mNames = new String[4];
@@ -1244,8 +1235,8 @@
         proto.end(workSourceToken);
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<WorkSource> CREATOR
-            = new Parcelable.Creator<WorkSource>() {
+    @NonNull
+    public static final Parcelable.Creator<WorkSource> CREATOR = new Parcelable.Creator<>() {
         public WorkSource createFromParcel(Parcel in) {
             return new WorkSource(in);
         }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3487b01..4a46beb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4677,16 +4677,22 @@
                 "display_color_mode_vendor_hint";
 
         /**
-         * Whether or not the peak refresh rate should be forced. 0=no, 1=yes
+         * The user selected min refresh rate in frames per second.
+         *
+         * If this isn't set, 0 will be used.
          * @hide
          */
-        public static final String FORCE_PEAK_REFRESH_RATE = "force_peak_refresh_rate";
+        @Readable
+        public static final String MIN_REFRESH_RATE = "min_refresh_rate";
 
         /**
-         * Whether or not the peak refresh rate should be used for some content. 0=no, 1=yes
+         * The user selected peak refresh rate in frames per second.
+         *
+         * If this isn't set, the system falls back to a device specific default.
          * @hide
          */
-        public static final String SMOOTH_DISPLAY = "smooth_display";
+        @Readable
+        public static final String PEAK_REFRESH_RATE = "peak_refresh_rate";
 
         /**
          * The amount of time in milliseconds before the device goes to sleep or begins
@@ -11496,6 +11502,8 @@
         public static final int DEVICE_STATE_ROTATION_KEY_HALF_FOLDED = 1;
         /** @hide */
         public static final int DEVICE_STATE_ROTATION_KEY_UNFOLDED = 2;
+        /** @hide */
+        public static final int DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY = 3;
 
         /**
          * The different postures that can be used as keys with
@@ -11507,6 +11515,7 @@
                 DEVICE_STATE_ROTATION_KEY_FOLDED,
                 DEVICE_STATE_ROTATION_KEY_HALF_FOLDED,
                 DEVICE_STATE_ROTATION_KEY_UNFOLDED,
+                DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY,
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface DeviceStateRotationLockKey {
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index 4a848dd..8afae74 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -97,8 +97,6 @@
      */
     public static final @RequestFlags int FLAG_VIEW_NOT_FOCUSED = 0x10;
 
-    // The flag value 0x20 has been defined in AutofillManager.
-
     /**
      * Indicates the request supports fill dialog presentation for the fields, the
      * system will send the request when the activity just started.
diff --git a/core/java/android/service/credentials/CredentialProviderInfoFactory.java b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
index 1a1df6f..751c675 100644
--- a/core/java/android/service/credentials/CredentialProviderInfoFactory.java
+++ b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
@@ -75,12 +75,13 @@
     /**
      * Constructs an information instance of the credential provider.
      *
-     * @param context the context object
+     * @param context          the context object
      * @param serviceComponent the serviceComponent of the provider service
-     * @param userId the android userId for which the current process is running
+     * @param userId           the android userId for which the current process is running
      * @param isSystemProvider whether this provider is a system provider
      * @throws PackageManager.NameNotFoundException If provider service is not found
-     * @throws SecurityException If provider does not require the relevant permission
+     * @throws SecurityException                    If provider does not require the relevant
+     *                                              permission
      */
     public static CredentialProviderInfo create(
             @NonNull Context context,
@@ -99,13 +100,15 @@
     /**
      * Constructs an information instance of the credential provider.
      *
-     * @param context the context object
-     * @param serviceInfo the service info for the provider app. This must be retrieved from the
-     *     {@code PackageManager}
-     * @param isSystemProvider whether the provider app is a system provider
+     * @param context                              the context object
+     * @param serviceInfo                          the service info for the provider app. This must
+     *                                             be retrieved from the
+     *                                             {@code PackageManager}
+     * @param isSystemProvider                     whether the provider app is a system provider
      * @param disableSystemAppVerificationForTests whether to disable system app permission
-     *     verification so that tests can install system providers
-     * @param isEnabled whether the user enabled this provider
+     *                                             verification so that tests can install system
+     *                                             providers
+     * @param isEnabled                            whether the user enabled this provider
      * @throws SecurityException If provider does not require the relevant permission
      */
     public static CredentialProviderInfo create(
@@ -374,7 +377,6 @@
                 if (appInfo == null || serviceInfo == null) {
                     continue;
                 }
-
                 services.add(serviceInfo);
             } catch (SecurityException | PackageManager.NameNotFoundException e) {
                 Slog.e(TAG, "Error getting info for " + serviceInfo, e);
diff --git a/core/java/android/service/credentials/CredentialProviderService.java b/core/java/android/service/credentials/CredentialProviderService.java
index 53a5fd5..cf2e6a6 100644
--- a/core/java/android/service/credentials/CredentialProviderService.java
+++ b/core/java/android/service/credentials/CredentialProviderService.java
@@ -18,7 +18,6 @@
 
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
-import android.Manifest;
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.SdkConstant;
@@ -35,7 +34,7 @@
 import android.os.Looper;
 import android.os.OutcomeReceiver;
 import android.os.RemoteException;
-import android.util.Log;
+import android.util.Slog;
 
 import java.util.Objects;
 
@@ -226,7 +225,7 @@
         if (SERVICE_INTERFACE.equals(intent.getAction())) {
             return mInterface.asBinder();
         }
-        Log.d(TAG, "Failed to bind with intent: " + intent);
+        Slog.w(TAG, "Failed to bind with intent: " + intent);
         return null;
     }
 
@@ -252,11 +251,6 @@
                             GetCredentialException>() {
                         @Override
                         public void onResult(BeginGetCredentialResponse result) {
-                            // If provider service does not possess the HYBRID permission, this
-                            // check will throw an exception in the provider process.
-                            if (result.getRemoteCredentialEntry() != null) {
-                                enforceRemoteEntryPermission();
-                            }
                             try {
                                 callback.onSuccess(result);
                             } catch (RemoteException e) {
@@ -274,15 +268,6 @@
                     }
             ));
         }
-        private void enforceRemoteEntryPermission() {
-            String permission =
-                    Manifest.permission.PROVIDE_REMOTE_CREDENTIALS;
-            getApplicationContext().enforceCallingOrSelfPermission(
-                    permission,
-                    String.format("Provider must have %s, in order to set a "
-                            + "remote entry", permission)
-            );
-        }
 
         @Override
         public void onBeginCreateCredential(BeginCreateCredentialRequest request,
@@ -305,11 +290,6 @@
                             BeginCreateCredentialResponse, CreateCredentialException>() {
                         @Override
                         public void onResult(BeginCreateCredentialResponse result) {
-                            // If provider service does not possess the HYBRID permission, this
-                            // check will throw an exception in the provider process.
-                            if (result.getRemoteCreateEntry() != null) {
-                                enforceRemoteEntryPermission();
-                            }
                             try {
                                 callback.onSuccess(result);
                             } catch (RemoteException e) {
diff --git a/core/java/android/service/dreams/DreamManagerInternal.java b/core/java/android/service/dreams/DreamManagerInternal.java
index 82571db..e9bb28c 100644
--- a/core/java/android/service/dreams/DreamManagerInternal.java
+++ b/core/java/android/service/dreams/DreamManagerInternal.java
@@ -84,6 +84,19 @@
          *
          * @param keepDreaming True if the current dream should continue when undocking.
          */
-        void onKeepDreamingWhenUnpluggingChanged(boolean keepDreaming);
+        default void onKeepDreamingWhenUnpluggingChanged(boolean keepDreaming) {
+        }
+
+        /**
+         * Called when dreaming has started.
+         */
+        default void onDreamingStarted() {
+        }
+
+        /**
+         * Called when dreaming has stopped.
+         */
+        default void onDreamingStopped() {
+        }
     }
 }
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 24c96ea..91c350a 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -1334,13 +1334,7 @@
     @Override
     public void destroy() {
         synchronized (mLock) {
-            if (mAvailability == STATE_KEYPHRASE_ENROLLED) {
-                try {
-                    stopRecognition();
-                } catch (Exception e) {
-                    Log.i(TAG, "failed to stopRecognition in destroy", e);
-                }
-            }
+            detachSessionLocked();
 
             mAvailability = STATE_INVALID;
             mIsAvailabilityOverriddenByTestApi = false;
@@ -1349,6 +1343,17 @@
         super.destroy();
     }
 
+    private void detachSessionLocked() {
+        try {
+            if (DBG) Slog.d(TAG, "detachSessionLocked() " + mSoundTriggerSession);
+            if (mSoundTriggerSession != null) {
+                mSoundTriggerSession.detach();
+            }
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
     /**
      * @hide
      */
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 68cce4a..7822dde 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -101,7 +101,7 @@
     public static final String SERVICE_META_DATA = "android.voice_interaction";
 
     /**
-     * For apps targeting Build.VERSION_CODES.TRAMISU and above, implementors of this
+     * For apps targeting Build.VERSION_CODES.UPSIDE_DOWN_CAKE and above, implementors of this
      * service can create multiple AlwaysOnHotwordDetector instances in parallel. They will
      * also e ale to create a single SoftwareHotwordDetector in parallel with any other
      * active AlwaysOnHotwordDetector instances.
@@ -128,7 +128,7 @@
      * @hide
      */
     @ChangeId
-    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT)
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
     static final long MULTIPLE_ACTIVE_HOTWORD_DETECTORS = 193232191L;
 
     IVoiceInteractionService mInterface = new IVoiceInteractionService.Stub() {
@@ -913,8 +913,6 @@
      * sandboxed process.
      * @param callback The callback to notify of detection events.
      * @return An instanece of {@link VisualQueryDetector}.
-     * @throws UnsupportedOperationException if only single detector is supported. Multiple detector
-     * is only available for apps targeting {@link Build.VERSION_CODES#TIRAMISU} and above.
      * @throws IllegalStateException when there is an existing {@link VisualQueryDetector}, or when
      * there is a non-trusted hotword detector running.
      *
@@ -935,21 +933,16 @@
             throw new IllegalStateException("Not available until onReady() is called");
         }
         synchronized (mLock) {
-            if (!CompatChanges.isChangeEnabled(MULTIPLE_ACTIVE_HOTWORD_DETECTORS)) {
-                throw new UnsupportedOperationException("VisualQueryDetector is only available if "
-                        + "multiple detectors are allowed");
-            } else {
-                if (mActiveVisualQueryDetector != null) {
+            if (mActiveVisualQueryDetector != null) {
+                throw new IllegalStateException(
+                            "There is already an active VisualQueryDetector. "
+                                    + "It must be destroyed to create a new one.");
+            }
+            for (HotwordDetector detector : mActiveDetectors) {
+                if (!detector.isUsingSandboxedDetectionService()) {
                     throw new IllegalStateException(
-                                "There is already an active VisualQueryDetector. "
-                                        + "It must be destroyed to create a new one.");
-                }
-                for (HotwordDetector detector : mActiveDetectors) {
-                    if (!detector.isUsingSandboxedDetectionService()) {
-                        throw new IllegalStateException(
-                                "It disallows to create trusted and non-trusted detectors "
-                                        + "at the same time.");
-                    }
+                            "It disallows to create trusted and non-trusted detectors "
+                                    + "at the same time.");
                 }
             }
 
@@ -1070,21 +1063,6 @@
                 mActiveVisualQueryDetector = null;
             }
             mActiveDetectors.remove(detector);
-            shutdownHotwordDetectionServiceIfRequiredLocked();
-        }
-    }
-
-    private void shutdownHotwordDetectionServiceIfRequiredLocked() {
-        for (HotwordDetector detector : mActiveDetectors) {
-            if (detector.isUsingSandboxedDetectionService()) {
-                return;
-            }
-        }
-
-        try {
-            mSystemService.shutdownHotwordDetectionService();
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
         }
     }
 
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index f2373fb..d8fa533 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -360,6 +360,14 @@
     public SparseArray<SurfaceControl.RefreshRateRange> thermalRefreshRateThrottling =
             new SparseArray<>();
 
+    /**
+     * The ID of the brightness throttling data that should be used. This can change e.g. in
+     * concurrent displays mode in which a stricter brightness throttling policy might need to be
+     * used.
+     */
+    @Nullable
+    public String thermalBrightnessThrottlingDataId;
+
     public static final @android.annotation.NonNull Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
         @Override
         public DisplayInfo createFromParcel(Parcel source) {
@@ -437,7 +445,9 @@
                 && Objects.equals(displayShape, other.displayShape)
                 && Objects.equals(layoutLimitedRefreshRate, other.layoutLimitedRefreshRate)
                 && BrightnessSynchronizer.floatEquals(hdrSdrRatio, other.hdrSdrRatio)
-                && thermalRefreshRateThrottling.contentEquals(other.thermalRefreshRateThrottling);
+                && thermalRefreshRateThrottling.contentEquals(other.thermalRefreshRateThrottling)
+                && Objects.equals(
+                thermalBrightnessThrottlingDataId, other.thermalBrightnessThrottlingDataId);
     }
 
     @Override
@@ -495,6 +505,7 @@
         layoutLimitedRefreshRate = other.layoutLimitedRefreshRate;
         hdrSdrRatio = other.hdrSdrRatio;
         thermalRefreshRateThrottling = other.thermalRefreshRateThrottling;
+        thermalBrightnessThrottlingDataId = other.thermalBrightnessThrottlingDataId;
     }
 
     public void readFromParcel(Parcel source) {
@@ -559,6 +570,7 @@
         hdrSdrRatio = source.readFloat();
         thermalRefreshRateThrottling = source.readSparseArray(null,
                 SurfaceControl.RefreshRateRange.class);
+        thermalBrightnessThrottlingDataId = source.readString8();
     }
 
     @Override
@@ -620,6 +632,7 @@
         dest.writeTypedObject(layoutLimitedRefreshRate, flags);
         dest.writeFloat(hdrSdrRatio);
         dest.writeSparseArray(thermalRefreshRateThrottling);
+        dest.writeString8(thermalBrightnessThrottlingDataId);
     }
 
     @Override
@@ -889,6 +902,8 @@
         }
         sb.append(", thermalRefreshRateThrottling ");
         sb.append(thermalRefreshRateThrottling);
+        sb.append(", thermalBrightnessThrottlingDataId ");
+        sb.append(thermalBrightnessThrottlingDataId);
         sb.append("}");
         return sb.toString();
     }
diff --git a/core/java/android/view/IRemoteAnimationRunner.aidl b/core/java/android/view/IRemoteAnimationRunner.aidl
index 1981c9d..1f64fb8 100644
--- a/core/java/android/view/IRemoteAnimationRunner.aidl
+++ b/core/java/android/view/IRemoteAnimationRunner.aidl
@@ -46,5 +46,5 @@
      * won't have any effect anymore.
      */
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    void onAnimationCancelled(boolean isKeyguardOccluded);
+    void onAnimationCancelled();
 }
diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java
index 43828d5..9714896 100644
--- a/core/java/android/view/ImeFocusController.java
+++ b/core/java/android/view/ImeFocusController.java
@@ -86,9 +86,12 @@
     void onPreWindowFocus(boolean hasWindowFocus, WindowManager.LayoutParams windowAttribute) {
         mHasImeFocus = WindowManager.LayoutParams.mayUseInputMethod(windowAttribute.flags);
         if (!hasWindowFocus || !mHasImeFocus || isInLocalFocusMode(windowAttribute)) {
-            return;
+            if (!hasWindowFocus) {
+                getImmDelegate().onWindowLostFocus(mViewRootImpl);
+            }
+        } else {
+            getImmDelegate().onPreWindowGainedFocus(mViewRootImpl);
         }
-        getImmDelegate().onPreWindowGainedFocus(mViewRootImpl);
     }
 
     @UiThread
@@ -163,6 +166,7 @@
         void onPreWindowGainedFocus(ViewRootImpl viewRootImpl);
         void onPostWindowGainedFocus(View viewForWindowFocus,
                 @NonNull WindowManager.LayoutParams windowAttribute);
+        void onWindowLostFocus(@NonNull ViewRootImpl viewRootImpl);
         void onViewFocusChanged(@NonNull View view, boolean hasFocus);
         void onScheduledCheckFocus(@NonNull ViewRootImpl viewRootImpl);
         void onViewDetachedFromWindow(View view, ViewRootImpl viewRootImpl);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index bc6a3b5..99deac4 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -220,6 +220,7 @@
             long newParentNativeObject);
     private static native void nativeSetBuffer(long transactionObj, long nativeObject,
             HardwareBuffer buffer, long fencePtr, Consumer<SyncFence> releaseCallback);
+    private static native void nativeUnsetBuffer(long transactionObj, long nativeObject);
     private static native void nativeSetBufferTransform(long transactionObj, long nativeObject,
             int transform);
     private static native void nativeSetDataSpace(long transactionObj, long nativeObject,
@@ -3664,6 +3665,22 @@
         }
 
         /**
+         * Unsets the buffer for the SurfaceControl in the current Transaction. This will not clear
+         * the buffer being rendered, but resets the buffer state in the Transaction only. The call
+         * will also invoke the release callback.
+         *
+         * Note, this call is different from passing a null buffer to
+         * {@link SurfaceControl.Transaction#setBuffer} which will release the last displayed
+         * buffer.
+         *
+         * @hide
+         */
+        public Transaction unsetBuffer(SurfaceControl sc) {
+            nativeUnsetBuffer(mNativeObject, sc.mNativeObject);
+            return this;
+        }
+
+        /**
          * Updates the HardwareBuffer displayed for the SurfaceControl.
          *
          * Note that the buffer must be allocated with {@link HardwareBuffer#USAGE_COMPOSER_OVERLAY}
@@ -3682,7 +3699,8 @@
          * until all presentation fences have signaled, ensuring the transaction remains consistent.
          *
          * @param sc The SurfaceControl to update
-         * @param buffer The buffer to be displayed
+         * @param buffer The buffer to be displayed. Pass in a null buffer to release the last
+         * displayed buffer.
          * @param fence The presentation fence. If null or invalid, this is equivalent to
          *              {@link #setBuffer(SurfaceControl, HardwareBuffer)}
          * @return this
@@ -3846,14 +3864,14 @@
          *                           100 nits and a max display brightness of 200 nits, this should
          *                           be set to 2.0f.
          *
-         *                           Default value is 1.0f.
+         *                           <p>Default value is 1.0f.
          *
-         *                           Transfer functions that encode their own brightness ranges,
+         *                           <p>Transfer functions that encode their own brightness ranges,
          *                           such as HLG or PQ, should also set this to 1.0f and instead
          *                           communicate extended content brightness information via
          *                           metadata such as CTA861_3 or SMPTE2086.
          *
-         *                           Must be finite && >= 1.0f
+         *                           <p>Must be finite && >= 1.0f
          *
          * @param desiredRatio The desired hdr/sdr ratio. This can be used to communicate the max
          *                     desired brightness range. This is similar to the "max luminance"
@@ -3862,13 +3880,17 @@
          *                     may not be able to, or may choose not to, deliver the
          *                     requested range.
          *
-         *                     If unspecified, the system will attempt to provide the best range
-         *                     it can for the given ambient conditions & device state. However,
-         *                     voluntarily reducing the requested range can help improve battery
-         *                     life as well as can improve quality by ensuring greater bit depth
-         *                     is allocated to the luminance range in use.
+         *                     <p>While requesting a large desired ratio will result in the most
+         *                     dynamic range, voluntarily reducing the requested range can help
+         *                     improve battery life as well as can improve quality by ensuring
+         *                     greater bit depth is allocated to the luminance range in use.
          *
-         *                     Must be finite && >= 1.0f
+         *                     <p>Default value is 1.0f and indicates that extended range brightness
+         *                     is not being used, so the resulting SDR or HDR behavior will be
+         *                     determined entirely by the dataspace being used (ie, typically SDR
+         *                     however PQ or HLG transfer functions will still result in HDR)
+         *
+         *                     <p>Must be finite && >= 1.0f
          * @return this
          **/
         public @NonNull Transaction setExtendedRangeBrightness(@NonNull SurfaceControl sc,
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6bd9538..8f20e2d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -647,11 +647,18 @@
     boolean mForceNextWindowRelayout;
     CountDownLatch mWindowDrawCountDown;
 
-    // Whether we have used applyTransactionOnDraw to schedule an RT
-    // frame callback consuming a passed in transaction. In this case
-    // we also need to schedule a commit callback so we can observe
-    // if the draw was skipped, and the BBQ pending transactions.
+    /**
+     * Value to indicate whether someone has called {@link #applyTransactionOnDraw}before the
+     * traversal. This is used to determine whether a RT frame callback needs to be registered to
+     * merge the transaction with the next frame. The value is cleared after the VRI has run a
+     * traversal pass.
+     */
     boolean mHasPendingTransactions;
+    /**
+     * The combined transactions passed in from {@link #applyTransactionOnDraw}
+     */
+    private Transaction mPendingTransaction = new Transaction();
+
 
     boolean mIsDrawing;
     int mLastSystemUiVisibility;
@@ -954,12 +961,20 @@
                 }
 
                 sAnrReported = true;
+                // If we're making an in-process call to ActivityManagerService
+                // and the previous binder call on this thread was oneway, the
+                // calling PID will be 0. Clearing the calling identity fixes
+                // this and ensures ActivityManager gets the correct calling
+                // pid.
+                final long identityToken = Binder.clearCallingIdentity();
                 try {
                     ActivityManager.getService().appNotResponding(reason);
                 } catch (RemoteException e) {
                     // We asked the system to crash us, but the system
                     // already crashed. Unfortunately things may be
                     // out of control.
+                } finally {
+                    Binder.restoreCallingIdentity(identityToken);
                 }
             }
         };
@@ -4548,9 +4563,13 @@
     }
 
     private void registerCallbackForPendingTransactions() {
+        Transaction t = new Transaction();
+        t.merge(mPendingTransaction);
+
         registerRtFrameCallback(new FrameDrawingCallback() {
             @Override
             public HardwareRenderer.FrameCommitCallback onFrameDraw(int syncResult, long frame) {
+                mergeWithNextTransaction(t, frame);
                 if ((syncResult
                         & (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) {
                     mBlastBufferQueue.applyPendingTransactions(frame);
@@ -8780,6 +8799,9 @@
             mActiveSurfaceSyncGroup.markSyncReady();
             mActiveSurfaceSyncGroup = null;
         }
+        if (mHasPendingTransactions) {
+            mPendingTransaction.apply();
+        }
         WindowManagerGlobal.getInstance().doRemoveView(this);
     }
 
@@ -11114,12 +11136,11 @@
         } else {
             // Copy and clear the passed in transaction for thread safety. The new transaction is
             // accessed on the render thread.
-            var localTransaction = new Transaction();
-            localTransaction.merge(t);
+            mPendingTransaction.merge(t);
             mHasPendingTransactions = true;
-            registerRtFrameCallback(frame -> {
-                mergeWithNextTransaction(localTransaction, frame);
-            });
+            // Schedule the traversal to ensure there's an attempt to draw a frame and apply the
+            // pending transactions. This is also where the registerFrameCallback will be scheduled.
+            scheduleTraversals();
         }
         return true;
     }
@@ -11260,6 +11281,10 @@
         if (DEBUG_BLAST) {
             Log.d(mTag, "registerCallbacksForSync syncBuffer=" + syncBuffer);
         }
+
+        Transaction t = new Transaction();
+        t.merge(mPendingTransaction);
+
         mAttachInfo.mThreadedRenderer.registerRtFrameCallback(new FrameDrawingCallback() {
             @Override
             public void onFrameDraw(long frame) {
@@ -11273,6 +11298,7 @@
                                     + frame + ".");
                 }
 
+                mergeWithNextTransaction(t, frame);
                 // If the syncResults are SYNC_LOST_SURFACE_REWARD_IF_FOUND or
                 // SYNC_CONTEXT_IS_STOPPED it means nothing will draw. There's no need to set up
                 // any blast sync or commit callback, and the code should directly call
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index f7b7d33..e39b3a1 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -16,7 +16,6 @@
 
 package android.view.autofill;
 
-import static android.Manifest.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS;
 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;
@@ -30,7 +29,6 @@
 import static android.view.autofill.Helper.toList;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
-import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -52,21 +50,16 @@
 import android.content.pm.ResolveInfo;
 import android.graphics.Rect;
 import android.metrics.LogMaker;
-import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.ICancellationSignal;
 import android.os.Looper;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.service.autofill.AutofillService;
-import android.service.autofill.FillCallback;
 import android.service.autofill.FillEventHistory;
-import android.service.autofill.IFillCallback;
 import android.service.autofill.UserData;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -87,7 +80,6 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.accessibility.AccessibilityWindowInfo;
-import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.CheckBox;
 import android.widget.DatePicker;
@@ -187,12 +179,6 @@
  * shows an autofill save UI if the value of savable views have changed. If the user selects the
  * option to Save, the current value of the views is then sent to the autofill service.
  *
- * <p>There is another choice for the application to provide it's datasets to the Autofill framework
- * by setting an {@link AutofillRequestCallback} through
- * {@link #setAutofillRequestCallback(Executor, AutofillRequestCallback)}. The application can use
- * its callback instead of the default {@link AutofillService}. See
- * {@link AutofillRequestCallback} for more details.
- *
  * <h3 id="additional-notes">Additional notes</h3>
  *
  * <p>It is safe to call <code>AutofillManager</code> methods from any thread.
@@ -326,7 +312,6 @@
     /** @hide */ public static final int FLAG_ADD_CLIENT_DEBUG = 0x2;
     /** @hide */ public static final int FLAG_ADD_CLIENT_VERBOSE = 0x4;
     /** @hide */ public static final int FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY = 0x8;
-    /** @hide */ public static final int FLAG_ENABLED_CLIENT_SUGGESTIONS = 0x20;
 
     // NOTE: flag below is used by the session start receiver only, hence it can have values above
     /** @hide */ public static final int RECEIVER_FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY = 0x1;
@@ -653,11 +638,6 @@
     @GuardedBy("mLock")
     private boolean mEnabledForAugmentedAutofillOnly;
 
-    @GuardedBy("mLock")
-    @Nullable private AutofillRequestCallback mAutofillRequestCallback;
-    @GuardedBy("mLock")
-    @Nullable private Executor mRequestCallbackExecutor;
-
     /**
      * Indicates whether there is already a field to do a fill request after
      * the activity started.
@@ -2338,44 +2318,6 @@
         return new AutofillId(parent.getAutofillViewId(), virtualId);
     }
 
-    /**
-     * Sets the client's suggestions callback for autofill.
-     *
-     * @see AutofillRequestCallback
-     *
-     * @param executor specifies the thread upon which the callbacks will be invoked.
-     * @param callback which handles autofill request to provide client's suggestions.
-     *
-     * @hide
-     */
-    @TestApi
-    @RequiresPermission(PROVIDE_OWN_AUTOFILL_SUGGESTIONS)
-    public void setAutofillRequestCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull AutofillRequestCallback callback) {
-        if (mContext.checkSelfPermission(PROVIDE_OWN_AUTOFILL_SUGGESTIONS)
-                != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Requires PROVIDE_OWN_AUTOFILL_SUGGESTIONS permission!");
-        }
-
-        synchronized (mLock) {
-            mRequestCallbackExecutor = executor;
-            mAutofillRequestCallback = callback;
-        }
-    }
-
-    /**
-     * clears the client's suggestions callback for autofill.
-     *
-     * @hide
-     */
-    @TestApi
-    public void clearAutofillRequestCallback() {
-        synchronized (mLock) {
-            mRequestCallbackExecutor = null;
-            mAutofillRequestCallback = null;
-        }
-    }
-
     @GuardedBy("mLock")
     private void startSessionLocked(@NonNull AutofillId id, @NonNull Rect bounds,
             @NonNull AutofillValue value, int flags) {
@@ -2436,13 +2378,6 @@
                 }
             }
 
-            if (mAutofillRequestCallback != null) {
-                if (sDebug) {
-                    Log.d(TAG, "startSession with the client suggestions provider");
-                }
-                flags |= FLAG_ENABLED_CLIENT_SUGGESTIONS;
-            }
-
             mService.startSession(client.autofillClientGetActivityToken(),
                     mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
                     mCallback != null, flags, clientActivity,
@@ -2796,28 +2731,6 @@
         }
     }
 
-    private void onFillRequest(InlineSuggestionsRequest request,
-            CancellationSignal cancellationSignal, FillCallback callback) {
-        final AutofillRequestCallback autofillRequestCallback;
-        final Executor executor;
-        synchronized (mLock) {
-            autofillRequestCallback = mAutofillRequestCallback;
-            executor = mRequestCallbackExecutor;
-        }
-        if (autofillRequestCallback != null && executor != null) {
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                executor.execute(() ->
-                        autofillRequestCallback.onFillRequest(
-                                request, cancellationSignal, callback));
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        } else {
-            callback.onSuccess(null);
-        }
-    }
-
     /** @hide */
     public static final int SET_STATE_FLAG_ENABLED = 0x01;
     /** @hide */
@@ -4374,23 +4287,6 @@
         }
 
         @Override
-        public void requestFillFromClient(int id, InlineSuggestionsRequest request,
-                IFillCallback callback) {
-            final AutofillManager afm = mAfm.get();
-            if (afm != null) {
-                ICancellationSignal transport = CancellationSignal.createTransport();
-                try {
-                    callback.onCancellable(transport);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Error requesting a cancellation", e);
-                }
-
-                afm.onFillRequest(request, CancellationSignal.fromTransport(transport),
-                        new FillCallback(callback, id));
-            }
-        }
-
-        @Override
         public void notifyFillDialogTriggerIds(List<AutofillId> ids) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
diff --git a/core/java/android/view/autofill/AutofillRequestCallback.java b/core/java/android/view/autofill/AutofillRequestCallback.java
deleted file mode 100644
index 10a088b..0000000
--- a/core/java/android/view/autofill/AutofillRequestCallback.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.autofill;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.TestApi;
-import android.os.CancellationSignal;
-import android.service.autofill.FillCallback;
-import android.view.inputmethod.InlineSuggestionsRequest;
-
-/**
- * <p>This class is used to provide some input suggestions to the Autofill framework.
- *
- * <P>When the user is requested to input something, Autofill will try to query input suggestions
- * for the user choosing. If the application want to provide some internal input suggestions,
- * implements this callback and register via
- * {@link AutofillManager#setAutofillRequestCallback(java.util.concurrent.Executor,
- * AutofillRequestCallback)}. Autofill will callback the
- * {@link #onFillRequest(InlineSuggestionsRequest, CancellationSignal, FillCallback)} to request
- * input suggestions.
- *
- * <P>To make sure the callback to take effect, must register before the autofill session starts.
- * If the autofill session is started, calls {@link AutofillManager#cancel()} to finish current
- * session, and then the callback will be used at the next restarted session.
- *
- * <P>To create a {@link android.service.autofill.FillResponse}, application should fetch
- * {@link AutofillId}s from its view structure. Below is an example:
- * <pre class="prettyprint">
- * AutofillId usernameId = findViewById(R.id.username).getAutofillId();
- * AutofillId passwordId = findViewById(R.id.password).getAutofillId();
- * </pre>
- * To learn more about creating a {@link android.service.autofill.FillResponse}, read
- * <a href="/guide/topics/text/autofill-services#fill">Fill out client views</a>.
- *
- * <P>To fallback to the default {@link android.service.autofill.AutofillService}, just respond
- * a null of the {@link android.service.autofill.FillResponse}. And then Autofill will do a fill
- * request with the default {@link android.service.autofill.AutofillService}. Or clear the callback
- * from {@link AutofillManager} via {@link AutofillManager#clearAutofillRequestCallback()}. If the
- * client would like to keep no suggestions for the field, respond with an empty
- * {@link android.service.autofill.FillResponse} which has no dataset.
- *
- * <P>IMPORTANT: This should not be used for displaying anything other than input suggestions, or
- * the keyboard may choose to block your app from the inline strip.
- *
- * @hide
- */
-@TestApi
-public interface AutofillRequestCallback {
-    /**
-     * Called by the Android system to decide if a screen can be autofilled by the callback.
-     *
-     * @param inlineSuggestionsRequest the {@link InlineSuggestionsRequest request} to handle if
-     *     currently inline suggestions are supported and can be displayed.
-     * @param cancellationSignal signal for observing cancellation requests. The system will use
-     *     this to notify you that the fill result is no longer needed and you should stop
-     *     handling this fill request in order to save resources.
-     * @param callback object used to notify the result of the request.
-     */
-    void onFillRequest(@Nullable InlineSuggestionsRequest inlineSuggestionsRequest,
-            @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback);
-}
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 2e5967c..51afe4c 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -24,11 +24,9 @@
 import android.content.IntentSender;
 import android.graphics.Rect;
 import android.os.IBinder;
-import android.service.autofill.IFillCallback;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutofillWindowPresenter;
-import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.KeyEvent;
 
 import com.android.internal.os.IResultReceiver;
@@ -144,12 +142,6 @@
    void requestShowSoftInput(in AutofillId id);
 
     /**
-     * Requests to determine if a screen can be autofilled by the client app.
-     */
-    void requestFillFromClient(int id, in InlineSuggestionsRequest request,
-            in IFillCallback callback);
-
-    /**
      * Notifies autofill ids that require to show the fill dialog.
      */
     void notifyFillDialogTriggerIds(in List<AutofillId> ids);
diff --git a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
index 77a2b5b..581feca 100644
--- a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
+++ b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
@@ -112,22 +112,6 @@
     private @Nullable InlinePresentationSpec mInlineTooltipPresentationSpec;
 
     /**
-     * Whether the IME supports inline suggestions from the default Autofill service that
-     * provides the input view.
-     *
-     * Note: The default value is {@code true}.
-     */
-    private boolean mServiceSupported;
-
-    /**
-     * Whether the IME supports inline suggestions from the application that provides the
-     * input view.
-     *
-     * Note: The default value is {@code true}.
-     */
-    private boolean mClientSupported;
-
-    /**
      * @hide
      * @see {@link #mHostInputToken}.
      */
@@ -221,15 +205,9 @@
         return Bundle.EMPTY;
     }
 
-    private static boolean defaultServiceSupported() {
-        return true;
-    }
-
-    private static boolean defaultClientSupported() {
-        return true;
-    }
-
-    /** @hide */
+    /**
+     * @hide
+     */
     abstract static class BaseBuilder {
         abstract Builder setInlinePresentationSpecs(
                 @NonNull List<android.widget.inline.InlinePresentationSpec> specs);
@@ -241,25 +219,14 @@
         abstract Builder setHostDisplayId(int value);
     }
 
-    /** @hide */
-    public boolean isServiceSupported() {
-        return mServiceSupported;
-    }
 
-    /** @hide */
-    public boolean isClientSupported() {
-        return mClientSupported;
-    }
-
-
-
-    // Code below generated by codegen v1.0.22.
+    // 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/view/inputmethod/InlineSuggestionsRequest.java
+    // $ codegen $ANDROID_BUILD_TOP/./frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
     //
     // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
     //   Settings > Editor > Code Style > Formatter Control
@@ -275,9 +242,7 @@
             @NonNull Bundle extras,
             @Nullable IBinder hostInputToken,
             int hostDisplayId,
-            @Nullable InlinePresentationSpec inlineTooltipPresentationSpec,
-            boolean serviceSupported,
-            boolean clientSupported) {
+            @Nullable InlinePresentationSpec inlineTooltipPresentationSpec) {
         this.mMaxSuggestionCount = maxSuggestionCount;
         this.mInlinePresentationSpecs = inlinePresentationSpecs;
         com.android.internal.util.AnnotationValidations.validate(
@@ -294,8 +259,6 @@
         this.mHostInputToken = hostInputToken;
         this.mHostDisplayId = hostDisplayId;
         this.mInlineTooltipPresentationSpec = inlineTooltipPresentationSpec;
-        this.mServiceSupported = serviceSupported;
-        this.mClientSupported = clientSupported;
 
         onConstructed();
     }
@@ -379,9 +342,7 @@
     }
 
     /**
-     * The {@link InlinePresentationSpec} for the inline suggestion tooltip in the response.
-     *
-     * @see android.service.autofill.InlinePresentation#createTooltipPresentation(Slice, InlinePresentationSpec)
+     * Specifies the UI specification for the inline suggestion tooltip in the response.
      */
     @DataClass.Generated.Member
     public @Nullable InlinePresentationSpec getInlineTooltipPresentationSpec() {
@@ -402,9 +363,7 @@
                 "extras = " + mExtras + ", " +
                 "hostInputToken = " + mHostInputToken + ", " +
                 "hostDisplayId = " + mHostDisplayId + ", " +
-                "inlineTooltipPresentationSpec = " + mInlineTooltipPresentationSpec + ", " +
-                "serviceSupported = " + mServiceSupported + ", " +
-                "clientSupported = " + mClientSupported +
+                "inlineTooltipPresentationSpec = " + mInlineTooltipPresentationSpec +
         " }";
     }
 
@@ -428,9 +387,7 @@
                 && extrasEquals(that.mExtras)
                 && java.util.Objects.equals(mHostInputToken, that.mHostInputToken)
                 && mHostDisplayId == that.mHostDisplayId
-                && java.util.Objects.equals(mInlineTooltipPresentationSpec, that.mInlineTooltipPresentationSpec)
-                && mServiceSupported == that.mServiceSupported
-                && mClientSupported == that.mClientSupported;
+                && java.util.Objects.equals(mInlineTooltipPresentationSpec, that.mInlineTooltipPresentationSpec);
     }
 
     @Override
@@ -448,8 +405,6 @@
         _hash = 31 * _hash + java.util.Objects.hashCode(mHostInputToken);
         _hash = 31 * _hash + mHostDisplayId;
         _hash = 31 * _hash + java.util.Objects.hashCode(mInlineTooltipPresentationSpec);
-        _hash = 31 * _hash + Boolean.hashCode(mServiceSupported);
-        _hash = 31 * _hash + Boolean.hashCode(mClientSupported);
         return _hash;
     }
 
@@ -460,8 +415,6 @@
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
         int flg = 0;
-        if (mServiceSupported) flg |= 0x100;
-        if (mClientSupported) flg |= 0x200;
         if (mHostInputToken != null) flg |= 0x20;
         if (mInlineTooltipPresentationSpec != null) flg |= 0x80;
         dest.writeInt(flg);
@@ -487,11 +440,9 @@
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
         int flg = in.readInt();
-        boolean serviceSupported = (flg & 0x100) != 0;
-        boolean clientSupported = (flg & 0x200) != 0;
         int maxSuggestionCount = in.readInt();
         List<InlinePresentationSpec> inlinePresentationSpecs = new ArrayList<>();
-        in.readParcelableList(inlinePresentationSpecs, InlinePresentationSpec.class.getClassLoader(), android.widget.inline.InlinePresentationSpec.class);
+        in.readParcelableList(inlinePresentationSpecs, InlinePresentationSpec.class.getClassLoader());
         String hostPackageName = in.readString();
         LocaleList supportedLocales = (LocaleList) in.readTypedObject(LocaleList.CREATOR);
         Bundle extras = in.readBundle();
@@ -515,8 +466,6 @@
         this.mHostInputToken = hostInputToken;
         this.mHostDisplayId = hostDisplayId;
         this.mInlineTooltipPresentationSpec = inlineTooltipPresentationSpec;
-        this.mServiceSupported = serviceSupported;
-        this.mClientSupported = clientSupported;
 
         onConstructed();
     }
@@ -550,8 +499,6 @@
         private @Nullable IBinder mHostInputToken;
         private int mHostDisplayId;
         private @Nullable InlinePresentationSpec mInlineTooltipPresentationSpec;
-        private boolean mServiceSupported;
-        private boolean mClientSupported;
 
         private long mBuilderFieldsSet = 0L;
 
@@ -684,9 +631,7 @@
         }
 
         /**
-         * The {@link InlinePresentationSpec} for the inline suggestion tooltip in the response.
-         *
-         * @see android.service.autofill.InlinePresentation#createTooltipPresentation(Slice, InlinePresentationSpec)s
+         * Specifies the UI specification for the inline suggestion tooltip in the response.
          */
         @DataClass.Generated.Member
         public @NonNull Builder setInlineTooltipPresentationSpec(@NonNull InlinePresentationSpec value) {
@@ -696,44 +641,10 @@
             return this;
         }
 
-        /**
-         * Whether the IME supports inline suggestions from the default Autofill service that
-         * provides the input view.
-         *
-         * Note: The default value is {@code true}.
-         *
-         * @hide
-         */
-        @TestApi
-        @DataClass.Generated.Member
-        public @NonNull Builder setServiceSupported(boolean value) {
-            checkNotUsed();
-            mBuilderFieldsSet |= 0x100;
-            mServiceSupported = value;
-            return this;
-        }
-
-        /**
-         * Whether the IME supports inline suggestions from the application that provides the
-         * input view.
-         *
-         * Note: The default value is {@code true}.
-         *
-         * @hide
-         */
-        @TestApi
-        @DataClass.Generated.Member
-        public @NonNull Builder setClientSupported(boolean value) {
-            checkNotUsed();
-            mBuilderFieldsSet |= 0x200;
-            mClientSupported = value;
-            return this;
-        }
-
         /** Builds the instance. This builder should not be touched after calling this! */
         public @NonNull InlineSuggestionsRequest build() {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x400; // Mark builder used
+            mBuilderFieldsSet |= 0x100; // Mark builder used
 
             if ((mBuilderFieldsSet & 0x1) == 0) {
                 mMaxSuggestionCount = defaultMaxSuggestionCount();
@@ -756,12 +667,6 @@
             if ((mBuilderFieldsSet & 0x80) == 0) {
                 mInlineTooltipPresentationSpec = defaultInlineTooltipPresentationSpec();
             }
-            if ((mBuilderFieldsSet & 0x100) == 0) {
-                mServiceSupported = defaultServiceSupported();
-            }
-            if ((mBuilderFieldsSet & 0x200) == 0) {
-                mClientSupported = defaultClientSupported();
-            }
             InlineSuggestionsRequest o = new InlineSuggestionsRequest(
                     mMaxSuggestionCount,
                     mInlinePresentationSpecs,
@@ -770,14 +675,12 @@
                     mExtras,
                     mHostInputToken,
                     mHostDisplayId,
-                    mInlineTooltipPresentationSpec,
-                    mServiceSupported,
-                    mClientSupported);
+                    mInlineTooltipPresentationSpec);
             return o;
         }
 
         private void checkNotUsed() {
-            if ((mBuilderFieldsSet & 0x400) != 0) {
+            if ((mBuilderFieldsSet & 0x100) != 0) {
                 throw new IllegalStateException(
                         "This Builder should not be reused. Use a new Builder instance instead");
             }
@@ -785,10 +688,10 @@
     }
 
     @DataClass.Generated(
-            time = 1615798784918L,
-            codegenVersion = "1.0.22",
+            time = 1682382296877L,
+            codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java",
-            inputSignatures = "public static final  int SUGGESTION_COUNT_UNLIMITED\nprivate final  int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.widget.inline.InlinePresentationSpec> mInlinePresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @android.annotation.NonNull android.os.Bundle mExtras\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate  int mHostDisplayId\nprivate @android.annotation.Nullable android.widget.inline.InlinePresentationSpec mInlineTooltipPresentationSpec\nprivate  boolean mServiceSupported\nprivate  boolean mClientSupported\nprivate static final @android.compat.annotation.ChangeId @android.compat.annotation.EnabledSince long IME_AUTOFILL_DEFAULT_SUPPORTED_LOCALES_IS_EMPTY\npublic  void setHostInputToken(android.os.IBinder)\nprivate  boolean extrasEquals(android.os.Bundle)\nprivate  void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic  void setHostDisplayId(int)\nprivate  void onConstructed()\npublic  void filterContentTypes()\nprivate static  int defaultMaxSuggestionCount()\nprivate static  java.lang.String defaultHostPackageName()\nprivate static  android.widget.inline.InlinePresentationSpec defaultInlineTooltipPresentationSpec()\nprivate static  android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.NonNull android.os.Bundle defaultExtras()\nprivate static  boolean defaultServiceSupported()\nprivate static  boolean defaultClientSupported()\npublic  boolean isServiceSupported()\npublic  boolean isClientSupported()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []")
+            inputSignatures = "public static final  int SUGGESTION_COUNT_UNLIMITED\nprivate final  int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.widget.inline.InlinePresentationSpec> mInlinePresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @android.annotation.NonNull android.os.Bundle mExtras\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate  int mHostDisplayId\nprivate @android.annotation.Nullable android.widget.inline.InlinePresentationSpec mInlineTooltipPresentationSpec\nprivate static final @android.compat.annotation.ChangeId @android.compat.annotation.EnabledSince long IME_AUTOFILL_DEFAULT_SUPPORTED_LOCALES_IS_EMPTY\npublic  void setHostInputToken(android.os.IBinder)\nprivate  boolean extrasEquals(android.os.Bundle)\nprivate  void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic  void setHostDisplayId(int)\nprivate  void onConstructed()\npublic  void filterContentTypes()\nprivate static  int defaultMaxSuggestionCount()\nprivate static  java.lang.String defaultHostPackageName()\nprivate static  android.widget.inline.InlinePresentationSpec defaultInlineTooltipPresentationSpec()\nprivate static  android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.NonNull android.os.Bundle defaultExtras()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java
index 8f270f5..62f3c90 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -412,4 +412,32 @@
     public boolean setImeConsumesInput(boolean imeConsumesInput) {
         return mTarget.setImeConsumesInput(imeConsumesInput);
     }
+
+    /**
+     * Called by the system when it needs to take a snapshot of multiple text-related data in an
+     * atomic manner.
+     *
+     * <p><strong>Editor authors</strong>: Supporting this method is strongly encouraged. Atomically
+     * taken {@link TextSnapshot} is going to be really helpful for the system when optimizing IPCs
+     * in a safe and deterministic manner.  Return {@code null} if an atomically taken
+     * {@link TextSnapshot} is unavailable.  The system continues supporting such a scenario
+     * gracefully.</p>
+     *
+     * <p><strong>IME authors</strong>: Currently IMEs cannot call this method directly and always
+     * receive {@code null} as the result.</p>
+     *
+     * <p>Beware that there is a bug that this method was not overridden in
+     * {@link InputConnectionWrapper}, which ended up always returning {@code null} when gets
+     * called even if the wrapped {@link InputConnection} implements this method.  The bug was
+     * fixed in {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}.</p>
+     *
+     * @return {@code null} if {@link TextSnapshot} is unavailable and/or this API is called from
+     *         IMEs. Beware the bug in older devices mentioned above.
+     * @throws NullPointerException if the target is {@code null}.
+     */
+    @Nullable
+    @Override
+    public TextSnapshot takeSnapshot() {
+        return mTarget.takeSnapshot();
+    }
 }
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 82cf073..41ef44e 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -482,13 +482,21 @@
     private View mNextServedView;
 
     /**
-     * This is the root view of the overall window that currently has input
-     * method focus.
+     * The latest {@link ViewRootImpl} that has, or most recently had, input method focus.
+     *
+     * <p>This value will be cleared when it becomes inactive and no longer has window focus.
      */
+    @Nullable
     @GuardedBy("mH")
     ViewRootImpl mCurRootView;
 
     /**
+     * Whether the {@link #mCurRootView} currently has window focus.
+     */
+    @GuardedBy("mH")
+    boolean mCurRootViewWindowFocused;
+
+    /**
      * This is set when we are in the process of connecting, to determine
      * when we have actually finished.
      */
@@ -745,6 +753,7 @@
         public void onPreWindowGainedFocus(ViewRootImpl viewRootImpl) {
             synchronized (mH) {
                 setCurrentRootViewLocked(viewRootImpl);
+                mCurRootViewWindowFocused = true;
             }
         }
 
@@ -822,6 +831,17 @@
         }
 
         @Override
+        public void onWindowLostFocus(@NonNull ViewRootImpl viewRootImpl) {
+            synchronized (mH) {
+                if (mCurRootView == viewRootImpl) {
+                    mCurRootViewWindowFocused = false;
+
+                    clearCurRootViewIfNeeded();
+                }
+            }
+        }
+
+        @Override
         public void onViewFocusChanged(@Nullable View view, boolean hasFocus) {
             onViewFocusChangedInternal(view, hasFocus);
         }
@@ -1114,6 +1134,10 @@
                             // Note that finishComposingText() is allowed to run
                             // even when we are not active.
                             mFallbackInputConnection.finishComposingTextFromImm();
+
+                            if (clearCurRootViewIfNeeded()) {
+                                return;
+                            }
                         }
                         // Check focus again in case that "onWindowFocus" is called before
                         // handling this message.
@@ -1756,8 +1780,7 @@
     }
 
     /**
-     * Return true if the given view is the currently active view for the
-     * input method.
+     * Return {@code true} if the given view is the currently active view for the input method.
      */
     public boolean isActive(View view) {
         // Re-dispatch if there is a context mismatch.
@@ -1773,7 +1796,7 @@
     }
 
     /**
-     * Return true if any view is currently active in the input method.
+     * Return {@code true} if any view is currently active for the input method.
      */
     public boolean isActive() {
         checkFocus();
@@ -1783,6 +1806,20 @@
     }
 
     /**
+     * Returns {@code true} if the given view's {@link ViewRootImpl} is the currently active one
+     * for the {@code InputMethodManager}.
+     *
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(Manifest.permission.TEST_INPUT_METHOD)
+    public boolean isCurrentRootView(@NonNull View attachedView) {
+        synchronized (mH) {
+            return mCurRootView == attachedView.getViewRootImpl();
+        }
+    }
+
+    /**
      * Return {@code true} if the currently served view is accepting full text edits.
      * If {@code false}, it has no input connection, so it can only handle raw key events.
      */
@@ -1908,6 +1945,24 @@
         mImeDispatcher.clear();
     }
 
+    /**
+     * Clears the {@link #mCurRootView} if it's no longer window focused and the connection is
+     * no longer active.
+     *
+     * @return {@code} true iff it was cleared.
+     */
+    @GuardedBy("mH")
+    private boolean clearCurRootViewIfNeeded() {
+        if (!mActive && !mCurRootViewWindowFocused) {
+            finishInputLocked();
+            mDelegate.setCurrentRootViewLocked(null);
+
+            return true;
+        }
+
+        return false;
+    }
+
     public void displayCompletions(View view, CompletionInfo[] completions) {
         // Re-dispatch if there is a context mismatch.
         final InputMethodManager fallbackImm = getFallbackInputMethodManagerIfNecessary(view);
diff --git a/core/java/android/view/inputmethod/TextBoundsInfo.java b/core/java/android/view/inputmethod/TextBoundsInfo.java
index d42d94e..d9f59d6 100644
--- a/core/java/android/view/inputmethod/TextBoundsInfo.java
+++ b/core/java/android/view/inputmethod/TextBoundsInfo.java
@@ -1025,6 +1025,7 @@
             mEnd = -1;
             mCharacterBounds = null;
             mCharacterFlags = null;
+            mCharacterBidiLevels = null;
             mLineSegmentFinder = null;
             mWordSegmentFinder = null;
             mGraphemeSegmentFinder = null;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 7931d1a..2dbff58 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -724,7 +724,10 @@
         }
 
         getPositionListener().addSubscriber(mCursorAnchorInfoNotifier, true);
-        makeBlink();
+        // Call resumeBlink here instead of makeBlink to ensure that if mBlink is not null the
+        // Blink object is uncancelled.  This ensures when a view is removed and added back the
+        // cursor will resume blinking.
+        resumeBlink();
     }
 
     void onDetachedFromWindow() {
@@ -1094,8 +1097,10 @@
     private void resumeBlink() {
         if (mBlink != null) {
             mBlink.uncancel();
-            makeBlink();
         }
+        // Moving makeBlink outside of the null check block ensures that mBlink object gets
+        // instantiated when the view is added to the window if mBlink is still null.
+        makeBlink();
     }
 
     void adjustInputType(boolean password, boolean passwordInputType,
@@ -2921,6 +2926,9 @@
         if (shouldBlink()) {
             mShowCursor = SystemClock.uptimeMillis();
             if (mBlink == null) mBlink = new Blink();
+            // Call uncancel as mBlink could have previously been cancelled and cursor will not
+            // resume blinking unless uncancelled.
+            mBlink.uncancel();
             mTextView.removeCallbacks(mBlink);
             mTextView.postDelayed(mBlink, BLINK);
         } else {
diff --git a/core/java/android/window/ScreenCapture.java b/core/java/android/window/ScreenCapture.java
index 95451a9..fa7f577 100644
--- a/core/java/android/window/ScreenCapture.java
+++ b/core/java/android/window/ScreenCapture.java
@@ -198,17 +198,21 @@
          * Create ScreenshotHardwareBuffer from an existing HardwareBuffer object.
          *
          * @param hardwareBuffer       The existing HardwareBuffer object
-         * @param namedColorSpace      Integer value of a named color space {@link ColorSpace.Named}
+         * @param dataspace            Dataspace describing the content.
+         *                             {@see android.hardware.DataSpace}
          * @param containsSecureLayers Indicates whether this graphic buffer contains captured
          *                             contents of secure layers, in which case the screenshot
          *                             should not be persisted.
          * @param containsHdrLayers    Indicates whether this graphic buffer contains HDR content.
          */
         private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
-                int namedColorSpace, boolean containsSecureLayers, boolean containsHdrLayers) {
-            ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
+                int dataspace, boolean containsSecureLayers, boolean containsHdrLayers) {
+            ColorSpace colorSpace = ColorSpace.getFromDataSpace(dataspace);
             return new ScreenshotHardwareBuffer(
-                    hardwareBuffer, colorSpace, containsSecureLayers, containsHdrLayers);
+                    hardwareBuffer,
+                    colorSpace != null ? colorSpace : ColorSpace.get(ColorSpace.Named.SRGB),
+                    containsSecureLayers,
+                    containsHdrLayers);
         }
 
         public ColorSpace getColorSpace() {
@@ -271,8 +275,8 @@
         public final boolean mAllowProtected;
         public final long mUid;
         public final boolean mGrayscale;
-
         final SurfaceControl[] mExcludeLayers;
+        public final boolean mHintForSeamlessTransition;
 
         private CaptureArgs(CaptureArgs.Builder<? extends CaptureArgs.Builder<?>> builder) {
             mPixelFormat = builder.mPixelFormat;
@@ -284,6 +288,7 @@
             mUid = builder.mUid;
             mGrayscale = builder.mGrayscale;
             mExcludeLayers = builder.mExcludeLayers;
+            mHintForSeamlessTransition = builder.mHintForSeamlessTransition;
         }
 
         private CaptureArgs(Parcel in) {
@@ -305,6 +310,7 @@
             } else {
                 mExcludeLayers = null;
             }
+            mHintForSeamlessTransition = in.readBoolean();
         }
 
         /** Release any layers if set using {@link Builder#setExcludeLayers(SurfaceControl[])}. */
@@ -352,6 +358,7 @@
             private long mUid = -1;
             private boolean mGrayscale;
             private SurfaceControl[] mExcludeLayers;
+            private boolean mHintForSeamlessTransition;
 
             /**
              * Construct a new {@link CaptureArgs} with the set parameters. The builder remains
@@ -449,6 +456,21 @@
             }
 
             /**
+             * Set whether the screenshot will be used in a system animation.
+             * This hint is used for picking the "best" colorspace for the screenshot, in particular
+             * for mixing HDR and SDR content.
+             * E.g., hintForSeamlessTransition is false, then a colorspace suitable for file
+             * encoding, such as BT2100, may be chosen. Otherwise, then the display's color space
+             * would be chosen, with the possibility of having an extended brightness range. This
+             * is important for screenshots that are directly re-routed to a SurfaceControl in
+             * order to preserve accurate colors.
+             */
+            public T setHintForSeamlessTransition(boolean hintForSeamlessTransition) {
+                mHintForSeamlessTransition = hintForSeamlessTransition;
+                return getThis();
+            }
+
+            /**
              * Each sub class should return itself to allow the builder to chain properly
              */
             T getThis() {
@@ -471,7 +493,6 @@
             dest.writeBoolean(mAllowProtected);
             dest.writeLong(mUid);
             dest.writeBoolean(mGrayscale);
-
             if (mExcludeLayers != null) {
                 dest.writeInt(mExcludeLayers.length);
                 for (SurfaceControl excludeLayer : mExcludeLayers) {
@@ -480,6 +501,7 @@
             } else {
                 dest.writeInt(0);
             }
+            dest.writeBoolean(mHintForSeamlessTransition);
         }
 
         public static final Parcelable.Creator<CaptureArgs> CREATOR =
@@ -627,6 +649,7 @@
                 setUid(args.mUid);
                 setGrayscale(args.mGrayscale);
                 setExcludeLayers(args.mExcludeLayers);
+                setHintForSeamlessTransition(args.mHintForSeamlessTransition);
             }
 
             public Builder(SurfaceControl layer) {
diff --git a/core/java/android/window/StartingWindowRemovalInfo.java b/core/java/android/window/StartingWindowRemovalInfo.java
index 5181236..6999e5b 100644
--- a/core/java/android/window/StartingWindowRemovalInfo.java
+++ b/core/java/android/window/StartingWindowRemovalInfo.java
@@ -16,6 +16,7 @@
 
 package android.window;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Rect;
@@ -23,6 +24,9 @@
 import android.os.Parcelable;
 import android.view.SurfaceControl;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Information when removing a starting window of a particular task.
  * @hide
@@ -55,11 +59,28 @@
      */
     public boolean playRevealAnimation;
 
+    /** The mode is no need to defer removing the starting window for IME */
+    public static final int DEFER_MODE_NONE = 0;
+
+    /** The mode to defer removing the starting window until IME has drawn */
+    public static final int DEFER_MODE_NORMAL = 1;
+
+    /** The mode to defer the starting window removal until IME drawn and finished the rotation */
+    public static final int DEFER_MODE_ROTATION = 2;
+
+    @IntDef(prefix = { "DEFER_MODE_" }, value = {
+            DEFER_MODE_NONE,
+            DEFER_MODE_NORMAL,
+            DEFER_MODE_ROTATION,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DeferMode {}
+
     /**
      * Whether need to defer removing the starting window for IME.
      * @hide
      */
-    public boolean deferRemoveForIme;
+    public @DeferMode int deferRemoveForImeMode;
 
     /**
      * The rounded corner radius
@@ -95,7 +116,7 @@
         windowAnimationLeash = source.readTypedObject(SurfaceControl.CREATOR);
         mainFrame = source.readTypedObject(Rect.CREATOR);
         playRevealAnimation = source.readBoolean();
-        deferRemoveForIme = source.readBoolean();
+        deferRemoveForImeMode = source.readInt();
         roundedCornerRadius = source.readFloat();
         windowlessSurface = source.readBoolean();
         removeImmediately = source.readBoolean();
@@ -107,7 +128,7 @@
         dest.writeTypedObject(windowAnimationLeash, flags);
         dest.writeTypedObject(mainFrame, flags);
         dest.writeBoolean(playRevealAnimation);
-        dest.writeBoolean(deferRemoveForIme);
+        dest.writeInt(deferRemoveForImeMode);
         dest.writeFloat(roundedCornerRadius);
         dest.writeBoolean(windowlessSurface);
         dest.writeBoolean(removeImmediately);
@@ -119,7 +140,7 @@
                 + " frame=" + mainFrame
                 + " playRevealAnimation=" + playRevealAnimation
                 + " roundedCornerRadius=" + roundedCornerRadius
-                + " deferRemoveForIme=" + deferRemoveForIme
+                + " deferRemoveForImeMode=" + deferRemoveForImeMode
                 + " windowlessSurface=" + windowlessSurface
                 + " removeImmediately=" + removeImmediately + "}";
     }
diff --git a/core/java/android/window/TaskConstants.java b/core/java/android/window/TaskConstants.java
index e18fd50..69d79b4 100644
--- a/core/java/android/window/TaskConstants.java
+++ b/core/java/android/window/TaskConstants.java
@@ -73,6 +73,13 @@
      */
     public static final int TASK_CHILD_LAYER_TASK_OVERLAY = 4 * TASK_CHILD_LAYER_REGION_SIZE;
 
+
+    /**
+     * Veil to cover task surface and other window decorations during resizes.
+     * @hide
+     */
+    public static final int TASK_CHILD_LAYER_RESIZE_VEIL = 6 * TASK_CHILD_LAYER_REGION_SIZE;
+
     /**
      * Z-orders of task child layers other than activities, task fragments and layers interleaved
      * with them, e.g. IME windows. [-10000, 10000) is reserved for these layers.
@@ -84,7 +91,8 @@
             TASK_CHILD_LAYER_COMPAT_UI,
             TASK_CHILD_LAYER_WINDOW_DECORATIONS,
             TASK_CHILD_LAYER_RECENTS_ANIMATION_PIP_OVERLAY,
-            TASK_CHILD_LAYER_TASK_OVERLAY
+            TASK_CHILD_LAYER_TASK_OVERLAY,
+            TASK_CHILD_LAYER_RESIZE_VEIL
     })
     public @interface TaskChildLayer {}
 }
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 51382a4..4d0132e 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -21,6 +21,8 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -421,36 +423,45 @@
                 return false;
             }
 
-            boolean requestsPredictiveBack;
+            boolean requestsPredictiveBack = false;
 
             // Check if the context is from an activity.
             while ((context instanceof ContextWrapper) && !(context instanceof Activity)) {
                 context = ((ContextWrapper) context).getBaseContext();
             }
 
+            boolean shouldCheckActivity = false;
+
             if (context instanceof Activity) {
                 final Activity activity = (Activity) context;
 
-                if (activity.getActivityInfo().hasOnBackInvokedCallbackEnabled()) {
-                    requestsPredictiveBack =
-                            activity.getActivityInfo().isOnBackInvokedCallbackEnabled();
-                } else {
-                    requestsPredictiveBack =
-                            context.getApplicationInfo().isOnBackInvokedCallbackEnabled();
-                }
+                final ActivityInfo activityInfo = activity.getActivityInfo();
+                if (activityInfo != null) {
+                    if (activityInfo.hasOnBackInvokedCallbackEnabled()) {
+                        shouldCheckActivity = true;
+                        requestsPredictiveBack = activityInfo.isOnBackInvokedCallbackEnabled();
 
-                if (DEBUG) {
-                    Log.d(TAG, TextUtils.formatSimple("Activity: %s isPredictiveBackEnabled=%s",
-                            activity.getComponentName(),
-                            requestsPredictiveBack));
+                        if (DEBUG) {
+                            Log.d(TAG, TextUtils.formatSimple(
+                                    "Activity: %s isPredictiveBackEnabled=%s",
+                                    activity.getComponentName(),
+                                    requestsPredictiveBack));
+                        }
+                    }
+                } else {
+                    Log.w(TAG, "The ActivityInfo is null, so we cannot verify if this Activity"
+                            + " has the 'android:enableOnBackInvokedCallback' attribute."
+                            + " The application attribute will be used as a fallback.");
                 }
-            } else {
-                requestsPredictiveBack =
-                        context.getApplicationInfo().isOnBackInvokedCallbackEnabled();
+            }
+
+            if (!shouldCheckActivity) {
+                final ApplicationInfo applicationInfo = context.getApplicationInfo();
+                requestsPredictiveBack = applicationInfo.isOnBackInvokedCallbackEnabled();
 
                 if (DEBUG) {
                     Log.d(TAG, TextUtils.formatSimple("App: %s requestsPredictiveBack=%s",
-                            context.getApplicationInfo().packageName,
+                            applicationInfo.packageName,
                             requestsPredictiveBack));
                 }
             }
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
index 3a8f427..4f9fc39 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
@@ -32,6 +32,9 @@
 import android.os.Build;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.telecom.TelecomManager;
+import android.telephony.Annotation;
+import android.telephony.TelephonyManager;
 import android.text.ParcelableSpan;
 import android.text.Spanned;
 import android.text.TextUtils;
@@ -204,6 +207,32 @@
     }
 
     /**
+     * Intercepts the {@link AccessibilityService#GLOBAL_ACTION_KEYCODE_HEADSETHOOK} action
+     * by directly interacting with TelecomManager if a call is incoming or in progress.
+     *
+     * <p>
+     * Provided here in shared utils to be used by both the legacy and modern (SysUI)
+     * system action implementations.
+     * </p>
+     *
+     * @return True if the action was propagated to TelecomManager, otherwise false.
+     */
+    public static boolean interceptHeadsetHookForActiveCall(Context context) {
+        final TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+        @Annotation.CallState final int callState =
+                telecomManager != null ? telecomManager.getCallState()
+                        : TelephonyManager.CALL_STATE_IDLE;
+        if (callState == TelephonyManager.CALL_STATE_RINGING) {
+            telecomManager.acceptRingingCall();
+            return true;
+        } else if (callState == TelephonyManager.CALL_STATE_OFFHOOK) {
+            telecomManager.endCall();
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Indicates whether the current user has completed setup via the setup wizard.
      * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE}
      *
diff --git a/core/java/com/android/internal/app/IVoiceInteractionSoundTriggerSession.aidl b/core/java/com/android/internal/app/IVoiceInteractionSoundTriggerSession.aidl
index 1ccc71a..23de50c 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionSoundTriggerSession.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionSoundTriggerSession.aidl
@@ -94,4 +94,9 @@
      */
     @nullable SoundTrigger.ModelParamRange queryParameter(int keyphraseId,
             in ModelParams modelParam);
+    /**
+     * Invalidates the sound trigger session and clears any associated resources. Subsequent calls
+     * to this object will throw IllegalStateException.
+     */
+    void detach();
 }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 499d38c..50f393b 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1725,16 +1725,17 @@
 
         if (inWorkProfile) {
             ((TextView) findViewById(R.id.open_cross_profile)).setText(
-                    devicePolicyResourcesManager.getString(MINIRESOLVER_OPEN_IN_WORK,
-                            () -> getString(R.string.miniresolver_open_in_work, targetDisplayLabel),
+                    devicePolicyResourcesManager.getString(MINIRESOLVER_OPEN_IN_PERSONAL,
+                            () -> getString(R.string.miniresolver_open_in_personal,
+                                    targetDisplayLabel),
                             targetDisplayLabel));
             ((Button) findViewById(R.id.use_same_profile_browser)).setText(
                     devicePolicyResourcesManager.getString(MINIRESOLVER_USE_WORK_BROWSER,
                             () -> getString(R.string.miniresolver_use_work_browser)));
         } else {
             ((TextView) findViewById(R.id.open_cross_profile)).setText(
-                    devicePolicyResourcesManager.getString(MINIRESOLVER_OPEN_IN_PERSONAL,
-                            () -> getString(R.string.miniresolver_open_in_personal,
+                    devicePolicyResourcesManager.getString(MINIRESOLVER_OPEN_IN_WORK,
+                            () -> getString(R.string.miniresolver_open_in_work,
                                     targetDisplayLabel),
                             targetDisplayLabel));
             ((Button) findViewById(R.id.use_same_profile_browser)).setText(
diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
index 853fe2f..86c2893 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
@@ -76,7 +76,7 @@
 
         /** Gating the removal of sorting-notifications-by-interruptiveness. */
         public static final Flag NO_SORT_BY_INTERRUPTIVENESS =
-                devFlag("persist.sysui.notification.no_sort_by_interruptiveness");
+                releasedFlag("persist.sysui.notification.no_sort_by_interruptiveness");
 
         /** Gating the logging of DND state change events. */
         public static final Flag LOG_DND_STATE_EVENTS =
@@ -115,7 +115,7 @@
     }
 
     /**
-     * Creates a flag that is enabled by default in debuggable builds.
+     * Creates a flag that is disabled 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.
diff --git a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
deleted file mode 100644
index 39d8380..0000000
--- a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
+++ /dev/null
@@ -1,92 +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.internal.display;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.Display;
-
-/**
- * Constants and utility methods for refresh rate settings.
- */
-public class RefreshRateSettingsUtils {
-
-    private static final String TAG = "RefreshRateSettingsUtils";
-
-    public static final float DEFAULT_REFRESH_RATE = 60f;
-
-    /**
-     * Find the highest refresh rate among all the modes of the default display.
-     * @param context The context
-     * @return The highest refresh rate
-     */
-    public static float findHighestRefreshRateForDefaultDisplay(Context context) {
-        final DisplayManager dm = context.getSystemService(DisplayManager.class);
-        final Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
-
-        if (display == null) {
-            Log.w(TAG, "No valid default display device");
-            return DEFAULT_REFRESH_RATE;
-        }
-
-        float maxRefreshRate = DEFAULT_REFRESH_RATE;
-        for (Display.Mode mode : display.getSupportedModes()) {
-            if (Math.round(mode.getRefreshRate()) > maxRefreshRate) {
-                maxRefreshRate = mode.getRefreshRate();
-            }
-        }
-        return maxRefreshRate;
-    }
-
-    /**
-     * Get the min refresh rate which is determined by
-     * {@link Settings.System.FORCE_PEAK_REFRESH_RATE}.
-     * @param context The context
-     * @return The min refresh rate
-     */
-    public static float getMinRefreshRate(Context context) {
-        final ContentResolver cr = context.getContentResolver();
-        int forcePeakRefreshRateSetting = Settings.System.getIntForUser(cr,
-                Settings.System.FORCE_PEAK_REFRESH_RATE, -1, cr.getUserId());
-        return forcePeakRefreshRateSetting == 1
-                ? findHighestRefreshRateForDefaultDisplay(context)
-                : 0;
-    }
-
-    /**
-     * Get the peak refresh rate which is determined by {@link Settings.System.SMOOTH_DISPLAY}.
-     * @param context The context
-     * @param defaultPeakRefreshRate The refresh rate to return if the setting doesn't have a value
-     * @return The peak refresh rate
-     */
-    public static float getPeakRefreshRate(Context context, float defaultPeakRefreshRate) {
-        final ContentResolver cr = context.getContentResolver();
-        int smoothDisplaySetting = Settings.System.getIntForUser(cr,
-                Settings.System.SMOOTH_DISPLAY, -1, cr.getUserId());
-        switch (smoothDisplaySetting) {
-            case 0:
-                return DEFAULT_REFRESH_RATE;
-            case 1:
-                return findHighestRefreshRateForDefaultDisplay(context);
-            default:
-                return defaultPeakRefreshRate;
-        }
-    }
-}
diff --git a/core/java/com/android/internal/util/TraceBuffer.java b/core/java/com/android/internal/util/TraceBuffer.java
index bfcd65d..fcc77bd4 100644
--- a/core/java/com/android/internal/util/TraceBuffer.java
+++ b/core/java/com/android/internal/util/TraceBuffer.java
@@ -103,6 +103,10 @@
         this(bufferCapacity, new ProtoOutputStreamProvider(), null);
     }
 
+    public TraceBuffer(int bufferCapacity, Consumer<T> protoDequeuedCallback) {
+        this(bufferCapacity, new ProtoOutputStreamProvider(), protoDequeuedCallback);
+    }
+
     public TraceBuffer(int bufferCapacity, ProtoProvider protoProvider,
             Consumer<T> protoDequeuedCallback) {
         mBufferCapacity = bufferCapacity;
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index fbad4b9..a554d0e 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -731,7 +731,7 @@
         return DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION,
                 FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                /* defaultValue= */ false);
+                /* defaultValue= */ true);
     }
 
     /** Returns if the given quality maps to an alphabetic password */
diff --git a/core/java/com/android/internal/widget/NotificationActionListLayout.java b/core/java/com/android/internal/widget/NotificationActionListLayout.java
index 302d2e7..a7a69c9 100644
--- a/core/java/com/android/internal/widget/NotificationActionListLayout.java
+++ b/core/java/com/android/internal/widget/NotificationActionListLayout.java
@@ -50,6 +50,8 @@
     private boolean mEmphasizedMode;
     private int mDefaultPaddingBottom;
     private int mDefaultPaddingTop;
+    private int mEmphasizedPaddingTop;
+    private int mEmphasizedPaddingBottom;
     private int mEmphasizedHeight;
     private int mRegularHeight;
     @DimenRes private int mCollapsibleIndentDimen = R.dimen.notification_actions_padding_start;
@@ -322,13 +324,16 @@
     }
 
     private void updateHeights() {
-        int paddingTop = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin);
+        int inset = getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.button_inset_vertical_material);
+        mEmphasizedPaddingTop = getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.notification_content_margin) - inset;
         // same padding on bottom and at end
-        int paddingBottom = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin_end);
-        mEmphasizedHeight = paddingBottom + paddingTop + getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_action_emphasized_height);
+        mEmphasizedPaddingBottom = getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.notification_content_margin_end) - inset;
+        mEmphasizedHeight = mEmphasizedPaddingTop + mEmphasizedPaddingBottom
+                + getResources().getDimensionPixelSize(
+                        com.android.internal.R.dimen.notification_action_emphasized_height);
         mRegularHeight = getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_action_list_height);
     }
@@ -356,18 +361,10 @@
         mEmphasizedMode = emphasizedMode;
         int height;
         if (emphasizedMode) {
-            int paddingTop = getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.notification_content_margin);
-            // same padding on bottom and at end
-            int paddingBottom = getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.notification_content_margin_end);
-            int buttonPaddingInternal = getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.button_inset_vertical_material);
             setPaddingRelative(getPaddingStart(),
-                    paddingTop - buttonPaddingInternal,
+                    mEmphasizedPaddingTop,
                     getPaddingEnd(),
-                    paddingBottom - buttonPaddingInternal);
-
+                    mEmphasizedPaddingBottom);
             setMinimumHeight(mEmphasizedHeight);
             height = ViewGroup.LayoutParams.WRAP_CONTENT;
         } else {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 8e96ac1..193099b 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -616,6 +616,12 @@
                            genReleaseCallback(env, releaseCallback));
 }
 
+static void nativeUnsetBuffer(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+    transaction->unsetBuffer(ctrl);
+}
+
 static void nativeSetBufferTransform(JNIEnv* env, jclass clazz, jlong transactionObj,
                                      jlong nativeObject, jint transform) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -2198,6 +2204,8 @@
             (void*)nativeSetGeometry },
     {"nativeSetBuffer", "(JJLandroid/hardware/HardwareBuffer;JLjava/util/function/Consumer;)V",
             (void*)nativeSetBuffer },
+    {"nativeUnsetBuffer", "(JJ)V", (void*)nativeUnsetBuffer },
+
     {"nativeSetBufferTransform", "(JJI)V", (void*) nativeSetBufferTransform},
     {"nativeSetDataSpace", "(JJI)V",
             (void*)nativeSetDataSpace },
diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp
index 1b67a0d..986dbe9 100644
--- a/core/jni/android_window_ScreenCapture.cpp
+++ b/core/jni/android_window_ScreenCapture.cpp
@@ -46,6 +46,7 @@
     jfieldID uid;
     jfieldID grayscale;
     jmethodID getNativeExcludeLayers;
+    jfieldID hintForSeamlessTransition;
 } gCaptureArgsClassInfo;
 
 static struct {
@@ -69,23 +70,6 @@
     jmethodID builder;
 } gScreenshotHardwareBufferClassInfo;
 
-enum JNamedColorSpace : jint {
-    // ColorSpace.Named.SRGB.ordinal() = 0;
-    SRGB = 0,
-
-    // ColorSpace.Named.DISPLAY_P3.ordinal() = 7;
-    DISPLAY_P3 = 7,
-};
-
-constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
-    switch (dataspace) {
-        case ui::Dataspace::DISPLAY_P3:
-            return JNamedColorSpace::DISPLAY_P3;
-        default:
-            return JNamedColorSpace::SRGB;
-    }
-}
-
 static void checkAndClearException(JNIEnv* env, const char* methodName) {
     if (env->ExceptionCheck()) {
         ALOGE("An exception was thrown by callback '%s'.", methodName);
@@ -119,12 +103,11 @@
         captureResults.fenceResult.value()->waitForever(LOG_TAG);
         jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
                 env, captureResults.buffer->toAHardwareBuffer());
-        const jint namedColorSpace =
-                fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
         jobject screenshotHardwareBuffer =
                 env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
                                             gScreenshotHardwareBufferClassInfo.builder,
-                                            jhardwareBuffer, namedColorSpace,
+                                            jhardwareBuffer,
+                                            static_cast<jint>(captureResults.capturedDataspace),
                                             captureResults.capturedSecureLayers,
                                             captureResults.capturedHdrLayers);
         checkAndClearException(env, "builder");
@@ -185,6 +168,9 @@
             captureArgs.excludeHandles.emplace(excludeObject->getHandle());
         }
     }
+    captureArgs.hintForSeamlessTransition =
+            env->GetBooleanField(captureArgsObject,
+                                 gCaptureArgsClassInfo.hintForSeamlessTransition);
 }
 
 static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
@@ -318,9 +304,10 @@
             GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z");
     gCaptureArgsClassInfo.uid = GetFieldIDOrDie(env, captureArgsClazz, "mUid", "J");
     gCaptureArgsClassInfo.grayscale = GetFieldIDOrDie(env, captureArgsClazz, "mGrayscale", "Z");
-
     gCaptureArgsClassInfo.getNativeExcludeLayers =
             GetMethodIDOrDie(env, captureArgsClazz, "getNativeExcludeLayers", "()[J");
+    gCaptureArgsClassInfo.hintForSeamlessTransition =
+            GetFieldIDOrDie(env, captureArgsClazz, "mHintForSeamlessTransition", "Z");
 
     jclass displayCaptureArgsClazz =
             FindClassOrDie(env, "android/window/ScreenCapture$DisplayCaptureArgs");
diff --git a/core/proto/android/companion/telecom.proto b/core/proto/android/companion/telecom.proto
index 9ccadbf..3a9e5ee 100644
--- a/core/proto/android/companion/telecom.proto
+++ b/core/proto/android/companion/telecom.proto
@@ -20,9 +20,9 @@
 
 option java_multiple_files = true;
 
-// Next index: 2
+// Next index: 4
 message Telecom {
-  // Next index: 5
+  // Next index: 6
   message Call {
     // UUID representing this call
     int64 id = 1;
@@ -34,6 +34,8 @@
       // Human-readable name of the app processing this call
       string app_name = 2;
       bytes app_icon = 3;
+      // Unique identifier for this app, such as a package name.
+      string app_identifier = 4;
     }
     Origin origin = 2;
 
@@ -59,9 +61,11 @@
       REJECT_AND_BLOCK = 9;
       IGNORE = 10;
     }
-    repeated Control controls_available = 4;
+    repeated Control controls = 4;
   }
 
   // The list of active calls.
   repeated Call calls = 1;
+  // The list of requested calls or call changes.
+  repeated Call requests = 2;
 }
diff --git a/core/proto/android/server/windowmanagertransitiontrace.proto b/core/proto/android/server/windowmanagertransitiontrace.proto
index c3cbc91..a776bd2 100644
--- a/core/proto/android/server/windowmanagertransitiontrace.proto
+++ b/core/proto/android/server/windowmanagertransitiontrace.proto
@@ -44,6 +44,10 @@
   // Additional debugging info only collected and dumped when explicitly requested to trace
   repeated TransitionState transition_states = 3;
   repeated TransitionInfo transition_info = 4;
+
+  /* offset between real-time clock and elapsed time clock in nanoseconds.
+   Calculated as: 1000000 * System.currentTimeMillis() - SystemClock.elapsedRealtimeNanos() */
+  optional fixed64 real_to_elapsed_time_offset_nanos = 5;
 }
 
 message Transition {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 11fcd1e..fefa79f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2542,7 +2542,7 @@
     <permission android:name="android.permission.TURN_SCREEN_ON"
         android:label="@string/permlab_turnScreenOn"
         android:description="@string/permdesc_turnScreenOn"
-        android:protectionLevel="normal|appop" />
+        android:protectionLevel="signature|privileged|appop" />
 
     <!-- ==================================================== -->
     <!-- Permissions related to changing audio settings   -->
@@ -5418,6 +5418,15 @@
     <permission android:name="android.permission.INSTALL_DPC_PACKAGES"
                 android:protectionLevel="signature|role" />
 
+    <!-- Allows an application to read resolved paths to the APKs (Base and any splits)
+         of a session based install.
+         <p>Not for use by third-party applications.
+         @hide
+    -->
+    <permission android:name="android.permission.READ_INSTALLED_SESSION_PATHS"
+                android:protectionLevel="signature|installer" />
+    <uses-permission android:name="android.permission.READ_INSTALLED_SESSION_PATHS" />
+
     <!-- Allows an application to use System Data Loaders.
          <p>Not for use by third-party applications.
          @hide
@@ -8058,16 +8067,6 @@
             </intent-filter>
         </receiver>
 
-        <!-- Broadcast Receiver listen to sufficient verifier requests from Package Manager
-             when install new SDK, to verifier SDK code during installation time
-             and terminate install if SDK not compatible with privacy sandbox restrictions. -->
-        <receiver android:name="com.android.server.sdksandbox.SdkSandboxVerifierReceiver"
-                 android:exported="false">
-            <intent-filter>
-                <action android:name="android.intent.action.PACKAGE_NEEDS_VERIFICATION"/>
-            </intent-filter>
-        </receiver>
-
         <service android:name="android.hardware.location.GeofenceHardwareService"
             android:permission="android.permission.LOCATION_HARDWARE"
             android:exported="false" />
@@ -8195,6 +8194,10 @@
             android:permission="android.permission.BIND_JOB_SERVICE">
         </service>
 
+        <service android:name="com.android.server.healthconnect.backuprestore.BackupRestore$BackupRestoreJobService"
+            android:permission="android.permission.BIND_JOB_SERVICE">
+        </service>
+
         <service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader"
             android:exported="false">
             <intent-filter>
@@ -8219,6 +8222,8 @@
         <service android:name="com.android.server.companion.datatransfer.contextsync.CallMetadataSyncInCallService"
                  android:permission="android.permission.BIND_INCALL_SERVICE"
                  android:exported="true">
+            <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+                       android:value="true" />
             <intent-filter>
                 <action android:name="android.telecom.InCallService"/>
             </intent-filter>
diff --git a/core/res/res/drawable-hdpi/pointer_all_scroll.png b/core/res/res/drawable-hdpi/pointer_all_scroll.png
index 095aadc..4af84c3 100644
--- a/core/res/res/drawable-hdpi/pointer_all_scroll.png
+++ b/core/res/res/drawable-hdpi/pointer_all_scroll.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/pointer_horizontal_double_arrow.png b/core/res/res/drawable-hdpi/pointer_horizontal_double_arrow.png
index 9388f16..c4018c8 100644
--- a/core/res/res/drawable-hdpi/pointer_horizontal_double_arrow.png
+++ b/core/res/res/drawable-hdpi/pointer_horizontal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/pointer_top_left_diagonal_double_arrow.png b/core/res/res/drawable-hdpi/pointer_top_left_diagonal_double_arrow.png
index ab52bff..58bb0d4 100644
--- a/core/res/res/drawable-hdpi/pointer_top_left_diagonal_double_arrow.png
+++ b/core/res/res/drawable-hdpi/pointer_top_left_diagonal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/pointer_top_right_diagonal_double_arrow.png b/core/res/res/drawable-hdpi/pointer_top_right_diagonal_double_arrow.png
index 1250d35..1981d41 100644
--- a/core/res/res/drawable-hdpi/pointer_top_right_diagonal_double_arrow.png
+++ b/core/res/res/drawable-hdpi/pointer_top_right_diagonal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/pointer_vertical_double_arrow.png b/core/res/res/drawable-hdpi/pointer_vertical_double_arrow.png
index 6730c7b..d4ba79a 100644
--- a/core/res/res/drawable-hdpi/pointer_vertical_double_arrow.png
+++ b/core/res/res/drawable-hdpi/pointer_vertical_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_all_scroll.png b/core/res/res/drawable-mdpi/pointer_all_scroll.png
index 3db456e..1b81d0a 100644
--- a/core/res/res/drawable-mdpi/pointer_all_scroll.png
+++ b/core/res/res/drawable-mdpi/pointer_all_scroll.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_all_scroll_large.png b/core/res/res/drawable-mdpi/pointer_all_scroll_large.png
index 120e1d7..9e1f5c9 100644
--- a/core/res/res/drawable-mdpi/pointer_all_scroll_large.png
+++ b/core/res/res/drawable-mdpi/pointer_all_scroll_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow.png b/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow.png
index 20f319a..d1b3441 100644
--- a/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow.png
+++ b/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow_large.png b/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow_large.png
index 33ef5c9..4e26371 100644
--- a/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow_large.png
+++ b/core/res/res/drawable-mdpi/pointer_horizontal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow.png b/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow.png
index fe7d496..34c0c6a 100644
--- a/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow.png
+++ b/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow_large.png b/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow_large.png
index 7b2e20c..87ec184 100644
--- a/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow_large.png
+++ b/core/res/res/drawable-mdpi/pointer_top_left_diagonal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow.png b/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow.png
index 95a6620..40b9c7e 100644
--- a/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow.png
+++ b/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow_large.png b/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow_large.png
index 2e2904b..6a85b49 100644
--- a/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow_large.png
+++ b/core/res/res/drawable-mdpi/pointer_top_right_diagonal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_vertical_double_arrow.png b/core/res/res/drawable-mdpi/pointer_vertical_double_arrow.png
index ae6bfed..9bd89bf 100644
--- a/core/res/res/drawable-mdpi/pointer_vertical_double_arrow.png
+++ b/core/res/res/drawable-mdpi/pointer_vertical_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_vertical_double_arrow_large.png b/core/res/res/drawable-mdpi/pointer_vertical_double_arrow_large.png
index 3beb1d1..5a69bbc 100644
--- a/core/res/res/drawable-mdpi/pointer_vertical_double_arrow_large.png
+++ b/core/res/res/drawable-mdpi/pointer_vertical_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_all_scroll.png b/core/res/res/drawable-xhdpi/pointer_all_scroll.png
index e9d05d5..85aa022 100644
--- a/core/res/res/drawable-xhdpi/pointer_all_scroll.png
+++ b/core/res/res/drawable-xhdpi/pointer_all_scroll.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_all_scroll_large.png b/core/res/res/drawable-xhdpi/pointer_all_scroll_large.png
index 1fd54fb..7448339 100644
--- a/core/res/res/drawable-xhdpi/pointer_all_scroll_large.png
+++ b/core/res/res/drawable-xhdpi/pointer_all_scroll_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow.png b/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow.png
index caf2a97..dd37f92 100644
--- a/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow.png
+++ b/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow_large.png b/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow_large.png
index 2f22640..9e031e8 100644
--- a/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow_large.png
+++ b/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow.png b/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow.png
index a36deb3..150d80d 100644
--- a/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow.png
+++ b/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow_large.png b/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow_large.png
index 6870e23..bae907a 100644
--- a/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow_large.png
+++ b/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow.png b/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow.png
index c8d6d1f..3b23143 100644
--- a/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow.png
+++ b/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow_large.png b/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow_large.png
index 5bfb771..a90b286 100644
--- a/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow_large.png
+++ b/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow.png b/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow.png
index 720df91..3e7f850 100644
--- a/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow.png
+++ b/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow_large.png b/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow_large.png
index 82b30d1..090e3ca 100644
--- a/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow_large.png
+++ b/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/pointer_all_scroll.png b/core/res/res/drawable-xxhdpi/pointer_all_scroll.png
index 808143a..92aae72 100644
--- a/core/res/res/drawable-xxhdpi/pointer_all_scroll.png
+++ b/core/res/res/drawable-xxhdpi/pointer_all_scroll.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/pointer_horizontal_double_arrow.png b/core/res/res/drawable-xxhdpi/pointer_horizontal_double_arrow.png
index 677ccad..b1e2509 100644
--- a/core/res/res/drawable-xxhdpi/pointer_horizontal_double_arrow.png
+++ b/core/res/res/drawable-xxhdpi/pointer_horizontal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/pointer_top_left_diagonal_double_arrow.png b/core/res/res/drawable-xxhdpi/pointer_top_left_diagonal_double_arrow.png
index e01aa64..2d1217c 100644
--- a/core/res/res/drawable-xxhdpi/pointer_top_left_diagonal_double_arrow.png
+++ b/core/res/res/drawable-xxhdpi/pointer_top_left_diagonal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/pointer_top_right_diagonal_double_arrow.png b/core/res/res/drawable-xxhdpi/pointer_top_right_diagonal_double_arrow.png
index e947e0e..a99fb24 100644
--- a/core/res/res/drawable-xxhdpi/pointer_top_right_diagonal_double_arrow.png
+++ b/core/res/res/drawable-xxhdpi/pointer_top_right_diagonal_double_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/pointer_vertical_double_arrow.png b/core/res/res/drawable-xxhdpi/pointer_vertical_double_arrow.png
index c867247..1f065fa 100644
--- a/core/res/res/drawable-xxhdpi/pointer_vertical_double_arrow.png
+++ b/core/res/res/drawable-xxhdpi/pointer_vertical_double_arrow.png
Binary files differ
diff --git a/core/res/res/layout-television/user_switching_dialog.xml b/core/res/res/layout-television/user_switching_dialog.xml
deleted file mode 100644
index 72150e3..0000000
--- a/core/res/res/layout-television/user_switching_dialog.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/message"
-        style="?attr/textAppearanceListItem"
-        android:layout_width="match_parent"
-        android:background="@color/background_leanback_dark"
-        android:textColor="@color/primary_text_leanback_dark"
-        android:layout_height="match_parent"
-        android:gravity="center"
-        android:paddingStart="?attr/dialogPreferredPadding"
-        android:paddingEnd="?attr/dialogPreferredPadding"
-        android:paddingTop="24dp"
-        android:paddingBottom="24dp" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index a12b3ac..2b778b2 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Laat die program toe om die vibrator te beheer."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Stel die program in staat om toegang tot die vibreerderstand te kry."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"skakel foonnommers direk"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Laat die program toe om telefoonnommers sonder jou tussentrede te bel. Dit kan tot onverwagte heffings of oproepe lei. Let daarop dat dit nie die program toelaat om noodnommers te bel nie. Kwaadwillige programme kan jou geld kos deur oproepe sonder jou bevestiging te maak."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"toegang tot kitsboodskapoproepdiens"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Laat die program toe om die kitsboodskapdiens te gebruik om oproepe sonder jou ingryping te maak."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"lees foonstatus en identiteit"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Gesighandeling is gekanselleer."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Gebruiker het Gesigslot gekanselleer"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Te veel pogings. Probeer later weer."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Te veel pogings. Gesigslot is onbeskikbaar."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Te veel pogings. Gebruik eerder skermslot."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kan nie gesig verifieer nie. Probeer weer."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Jy het nie Gesigslot opgestel nie"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Hierdie inhoud kan nie met werkprogramme oopgemaak word nie"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Hierdie inhoud kan nie met persoonlike programme gedeel word nie"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Hierdie inhoud kan nie met persoonlike programme oopgemaak word nie"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Werkprofiel is onderbreek"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tik om aan te skakel"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Geen werkprogramme nie"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Geen persoonlike programme nie"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Maak persoonlike <xliff:g id="APP">%s</xliff:g> oop"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Maak werk-<xliff:g id="APP">%s</xliff:g> oop"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Gebruik persoonlike blaaier"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Gebruik werkblaaier"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM se netwerkontsluiting-PIN"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index c923218..7c99b8a 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -249,16 +249,16 @@
     <string name="global_action_emergency" msgid="1387617624177105088">"ድንገተኛ አደጋ"</string>
     <string name="global_action_bug_report" msgid="5127867163044170003">"የሳንካ ሪፖርት"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"ክፍለ-ጊዜን አብቃ"</string>
-    <string name="global_action_screenshot" msgid="2610053466156478564">"ቅጽበታዊ ገጽ እይታ"</string>
+    <string name="global_action_screenshot" msgid="2610053466156478564">"ቅጽበታዊ ገፅ እይታ"</string>
     <string name="bugreport_title" msgid="8549990811777373050">"የሳንካ ሪፖርት"</string>
     <string name="bugreport_message" msgid="5212529146119624326">"ይሄ እንደ የኢሜይል መልዕክት አድርጎ የሚልከውን ስለመሣሪያዎ የአሁኑ ሁኔታ መረጃ ይሰበስባል። የሳንካ ሪፖርቱን ከመጀመር ጀምሮ እስኪላክ ድረስ ትንሽ ጊዜ ይወስዳል፤ እባክዎ ይታገሱ።"</string>
     <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"መስተጋብራዊ ሪፖርት"</string>
-    <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"በአብዛኛዎቹ ሁኔታዎች ላይ ይህን ይጠቀሙ። የሪፖርቱን ሂደት እንዲከታተሉ፣ ስለችግሩ ተጨማሪ ዝርዝሮችን እንዲያስገቡ እና ቅጽበታዊ ገጽ እይታዎችን እንዲያነሱ ያስችልዎታል። ሪፖርት ለማድረግ ረዥም ጊዜ የሚወስዱ አንዳንድ ብዙም ጥቅም ላይ የማይውሉ ክፍሎችን ሊያልፋቸው ይችላል።"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"በአብዛኛዎቹ ሁኔታዎች ላይ ይህን ይጠቀሙ። የሪፖርቱን ሂደት እንዲከታተሉ፣ ስለችግሩ ተጨማሪ ዝርዝሮችን እንዲያስገቡ እና ቅጽበታዊ ገፅ እይታዎችን እንዲያነሱ ያስችልዎታል። ሪፖርት ለማድረግ ረዥም ጊዜ የሚወስዱ አንዳንድ ብዙም ጥቅም ላይ የማይውሉ ክፍሎችን ሊያልፋቸው ይችላል።"</string>
     <string name="bugreport_option_full_title" msgid="7681035745950045690">"ሙሉ ሪፖርት"</string>
-    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"መሣሪያዎ ምላሽ የማይሰጥ ወይም በጣም ቀርፋፋ ከሆነ፣ ወይም ሁሉንም የሪፖርት ክፍሎች የሚያስፈልገዎት ከሆነ ለዝቅተኛ የስርዓት ጣልቃ-ገብነት ይህን አማራጭ ይጠቀሙ። ተጨማሪ ዝርዝሮችን እንዲያስገቡ ወይም ተጨማሪ ቅጽበታዊ ገጽ እይታዎችን እንዲያነሱ አያስችልዎትም።"</string>
-    <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{በ# ሰከንድ ውስጥ ለሳንካ ሪፖርት ቅጽበታዊ ገጽ ዕይታን በማንሳት ላይ።}one{በ# ሰከንዶች ውስጥ ለሳንካ ሪፖርት ቅጽበታዊ ገጽ ዕይታን በማንሳት ላይ።}other{በ# ሰከንዶች ውስጥ ለሳንካ ሪፖርት ቅጽበታዊ ገጽ ዕይታን በማንሳት ላይ።}}"</string>
-    <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"ቅጽበታዊ ገጽ እይታ ከሳንካ ሪፖርት ጋር ተነስቷል"</string>
-    <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"ቅጽበታዊ ገጽ እይታን ከሳንካ ሪፖርት ጋር ማንሳት አልተሳካም"</string>
+    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"መሣሪያዎ ምላሽ የማይሰጥ ወይም በጣም ቀርፋፋ ከሆነ፣ ወይም ሁሉንም የሪፖርት ክፍሎች የሚያስፈልገዎት ከሆነ ለዝቅተኛ የስርዓት ጣልቃ-ገብነት ይህን አማራጭ ይጠቀሙ። ተጨማሪ ዝርዝሮችን እንዲያስገቡ ወይም ተጨማሪ ቅጽበታዊ ገፅ እይታዎችን እንዲያነሱ አያስችልዎትም።"</string>
+    <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{በ# ሰከንድ ውስጥ ለሳንካ ሪፖርት ቅጽበታዊ ገፅ ዕይታን በማንሳት ላይ።}one{በ# ሰከንዶች ውስጥ ለሳንካ ሪፖርት ቅጽበታዊ ገፅ ዕይታን በማንሳት ላይ።}other{በ# ሰከንዶች ውስጥ ለሳንካ ሪፖርት ቅጽበታዊ ገፅ ዕይታን በማንሳት ላይ።}}"</string>
+    <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"ቅጽበታዊ ገፅ እይታ ከሳንካ ሪፖርት ጋር ተነስቷል"</string>
+    <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"ቅጽበታዊ ገፅ እይታን ከሳንካ ሪፖርት ጋር ማንሳት አልተሳካም"</string>
     <string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"የፀጥታ ሁነታ"</string>
     <string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"ድምፅ ጠፍቷል"</string>
     <string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"ድምፅ በርቷል"</string>
@@ -340,8 +340,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"መታ ማድረግ፣ ማንሸራተት፣ መቆንጠጥ እና ሌሎች የጣት ምልክቶችን ማከናወን ይችላል።"</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"የጣት አሻራ ምልክቶች"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"በመሣሪያው የጣት አሻራ ዳሳሽ ላይ የተከናወኑ የጣት ምልክቶችን መያዝ ይችላል።"</string>
-    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ቅጽበታዊ ገጽ እይታን ያነሳል"</string>
-    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"የማሳያው ቅጽበታዊ ገጽ እይታን ማንሳት ይችላል።"</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ቅጽበታዊ ገፅ እይታን ያነሳል"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"የማሳያው ቅጽበታዊ ገፅ እይታን ማንሳት ይችላል።"</string>
     <string name="dream_preview_title" msgid="5570751491996100804">"ቅድመ ዕይታ፣ <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"የሁኔቴ አሞሌ አቦዝን ወይም ቀይር"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"የስርዓት አዶዎችን ወደ ሁኔታ አሞሌ ላለማስቻል ወይም ለማከል እና ለማስወገድ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
@@ -349,12 +349,12 @@
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"የኹናቴ አሞሌ እንዲሆን ለመተግበሪያው ይፈቅዳሉ።"</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"የሁኔታ አሞሌ ዘርጋ/ሰብስብ"</string>
     <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"የሁኔታ አሞሌን ለመዝረጋት እና ለመሰብሰብ ለመተግበሪያው ይፈቅዳሉ።"</string>
-    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"በአንድ የተቆለፈ መሣሪያ ላይ ማሳወቂያዎችን እንደ የሙሉ ገጽ እይታ እንቅስቃሴዎችን ማሳየት"</string>
-    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"መተግበሪያው በአንድ የተቆለፈ መሣሪያ ላይ ማሳወቂያዎችን እንደ የሙሉ ገጽ እይታ እንቅስቃሴዎች አድርጎ እንዲያሳይ ያስችለዋል"</string>
+    <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"በአንድ የተቆለፈ መሣሪያ ላይ ማሳወቂያዎችን እንደ የሙሉ ገፅ እይታ እንቅስቃሴዎችን ማሳየት"</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"መተግበሪያው በአንድ የተቆለፈ መሣሪያ ላይ ማሳወቂያዎችን እንደ የሙሉ ገፅ እይታ እንቅስቃሴዎች አድርጎ እንዲያሳይ ያስችለዋል"</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"አቋራጮችን ይጭናል"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"አንድ መተግበሪያ ያለተጠቃሚ ጣልቃ-ገብነት የመነሻ ማያ ገጽ አቋራጮችን እንዲያክል ያስችለዋል።"</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"አንድ መተግበሪያ ያለተጠቃሚ ጣልቃ-ገብነት የመነሻ ማያ ገፅ አቋራጮችን እንዲያክል ያስችለዋል።"</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"አቋራጮችን ያራግፋል"</string>
-    <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"መተግበሪያው ያለተጠቃሚ ጣልቃ-ገብነት የመነሻ ማያ ገጽ አቋራጮችን እንዲያስወግድ ያስችለዋል።"</string>
+    <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"መተግበሪያው ያለተጠቃሚ ጣልቃ-ገብነት የመነሻ ማያ ገፅ አቋራጮችን እንዲያስወግድ ያስችለዋል።"</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"የወጪ ጥሪዎች አቅጣጫ ቀይር"</string>
     <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"በወጪ ጥሪ ጊዜ ጥሪውን ወደተለየ ቁጥር ከማዞር ወይም ጥሪውን በአጠቃላይ ከመተው አማራጭ ጋር እየተደወለለት ያለውን ቁጥር እንዲያይ ያስችለዋል።"</string>
     <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"የስልክ ጥሪዎችን አንሳ"</string>
@@ -485,8 +485,8 @@
     <string name="permdesc_recordAudio" msgid="5857246765327514062">"ይህ መተግበሪያ መተግበሪያው ስራ ላይ ሳለ ማይክሮፎኑን በመጠቀም ኦዲዮን መቅዳት ይችላል።"</string>
     <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"በበስተጀርባ ኦዲዮን ይቅዱ"</string>
     <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"ይህ መተግበሪያ በማናቸውም ጊዜ ማይክራፎኑን በመጠቀም ኦዲዮን መቅዳት ይችላል።"</string>
-    <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"የመተግበሪያ መስኮቶች የማያ ገጽ ቀረጻዎችን ማወቅ"</string>
-    <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"መተግበሪያው በጥቅም ላይ ሳለ ቅጽበታዊ ገጽ እይታ ሲነሳ ይህ መተግበሪያ ማሳወቂያ ይደርሰዋል።"</string>
+    <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"የመተግበሪያ መስኮቶች የማያ ገፅ ቀረጻዎችን ማወቅ"</string>
+    <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"መተግበሪያው በጥቅም ላይ ሳለ ቅጽበታዊ ገፅ እይታ ሲነሳ ይህ መተግበሪያ ማሳወቂያ ይደርሰዋል።"</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"ወደ ሲሙ ትዕዛዞችን መላክ"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"መተግበሪያው ትዕዛዞችን ወደ ሲሙ እንዲልክ ያስችለዋል። ይሄ በጣማ አደገኛ ነው።"</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"አካላዊ እንቅስቃሴን ለይቶ ማወቅ"</string>
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ነዛሪውን ለመቆጣጠር ለመተግበሪያው ይፈቅዳሉ።"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"መተግበሪያው የንዝረት ሁኔታውን እንዲደርስ ያስችለዋል።"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"በቀጥታ ስልክ ቁጥሮች ደውል"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"መተግበሪያው ያላንተ ጣልቃ ገብነት የስልክ ቁጥሮች ላይ እንዲደውል ይፈቅድለታል። ይህ ያልተጠበቁ ክፍያዎችን ወይም ጥሪዎችን ሊያስከትል ይችላል። ይህ መተግበሪያው የድንገተኛ ስልክ ቁጥሮችን እንዲደውል እንደማይፈቅድለት ልብ በል። ተንኮል አዘል መተግበሪያዎች ያላንተ ማረጋገጫ ጥሪዎችን በማድረግ ገንዘብ ሊያስወጡህ ይችላሉ።"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"የአይኤምኤስ ጥሪ አገልግሎትን ይደርሳል"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"መተግበሪያው ያለእርስዎ ጣልቃ ገብነት ጥሪዎችን ለማድረግ የአይኤምኤስ አገልግሎቱን እንዲጠቀም ያስችለዋል።"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"የስልክ ሁኔታና ማንነት አንብብ"</string>
@@ -520,11 +521,11 @@
     <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"መተግበሪያው በሌላ መተግበሪያ ውስጥ የተጀመረ ጥሪ እንዲቀጥል ያስችለዋል።"</string>
     <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"ስልክ ቁጥሮች ያንብቡ"</string>
     <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"መተግበሪያው የመሣሪያውን የስልክ ቁጥሮች እንዲደርስባቸው ይፈቅድለታል።"</string>
-    <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"የመኪና ማያ ገጽ እንደበራ አቆይ"</string>
+    <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"የመኪና ማያ ገፅ እንደበራ አቆይ"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"ጡባዊ ከማንቀላፋት ተከላከል"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"የእርስዎ Android TV መሣሪያ እንዳይተኛ ይከላከሉ"</string>
     <string name="permlab_wakeLock" product="default" msgid="569409726861695115">"ስልክ ከማንቀላፋት ተከላከል"</string>
-    <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"መተግበሪያው የመኪናው ማያ ገጽ እንደበራ እንዲያቆየው ያስችለዋል።"</string>
+    <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"መተግበሪያው የመኪናው ማያ ገፅ እንደበራ እንዲያቆየው ያስችለዋል።"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"ጡባዊውን ከመተኛት መከልከል ለመተግበሪያው ይፈቅዳሉ።"</string>
     <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"የእርስዎን Android TV ከመተኛት እንዲከላከል ለመተግበሪያው ይፈቅድለታል።"</string>
     <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"ስልኩን ከመተኛት መከልከል ለመተግበሪያው ይፈቅዳሉ።"</string>
@@ -590,8 +591,8 @@
     <string name="permdesc_nfc" msgid="8352737680695296741">"ከቅርብ ግኑኙነት መስክ (NFC) መለያዎች፣ ካርዶች እና አንባቢ ጋር ለማገናኘት ለመተግበሪያው ይፈቅዳሉ።"</string>
     <string name="permlab_disableKeyguard" msgid="3605253559020928505">"የማያ ገጽዎን መቆለፊያ ያሰናክሉ"</string>
     <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"መተግበሪያው መቆለፊያውና ማንኛውም የተጎዳኘ የይለፍ ቃል ደህንነት እንዲያሰናክል ይፈቅድለታል። ለምሳሌ ስልኩ ገቢ የስልክ ጥሪ በሚቀበልበት ጊዜ መቆለፊያውን ያሰናክልና ከዚያም ጥሪው ሲጠናቀቅ መቆለፊያውን በድጋሚ ያነቃዋል።"</string>
-    <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"የማያ ገጽ መቆለፊያ ውስብስብነትን ጠይቅ"</string>
-    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"መተግበሪያው የማያ ገጽ መቆለፊያው ውስብስብነት ደረጃ (ከፍተኛ፣ መካከለኛ፣ ዝቅተኛ ወይም ምንም) እንዲያውቅ ያስችለዋል፣ ይህም ሊሆኑ የሚችለው የማያ ገጽ መቆለፊያው ርዝመት እና ዓይነት ክልል ያመለክታል። መተግበሪያው እንዲሁም ለተጠቃሚዎች የማያ ገጽ መቆለፊያውን ወደተወሰነ ደረጃ እንዲያዘምኑት ሊጠቁማቸው ይችላል። የማያ ገጽ መቆለፊያው በስነጣ አልባ ጽሁፍ እንደማይከማች ልብ ይበሉ፣ በዚህም መተግበሪያው ትክክለኛውን የይለፍ ቃል አያውቅም።"</string>
+    <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"የማያ ገፅ መቆለፊያ ውስብስብነትን ጠይቅ"</string>
+    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"መተግበሪያው የማያ ገፅ መቆለፊያው ውስብስብነት ደረጃ (ከፍተኛ፣ መካከለኛ፣ ዝቅተኛ ወይም ምንም) እንዲያውቅ ያስችለዋል፣ ይህም ሊሆኑ የሚችለው የማያ ገፅ መቆለፊያው ርዝመት እና ዓይነት ክልል ያመለክታል። መተግበሪያው እንዲሁም ለተጠቃሚዎች የማያ ገፅ መቆለፊያውን ወደተወሰነ ደረጃ እንዲያዘምኑት ሊጠቁማቸው ይችላል። የማያ ገፅ መቆለፊያው በስነጣ አልባ ጽሁፍ እንደማይከማች ልብ ይበሉ፣ በዚህም መተግበሪያው ትክክለኛውን የይለፍ ቃል አያውቅም።"</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"ማሳወቂያዎች አሳይ"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"መተግበሪያው ማሳወቂያዎችን እንዲያሳይ ያስችለዋል"</string>
     <string name="permlab_turnScreenOn" msgid="219344053664171492">"ማያ ገጹን አብራ"</string>
@@ -611,18 +612,18 @@
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"አካባቢዎችን ከሚዲያ ስብስብዎ ማንበብ"</string>
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"መተግበሪያው አካባቢዎችን ከሚዲያ ስብስብዎ እንዲያነብብ ያስችለዋል።"</string>
     <string name="biometric_app_setting_name" msgid="3339209978734534457">"ባዮሜትሪኮችን ይጠቀሙ"</string>
-    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ባዮሜትሪክስ ወይም ማያ ገጽ መቆለፊያን ይጠቀሙ"</string>
+    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ባዮሜትሪክስ ወይም ማያ ገፅ መቆለፊያን ይጠቀሙ"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"እርስዎን መሆንዎን ያረጋግጡ"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ለመቀጠል ባዮሜትሪክዎን ይጠቀሙ"</string>
-    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ለመቀጠል የባዮሜትሪክ ወይም የማያ ገጽ ቁልፍዎን ይጠቀሙ"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"ለመቀጠል የባዮሜትሪክ ወይም የማያ ገፅ ቁልፍዎን ይጠቀሙ"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ባዮሜትራዊ ሃርድዌር አይገኝም"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"ማረጋገጥ ተሰርዟል"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"አልታወቀም"</string>
     <string name="biometric_error_canceled" msgid="8266582404844179778">"ማረጋገጥ ተሰርዟል"</string>
     <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ምንም ፒን፣ ሥርዓተ ጥለት ወይም የይለፍ ቃል አልተቀናበረም"</string>
     <string name="biometric_error_generic" msgid="6784371929985434439">"ማረጋገጥ ላይ ስህተት"</string>
-    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"የማያ ገጽ መቆለፊን ይጠቀሙ"</string>
-    <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ለመቀጠል የማያ ገጽ ቁልፍዎን ያስገቡ"</string>
+    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"የማያ ገፅ መቆለፊን ይጠቀሙ"</string>
+    <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ለመቀጠል የማያ ገፅ ቁልፍዎን ያስገቡ"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ዳሳሹን በደንብ ይጫኑት"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"የጣት አሻራን መለየት አልተቻለም። እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"የጣት አሻራ ዳሳሽን ያጽዱ እና እንደገና ይሞክሩ"</string>
@@ -646,8 +647,8 @@
     <string name="fingerprint_error_timeout" msgid="7361192266621252164">"የጣት አሻራ ውቅረት ጊዜው አብቅቷል። እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"የጣት አሻራ ስርዓተ ክወና ተትቷል።"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"የጣት አሻራ ክወና በተጠቃሚ ተሰርዟል።"</string>
-    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገጽ መቆለፊያን ይጠቀሙ።"</string>
-    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገጽ መቆለፊያን ይጠቀሙ።"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገፅ መቆለፊያን ይጠቀሙ።"</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገፅ መቆለፊያን ይጠቀሙ።"</string>
     <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"የጣት አሻራን ማሰናዳት አልተቻለም። እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ምንም የጣት አሻራዎች አልተመዘገቡም።"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
@@ -656,9 +657,9 @@
     <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"የኃይል አዝራር ተጭኗል"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string>
-    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገጽ መቆለፊያ ይጠቀሙ"</string>
+    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገፅ መቆለፊያ ይጠቀሙ"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ለመቀጠል የእርስዎን የጣት አሻራ ይጠቀሙ"</string>
-    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ለመቀጠል የጣት አሻራዎን ወይም የማያ ገጽ ቁልፍዎን ይጠቀሙ"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"ለመቀጠል የጣት አሻራዎን ወይም የማያ ገፅ ቁልፍዎን ይጠቀሙ"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"የሆነ ችግር ተፈጥሯል። እንደገና ይሞክሩ።"</string>
@@ -709,16 +710,15 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"የፊት ሥርዓተ ክወና ተሰርዟል።"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"በመልክ መክፈት በተጠቃሚ ተሰርዟል"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"ከልክ በላይ ብዙ ሙከራዎች። በኋላ ላይ እንደገና ይሞክሩ።"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
-    <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገጽ መቆለፊያን ያስገቡ።"</string>
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"በጣም ብዙ ሙከራዎች። በመልክ መክፈት አይገኝም።"</string>
+    <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"በጣም ብዙ ሙከራዎች። በምትኩ የማያ ገፅ መቆለፊያን ያስገቡ።"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ፊትን ማረጋገጥ አይቻልም። እንደገና ይሞክሩ።"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"በመልክ መክፈትን አላዋቀሩም።"</string>
     <string name="face_error_hw_not_present" msgid="7940978724978763011">"በመልክ መክፈት በዚህ መሣሪያ ላይ አይደገፍም"</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
     <string name="face_name_template" msgid="3877037340223318119">"ፊት <xliff:g id="FACEID">%d</xliff:g>"</string>
     <string name="face_app_setting_name" msgid="5854024256907828015">"በመልክ መክፈትን ይጠቀሙ"</string>
-    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"የመልክ ወይም የማያ ገጽ መቆለፊያን ይጠቀሙ"</string>
+    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"የመልክ ወይም የማያ ገፅ መቆለፊያን ይጠቀሙ"</string>
     <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"ለመቀጠል መልክዎን ይጠቀሙ"</string>
     <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"ለመቀጠል መልክዎን ወይም የማያ ገጽዎን መቆለፊያ ይጠቀሙ"</string>
   <string-array name="face_error_vendor">
@@ -751,8 +751,8 @@
     <string name="permdesc_register_call_provider" msgid="4201429251459068613">"መተግበሪያው አዲስ የቴሌኮም ግንኙነቶችን እንዲመዘግብ ያስችለዋል።"</string>
     <string name="permlab_connection_manager" msgid="3179365584691166915">"የቴሌኮም ግንኙነቶችን ያቀናብራል"</string>
     <string name="permdesc_connection_manager" msgid="1426093604238937733">"መተግበሪያው የቴሌኮም ግንኙነቶችን እንዲያቀናብር ያስችለዋል።"</string>
-    <string name="permlab_bind_incall_service" msgid="5990625112603493016">"ከውስጠ-ጥሪ ማያ ገጽ ጋር መስተጋብር ይፈጥራል"</string>
-    <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"መተግበሪያው ተጠቃሚው በጥሪ ውስጥ ያለውን ማያ ገጽ መቼ እና እንዴት ማየት እንደሚችል እንዲቆጣጠር ይፈቅድለታል።"</string>
+    <string name="permlab_bind_incall_service" msgid="5990625112603493016">"ከውስጠ-ጥሪ ማያ ገፅ ጋር መስተጋብር ይፈጥራል"</string>
+    <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"መተግበሪያው ተጠቃሚው በጥሪ ውስጥ ያለውን ማያ ገፅ መቼ እና እንዴት ማየት እንደሚችል እንዲቆጣጠር ይፈቅድለታል።"</string>
     <string name="permlab_bind_connection_service" msgid="5409268245525024736">"ከስልክ አገልግሎቶች ጋር መስተጋብር ይፈጥራል"</string>
     <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"መተግበሪያው ጥሪዎችን እንዲያደርግ/እንዲቀበል ከስልክ አገልግሎቶች ጋር መስተጋብር እንዲፈጥር ያስችለዋል።"</string>
     <string name="permlab_control_incall_experience" msgid="6436863486094352987">"የውስጠ-ጥሪ ተጠቃሚ ተሞክሮ ያቀርባል"</string>
@@ -784,7 +784,7 @@
     <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"የDRM እውቅና ማረጋገጫዎችን ያስወግዳል"</string>
     <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"አንድ መተግበሪያ የDRM እውቅና ማረጋገጫዎችን እንዲያስወግድ ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"ወደሞባይል አገልግሎት ሰጪ የመልዕክት አገልግሎት አያይዝ"</string>
-    <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ያዢው በሞባይል አገልግሎት ሰጪ የመልዕክት አላላክ አገልግሎት ላይ ከፍተኛውን ደረጃ በይነ ገጽ እንዲይዝ ይፈቅድለታል። ለመደበኛ መተግበሪያ በጭራሽ አያስፈልግም።"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ያዢው በሞባይል አገልግሎት ሰጪ የመልዕክት አላላክ አገልግሎት ላይ ከፍተኛውን ደረጃ በይነ ገፅ እንዲይዝ ይፈቅድለታል። ለመደበኛ መተግበሪያ በጭራሽ አያስፈልግም።"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"ከአገልግሎት አቅራቢ አገልግሎቶች ጋር እሰር"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"ያዢው የአገልግሎት አቅራቢ አገልግሎቶችን እንዲያስር ይፈቅድለታል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="permlab_access_notification_policy" msgid="5524112842876975537">"አትረብሽን ድረስበት"</string>
@@ -792,7 +792,7 @@
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"የእይታ ፈቃድ መጠቀምን መጀመር"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ያዢው ለአንድ መተግበሪያ የፈቃድ አጠቃቀሙን እንዲያስጀምር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"የእይታ ፈቃድ ውሳኔዎችን ይጀምሩ"</string>
-    <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"ያዢው የፈቃድ ውሳኔዎችን ለመገምገም ማያ ገጽ እንዲጀምሩ ያስችላቸዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
+    <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"ያዢው የፈቃድ ውሳኔዎችን ለመገምገም ማያ ገፅ እንዲጀምሩ ያስችላቸዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"የመተግበሪያ ባህሪያትን ማየት መጀመር"</string>
     <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"ያዢው የአንድ መተግበሪያ የባህሪያት መረጃን ማየት እንዲጀምር ያስችለዋል።"</string>
     <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"የዳሳሽ ውሂቡን በከፍተኛ የናሙና ብዛት ላይ ይድረሱበት"</string>
@@ -800,7 +800,7 @@
     <string name="permlab_updatePackagesWithoutUserAction" msgid="3363272609642618551">"መተግበሪያን ያለ ተጠቃሚ እርምጃ ያዘምኑ"</string>
     <string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"ያዢው ያለ ተጠቃሚ እርምጃ ከዚህ በፊት የጫነውን መተግበሪያ እንዲያዘምነው ይፈቅዳል"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
-    <string name="policydesc_limitPassword" msgid="4105491021115793793">"በማያ ገጽ መቆለፊያ የይለፍ ቃሎች እና ፒኖች ውስጥ የሚፈቀዱ ቁምፊዎችን እና ርዝመታቸውን ተቆጣጠር።"</string>
+    <string name="policydesc_limitPassword" msgid="4105491021115793793">"በማያ ገፅ መቆለፊያ የይለፍ ቃሎች እና ፒኖች ውስጥ የሚፈቀዱ ቁምፊዎችን እና ርዝመታቸውን ተቆጣጠር።"</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"የማሳያ-ክፈት ሙከራዎችን ክትትል ያድርጉባቸው"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ማሳያውን በምትከፍትበት ጊዜ በስህተት የተተየቡ የይለፍ ቃሎችን ቁጥር ተቆጣጠር፤ እና ጡባዊ ተኮውን ቆልፍ  ወይም በጣም ብዙ የተሳሳቱ የይለፍ ቃሎች ከተተየቡ የጡባዊ ተኮን ውሂብ አጥፋ፡፡"</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"ማያ ገጹን ሲከፍቱ በትክክል ያልተተየቡ የይለፍ ቃላት ብዛት ተከታተል፣ እና በጣም ብዙ ትክክል ያልሆኑ የይለፍ ቃላት ከተተየቡ የእርስዎን Android TV ን ቆልፍ ወይም ሁሉንም የእርስዎን Android TV ደምስስ።"</string>
@@ -811,7 +811,7 @@
     <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"ማያ ገጹን ሲያስከፍቱ በትክክል ያልተተየቡ የይለፍ ቃላት ብዛት ተከታተል፣ እና በጣም ብዙ ትክክል ያልሆኑ የይለፍ ቃላት ከተተየቡ የኢንፎቴይንመንት ስርዓቱን ቆልፍ ወይም ሁሉንም የዚህን ተጠቃሚ ውሂብ ደምስስ።"</string>
     <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"ማያ ገጹን ሲያስከፍቱ በትክክል ያልተተየቡ የይለፍ ቃላት ብዛት ተከታተል፣ እና በጣም ብዙ ትክክል ያልሆኑ የይለፍ ቃላት ከተተየቡ ስልኩን ቆልፍ ወይም ሁሉንም የዚህን ተጠቃሚ ውሂብ ደምስስ።"</string>
     <string name="policylab_resetPassword" msgid="214556238645096520">"የማያ ገጹን መቆለፊያ መለወጥ"</string>
-    <string name="policydesc_resetPassword" msgid="4626419138439341851">"የማያ ገጽ መቆለፊያውን ለውጥ።"</string>
+    <string name="policydesc_resetPassword" msgid="4626419138439341851">"የማያ ገፅ መቆለፊያውን ለውጥ።"</string>
     <string name="policylab_forceLock" msgid="7360335502968476434">"ማያ ቆልፍ"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"ማያው እንዴት እና መቼ እንደሚቆልፍ ተቆጣጠር።"</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"ሁሉንም ውሂብ መሰረዝ"</string>
@@ -827,14 +827,14 @@
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"ያለምንም ማስጠንቀቂያ የዚህን ስልክ የተጠቃሚ ውሂብ ደምስስ።"</string>
     <string name="policylab_setGlobalProxy" msgid="215332221188670221">"የመሣሪያውን ሁሉንም ፕሮክሲ አዘጋጅ"</string>
     <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"መመሪያ ነቅቶ እያለ ጥቅም ላይ ሊውል የሚችለውን የመሣሪያውን ሁሉንተናዊ ተኪ አዘጋጅ። የመሣሪያ ባለቤት ብቻ የሁሉንተናዊ ተኪውን ማዘጋጀት ይችላል።"</string>
-    <string name="policylab_expirePassword" msgid="6015404400532459169">"የማያ ገጽ መቆለፊያ የአገልግሎት ማብቂያ ጊዜን አዘጋጅ"</string>
-    <string name="policydesc_expirePassword" msgid="9136524319325960675">"የማያ ገጽ መቆለፊያ የይለፍ ቃል፣ ፒን፣ ወይም ስርዓተ ጥለት በምን ያህል ጊዜ ተደጋግሞ መለወጥ እንዳለበት ለውጥ።"</string>
+    <string name="policylab_expirePassword" msgid="6015404400532459169">"የማያ ገፅ መቆለፊያ የአገልግሎት ማብቂያ ጊዜን አዘጋጅ"</string>
+    <string name="policydesc_expirePassword" msgid="9136524319325960675">"የማያ ገፅ መቆለፊያ የይለፍ ቃል፣ ፒን፣ ወይም ስርዓተ ጥለት በምን ያህል ጊዜ ተደጋግሞ መለወጥ እንዳለበት ለውጥ።"</string>
     <string name="policylab_encryptedStorage" msgid="9012936958126670110">"ማከማቻ ማመስጠር አዘጋጅ"</string>
     <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"የተከማቸ ትግበራ ውሂብ የተመሰጠረ እንዲሆን ጠይቅ።"</string>
     <string name="policylab_disableCamera" msgid="5749486347810162018">"ካሜራዎችን አቦዝን"</string>
     <string name="policydesc_disableCamera" msgid="3204405908799676104">"የሁሉንም መሣሪያ ካሜራዎች መጠቀም ከልክል።"</string>
-    <string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"የጥቂት ማያ ገጽ ቁልፍ ባህሪዎችን አቦዝን"</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"የጥቂት ማያ ገጽ ቁልፍ ባህሪዎችን ተከላከል።"</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"የጥቂት ማያ ገፅ ቁልፍ ባህሪዎችን አቦዝን"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"የጥቂት ማያ ገፅ ቁልፍ ባህሪዎችን ተከላከል።"</string>
   <string-array name="phoneTypes">
     <item msgid="8996339953292723951">"መነሻ"</item>
     <item msgid="7740243458912727194">"ተንቀሳቃሽ"</item>
@@ -1058,12 +1058,12 @@
     <string name="factorytest_not_system" msgid="5658160199925519869">"የፋብሪካ_ ሙከራ ርምጃበ/system/app አካታች ውስጥ የተጫነ ብቻ ተደግፏል።"</string>
     <string name="factorytest_no_action" msgid="339252838115675515">"የፋብሪካ_ሙከራ ርምጃ የሚያቀርብምንም አካታች አልተገኘም።"</string>
     <string name="factorytest_reboot" msgid="2050147445567257365">"ድጋሚ አስነሳ"</string>
-    <string name="js_dialog_title" msgid="7464775045615023241">"በ«<xliff:g id="TITLE">%s</xliff:g>» ያለው ገጽ ይህን ይላል፦"</string>
+    <string name="js_dialog_title" msgid="7464775045615023241">"በ«<xliff:g id="TITLE">%s</xliff:g>» ያለው ገፅ ይህን ይላል፦"</string>
     <string name="js_dialog_title_default" msgid="3769524569903332476">"ጃቫስክሪፕት"</string>
     <string name="js_dialog_before_unload_title" msgid="7012587995876771246">"አሰሳን አረጋግጥ"</string>
-    <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"ከዚህ ገጽ ውጣ"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"ከዚህ ገፅ ውጣ"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"እዚህ ገፅ ላይ ቆይ"</string>
-    <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nእርግጠኛ ነዎት ከዚህ ገጽ ወደ ሌላ ቦታ መሄድ ይፈልጋሉ?"</string>
+    <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nእርግጠኛ ነዎት ከዚህ ገፅ ወደ ሌላ ቦታ መሄድ ይፈልጋሉ?"</string>
     <string name="autofill_window_title" msgid="4379134104008111961">"በ<xliff:g id="SERVICENAME">%1$s</xliff:g> በራስ-ሙላ"</string>
     <string name="permlab_setAlarm" msgid="1158001610254173567">"ማንቂያ አስቀምጥ"</string>
     <string name="permdesc_setAlarm" msgid="2185033720060109640">"በተጫነው የማንቂያ ሰዓት መተግበሪያ ውስጥ ማንቅያን ለማደራጀት ለመተግበሪያው ይፈቅዳሉ፡፡አንዳንድ የማንቂያ ሰዓት መተግበሪያዎች ይሄንን ባህሪ ላይፈፅሙ ይችላሉ፡፡"</string>
@@ -1391,7 +1391,7 @@
     <string name="share_remote_bugreport_action" msgid="7630880678785123682">"አጋራ"</string>
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"አትቀበል"</string>
     <string name="select_input_method" msgid="3971267998568587025">"የግቤት ስልት ምረጥ"</string>
-    <string name="show_ime" msgid="6406112007347443383">"አካላዊ የቁልፍ ሰሌዳ ገቢር ሆኖ ሳለ በማያ ገጽ ላይ አቆየው"</string>
+    <string name="show_ime" msgid="6406112007347443383">"አካላዊ የቁልፍ ሰሌዳ ገቢር ሆኖ ሳለ በማያ ገፅ ላይ አቆየው"</string>
     <string name="hardware" msgid="1800597768237606953">"ምናባዊ የቁልፍ ሰሌዳን አሳይ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>ን ያዋቅሩ"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"አካላዊ የቁልፍ ሰሌዳዎችን ያዋቅሩ"</string>
@@ -1636,8 +1636,8 @@
     <string name="media_route_status_available" msgid="1477537663492007608">"የሚገኙ"</string>
     <string name="media_route_status_not_available" msgid="480912417977515261">"አይገኝም"</string>
     <string name="media_route_status_in_use" msgid="6684112905244944724">"በጥቅም ላይ"</string>
-    <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"ውስጥ የተሰራ ማያ ገጽ"</string>
-    <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI ማያ ገጽ"</string>
+    <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"ውስጥ የተሰራ ማያ ገፅ"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI ማያ ገፅ"</string>
     <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"ተደራቢ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>፦ <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>፣ <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">"፣ የተጠበቀ"</string>
@@ -1847,7 +1847,7 @@
     <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"ፒኖች አይዛመዱም። እንደገና ይሞክሩ።"</string>
     <string name="restr_pin_error_too_short" msgid="1547007808237941065">"ፒን በጣም አጭር ነው። ቢያንስ 4 አሃዝ መሆን አለበት።"</string>
     <string name="restr_pin_try_later" msgid="5897719962541636727">"ቆይተው እንደገና ይሞክሩ"</string>
-    <string name="immersive_cling_title" msgid="2307034298721541791">"ሙሉ ገጽ በማሳየት ላይ"</string>
+    <string name="immersive_cling_title" msgid="2307034298721541791">"ሙሉ ገፅ በማሳየት ላይ"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"ለመውጣት፣ ከላይ ወደታች ጠረግ ያድርጉ።"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"ገባኝ"</string>
     <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ለተሻለ ዕይታ ያሽከርክሩ"</string>
@@ -2131,11 +2131,11 @@
     <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"ማሳወቂያዎች"</string>
     <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"ፈጣን ቅንብሮች"</string>
     <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"የኃይል መገናኛ"</string>
-    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"የማያ ገጽ ቁልፍ"</string>
-    <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ቅጽበታዊ ገጽ እይታ"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"የማያ ገፅ ቁልፍ"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ቅጽበታዊ ገፅ እይታ"</string>
     <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"የማዳመጫ መንጠቆ"</string>
-    <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"የማያ ገጽ ላይ ተደራሽነት አቋራጭ"</string>
-    <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"የማያ ገጽ ላይ ተደራሽነት አቋራጭ መራጭ"</string>
+    <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"የማያ ገፅ ላይ ተደራሽነት አቋራጭ"</string>
+    <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"የማያ ገፅ ላይ ተደራሽነት አቋራጭ መራጭ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"የተደራሽነት አቋራጭ"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"የማሳወቂያ ጥላን አሰናብት"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ከDpad በላይ"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ይህ ይዘት በሥራ መተግበሪያዎች መከፈት አይችልም"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ይህ ይዘት በግል መተግበሪያዎች መጋራት አይችልም"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ይህ ይዘት በግል መተግበሪያዎች መከፈት አይችልም"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"የሥራ መገለጫ ባለበት ቆሟል"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ለማብራት መታ ያድርጉ"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ምንም የሥራ መተግበሪያዎች የሉም"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ምንም የግል መተግበሪያዎች የሉም"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"የግል <xliff:g id="APP">%s</xliff:g> ይክፈቱ"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"የሥራ <xliff:g id="APP">%s</xliff:g> ይክፈቱ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"የግል አሳሽ ተጠቀም"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"የስራ አሳሽ ተጠቀም"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"የሲም አውታረ መረብ መክፈቻ ፒን"</string>
@@ -2318,11 +2318,11 @@
     <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_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="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ስልክዎ በጣም እየሞቀ ስለሆነ ባለሁለት ማያ ገፅ አይገኝም"</string>
     <string name="concurrent_display_notification_power_save_title" msgid="1794569070730736281">"Dual Screen አይገኝም"</string>
     <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"የባትሪ ቆጣቢ ስለበራ Dual Screen አይገኝም። ይህን በቅንብሮች ውስጥ ሊያጠፉት ይችላሉ።"</string>
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"ወደ ቅንብሮች ሂድ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 0d52cac..90513b2 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -507,7 +507,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"للسماح للتطبيق بالتحكم في الهزّاز."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"يسمح هذا الإذن للتطبيق بالوصول إلى حالة الهزّاز."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"اتصال مباشر بأرقام الهواتف"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"للسماح للتطبيق بطلب أرقام هاتفية بدون تدخل منك. وقد يؤدي ذلك إلى تحمل رسوم غير متوقعة أو إجراء مكالمات غير متوقعة. ومن الجدير بالذكر أن ذلك لا يتيح للتطبيق الاتصال بأرقام الطوارئ. وقد تؤدي التطبيقات الضارة إلى تحملك تكاليف مالية من خلال إجراء مكالمات بدون موافقة منك."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"الوصول إلى خدمة الاتصال عبر الرسائل الفورية"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"للسماح للتطبيق باستخدام خدمة الرسائل الفورية لإجراء المكالمات بدون تدخل منك."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"قراءة حالة الهاتف والهوية"</string>
@@ -2163,8 +2164,10 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"لا يمكن فتح هذا المحتوى باستخدام تطبيقات العمل."</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"لا يمكن مشاركة هذا المحتوى مع التطبيقات الشخصية."</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"لا يمكن فتح هذا المحتوى باستخدام التطبيقات الشخصية."</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"الملف الشخصي للعمل متوقف مؤقتًا."</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"انقر لتفعيل الميزة"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ما مِن تطبيقات عمل."</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ما مِن تطبيقات شخصية."</string>
     <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index a113934..6132b94 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ভাইব্ৰেটৰ নিয়ন্ত্ৰণ কৰিবলৈ এপ্‌টোক অনুমতি দিয়ে।"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"এপ্‌টোক কম্পন স্থিতিটো এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"পোনপটীয়াকৈ ফ\'ন নম্বৰলৈ কল কৰক"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"আপোনাৰ কোনো ব্যাঘাত নোহোৱাকৈ ফ\'ন নম্বৰবোৰত কল কৰিবলৈ এপক অনুমতি দিয়ে৷ ইয়াৰ ফলত অপ্ৰত্যাশিত মাচুল ভৰিবলগা বা কলবোৰ কৰা হ\'ব পাৰে৷ মনত ৰাখিব যে ই এপ্‌টোক জৰুৰীকালীন নম্বৰবোৰত কল কৰিবলৈ অনুমতি নিদিয়ে৷ ক্ষতিকাৰক এপসমূহে আপোনাৰ অনুমতি নোলোৱাকৈয়ে কল কৰি আপোনাক টকা খৰছ কৰাব পাৰে৷"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"আইএমএছ কল সেৱা ব্যৱহাৰ কৰিব পাৰে"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"আপোনাৰ হস্তক্ষেপৰ অবিহনে আইএমএছ সেৱা ব্যৱহাৰ কৰি কল কৰিবলৈ এপক অনুমতি দিয়ে।"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ফ\'নৰ স্থিতি আৰু পৰিচয় পঢ়ক"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"মুখমণ্ডলৰ প্ৰক্ৰিয়া বাতিল কৰা হ’ল।"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"ব্যৱহাৰকাৰীয়ে ফেচ আনলক বাতিল কৰিছে"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"অত্যধিক ভুল প্ৰয়াস। কিছুসময়ৰ পাছত আকৌ চেষ্টা কৰক।"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"অতি বেছিসংখ্যক প্ৰয়াস। ফেচ আনলকৰ সুবিধাটো উপলব্ধ নহয়।"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"অতি বেছিসংখ্যক প্ৰয়াস। ইয়াৰ সলনি স্ক্ৰীন লক দিয়ক।"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"মুখমণ্ডল সত্যাপন কৰিব পৰা নগ’ল। আকৌ চেষ্টা কৰক।"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"ফেচ আনলক সুবিধাটো ছেট আপ কৰা নাই"</string>
@@ -986,7 +986,7 @@
     <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"বন্ধ কৰক"</string>
     <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"ৰিৱাইণ্ড কৰক"</string>
     <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"ফাষ্ট ফৰৱাৰ্ড"</string>
-    <string name="emergency_calls_only" msgid="3057351206678279851">"জৰুৰীকালীন কল মাত্ৰ"</string>
+    <string name="emergency_calls_only" msgid="3057351206678279851">"কেৱল জৰুৰীকালীন কল"</string>
     <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"নেটৱর্ক অৱৰোধিত"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="2867953953604224166">"ছিমখন PUKৰ দ্বাৰা লক হৈ আছে।"</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"ব্যৱহাৰকাৰীৰ নিৰ্দেশনা চাওক বা গ্ৰাহক সেৱা কেন্দ্ৰৰ সৈতে যোগাযোগ কৰক।"</string>
@@ -1357,7 +1357,7 @@
     <string name="perm_costs_money" msgid="749054595022779685">"ইয়াৰ ফলত আপোনাৰ টকা খৰচ হ\'ব পাৰে"</string>
     <string name="dlg_ok" msgid="5103447663504839312">"ঠিক আছে"</string>
     <string name="usb_charging_notification_title" msgid="1674124518282666955">"ইউএছবিৰ জৰিয়তে এই ডিভাইচটো চাৰ্জ কৰি থকা হৈছে"</string>
-    <string name="usb_supplying_notification_title" msgid="5378546632408101811">"ইউএছবিৰ জৰিয়তে সংযুক্ত ডিভাইচটো চ্চাৰ্জ কৰি থকা হৈছে"</string>
+    <string name="usb_supplying_notification_title" msgid="5378546632408101811">"ইউএছবিৰ জৰিয়তে সংযুক্ত ডিভাইচটো চাৰ্জ কৰি থকা হৈছে"</string>
     <string name="usb_mtp_notification_title" msgid="1065989144124499810">"ইউএছবি জৰিয়তে ফাইল স্থানান্তৰণ অন কৰা হ’ল"</string>
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"ইউএছবিৰ জৰিয়তে পিটিপি অন কৰা হ’ল"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"ইউএছবি টেডাৰিং অন কৰা হ’ল"</string>
@@ -1365,7 +1365,7 @@
     <string name="usb_uvc_notification_title" msgid="2030032862673400008">"ৱেবকেম হিচাপে সংযোগ কৰা ডিভাইচ"</string>
     <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>
+    <string name="usb_power_notification_message" msgid="7284765627437897702">"সংযুক্ত ডিভাইচ চাৰ্জ কৰি থকা হৈছে। অধিক বিকল্পৰ বাবে টিপক।"</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"এনাল\'গ অডিঅ\' সহায়ক সামগ্ৰী পোৱা গৈছে"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"সংলগ্ন কৰা ডিভাইচটোৱে এই ফ\'নটোৰ সৈতে কাম কৰিব নোৱাৰে। অধিক জানিবলৈ টিপক।"</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"ইউএছবি ডিবাগিং সংযোগ কৰা হ’ল"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"এই সমল কৰ্মস্থানৰ এপৰ জৰিয়তে খুলিব নোৱাৰি"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"এই সমল ব্যক্তিগত এপৰ সৈতে শ্বেয়াৰ কৰিব নোৱাৰি"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"এই সমল ব্যক্তিগত এপৰ জৰিয়তে খুলিব নোৱাৰি"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"কৰ্মস্থানৰ প্ৰ\'ফাইলটো পজ কৰা আছে"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"অন কৰিবলৈ টিপক"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"কোনো কৰ্মস্থানৰ এপ্‌ নাই"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"কোনো ব্যক্তিগত এপ্‌ নাই"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"ব্যক্তিগত <xliff:g id="APP">%s</xliff:g> খোলক"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"কৰ্মস্থানৰ <xliff:g id="APP">%s</xliff:g> খোলক"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ব্যক্তিগত ব্ৰাউজাৰ ব্যৱহাৰ কৰক"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"কৰ্মস্থানৰ ব্ৰাউজাৰ ব্যৱহাৰ কৰক"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ছিম নেটৱৰ্ক আনলক কৰা পিন"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index c9876b0..8050996 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Tətbiqə vibratoru idarə etmə icazəsi verir."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Tətbiqə vibrasiya vəziyyətinə daxil olmaq imkanı verir."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefon nömrələrinə birbaşa zəng edir"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Tətbiqə Sizin müdaxiləniz olmadan telefon zəngləri etməyə imkan verir. Zərərli tətbiqlər Sizdən xəbərsiz şəkildə müxtəlif zənglər edərək, Sizə maddi ziyan vura bilər. Qeyd: Bu, tətbiqlərə təcili nömrələrə zəng etməyə icazə vermir."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS zəng xidmətinə giriş"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Tətbiqə müdaxilə olmadan zəng etmək üçün IMS xidmətindən istifadə etməyə imkan verir."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"telefon statusunu və identifikasiyanı oxuyur"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Üz əməliyyatı ləğv edildi."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"İstifadəçi üz ilə kiliddən çıxarmanı ləğv edib"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Həddindən çox cəhd. Sonraya saxlayın."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Çox cəhd edilib. Üz ilə Kiliddən Açma əlçatan deyil."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Həddindən çox cəhd. Əvəzində ekran kilidi daxil edin."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Üz doğrulanmadı. Yenidən cəhd edin."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Üz ilə kiliddən çıxarma ayarlamamısınız"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Bu kontenti iş tətbiqləri ilə açmaq mümkün deyil"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Bu kontenti şəxsi tətbiqlər ilə paylaşmaq mümkün deyil"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Bu kontenti şəxsi tətbiqlər ilə açmaq mümkün deyil"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"İş profilinə fasilə verilib"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Aktiv etmək üçün toxunun"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"İş tətbiqi yoxdur"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Şəxsi tətbiq yoxdur"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Açın: <xliff:g id="APP">%s</xliff:g> (şəxsi)"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Açın: <xliff:g id="APP">%s</xliff:g> (iş)"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Şəxsi brauzerdən istifadə edin"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"İş brauzerindən istifadə edin"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM şəbəkəsi kilidaçma PİN\'i"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 4d8bc70..125d1cd 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -248,10 +248,10 @@
     <string name="global_action_power_options" msgid="1185286119330160073">"Napajanje"</string>
     <string name="global_action_restart" msgid="4678451019561687074">"Restartuj"</string>
     <string name="global_action_emergency" msgid="1387617624177105088">"Hitan poziv"</string>
-    <string name="global_action_bug_report" msgid="5127867163044170003">"Izveštaj o grešci"</string>
+    <string name="global_action_bug_report" msgid="5127867163044170003">"Javi grešku"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"Završi sesiju"</string>
     <string name="global_action_screenshot" msgid="2610053466156478564">"Snimak ekrana"</string>
-    <string name="bugreport_title" msgid="8549990811777373050">"Izveštaj o grešci"</string>
+    <string name="bugreport_title" msgid="8549990811777373050">"Javi grešku"</string>
     <string name="bugreport_message" msgid="5212529146119624326">"Ovim će se prikupiti informacije o trenutnom stanju uređaja kako bi bile poslate u poruci e-pošte. Od započinjanja izveštaja o grešci do trenutka za njegovo slanje proći će neko vreme; budite strpljivi."</string>
     <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv. izveštaj"</string>
     <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Koristite ovo u većini slučajeva. To vam omogućava da pratite napredak izveštaja, da unosite dodatne detalje o problemu i da snimate snimke ekrana. Verovatno će izostaviti neke manje korišćene odeljke za koje pravljenje izveštaja dugo traje."</string>
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Dozvoljava aplikaciji da kontroliše vibraciju."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Dozvoljava aplikaciji da pristupa stanju vibriranja."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"direktno pozivanje brojeva telefona"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Dozvoljava aplikaciji da poziva brojeve telefona bez vaše dozvole. Ovo može da dovede do neočekivanih troškova ili poziva. Imajte na umu da ovo ne dozvoljava aplikaciji da poziva brojeve za hitne slučajeve. Zlonamerne aplikacije mogu da pozivaju bez vaše potvrde, što može da dovede do troškova."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pristup usluzi poziva pomoću razmene trenutnih poruka"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Dozvoljava aplikaciji da koristi uslugu razmene trenutnih poruka da bi upućivala pozive bez vaše intervencije."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"čitanje statusa i identiteta telefona"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Obrada lica je otkazana."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Korisnik je otkazao otključavanje licem"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Previše pokušaja. Probajte ponovo kasnije."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Previše pokušaja. Otključavanje licem nije dostupno."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Previše pokušaja. Koristite zaključavanje ekrana za to."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Provera lica nije uspela. Probajte ponovo."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Niste podesili otključavanje licem"</string>
@@ -1716,7 +1716,7 @@
     <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inverzija boja"</string>
     <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>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamni"</string>
     <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Ovaj sadržaj ne može da se otvara pomoću poslovnih aplikacija"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Ovaj sadržaj ne može da se deli pomoću ličnih aplikacija"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Ovaj sadržaj ne može da se otvara pomoću ličnih aplikacija"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Poslovni profil je pauziran"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Dodirnite da biste uključili"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nema poslovnih aplikacija"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nema ličnih aplikacija"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Otvorite ličnu aplikaciju <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Otvorite poslovnu aplikaciju <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Koristi lični pregledač"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Koristi poslovni pregledač"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN za otključavanje SIM mreže"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 2925fe6..2cc38d6 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -505,7 +505,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Дазваляе прыкладанням кіраваць вібрацыяй."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Дазваляе праграме атрымліваць доступ да вібрасігналу."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"непасрэдна набіраць тэлефонныя нумары"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Дазваляе прыкладанням званiць на тэлефонныя нумары без вашага ўмяшання. Гэта можа прывесці да нечаканага спагнання сродкаў або званкоў. Звярніце ўвагу, што прыкладанне не можа рабiць экстраныя выклікi. Шкоднасныя прыкладаннi могуць спаганяць з вас сродкi, робячы званкі без вашага пацверджання."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"атрымліваць доступ да сэрвісу выклікаў IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Дазваляе праграмам выкарыстоўваць службу IMS, каб рабіць выклікі без вашага ўмяшання."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"чытанне статусу тэлефона і ідэнтыфікацыя"</string>
@@ -2161,8 +2162,10 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Не ўдалося адкрыць гэта змесціва з дапамогай працоўных праграм"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Не ўдалося абагуліць гэта змесціва з асабістымі праграмамі"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Не ўдалося адкрыць гэта змесціва з дапамогай асабістых праграм"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Працоўны профіль прыпынены"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Націсніце, каб уключыць"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Няма працоўных праграм"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Няма асабістых праграм"</string>
     <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 35efb0a..e4d72ee 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="byteShort" msgid="202579285008794431">"Б"</string>
+    <string name="byteShort" msgid="202579285008794431">"B"</string>
     <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="3381766946944136678">"&lt;Без заглавие&gt;"</string>
     <string name="emptyPhoneNumber" msgid="5812172618020360048">"(Няма телефонен номер)"</string>
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Разрешава на приложението да контролира устройството за вибрация."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Дава възможност на приложението да осъществява достъп до състоянието на вибриране."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"директно обаждане до телефонни номера"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Разрешава на приложението да се обажда без ваша намеса до телефонни номера, което може да доведе до неочаквано таксуване или обаждания. Обърнете внимание, че това не му позволява да извършва обаждания до спешните служби. Злонамерените приложения могат да ви въвлекат в разходи, като извършват обаждания без потвърждение от ваша страна."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"достъп до услугата за незабавни съобщения за обаждания"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Разрешава на приложението да използва услугата за незабавни съобщения за извършване на обаждания без намеса от ваша страна."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"четене на състоянието и идентификационните данни на телефона"</string>
@@ -684,7 +685,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Преместете телефона наляво"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Преместете телефона надясно"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Моля, гледайте точно към устройството си."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Лицето ви не се вижда. Дръжте телефона на нивото на очите си."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Лицето не се вижда. Задръжте на нивото на очите."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Твърде много движение. Дръжте телефона неподвижно."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Моля, регистрирайте лицето си отново."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Лицето не е разпознато. Опитайте отново."</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Операцията с лице е анулирана."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Отключването с лице е анулирано от потребителя"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Твърде много опити. Опитайте отново по-късно."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Твърде много опити. „Отключване с лице“ не е налице."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Твърде много опити. Използвайте опцията за заключване на екрана."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Лицето не може да се потвърди. Опитайте отново."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Не сте настроили отключването с лице"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Това съдържание не може да се отваря със служебни приложения"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Това съдържание не може да се споделя с лични приложения"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Това съдържание не може да се отваря с лични приложения"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Служебният потребителски профил е поставен на пауза"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Докоснете за включване"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Няма подходящи служебни приложения"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Няма подходящи лични приложения"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Към личния потребителски профил в(ъв) <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Към служебния потребителски профил в(ъв) <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Използване на личния браузър"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Използване на служебния браузър"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ПИН за отключване на мрежата за SIM"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 05d40bf..a5cbfa0 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -503,7 +503,7 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"অ্যাপ্লিকেশানকে কম্পক নিয়ন্ত্রণ করতে দেয়৷"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ভাইব্রেট করার স্থিতি অ্যাক্সেস করার অনুমতি দিন।"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"সরাসরি ফোন নম্বরগুলিতে কল করে"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"অ্যাপ্লিকেশানটিকে আপনার হস্তক্ষেপ ছাড়াই ফোন নম্বরগুলিতে কল করতে মঞ্জুর করে৷ এটি অপ্রত্যাশিত পরিমাণ খরচা বা কলের কারণ হতে পারে৷ মনে রাখবেন, এটি অ্যাপ্লিকেশানটির দ্বারা জরুরি নম্বরগুলিতে কল করাকে অনুমতি দেয় না৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার সম্মতি ছাড়াই কল করার ফলে আপনাকে অহেতুক পেমেন্ট করতে হতে পারে৷"</string>
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"আপনার হস্তক্ষেপ ছাড়াই ফোন নম্বরে কল করার অনুমতি দেয়। এর ফলে অপ্রত্যাশিত চার্জ লাগতে বা কল হতে পারে। মনে রাখবেন, এটি অ্যাপকে জরুরি নম্বরে কল করার অনুমতি দেয় না। ক্ষতিকর অ্যাপ, আপনার কনফার্মেশন ছাড়াই কল করে আপনার আর্থিক ক্ষতি করতে পারে অথবা পরিষেবা প্রদানকারীর কোড ডায়াল করে, যার ফলে ইনকামিং কল অটোমেটিক অন্য নম্বরে ফরওয়ার্ড হয়ে যায়।"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS পরিষেবাতে অ্যাক্সেস"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"আপনার হস্তক্ষেপ ছাড়াই কল করতে অ্যাপ্লিকেশানটিকে IMS পরিষেবা ব্যবহারের অনুমতি দিন৷"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ফোনের স্থিতি এবং পরিচয় পড়ুন"</string>
@@ -709,8 +709,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"ফেস অপারেশন বাতিল করা হয়েছে৷"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"ব্যবহারকারী \'ফেস আনলক\' বাতিল করে দিয়েছেন"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"অনেকবার চেষ্টা করা হয়েছে। পরে আবার চেষ্টা করুন।"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"অনেকবার চেষ্টা করেছেন। \'ফেস আনলক\' উপলভ্য নেই।"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"অনেকবার চেষ্টা করেছেন। এর পরিবর্তে স্ক্রিন লক ব্যবহার করুন।"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"আপনার মুখ যাচাই করা যাচ্ছে না। আবার চেষ্টা করুন।"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"এখনও \'ফেস আনলক\' সেট আপ করেননি"</string>
@@ -2159,14 +2158,12 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"অফিসের অ্যাপে এই খোলা যাবে না"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ব্যক্তিগত অ্যাপে এই কন্টেন্ট শেয়ার করা যাবে না"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ব্যক্তিগত অ্যাপে এই কন্টেন্ট খোলা যাবে না"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"অফিস প্রোফাইল বন্ধ করা আছে"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"চালু করতে ট্যাপ করুন"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"অফিসের অ্যাপ পজ করা আছে"</string>
+    <string name="resolver_switch_on_work" msgid="4527096360772311894">"আনপজ করুন"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"এর জন্য কোনও অফিস অ্যাপ নেই"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ব্যক্তিগত অ্যাপে দেখা যাবে না"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"ব্যক্তিগত <xliff:g id="APP">%s</xliff:g> অ্যাপ খুলুন"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"অফিসের <xliff:g id="APP">%s</xliff:g> অ্যাপ খুলুন"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ব্যক্তিগত ব্রাউজার ব্যবহার করুন"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"অফিস ব্রাউজার ব্যবহার করুন"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"সিম নেটওয়ার্ক আনলক পিন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 6688938..478a3b6 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -504,7 +504,7 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Dozvoljava aplikaciji upravljanje vibracijom."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Dozvoljava aplikaciji pristup stanju vibracije."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"izravno zvanje telefonskih brojeva"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Omogućava aplikaciji pozivanje telefonskih brojeva bez vašeg angažiranja. Ovo može uzrokovati neočekivane troškove ili pozive. Imajte na umu da ovo ne daje aplikaciji mogućnost pozivanja brojeva za hitne slučajeve. Zlonamjerne aplikacije vam mogu napraviti neočekivane troškove kroz vršenje poziva bez vašeg znanja."</string>
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"Dozvoljava aplikaciji da pozove brojeve telefona bez vaše intervencije. Ovo može dovesti do neočekivanih troškova ili poziva. Napominjemo da ovo ne dozvoljava aplikaciji da pozove brojeve za hitne slučajeve. Zlonamjerne aplikacije vam mogu uzrokovati troškove upućivanjem poziva bez vaše potvrde ili pozvati kodove operatera što uzrokuje automatsko prosljeđivanje dolaznih poziva na drugi broj."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pristup usluzi IMS pozivanja"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Omogućava aplikaciji da koristi IMS uslugu za pozivanje bez vaše intervencije."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"čitanje statusa i identiteta telefona"</string>
@@ -710,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Prepoznavanje lica je otkazano."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Korisnik je otkazao otključavanje licem"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Previše pokušaja. Otključavanje licem nije dostupno."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Previše pokušaja. Umjesto toga unesite zaključavanje ekrana."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nije moguće potvrditi lice. Pokušajte ponovo."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Niste postavili otključavanje licem"</string>
@@ -2160,14 +2159,12 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Ovaj sadržaj nije moguće otvoriti pomoću poslovnih aplikacija"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Ovaj sadržaj nije moguće dijeliti pomoću ličnih aplikacija"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Ovaj sadržaj nije moguće otvoriti pomoću ličnih aplikacija"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Radni profil je pauziran"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Dodirnite da uključite"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Poslovne aplikacije su pauzirane"</string>
+    <string name="resolver_switch_on_work" msgid="4527096360772311894">"Prekini pauzu"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nema poslovnih aplikacija"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nema ličnih aplikacija"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Otvorite ličnu aplikaciju <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Otvorite poslovnu aplikaciju <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Koristi lični preglednik"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Koristi poslovni preglednik"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN za otključavanje mreže na SIM-u"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 11e052a..b13e9e8 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet que l\'aplicació controli el vibrador."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet que l\'aplicació accedeixi a l\'estat de vibració."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"trucar directament a números de telèfon"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permet que l\'aplicació truqui a números de telèfon sense la teva intervenció. Aquesta acció pot produir càrrecs o trucades inesperades. Tingues en compte que això no permet que l\'aplicació truqui a números d\'emergència. Les aplicacions malicioses poden fer trucades sense la teva confirmació, cosa que et pot fer gastar diners."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accés al servei de trucades IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permet que l\'aplicació utilitzi el servei IMS per fer trucades sense la teva intervenció."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"veure l\'estat i la identitat del telèfon"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"S\'ha cancel·lat el reconeixement facial."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"L\'usuari ha cancel·lat Desbloqueig facial"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Massa intents. Torna-ho a provar més tard."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Massa intents. Desbloqueig facial no està disponible."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Massa intents. Introdueix el bloqueig de pantalla."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"No es pot verificar la cara. Torna-ho a provar."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"No has configurat Desbloqueig facial"</string>
@@ -2093,7 +2093,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"D\'acord"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desactiva"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Més informació"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Les notificacions millorades han substituït les notificacions adaptatives d\'Android a Android 12. Aquesta funció mostra les accions i respostes suggerides, i organitza les teves notificacions.\n\nLes notificacions millorades poden accedir al contingut de les notificacions, inclosa la informació personal com els noms dels contactes i els missatges. Aquesta funció també pot ignorar les notificacions o respondre-hi; per exemple, pot contestar a trucades i controlar el mode No molestis."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Les notificacions millorades han substituït les notificacions adaptatives d\'Android a Android 12. Aquesta funció mostra accions i respostes suggerides, i organitza les teves notificacions.\n\nLes notificacions millorades poden accedir al contingut de les notificacions, inclosa la informació personal com ara noms de contactes i missatges. Aquesta funció també pot ignorar les notificacions o respondre-hi, per exemple pot contestar a trucades, i controlar el mode No molestis."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificació d\'informació del mode de rutina"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Estalvi de bateria s\'ha activat"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"S\'està reduint l\'ús de la bateria per allargar-ne la durada"</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"No es pot obrir aquest contingut amb aplicacions de treball"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"No es pot compartir aquest contingut amb aplicacions personals"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"No es pot obrir aquest contingut amb aplicacions personals"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"El perfil de treball està en pausa"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Toca per activar"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Cap aplicació de treball"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Cap aplicació personal"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Obre <xliff:g id="APP">%s</xliff:g> al perfil personal"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Obre <xliff:g id="APP">%s</xliff:g> al perfil de treball"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utilitza el navegador personal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utilitza el navegador de treball"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueig de la xarxa SIM"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index d93efa2..df6869b 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -505,7 +505,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Umožňuje aplikaci ovládat vibrace."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Umožňuje aplikaci přístup ke stavu vibrací."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"přímé volání na telefonní čísla"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Umožňuje aplikaci volat na telefonní čísla bez vašeho přičinění. Může mít za následek neočekávané poplatky nebo hovory. Toto oprávnění neumožňuje aplikaci volat na tísňová čísla. Škodlivé aplikace vás mohou připravit o peníze uskutečňováním hovorů bez vašeho svolení."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"přístup ke službě zasílání rychlých zpráv pro účely hovorů"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Umožňuje aplikaci používat službu zasílání rychlých zpráv k uskutečňování hovorů bez vašeho zásahu."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"čtení stavu a identity telefonu"</string>
@@ -711,8 +712,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Operace snímání obličeje byla zrušena."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Odemknutí obličejem zrušeno uživatelem"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Příliš mnoho pokusů. Zkuste to později."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Příliš mnoho pokusů. Odemknutí obličejem je nedostupné."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Příliš mnoho pokusů. Zadejte zámek obrazovky."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Obličej se nepodařilo ověřit. Zkuste to znovu."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Odemknutí obličejem nemáte nastavené."</string>
@@ -2161,14 +2161,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Tento obsah nelze otevřít pomocí pracovních aplikací"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Tento obsah nelze sdílet pomocí osobních aplikací"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Tento obsah nelze otevřít pomocí osobních aplikací"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Pracovní profil je pozastaven"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Klepnutím ho zapnete"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Žádné pracovní aplikace"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Žádné osobní aplikace"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Otevřít osobní aplikaci <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Otevřít pracovní aplikaci <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Použít osobní prohlížeč"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Použít pracovní prohlížeč"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Kód PIN odblokování sítě pro SIM kartu"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 36c6ddc..ff3fb8d 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -268,7 +268,7 @@
     <string name="global_action_settings" msgid="4671878836947494217">"Indstillinger"</string>
     <string name="global_action_assist" msgid="2517047220311505805">"Assistance"</string>
     <string name="global_action_voice_assist" msgid="6655788068555086695">"Taleassistent"</string>
-    <string name="global_action_lockdown" msgid="2475471405907902963">"Lås enhed"</string>
+    <string name="global_action_lockdown" msgid="2475471405907902963">"Ekstralås"</string>
     <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
     <string name="notification_hidden_text" msgid="2835519769868187223">"Ny notifikation"</string>
     <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fysisk tastatur"</string>
@@ -503,7 +503,7 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Tillader, at appen kan administrere vibratoren."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Tillader, at appen bruger vibration."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ringe direkte op til telefonnumre"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Tillader, at appen kan ringe til telefonnumre uden din indgriben. Dette kan resultere i uventede opkrævninger eller opkald. Bemærk, at appen med denne tilladelse ikke kan ringe til nødopkaldsnumre. Skadelige apps kan koste dig penge ved at foretage opkald uden din bekræftelse."</string>
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"Tillader, at appen kan ringe til telefonnumre uden din indgriben. Dette kan resultere i uventede debiteringer eller opkald. Vær opmærksom på, at dette ikke giver appen tilladelse til at ringe til alarmnumre. Skadelige apps kan koste dig penge ved at foretage opkald uden din bekræftelse eller ved at ringe op til operatørkoder, hvilket resulterer i, at indgående opkald automatisk viderestilles til et andet nummer."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"få adgang til chat-opkaldstjeneste"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Tillader, at appen kan bruge chat-tjenesten til at foretage opkald, uden du gør noget."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"læse telefonens status og identitet"</string>
@@ -709,8 +709,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Ansigtshandlingen blev annulleret."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Ansigtslås blev annulleret af brugeren"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Du har prøvet for mange gange. Prøv igen senere."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Du har brugt for mange forsøg. Ansigtslås er utilgængelig."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Du har brugt for mange forsøg. Angiv skærmlåsen i stedet."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ansigtet kan ikke genkendes. Prøv igen."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Du har ikke konfigureret ansigtslås."</string>
@@ -2159,14 +2158,12 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Dette indhold kan ikke åbnes med arbejdsapps"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Dette indhold kan ikke deles med personlige apps"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Dette indhold kan ikke åbnes med personlige apps"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Arbejdsprofilen er sat på pause"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tryk for at aktivere"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Dine arbejdsapps er sat på pause"</string>
+    <string name="resolver_switch_on_work" msgid="4527096360772311894">"Genoptag"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Der er ingen arbejdsapps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Der er ingen personlige apps"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Åbn <xliff:g id="APP">%s</xliff:g> (privat)"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Åbn <xliff:g id="APP">%s</xliff:g> (arbejde)"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Brug personlig browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Brug arbejdsbrowser"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Pinkode til oplåsning af SIM-netværket"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index db97bc1..676f744 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Ermöglicht der App, den Vibrationsalarm zu steuern"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ermöglicht der App, auf den Vibrationsstatus zuzugreifen."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"Telefonnummern direkt anrufen"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Ermöglicht der App, ohne dein Eingreifen Telefonnummern zu wählen. Dies kann zu unerwarteten Kosten und Anrufen führen. Beachte, dass die App keine Notrufnummern wählen kann. Schädliche Apps verursachen möglicherweise Kosten, indem sie Anrufe ohne deine Bestätigung tätigen."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"Zugriff auf IMS-Anrufdienst"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Ermöglicht der App die Verwendung des IMS-Dienstes zum Tätigen von Anrufen ohne Nutzereingriffe"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"Telefonstatus und Identität abrufen"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Gesichtserkennung abgebrochen."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Entsperrung per Gesichtserkennung vom Nutzer abgebrochen"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Zu viele Versuche, bitte später noch einmal versuchen"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Zu oft versucht. Entsperrung per Gesichtserkennung nicht verfügbar."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Zu viele Versuche. Verwende stattdessen die Displaysperre."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Gesichtsprüfung nicht möglich. Noch mal versuchen."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Entsperrung per Gesichtserkennung ist nicht eingerichtet"</string>
@@ -1851,7 +1851,7 @@
     <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="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Splitscreen-Modus 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>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Diese Art von Inhalt kann nicht mit geschäftlichen Apps geöffnet werden"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Diese Art von Inhalt kann nicht über private Apps geteilt werden"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Diese Art von Inhalt kann nicht mit privaten Apps geöffnet werden"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Arbeitsprofil pausiert"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Zum Aktivieren tippen"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Keine geschäftlichen Apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Keine privaten Apps"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Private App „<xliff:g id="APP">%s</xliff:g>“ öffnen"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Geschäftliche App „<xliff:g id="APP">%s</xliff:g>“ öffnen"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Privaten Browser verwenden"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Arbeitsbrowser verwenden"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Entsperr-PIN für netzgebundenes Gerät"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 96eacaa..2520400 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Επιτρέπει στην εφαρμογή τον έλεγχο της δόνησης."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Επιτρέπει στην εφαρμογή να έχει πρόσβαση στην κατάσταση δόνησης."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"πραγματοποιεί απευθείας κλήση τηλεφωνικών αριθμών"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Επιτρέπει στην εφαρμογή την κλήση αριθμών τηλεφώνου χωρίς δική σας παρέμβαση. Αυτό μπορεί να προκαλέσει μη αναμενόμενες χρεώσεις ή κλήσεις. Έχετε υπόψη ότι δεν επιτρέπεται στην εφαρμογή η κλήση αριθμών έκτακτης ανάγκης. Οι κακόβουλες εφαρμογές ενδέχεται να σας κοστίσουν χρήματα, πραγματοποιώντας κλήσεις χωρίς την έγκρισή σας."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"έχει πρόσβαση στην υπηρεσία κλήσεων της IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Επιτρέπει στην εφαρμογή τη χρήση της υπηρεσίας IMS για την πραγματοποίηση κλήσεων χωρίς τη δική σας παρέμβαση."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"διαβάζει την κατάσταση και ταυτότητα τηλεφώνου"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Η ενέργεια προσώπου ακυρώθηκε."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Το Ξεκλείδωμα με το πρόσωπο ακυρώθηκε από τον χρήστη"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Πάρα πολλές προσπάθειες. Δοκιμάστε ξανά αργότερα."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Πάρα πολλές προσπάθειες. Το Ξεκλείδωμα με το πρόσωπο δεν είναι διαθέσιμο"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Πάρα πολλές προσπάθειες. Χρησιμοποιήστε εναλλακτικά το κλείδωμα οθόνης."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Αδύνατη επαλήθευση του προσώπου. Επανάληψη."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Δεν έχετε ρυθμίσει το Ξεκλείδωμα με το πρόσωπο"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Δεν είναι δυνατό το άνοιγμα αυτού του περιεχομένου με εφαρμογές εργασιών"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Δεν είναι δυνατή η κοινοποίηση αυτού του περιεχομένου με προσωπικές εφαρμογές"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Δεν είναι δυνατό το άνοιγμα αυτού του περιεχομένου με προσωπικές εφαρμογές"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Το προφίλ εργασίας σας έχει τεθεί σε παύση."</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Πατήστε για ενεργοποίηση"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Δεν υπάρχουν εφαρμογές εργασιών"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Δεν υπάρχουν προσωπικές εφαρμογές"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Άνοιγμα προσωπικού <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Άνοιγμα <xliff:g id="APP">%s</xliff:g> εργασίας"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Χρήση προσωπικού προγράμματος περιήγησης"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Χρήση προγράμματος περιήγησης εργασίας"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ξεκλειδώματος δικτύου κάρτας SIM"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 623460b..bc92e09 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Allows the app to control the vibrator."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Allows the app to access the vibrator state."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"directly call phone numbers"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"access IMS call service"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Allows the app to use the IMS service to make calls without your intervention."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"read phone status and identity"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Face operation cancelled."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Face Unlock cancelled by user"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Too many attempts. Try again later."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Too many attempts. Face Unlock unavailable."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Too many attempts. Enter screen lock instead."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Can’t verify face. Try again."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"You haven’t set up Face Unlock"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"This content can’t be opened with work apps"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"This content can’t be shared with personal apps"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"This content can’t be opened with personal apps"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Work profile is paused"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tap to turn on"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"No work apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"No personal apps"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Open personal <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Open work <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Use personal browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Use work browser"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM network unlock PIN"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index efe2c52..54484f0 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -503,7 +503,7 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Allows the app to control the vibrator."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Allows the app to access the vibrator state."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"directly call phone numbers"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation, or dial carrier codes which cause incoming calls to be automatically forwarded to another number."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"access IMS call service"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Allows the app to use the IMS service to make calls without your intervention."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"read phone status and identity"</string>
@@ -709,8 +709,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Face operation canceled."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Face Unlock canceled by user"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Too many attempts. Try again later."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Too many attempts. Face Unlock unavailable."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Too many attempts. Enter screen lock instead."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Can’t verify face. Try again."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"You haven’t set up Face Unlock"</string>
@@ -1538,7 +1537,7 @@
     <string name="add_account_button_label" msgid="322390749416414097">"Add account"</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"Increase"</string>
     <string name="number_picker_decrement_button" msgid="5116948444762708204">"Decrease"</string>
-    <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> touch &amp; hold."</string>
+    <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> touch and hold."</string>
     <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"Slide up to increase and down to decrease."</string>
     <string name="time_picker_increment_minute_button" msgid="7195870222945784300">"Increase minute"</string>
     <string name="time_picker_decrement_minute_button" msgid="230925389943411490">"Decrease minute"</string>
@@ -1565,7 +1564,7 @@
     <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Couldn\'t launch <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Share with"</string>
     <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Share with <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="content_description_sliding_handle" msgid="982510275422590757">"Sliding handle. Touch &amp; hold."</string>
+    <string name="content_description_sliding_handle" msgid="982510275422590757">"Sliding handle. Touch and hold."</string>
     <string name="description_target_unlock_tablet" msgid="7431571180065859551">"Swipe to unlock."</string>
     <string name="action_bar_home_description" msgid="1501655419158631974">"Navigate home"</string>
     <string name="action_bar_up_description" msgid="6611579697195026932">"Navigate up"</string>
@@ -1723,7 +1722,7 @@
     <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the accessibility button:"</string>
     <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch &amp; hold the accessibility button."</string>
+    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch and hold the accessibility button."</string>
     <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
@@ -2159,14 +2158,12 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"This content can’t be opened with work apps"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"This content can’t be shared with personal apps"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"This content can’t be opened with personal apps"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Work profile is paused"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tap to turn on"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Work apps are paused"</string>
+    <string name="resolver_switch_on_work" msgid="4527096360772311894">"Unpause"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"No work apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"No personal apps"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Open personal <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Open work <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Use personal browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Use work browser"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM network unlock PIN"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index ca28756..69db8d3 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Allows the app to control the vibrator."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Allows the app to access the vibrator state."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"directly call phone numbers"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"access IMS call service"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Allows the app to use the IMS service to make calls without your intervention."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"read phone status and identity"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Face operation cancelled."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Face Unlock cancelled by user"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Too many attempts. Try again later."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Too many attempts. Face Unlock unavailable."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Too many attempts. Enter screen lock instead."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Can’t verify face. Try again."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"You haven’t set up Face Unlock"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"This content can’t be opened with work apps"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"This content can’t be shared with personal apps"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"This content can’t be opened with personal apps"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Work profile is paused"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tap to turn on"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"No work apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"No personal apps"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Open personal <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Open work <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Use personal browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Use work browser"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM network unlock PIN"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index b20520f..95cf753 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Allows the app to control the vibrator."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Allows the app to access the vibrator state."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"directly call phone numbers"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"access IMS call service"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Allows the app to use the IMS service to make calls without your intervention."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"read phone status and identity"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Face operation cancelled."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Face Unlock cancelled by user"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Too many attempts. Try again later."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Too many attempts. Face Unlock unavailable."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Too many attempts. Enter screen lock instead."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Can’t verify face. Try again."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"You haven’t set up Face Unlock"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"This content can’t be opened with work apps"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"This content can’t be shared with personal apps"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"This content can’t be opened with personal apps"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Work profile is paused"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tap to turn on"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"No work apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"No personal apps"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Open personal <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Open work <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Use personal browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Use work browser"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM network unlock PIN"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 30ed170..8550f2e 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -503,7 +503,7 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎Allows the app to control the vibrator.‎‏‎‎‏‎"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎Allows the app to access the vibrator state.‎‏‎‎‏‎"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎directly call phone numbers‎‏‎‎‏‎"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation.‎‏‎‎‏‎"</string>
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation, or dial carrier codes which cause incoming calls to be automatically forwarded to another number.‎‏‎‎‏‎"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎access IMS call service‎‏‎‎‏‎"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎Allows the app to use the IMS service to make calls without your intervention.‎‏‎‎‏‎"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎read phone status and identity‎‏‎‎‏‎"</string>
@@ -709,8 +709,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎Face operation canceled.‎‏‎‎‏‎"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‎Face Unlock canceled by user‎‏‎‎‏‎"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎Too many attempts. Try again later.‎‏‎‎‏‎"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎Too many attempts. Face Unlock unavailable.‎‏‎‎‏‎"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‎‎Too many attempts. Enter screen lock instead.‎‏‎‎‏‎"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎Can’t verify face. Try again.‎‏‎‎‏‎"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎You haven’t set up Face Unlock‎‏‎‎‏‎"</string>
@@ -2159,14 +2158,12 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎This content can’t be opened with work apps‎‏‎‎‏‎"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‎This content can’t be shared with personal apps‎‏‎‎‏‎"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎This content can’t be opened with personal apps‎‏‎‎‏‎"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎Work profile is paused‎‏‎‎‏‎"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎Tap to turn on‎‏‎‎‏‎"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎Work apps are paused‎‏‎‎‏‎"</string>
+    <string name="resolver_switch_on_work" msgid="4527096360772311894">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎Unpause‎‏‎‎‏‎"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎No work apps‎‏‎‎‏‎"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎No personal apps‎‏‎‎‏‎"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎Open personal ‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎Open work ‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎Use personal browser‎‏‎‎‏‎"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎Use work browser‎‏‎‎‏‎"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‎SIM network unlock PIN‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 55da602..4ac6311 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite que la aplicación controle la vibración."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que la app acceda al estado del modo de vibración."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"llamar directamente a números de teléfono"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que la aplicación haga llamadas a números de teléfono sin intervención del usuario, lo que puede dar lugar a llamadas o cargos inesperados. Ten en cuenta que las aplicaciones no pueden usar este servicio para realizar llamadas a números de emergencia, pero las aplicaciones malintencionadas pueden causarte gastos imprevistos al realizar llamadas sin tu confirmación."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acceder al servicio IMS para realizar llamadas"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permite que la aplicación utilice el servicio IMS para hacer llamadas sin tu intervención."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"leer la identidad y el estado del dispositivo"</string>
@@ -2093,7 +2094,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Aceptar"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desactivar"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Más información"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Las notificaciones mejoradas reemplazaron a las notificaciones adaptables en Android 12. Esta función muestra respuestas y acciones sugeridas, y organiza tus notificaciones.\n\nLas notificaciones mejoradas pueden acceder a todo el contenido de notificaciones, lo que incluye información personal, como nombres de contactos y mensajes. También puede descartar o responder notificaciones (como contestar llamadas) y controlar la función No interrumpir."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Las notificaciones mejoradas reemplazaron a las notificaciones adaptables en Android 12. Esta función muestra respuestas y acciones sugeridas, y organiza tus notificaciones.\n\nLas notificaciones mejoradas pueden acceder a todo el contenido de notificaciones, lo que incluye información personal, como nombres de contactos y mensajes. También pueden descartar o responder notificaciones (como contestar llamadas) y controlar la función No interrumpir."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación de información del modo de Rutinas"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Ahorro de batería activado"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Reduciendo el uso de la batería para extender su duración"</string>
@@ -2160,8 +2161,10 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"No se puede abrir este contenido con apps de trabajo"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"No se pueden usar apps personales para compartir este contenido"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"No se puede abrir este contenido con apps personales"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"El perfil de trabajo está en pausa"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Presionar para activar"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"El contenido no es compatible con apps de trabajo"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"El contenido no es compatible con apps personales"</string>
     <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4b4b481..7558b7e 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite que la aplicación controle la función de vibración."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que la aplicación acceda al ajuste de vibración."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"llamar directamente a números de teléfono"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que la aplicación haga llamadas sin intervención del usuario, lo que puede dar lugar a llamadas o cargos inesperados. Ten en cuenta que las aplicaciones no pueden usar este servicio para realizar llamadas a números de emergencia, pero las aplicaciones malintencionadas pueden causarte gastos imprevistos al realizar llamadas sin tu confirmación."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acceder al servicio de llamadas IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permite que la aplicación utilice el servicio IMS para realizar llamadas sin tu intervención."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"consultar la identidad y el estado del teléfono"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Se ha cancelado el reconocimiento facial."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"El usuario ha cancelado Desbloqueo facial"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Demasiados intentos. Inténtalo de nuevo más tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Demasiados intentos. Desbloqueo facial no disponible."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Demasiados intentos. Usa el bloqueo de pantalla."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"No se ha verificado tu cara. Vuelve a intentarlo."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"No has configurado Desbloqueo facial"</string>
@@ -822,7 +822,7 @@
     <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Borra los datos del teléfono sin avisar restableciendo el estado de fábrica"</string>
     <string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"Borrar datos del perfil"</string>
     <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"Borrar datos del usuario"</string>
-    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Borra los datos del usuario en este tablet sin avisar."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Borra los datos del usuario en esta tablet sin avisar."</string>
     <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Eliminar los datos de este usuario del dispositivo Android TV sin previo aviso."</string>
     <string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"Borra los datos del perfil de este sistema de infoentretenimiento sin avisar."</string>
     <string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Borra los datos del usuario en este teléfono sin avisar."</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Este contenido no se puede abrir con aplicaciones de trabajo"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Este contenido no se puede compartir con aplicaciones personales"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Este contenido no se puede abrir con aplicaciones personales"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"El perfil de trabajo está en pausa"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Toca para activar"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ninguna aplicación de trabajo"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ninguna aplicación personal"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Abrir <xliff:g id="APP">%s</xliff:g> en el perfil personal"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Abrir <xliff:g id="APP">%s</xliff:g> en el perfil de trabajo"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar navegador personal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar navegador de trabajo"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueo de red de tarjeta SIM"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 528d42f4..e22fdea 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Võimaldab rakendusel juhtida vibreerimist."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Võimaldab rakendusel juurde pääseda vibreerimise olekule."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"helista otse telefoninumbritele"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Võimaldab rakendusel teie sekkumiseta telefoninumbritele helistada. See võib põhjustada ootamatuid tasusid või telefonikõnesid. Pange tähele, et see ei luba rakendusel helistada hädaabinumbritele. Pahatahtlikud rakendused võivad teile kulusid tekitada, tehes telefonikõnesid teie kinnituseta."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"juurdepääs IMS-kõneteenusele"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Võimaldab rakendusel kasutada IMS-teenust kõnede tegemiseks ilma, et peaksite sekkuma."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"Telefoni oleku ja identiteedi lugemine"</string>
@@ -623,11 +624,11 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"Viga autentimisel"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekraaniluku kasutamine"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Jätkamiseks sisestage oma ekraanilukk"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Vajutage tugevalt andurile"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Vajutage kindlalt andurile"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Sõrmejälge ei õnnestu tuvastada. Proovige uuesti."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Puhastage sõrmejäljeandur ja proovige uuesti"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Puhastage andur ja proovige uuesti"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Vajutage tugevalt andurile"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Vajutage kindlalt andurile"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Sõrm liikus liiga aeglaselt. Proovige uuesti."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Proovige teist sõrmejälge"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Liiga ere"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Näotuvastuse toiming tühistati."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Kasutaja tühistas näoga avamise"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Liiga palju katseid. Proovige hiljem uuesti."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Liiga palju katseid. Näoga avamine pole saadaval."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Liiga palju katseid. Kasutage selle asemel ekraanilukku."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nägu ei saa kinnitada. Proovige uuesti."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Näoga avamine ei ole seadistatud"</string>
@@ -1952,7 +1952,7 @@
     <string name="app_suspended_more_details" msgid="211260942831587014">"Lisateave"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Jätka rakendust"</string>
     <string name="work_mode_off_title" msgid="6367463960165135829">"Kas jätkata töörakendusi?"</string>
-    <string name="work_mode_turn_on" msgid="5316648862401307800">"Jätka"</string>
+    <string name="work_mode_turn_on" msgid="5316648862401307800">"Lõpeta peatamine"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hädaolukord"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Rakendus ei ole saadaval"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole praegu saadaval."</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Seda sisu ei saa töörakendustega avada"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Seda sisu ei saa isiklike rakendustega jagada"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Seda sisu ei saa isiklike rakendustega avada"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Tööprofiil on peatatud"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Puudutage sisselülitamiseks"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Töörakendusi pole"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Isiklikke rakendusi pole"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Ava isikliku profiili <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Ava tööprofiili <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Kasuta isiklikku brauserit"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Kasuta tööbrauserit"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM-kaardi võrgu avamise PIN-kood"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 20caa3c..6ddd2c4 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Bibragailua kontrolatzeko 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>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <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>
@@ -666,7 +667,7 @@
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Aurpegi bidez desblokeatzea"</string>
     <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Arazoak ditugu aurpegi bidez desblokeatzeko eginbidearekin"</string>
     <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_title" msgid="8843461561970741790">"Konfiguratu Aurpegi bidez desblokeatzea"</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 erabiltzeko baimena"</b>" Ezarpenak &gt; Pribatutasuna atalean"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfiguratu telefonoa desblokeatzeko modu gehiago"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Utzi da aurpegiaren bidezko eragiketa."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Erabiltzaileak aurpegi bidez desblokeatzeko aukera utzi du"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Saiakera gehiegi egin dituzu. Saiatu berriro geroago."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Saiakera gehiegi egin dira. Aurpegi bidez desblokeatzeko eginbidea ez dago erabilgarri."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Saiakera gehiegi egin dira. Horren ordez, erabili pantailaren blokeoa."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ezin da egiaztatu aurpegia. Saiatu berriro."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Ez duzu konfiguratu aurpegi bidez desblokeatzeko eginbidea"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Eduki hau ezin da laneko aplikazioekin ireki"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Eduki hau ezin da aplikazio pertsonalekin partekatu"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Eduki hau ezin da aplikazio pertsonalekin ireki"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Laneko profila pausatuta dago"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Sakatu aktibatzeko"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ez dago laneko aplikaziorik"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ez dago aplikazio pertsonalik"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Ireki <xliff:g id="APP">%s</xliff:g> pertsonala"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Ireki lanerako <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Erabili arakatzaile pertsonala"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Erabili laneko arakatzailea"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIMaren sarearen bidez desblokeatzeko PINa"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 519f89f..21ed614 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"‏به برنامه اجازه می‎دهد تا لرزاننده را کنترل کند."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"به برنامه اجازه می‌دهد تا به وضعیت لرزاننده دسترسی داشته باشد."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"تماس مستقیم با شماره تلفن‌ها"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"به برنامه اجازه می‌دهد بدون دخالت شما با شماره‌های تلفن تماس بگیرد. این ممکن است باعث ایجاد هزینه یا تماس‌های پیش‌بینی نشده شود. توجه داشته باشید که این به برنامه اجازه نمی‌دهد به برقراری تماس‌های اضطراری بپردازد. برنامه‌های مخرب ممکن است با برقراری تماس بدون تأیید شما هزینه‌هایی را برای شما ایجاد کنند."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"‏دسترسی به سرویس تماس IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"‏به برنامه اجازه می‌دهد از سرویس IMS برای برقراری تماس‌ها بدون دخالت شما استفاده کند."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"خواندن وضعیت تلفن و شناسه"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"عملیات شناسایی چهره لغو شد."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"کاربر «قفل‌گشایی با چهره» را لغو کرد"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"تعداد زیادی تلاش ناموفق. بعداً دوباره امتحان کنید."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"تعداد تلاش‌ها از حد مجاز بیشتر شده است. قفل‌گشایی با چهره دردسترس نیست."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"تلاش‌ها بیش از حدمجاز شده است. درعوض قفل صفحه را وارد کنید."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"چهره تأیید نشد. دوباره امتحان کنید."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"«قفل‌گشایی با چهره» را راه‌اندازی نکرده‌اید"</string>
@@ -1476,7 +1476,7 @@
     <string name="ime_action_default" msgid="8265027027659800121">"اجرا کردن"</string>
     <string name="dial_number_using" msgid="6060769078933953531">"شماره گیری \nبا استفاده از <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="6200708808003692594">"ایجاد مخاطب\nبا استفاده از <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"یک یا چند برنامه زیر برای دسترسی به حساب شما در زمان حال و آینده درخواست مجوز کرده‌اند."</string>
+    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"یک یا چند برنامه زیر برای دسترسی به حساب شما در زمان حال و آینده درخواست اجازه کرده‌اند."</string>
     <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"می‌خواهید به این درخواست اجازه دهید؟"</string>
     <string name="grant_permissions_header_text" msgid="3420736827804657201">"درخواست دسترسی"</string>
     <string name="allow" msgid="6195617008611933762">"ارزیابی‌شده"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"نمی‌توان این محتوا را با برنامه‌های کاری باز کرد"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"نمی‌توان این محتوا را با برنامه‌های شخصی هم‌رسانی کرد"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"نمی‌توان این محتوا را با برنامه‌های شخصی باز کرد"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"نمایه کاری موقتاً متوقف شده است"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"برای روشن کردن، ضربه بزنید"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"برنامه کاری‌ای وجود ندارد"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"برنامه شخصی‌ای وجود ندارد"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"باز کردن <xliff:g id="APP">%s</xliff:g> شخصی"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"باز کردن <xliff:g id="APP">%s</xliff:g> کاری"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"استفاده از مرورگر شخصی"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"استفاده از مرورگر کاری"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"پین باز کردن قفل شبکه سیم‌کارت"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index e4227ce..0695d12 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Antaa sovelluksen hallita värinää."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Sallii sovelluksen käyttää värinätilaa."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"soittaa puhelinnumeroihin suoraan"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Antaa sovelluksen soittaa puhelinnumeroihin kysymättä sinulta. Tämä voi aiheuttaa odottamattomia kuluja tai puheluita. Huomaa, että tämä ei anna sovellukselle lupaa soittaa hätänumeroihin. Haitalliset sovellukset voivat aiheuttaa sinulle kuluja soittamalla puheluita ilman lupaa."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pikaviestipalvelun puhelukäyttöoikeus"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Antaa sovelluksen soittaa puheluita pikaviestipalvelun avulla ilman käyttäjän toimia."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"lue puhelimen tila ja identiteetti"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Kasvotoiminto peruutettu"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Käyttäjä perui kasvojentunnistusavauksen"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Liian monta yritystä. Yritä myöhemmin uudelleen."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Liikaa yrityksiä. Face Unlock ei saatavilla."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Liian monta yritystä. Lisää sen sijaan näytön lukitus."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kasvoja ei voi vahvistaa. Yritä uudelleen."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Et ole ottanut käyttöön kasvojentunnistusavausta"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Tätä sisältöä ei voi avata työsovelluksilla"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Tätä sisältöä ei voi jakaa henkilökohtaisilla sovelluksilla"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Tätä sisältöä ei voi avata henkilökohtaisilla sovelluksilla"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Työprofiilin käyttö on keskeytetty"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Laita päälle napauttamalla"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ei työsovelluksia"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ei henkilökohtaisia sovelluksia"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Avaa henkilökohtainen sovellus (<xliff:g id="APP">%s</xliff:g>)"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Avaa työsovellus (<xliff:g id="APP">%s</xliff:g>)"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Käytä henkilökohtaista selainta"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Käytä työselainta"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM-kortin verkkoversion lukituksen avaamisen PIN-koodi"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index af769ab..5296fb2 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'application de gérer le vibreur de l\'appareil."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet à l\'application d\'accéder au mode vibration."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"appeler directement des numéros de téléphone"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permet à l\'application d\'appeler des numéros de téléphone sans votre intervention. Cette autorisation peut entraîner des frais ou des appels imprévus et ne permet pas à l\'application d\'appeler des numéros d\'urgence. Des applications malveillantes peuvent générer des frais en passant des appels sans votre consentement."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accéder au service d\'appel IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permet à l\'application d\'utiliser le service IMS pour faire des appels sans votre intervention."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"voir l\'état et l\'identité du téléphone"</string>
@@ -685,7 +686,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Déplacez le téléphone vers la gauche"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Déplacez le téléphone vers la droite"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Veuillez regarder plus directement votre appareil."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Impossible de voir votre visage. Tenez votre téléphone à la hauteur des yeux."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Visage non détecté. Tenez votre téléphone à hauteur des yeux."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Trop de mouvement. Tenez le téléphone immobile."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Veuillez inscrire votre visage à nouveau."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Visage non reconnu. Réessayez."</string>
@@ -2160,8 +2161,10 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Impossible d\'ouvrir ce contenu avec des applications professionnelles"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Impossible de partager ce contenu avec des applications personnelles"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Impossible d\'ouvrir ce contenu avec des applications personnelles"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Le profil professionnel est interrompu"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Touchez pour activer"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune application professionnelle"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune application personnelle"</string>
     <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index b2cef66..1da7374 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'application de contrôler le vibreur."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet à l\'application d\'accéder à l\'état du vibreur."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"appeler directement les numéros de téléphone"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permet à l\'application d\'appeler des numéros de téléphone sans votre intervention. Cette autorisation peut entraîner des frais ou des appels imprévus et ne permet pas à l\'application d\'appeler des numéros d\'urgence. Les applications malveillantes peuvent générer des frais en passant des appels sans votre consentement."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accéder au service d\'appel IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permet à l\'application d\'utiliser le service IMS pour passer des appels sans votre intervention."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"Voir l\'état et l\'identité du téléphone"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Opération de reconnaissance faciale annulée."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Déverrouillage par reconnaissance faciale annulé par l\'utilisateur"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Trop de tentatives. Réessayez plus tard."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Trop de tentatives. Déverrouillage par reconnaissance faciale indisponible."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Tentatives trop nombreuses. Utilisez le verrouillage de l\'écran."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Impossible de valider votre visage. Réessayez."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Déverrouillage par reconnaissance faciale non configuré"</string>
@@ -1717,7 +1717,7 @@
     <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>
-    <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Prothèses auditives"</string>
+    <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Appareils auditifs"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les boutons de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, appuyez de nouveau sur les deux boutons de volume pendant trois secondes."</string>
@@ -1888,7 +1888,7 @@
     <string name="zen_mode_until_next_day" msgid="1403042784161725038">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_until" msgid="2250286190237669079">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarme suivante)"</string>
-    <string name="zen_mode_forever" msgid="740585666364912448">"Jusqu\'à la désactivation"</string>
+    <string name="zen_mode_forever" msgid="740585666364912448">"Jusqu\'à ce que vous le désactiviez"</string>
     <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Jusqu\'à ce que vous désactiviez la fonctionnalité \"Ne pas déranger\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Réduire"</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Impossible d\'ouvrir ce contenu avec des applis professionnelles"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Impossible de partager ce contenu avec des applis personnelles"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Impossible d\'ouvrir ce contenu avec des applis personnelles"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Profil professionnel en pause"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Appuyez pour l\'activer"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune appli professionnelle"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune appli personnelle"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Ouvrir l\'appli personnelle <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Ouvrir l\'appli professionnelle <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utiliser le navigateur personnel"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utiliser le navigateur professionnel"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Code PIN de déblocage du réseau SIM"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 8bd6b9e..5ca9724 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite á aplicación controlar o vibrador."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que a aplicación acceda ao estado de vibrador"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"chamar directamente aos números de teléfono"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite á aplicación chamar a números de teléfono sen a túa intervención. Esta acción pode implicar chamadas ou custos inesperados. Ten en conta que isto non permite á aplicación chamar a números de emerxencia. É posible que aplicacións maliciosas che custen diñeiro debido á realización de chamadas sen a túa confirmación."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acceso ao servizo de chamadas de IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permite que a aplicación use o servizo de IMS para facer chamadas sen a túa intervención."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ler o estado e a identidade do teléfono"</string>
@@ -684,7 +685,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Move o teléfono cara á esquerda"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Move o teléfono cara á dereita"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Mira o dispositivo de forma máis directa."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Non se pode ver a túa cara. Coloca o teléfono á altura dos ollos."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"A túa cara non é visible. Pon o teléfono frente ós ollos."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Demasiado movemento. Non movas o teléfono."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Volve rexistrar a túa cara."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Non se recoñeceu a cara. Téntao de novo."</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Cancelouse a operación relacionada coa cara"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"O usuario cancelou o desbloqueo facial"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Demasiados intentos. Téntao de novo máis tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Houbo demasiados intentos. O desbloqueo facial non está dispoñible."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Realizaches demasiados intentos. Mellor usa o bloqueo de pantalla."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Non se puido verificar a cara. Téntao de novo."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Non configuraches o desbloqueo facial"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Este contido non pode abrirse con aplicacións do traballo"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Este contido non pode compartirse con aplicacións persoais"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Este contido non pode abrirse con aplicacións persoais"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"O perfil de traballo está en pausa"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tocar para activar o perfil"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Non hai ningunha aplicación do traballo compatible"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Non hai ningunha aplicación persoal compatible"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Abrir <xliff:g id="APP">%s</xliff:g> no perfil persoal"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Abrir <xliff:g id="APP">%s</xliff:g> no perfil de traballo"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utilizar navegador persoal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utilizar navegador de traballo"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueo da rede SIM"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index a96de9c..aa25626 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"એપ્લિકેશનને વાઇબ્રેટરને નિયંત્રિત કરવાની મંજૂરી આપે છે."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ઍપને વાઇબ્રેટર સ્થિતિને ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"સીધા જ ફોન નંબર્સ પર કૉલ કરો"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"એપ્લિકેશનને તમારા હસ્તક્ષેપ વિના ફોન નંબર્સ પર કૉલ કરવાની મંજૂરી આપે છે. આ અનપેક્ષિત શુલ્ક અથવા કૉલ્સમાં પરિણમી શકે છે. નોંધો કે આ એપ્લિકેશનને કટોકટીના નંબર્સ પર કૉલ કરવાની મંજૂરી આપતું નથી. દુર્ભાવનાપૂર્ણ ઍપ્લિકેશનો તમારી પુષ્ટિ વિના કૉલ્સ કરીને તમારા પૈસા ખર્ચ કરી શકે છે."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS કૉલ સેવા ઍક્સેસ કરો"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"તમારા હસ્તક્ષેપ વગર કૉલ્સ કરવા માટે IMS સેવાનો ઉપયોગ કરવાની એપ્લિકેશનને મંજૂરી આપે છે."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ફોન સ્થિતિ અને ઓળખ વાંચો"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"ચહેરા સંબંધિત કાર્યવાહી રદ કરવામાં આવી છે."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"વપરાશકર્તાએ ફેસ અનલૉક કાર્ય રદ કર્યું"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"ઘણા બધા પ્રયત્નો. થોડા સમય પછી ફરી પ્રયાસ કરો."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"ઘણા બધા પ્રયાસો કર્યા. ફેસ અનલૉક ઉપલબ્ધ નથી."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"ઘણા બધા પ્રયાસો. તેને બદલે સ્ક્રીન લૉકનો ઉપયોગ કરો."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ચહેરો ચકાસી શકાતો નથી. ફરી પ્રયાસ કરો."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"તમે ફેસ અનલૉક સુવિધાનું સેટઅપ કર્યું નથી"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"આ કન્ટેન્ટ ઑફિસ માટેની ઍપ વડે ખોલી શકાતું નથી"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"આ કન્ટેન્ટ વ્યક્તિગત ઍપ સાથે શેર કરી શકાતું નથી"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"આ કન્ટેન્ટ વ્યક્તિગત ઍપ વડે ખોલી શકાતું નથી"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ઑફિસની પ્રોફાઇલ થોભાવી છે"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ચાલુ કરવા માટે ટૅપ કરો"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"કોઈ ઑફિસ માટેની ઍપ સપોર્ટ કરતી નથી"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"કોઈ વ્યક્તિગત ઍપ સપોર્ટ કરતી નથી"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"વ્યક્તિગત પ્રોફાઇલવાળી <xliff:g id="APP">%s</xliff:g> ઍપ ખોલો"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"ઑફિસની પ્રોફાઇલવાળી <xliff:g id="APP">%s</xliff:g> ઍપ ખોલો"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"વ્યક્તિગત બ્રાઉઝરનો ઉપયોગ કરો"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ઑફિસના બ્રાઉઝરના ઉપયોગ કરો"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"સિમ નેટવર્કને અનલૉક કરવાનો પિન"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 84634d4..f4f77a9 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ऐप्स को कंपनकर्ता नियंत्रित करने देता है."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"इससे ऐप्लिकेशन, डिवाइस का वाइब्रेटर ऐक्सेस कर पाएगा."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"फ़ोन नंबर पर सीधे कॉल करें"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"ऐप्लिकेशन को आपके हस्‍तक्षेप के बिना फ़ोन नंबर पर कॉल करने देता है. इसके परिणाम अनचाहे शुल्‍क या कॉल हो सकते हैं. ध्यान दें कि यह ऐप्लिकेशन को आपातकालीन नंबर पर कॉल नहीं करने देता. नुकसान पहुंचाने वाला ऐप्लिकेशन आपकी पुष्टि के बिना कॉल करके आपके पैसे खर्च करवा सकते हैं."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS कॉल सेवा ऐक्‍सेस करें"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"आपके हस्‍तक्षेप के बिना कॉल करने के लिए, ऐप को IMS सेवा का उपयोग करने देती है."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"फ़ोन की स्‍थिति और पहचान पढ़ें"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"चेहरा पहचानने की कार्रवाई रद्द की गई."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"उपयोगकर्ता ने फ़ेस अनलॉक को रद्द किया"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"कई बार कोशिश की गई. बाद में कोशिश करें."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"कई बार कोशिश की गई. फ़ेस अनलॉक की सुविधा उपलब्ध नहीं है."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"कई बार कोशिश की जा चुकी है. इसके बजाय, स्क्रीन लॉक का इस्तेमाल करें."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"चेहरा नहीं पहचान पा रहे. फिर से कोशिश करें."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"आपने फ़ेस अनलॉक सेट अप नहीं किया है"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"इस कॉन्टेंट को ऑफ़िस के काम से जुड़े ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"इस कॉन्टेंट को निजी ऐप्लिकेशन का इस्तेमाल करके, शेयर नहीं किया जा सकता"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"इस कॉन्टेंट को निजी ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"वर्क प्रोफ़ाइल रोक दी गई है"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"वर्क प्रोफ़ाइल चालू करने के लिए टैप करें"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"यह कॉन्टेंट, ऑफ़िस के काम से जुड़े आपके किसी भी ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"यह कॉन्टेंट आपके किसी भी निजी ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"निजी प्रोफ़ाइल वाला <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन खोलें"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"वर्क प्रोफ़ाइल वाला <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन खोलें"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"निजी ब्राउज़र का इस्तेमाल करें"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ऑफ़िस के काम से जुड़े ब्राउज़र का इस्तेमाल करें"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"सिम नेटवर्क को अनलॉक करने का पिन"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 1246649..86869fa 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Aplikaciji omogućuje nadzor nad vibratorom."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Aplikaciji omogućuje da pristupi stanju vibracije."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"izravno pozivanje telefonskog broja"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Aplikaciji omogućuje pozivanje telefonskih brojeva bez vašeg sudjelovanja. To može dovesti do neočekivanih troškova ili poziva. Uzmite u obzir da se aplikaciji time ne omogućuje pozivanje brojeva u nuždi. Zlonamjerne aplikacije mogu vam uzrokovati dodatne troškove postavljanjem poziva bez vašeg odobrenja."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pristupiti usluzi poziva izravnih poruka"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Omogućuje aplikaciji upotrebu usluge izravnih poruka za uspostavljanje poziva bez vaše intervencije."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"čitanje statusa i identiteta telefona"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Otkazana je radnja s licem."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Korisnik je otkazao otključavanje licem"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Previše pokušaja. Otključavanje licem nije dostupno."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Previše pokušaja. Umjesto toga prijeđite na zaključavanje zaslona."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Lice nije potvrđeno. Pokušajte ponovo."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Niste postavili otključavanje licem"</string>
@@ -1717,7 +1717,7 @@
     <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>
-    <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni uređaji"</string>
+    <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušna pomagala"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za glasnoću. Da biste uključili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za glasnoću tri sekunde."</string>
@@ -1875,7 +1875,7 @@
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Štednja baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizualne efekte, određene značajke i neke mrežne veze."</string>
     <string name="battery_saver_description" msgid="8518809702138617167">"Štednja baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizualne efekte, određene značajke i neke mrežne veze."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"Da bi se smanjila potrošnja podatkovnog prometa, štednja podatkovnog prometa onemogućuje nekim aplikacijama slanje ili primanje podataka u pozadini. Aplikacija koju trenutačno upotrebljavate može pristupati podacima, no to će možda činiti rjeđe. To može značiti da se, na primjer, slike neće prikazivati dok ih ne dodirnete."</string>
-    <string name="data_saver_enable_title" msgid="7080620065745260137">"Uključiti štednju podatkovnog prometa?"</string>
+    <string name="data_saver_enable_title" msgid="7080620065745260137">"Želite li uključiti štednju podatkovnog prometa?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string>
     <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{1 min (do {formattedTime})}one{# min (do {formattedTime})}few{# min (do {formattedTime})}other{# min (do {formattedTime})}}"</string>
     <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{1 min (do {formattedTime})}one{# min (do {formattedTime})}few{# min (do {formattedTime})}other{# min (do {formattedTime})}}"</string>
@@ -1888,7 +1888,7 @@
     <string name="zen_mode_until_next_day" msgid="1403042784161725038">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sljedeći alarm)"</string>
-    <string name="zen_mode_forever" msgid="740585666364912448">"Dok ne isključite"</string>
+    <string name="zen_mode_forever" msgid="740585666364912448">"Do isključivanja"</string>
     <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dok ne isključite \"Ne uznemiravaj\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Sažmi"</string>
@@ -2093,7 +2093,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"U redu"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Isključi"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"U Androidu 12 poboljšane obavijesti zamjenjuju prilagodljive obavijesti za Android. Ta značajka prikazuje predložene radnje i odgovore te organizira vaše obavijesti.\n\nPoboljšane obavijesti mogu pristupati sadržaju obavijesti, uključujući osobne podatke kao što su imena kontakata i poruke. Ta značajka može i odbacivati obavijesti ili poduzimati radnje u vezi s njima, na primjer može odgovarati na telefonske pozive i upravljati značajkom Ne uznemiravaj."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Androidove prilagodljive obavijesti zamijenjene su poboljšanim obavijestima na Androidu 12. Ta značajka prikazuje predložene radnje i odgovore te organizira vaše obavijesti.\n\nPoboljšane obavijesti mogu pristupati sadržaju obavijesti, uključujući osobne podatke kao što su imena kontakata i poruke. Ta značajka može i odbacivati obavijesti ili poduzimati radnje u vezi s njima, na primjer može odgovarati na telefonske pozive i upravljati značajkom Ne uznemiravaj."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obavještavanje o informacijama u Rutinskom načinu rada"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Uključena je štednja baterije"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Smanjuje se potrošnja baterije radi produženja njezinog trajanja"</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Taj se sadržaj ne može otvoriti pomoću poslovnih aplikacija"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Taj se sadržaj ne može dijeliti pomoću osobnih aplikacija"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Taj se sadržaj ne može otvoriti pomoću osobnih aplikacija"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Poslovni profil je pauziran"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Dodirnite da biste uključili"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Poslovne aplikacije nisu dostupne"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Osobne aplikacije nisu dostupne"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Otvorite osobnu aplikaciju <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Otvorite poslovnu aplikaciju <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Koristi osobni preglednik"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Koristi poslovni preglednik"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN za otključavanje SIM mreže."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 27e4ab7..9a585f81 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Lehetővé teszi az alkalmazás számára a rezgés vezérlését."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Lehetővé teszi az alkalmazás számára a rezgés állapotához való hozzáférést."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefonszámok közvetlen hívása"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Lehetővé teszi az alkalmazás számára, hogy az Ön jóváhagyása nélkül hívjon fel telefonszámokat. Ennek eredményeként váratlan terhelésekkel vagy telefonhívásokkal találkozhat. Vegye figyelembe, hogy ez nem teszi lehetővé segélyhívó számok hívását az alkalmazás számára. A rosszindulatú alkalmazások az Ön jóváhagyása nélkül kezdeményezhetnek hívásokat, így költségek merülhetnek fel."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"hozzáférés az IMS-hívásszolgáltatáshoz"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Az alkalmazás az IMS-szolgáltatást használhatja híváskezdeményezéshez az Ön közbeavatkozása nélkül."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"telefonállapot és azonosító olvasása"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Az arccal kapcsolatos művelet törölve."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Az Arcalapú feloldást megszakította a felhasználó"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Túl sok próbálkozás. Próbálja újra később."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Túl sokszor próbálkozott. Az Arcalapú feloldás nem áll rendelkezésre."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Túl sok próbálkozás. Használja inkább a képernyőzárat."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nem sikerült ellenőrizni az arcát. Próbálja újra."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Nem állította be az Arcalapú feloldást"</string>
@@ -2095,7 +2095,7 @@
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"A bővített értesítések felváltják az androidos alkalmazkodó értesítéseket az Android 12-es verziójában. Ez a funkció javasolt műveleteket és válaszokat mutat, és rendszerezi az értesítéseket.\n\nA bővített értesítések minden értesítéstartalmat olvashatnak (így a személyes adatokat, mint például a névjegyek nevét és az üzeneteket is). Ez a funkció emellett elvetheti az értesítéseket, valamint reagálhat rájuk, például felveheti a telefonhívásokat, és vezérelheti a Ne zavarjanak módot."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Információs értesítés a rutinmódról"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Akkumulátorkímélő mód bekapcsolva"</string>
-    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Akkumulátorhasználat csökkentése a hosszabb akkumulátor-élettartam érdekében"</string>
+    <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Akkuhasználat csökkentése a hosszabb akkumulátor-élettartam érdekében"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Akkumulátorkímélő mód"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Akkumulátorkímélő mód kikapcsolva"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"A telefon töltöttsége elegendő. A funkciók használata már nincs korlátozva."</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Ez a tartalom nem nyitható meg munkahelyi alkalmazásokkal"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Ez a tartalom nem osztható meg személyes alkalmazásokkal"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Ez a tartalom nem nyitható meg személyes alkalmazásokkal"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"A munkaprofil használata szünetel"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Koppintson a bekapcsoláshoz"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nincs munkahelyi alkalmazás"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nincs személyes alkalmazás"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Személyes <xliff:g id="APP">%s</xliff:g> megnyitása"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Munkahelyi <xliff:g id="APP">%s</xliff:g> megnyitása"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Személyes böngésző használata"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Munkahelyi böngésző használata"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Hálózati SIM feloldó PIN-kódja"</string>
@@ -2299,7 +2299,7 @@
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Háttértevékenység"</string>
     <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Egy alkalmazás meríti az akkumulátort"</string>
     <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Az egyik alkalmazás még aktív"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"A(z) <xliff:g id="APP">%1$s</xliff:g> fut a háttérben. Koppintson az akkumulátorhasználat kezeléséhez."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"A(z) <xliff:g id="APP">%1$s</xliff:g> fut a háttérben. Koppintson az akkuhasználat kezeléséhez."</string>
     <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"A(z) <xliff:g id="APP">%1$s</xliff:g> befolyásolhatja az akkumulátor üzemidejét. Koppintson az aktív alkalmazások áttekintéséhez."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktív alkalmazások ellenőrzése"</string>
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nem lehet hozzáférni a telefon kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 56281fe..ea57ed4 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Թույլ է տալիս հավելվածին կառավարել թրթռոցը:"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Հավելվածին թույլ է տալիս օգտագործել սարքի թրթռալու ռեժիմը։"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ուղղակիորեն զանգել հեռախոսահամարներին"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Թույլ է տալիս հավելվածին զանգել հեռախոսահամարներին առանց ձեր միջամտության: Սա կարող է հանգեցնել անկանխատեսելի գանձումների կամ զանգերի: Նկատի ունեցեք, որ սա թույլ չի տալիս հավելվածին զանգել արտակարգ իրավիճակների համարներին: Վնասարար հավելվածները կարող են ձեր հաշվից զանգեր կատարել` առանց ձեր հաստատման:"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"օգտվել IMS զանգերի ծառայությունից"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Թույլ է տալիս հավելվածին IMS ծառայության միջոցով կատարել զանգեր՝ առանց ձեր միջամտության:"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"կարդալ հեռախոսի կարգավիճակը և ինքնությունը"</string>
@@ -684,7 +685,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Տեղափոխեք հեռախոսը ձախ"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Տեղափոխեք հեռախոսը աջ"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Նայեք ուղիղ էկրանին։"</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Ձեր դեմքը չի երևում։ Հեռախոսը պահեք աչքերի մակարդակում։"</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Դեմքը չի երևում։ Հեռախոսը պահեք աչքերի մակարդակում։"</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Շատ եք շարժում։ Հեռախոսն անշարժ պահեք։"</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Նորից փորձեք։"</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Դեմքը չի հաջողվում ճանաչել։ Նորից փորձեք։"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Դեմքի ճանաչումը չեղարկվել է։"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Դեմքով ապակողմումը չեղարկվել է օգտատիրոջ կողմից"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Չափից շատ փորձեր եք կատարել: Փորձեք ավելի ուշ:"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Չափազանց շատ փորձեր են արվել։ Դեմքով ապակողպումն անհասանելի է։"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Չափազանց շատ փորձեր են արվել։ Օգտագործեք էկրանի կողպումը։"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Չհաջողվեց հաստատել դեմքը։ Նորից փորձեք։"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Դուք չեք կարգավորել դեմքով ապակողպումը։"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Այս բովանդակությունը հնարավոր չէ բացել աշխատանքային հավելվածներով"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Այս բովանդակությունը հնարավոր չէ ուղարկել անձնական հավելվածներով"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Այս բովանդակությունը հնարավոր չէ բացել անձնական հավելվածներով"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Աշխատանքային պրոֆիլի ծառայությունը դադարեցված է"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Հպեք միացնելու համար"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Աշխատանքային հավելվածներ չկան"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Անձնական հավելվածներ չկան"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Անձնական <xliff:g id="APP">%s</xliff:g> պրոֆիլի բացում"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Աշխատանքային <xliff:g id="APP">%s</xliff:g> պրոֆիլի բացում"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Օգտագործել անձնական դիտարկիչը"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Օգտագործել աշխատանքային դիտարկիչը"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM Network քարտի ապակողպման PIN"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index cd7f613..568f12a 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Mengizinkan aplikasi untuk mengendalikan vibrator."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Mengizinkan aplikasi untuk mengakses status vibrator."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"panggil nomor telepon secara langsung"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Memungkinkan aplikasi menghubungi nomor telepon tanpa campur tangan Anda. Izin ini dapat mengakibatkan biaya atau panggilan tak terduga. Perhatikan bahwa izin ini tidak memungkinkan aplikasi menghubungi nomor darurat. Aplikasi berbahaya dapat menyebabkan Anda dikenakan biaya dengan melakukan panggilan tanpa konfirmasi Anda."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"akses layanan panggilan IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Memungkinkan aplikasi menggunakan layanan IMS untuk melakukan panggilan tanpa campur tangan Anda."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"baca identitas dan status ponsel"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Pemrosesan wajah dibatalkan."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Buka dengan Wajah dibatalkan oleh pengguna"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Terlalu banyak percobaan. Coba lagi nanti."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Terlalu banyak upaya gagal. Buka dengan Wajah tidak tersedia."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Terlalu banyak upaya gagal. Masukkan kunci layar."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Tidak dapat memverifikasi wajah. Coba lagi."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Anda belum menyiapkan Buka dengan Wajah"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Konten ini tidak dapat dibuka dengan aplikasi kerja"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Konten ini tidak dapat dibagikan dengan aplikasi pribadi"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Konten ini tidak dapat dibuka dengan aplikasi pribadi"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Profil kerja dijeda"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Ketuk untuk mengaktifkan"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Tidak ada aplikasi kerja"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Tidak ada aplikasi pribadi"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Buka <xliff:g id="APP">%s</xliff:g> pribadi"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Buka <xliff:g id="APP">%s</xliff:g> kerja"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Gunakan browser pribadi"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Gunakan browser kerja"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN pembuka kunci SIM network"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 2558dae..eb34c84 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Leyfir forriti að stjórna titraranum."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Veitir forritinu aðgang að stöðu titrings."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"hringja beint í símanúmer"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Leyfir forriti að hringja í símanúmer án íhlutunar notanda. Þetta getur haft í för með sér óumbeðin gjöld og símtöl. Athugaðu að þetta leyfir forritinu ekki að hringja í neyðarnúmer. Spilliforrit geta stofnað til kostnaðar fyrir þig með því að hringja símtöl án þinnar heimildar."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"fá aðgang að IMS-símtalsþjónustu"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Leyfir forriti að nota IMS-þjónustu til að hringja án inngrips frá þér."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"lesa stöðu símans og auðkenni"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Hætt við andlitsgreiningu."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Notandi hætti við andlitskenni."</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Of margar tilraunir. Reyndu aftur síðar."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Of margar tilraunir. Andlitskenni ekki í boði."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Of margar tilraunir. Sláðu inn skjálásinn í staðinn."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ekki tókst að staðfesta andlit. Reyndu aftur."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Þú hefur ekki sett upp andlitskenni."</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Ekki er hægt að opna þetta efni með vinnuforritum"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Ekki er hægt að deila þessu efni með forritum til einkanota"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Ekki er hægt að opna þetta efni með forritum til einkanota"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Hlé gert á vinnusniði"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Ýttu til að kveikja"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Engin vinnuforrit"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Engin forrit til einkanota"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Opna <xliff:g id="APP">%s</xliff:g> með einkaprófíl"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Opna <xliff:g id="APP">%s</xliff:g> með vinnuprófíl"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Nota einkavafra"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Nota vinnuvafra"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-númer fyrir opnun á SIM-korti netkerfis"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 0bfa643..a170c92 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Consente all\'applicazione di controllare la vibrazione."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Consente all\'app di accedere allo stato di vibrazione."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"chiamata diretta n. telefono"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Consente all\'applicazione di chiamare numeri di telefono senza il tuo intervento. Ciò può comportare chiamate o addebiti imprevisti. Tieni presente che ciò non consente all\'applicazione di chiamare numeri di emergenza. Applicazioni dannose potrebbero generare dei costi effettuando chiamate senza la tua conferma."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accesso al servizio di chiamata IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Consente all\'app di utilizzare il servizio IMS per fare chiamate senza il tuo intervento."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"lettura stato e identità telefono"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Operazione associata al volto annullata."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Sblocco con il volto annullato dall\'utente"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Troppi tentativi. Riprova più tardi."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Troppi tentativi. Sblocco con il volto non disponibile."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Troppi tentativi. Inserisci il blocco schermo."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Impossibile verificare il volto. Riprova."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Non hai configurato lo sblocco con il volto"</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Questi contenuti non possono essere aperti con app di lavoro"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Questi contenuti non possono essere condivisi con app personali"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Questi contenuti non possono essere aperti con app personali"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Profilo di lavoro in pausa"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tocca per attivare"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nessuna app di lavoro"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nessuna app personale"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Apri l\'app <xliff:g id="APP">%s</xliff:g> personale"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Apri l\'app <xliff:g id="APP">%s</xliff:g> di lavoro"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usa il browser personale"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usa il browser di lavoro"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN di sblocco rete SIM"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 40dead0..0d8eca0 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"מאפשרת לאפליקציה לשלוט ברטט."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"מאפשרת לאפליקציה לקבל גישה למצב רטט."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"חיוג ישירות למספרי טלפון"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"מאפשרת לאפליקציה להתקשר למספרי טלפון ללא התערבות המשתמש. הפעולה הזו עשויה לגרום לשיחות או לחיובים לא צפויים. ההרשאה הזו לא מאפשרת לאפליקציה להתקשר למספרי חירום. אפליקציות זדוניות עשויות לגרום לחיובים על ידי ביצוע שיחות ללא האישור שלך."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"‏גישה אל שירות שיחות IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"‏מאפשרת לאפליקציה להשתמש בשירות ה-IMS לביצוע שיחות ללא התערבות שלך."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"קריאת הסטטוס והזהות של הטלפון"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"הפעולה לאימות הפנים בוטלה."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"הפתיחה ע\"י זיהוי הפנים בוטלה על ידי המשתמש"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"יותר מדי ניסיונות. יש לנסות שוב מאוחר יותר."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"בוצעו יותר מדי ניסיונות. אי אפשר לפתוח בזיהוי פנים."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"בוצעו יותר מדי ניסיונות. יש להשתמש בנעילת המסך במקום."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"לא ניתן לאמת את הפנים. יש לנסות שוב."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"לא הגדרת פתיחה ע\"י זיהוי הפנים"</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"אי אפשר לפתוח את התוכן הזה באמצעות אפליקציות לעבודה"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"אי אפשר לשתף את התוכן הזה עם אפליקציות לשימוש אישי"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"אי אפשר לפתוח את התוכן הזה באמצעות אפליקציות לשימוש אישי"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"פרופיל העבודה מושהה"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"יש להקיש כדי להפעיל את פרופיל העבודה"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"אין אפליקציות לעבודה"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"אין אפליקציות לשימוש אישי"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"פתיחת <xliff:g id="APP">%s</xliff:g> בפרופיל האישי"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"פתיחת <xliff:g id="APP">%s</xliff:g> בפרופיל העבודה"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"בדפדפן האישי"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"בדפדפן של העבודה"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‏קוד אימות לביטול הנעילה של רשת SIM"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 6b3bc87..4c63c1d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"バイブレーションの制御をアプリに許可します。"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"バイブレーションのオン / オフ状態の把握をアプリに許可します。"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"電話番号発信"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"電話番号への自動発信をアプリに許可します。これにより、予期せぬ発信や料金が発生する可能性があります。なお、緊急通報番号への発信は許可されません。悪意のあるアプリが確認なしで発信し、料金が発生する恐れがあります。"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS通話サービスへのアクセス"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"IMSサービスがユーザー操作なしで電話をかけることをアプリに許可します。"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"デバイス情報と ID の読み取り"</string>
@@ -684,7 +685,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"スマートフォンを左に動かしてください"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"スマートフォンを右に動かしてください"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"もっとまっすぐデバイスに顔を向けてください。"</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"顔を確認できません。スマートフォンを目の高さに合わせて持ってください。"</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"顔を確認できません。スマートフォンを目の高さに合わせます。"</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"あまり動かさないでください。安定させてください。"</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"顔を登録し直してください。"</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"顔を認識できません。もう一度お試しください。"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"顔の操作をキャンセルしました。"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"顔認証はユーザーによりキャンセルされました"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"試行回数の上限です。後でもう一度お試しください。"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"試行回数が上限を超えました。顔認証を利用できません。"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"試行回数が上限を超えました。代わりに画面ロック解除を入力してください。"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"顔を確認できません。もう一度お試しください。"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"顔認証を設定していません"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"このコンテンツを仕事用アプリで開くことはできません"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"このコンテンツを個人用アプリと共有することはできません"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"このコンテンツを個人用アプリで開くことはできません"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"仕事用プロファイルが一時停止しています"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"タップして ON にする"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"仕事用アプリはありません"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"個人用アプリはありません"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"個人用 <xliff:g id="APP">%s</xliff:g> を開く"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"仕事用 <xliff:g id="APP">%s</xliff:g> を開く"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"個人用ブラウザを使用"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"仕事用ブラウザを使用"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM のネットワーク ロック解除 PIN"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 2c05e82..b4cb0cf 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -503,7 +503,7 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"აპს შეეძლება, მართოს ვიბრირება."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ნებას რთავს აპს, ჰქონდეს წვდომა ვიბრაციის მდგომარეობაზე."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"პირდაპირი დარეკვა ტელეფონის ნომრებზე"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"აპს შეეძლება დარეკოს ტელეფონის ნომრებზე თქვენი ჩარევის გარეშე. ამან შესაძლოა გამოიწვიოს თქვენს სატელეფონი ქვითარზე მოულოდნელი ხარჯებისა და ზარების გაჩენა. გაითვალისწინეთ, რომ აპს გადაუდებელი დახმარების ნომრებზე დარეკვა არ შეუძლია. მავნე აპებს შეეძლება თქვენი დადასტურების გარეშე ზარების განხორციელება და შესაბამისი საფასურის გადახდაც მოგიწევთ."</string>
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"საშუალებას აძლევს აპს, დარეკოს ტელეფონის ნომრებზე თქვენი ჩარევის გარეშე. ამან შეიძლება გამოიწვიოს მოულოდნელი ზარები ან თანხის ჩამოჭრა. გაითვალისწინეთ, რომ ეს საშუალებას არ აძლევს აპს, დარეკოს საგანგებო ვითარებაში საკონტაქტო პირის ნომრებზე. მავნე აპების გამოყენებით, შესაძლოა, თანხის გადახდა მოგიწიოთ თქვენი ნებართვის გარეშე განხორციელებული ზარების გამო, ან იმ ოპერატორების კოდების აკრეფის გამო, რომლებიც ავტომატურად გადაამისამართებს შემომავალ ზარებს სხვა ნომერზე."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ზარების სერვისზე წვდომა"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"აპს შეეძლება, გამოიყენოს IMS სერვისი ზარების თქვენი ჩარევის გარეშე განსახორციელებლად."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ტელეფონის სტატუსისა და იდენტობის წაკითხვა"</string>
@@ -709,8 +709,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"სახის ამოცნობა გაუქმდა."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"სახით განბლოკვა გაუქმდა მომხმარებლის მიერ"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"დაფიქსირდა ბევრი მცდელობა. ცადეთ მოგვიანებით."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"მეტისმეტად ბევრი მცდელობა იყო. სახით განბლოკვა მიუწვდომელია."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"მეტისმეტად ბევრი მცდელობა იყო. შეიყვანეთ ეკრანის დაბლოკვის პარამეტრები."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"სახის დადასტურება ვერ ხერხდება. ცადეთ ხელახლა."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"თქვენ არ დაგიყენებიათ სახით განბლოკვა."</string>
@@ -986,7 +985,7 @@
     <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"შეწყვეტა"</string>
     <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"უკან გადახვევა"</string>
     <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"წინ გადახვევა"</string>
-    <string name="emergency_calls_only" msgid="3057351206678279851">"მხოლოდ გადაუდებელი დახმარების ზარები"</string>
+    <string name="emergency_calls_only" msgid="3057351206678279851">"მხოლოდ გადაუდებელი ზარები"</string>
     <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"ქსელი ჩაკეტილია"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="2867953953604224166">"SIM დაბლოკილია PUK-ით."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"იხილეთ მომხმარებლის სახელმძღვანელო ან დაუკავშირდით კლიენტების მომსახურებას."</string>
@@ -2159,14 +2158,12 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ამ კონტენტის სამსახურის აპებით გახსნა შეუძლებელია"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ამ კონტენტის პირადი აპებისთვის გაზიარება შეუძლებელია"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ამ კონტენტის პირადი აპებით გახსნა შეუძლებელია"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"სამსახურის პროფილი დაპაუზებულია"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"შეეხეთ ჩასართავად"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"სამსახურის აპები დაპაუზებულია"</string>
+    <string name="resolver_switch_on_work" msgid="4527096360772311894">"პაუზის გაუქმება"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"სამსახურის აპები არ არის"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"პირადი აპები არ არის"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"გახსენით პერსონალური <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"გახსენით სამუშაო <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"პირადი ბრაუზერის გამოყენება"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"სამსახურის ბრაუზერის გამოყენება"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ქსელის განბლოკვის PIN-კოდი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 543aaa5..be3778b 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Қолданбаға вибраторды басқаруға рұқсат береді."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Қолданбаға діріл күйін пайдалануға мүмкіндік береді."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"нөмірлерге тікелей телефон шалу"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Қолданбаға сіздің қатысуыңызсыз қоңырау шалу мүмкіндігін береді. Нәтижесінде қосымша төлем немесе күтпеген қоңырау алуыңыз мүмкін. Есіңізде болсын, қолданба төтенше байланыстарға қоңырау шала алмайды. Залалды қолданбалар сіздің рұқсатыңызсыз қоңыраулар шалып, күтпеген төлемдерге себеп болуы мүмкін."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS қоңырау қызметін пайдалану"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Сіздің қатысуыңызсыз қоңыраулар соғу үшін қолданбаға IMS қызметін пайдалануға рұқсат етеді."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"телефон күйін оқу немесе анықтау"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Бетті танудан бас тартылды."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Пайдаланушы бет тану функциясынан бас тартты."</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Тым көп әрекет жасалды. Кейінірек қайталаңыз."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Тым көп әрекет жасалды. Бет тану функциясы қолжетімді емес."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Тым көп әрекет жасалды. Оның орнына экран құлпын енгізіңіз."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Бетті тану мүмкін емес. Әрекетті қайталаңыз."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Бет тану функциясы реттелмеген."</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Бұл контентті жұмыс қолданбаларымен ашу мүмкін емес."</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Бұл контентті жеке қолданбалармен бөлісу мүмкін емес."</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Бұл контентті жеке қолданбалармен ашу мүмкін емес."</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Жұмыс профилі кідіртілді."</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Қосу үшін түртіңіз"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Жұмыс қолданбалары жоқ."</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Жеке қолданбалар жоқ."</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Жеке <xliff:g id="APP">%s</xliff:g> қолданбасын ашу"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Жұмыстағы <xliff:g id="APP">%s</xliff:g> қолданбасын ашу"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Жеке браузерді пайдалану"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Жұмыс браузерін пайдалану"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM желісінің құлпын ашатын PIN коды"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index aef2196..2f9c2e7 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -324,7 +324,7 @@
     <string name="permgroupdesc_calllog" msgid="2026996642917801803">"អាន និងសរសេរ​កំណត់​ហេតុ​ហៅ​ទូរសព្ទ"</string>
     <string name="permgrouplab_phone" msgid="570318944091926620">"ទូរសព្ទ"</string>
     <string name="permgroupdesc_phone" msgid="270048070781478204">"ហៅទូរស័ព្ទ និងគ្រប់គ្រងការហៅទូរស័ព្ទ"</string>
-    <string name="permgrouplab_sensors" msgid="9134046949784064495">"ឧបករណ៍​ចាប់សញ្ញា​រាងកាយ"</string>
+    <string name="permgrouplab_sensors" msgid="9134046949784064495">"សេនស័រ​រាងកាយ"</string>
     <string name="permgroupdesc_sensors" msgid="2610631290633747752">"ចូលដំណើរការទិន្នន័យឧបករណ៍ចាប់សញ្ញាអំពីស្ថានភាពសុខភាពរបស់អ្នក"</string>
     <string name="permgrouplab_notifications" msgid="5472972361980668884">"ការ​ជូនដំណឹង"</string>
     <string name="permgroupdesc_notifications" msgid="4608679556801506580">"បង្ហាញ​ការជូនដំណឹង"</string>
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​កម្មវិធី​ញ័រ។"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"អនុញ្ញាតឱ្យ​កម្មវិធី​ចូលប្រើ​ស្ថានភាពកម្មវិធី​ញ័រ។"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​ផ្ទាល់"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"ឲ្យ​កម្មវិធី​ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​គ្មាន​សកម្មភាព​របស់​អ្នក។​ វា​អាច​កាត់​លុយ​ ឬ​ហៅ​ដោយ​មិន​រំពឹង​ទុក។ ចំណាំ​ថា​ វា​មិន​អនុញ្ញាត​ឲ្យ​កម្មវិធី​ហៅ​លេខ​ពេល​អាសន្ន​ទេ។ កម្មវិធី​ព្យាបាទ​អាច​កាត់​លុយ​របស់​អ្នក​ ដោយ​ធ្វើការ​ហៅ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"ចូលដំណើរការសេវាកម្មការហៅតាម IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"អនុញ្ញាតឲ្យកម្មវិធីនេះប្រើសេវាកម្ម IMS ដើម្បីធ្វើការហៅដោយគ្មានការអន្តរាគមន៍ពីអ្នក។"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"អាន​ស្ថានភាព និង​អត្តសញ្ញាណ​ទូរស័ព្ទ"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"បាន​បោះបង់​ប្រតិបត្តិការចាប់​ផ្ទៃមុខ។"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"អ្នកប្រើប្រាស់​បានបោះបង់​ការដោះសោ​តាមទម្រង់មុខ"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"ព្យាយាមចូលច្រើនពេកហើយ។ សូមព្យាយាមម្តងទៀតពេលក្រោយ។"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"ព្យាយាម​ច្រើនដងពេក។ មិនអាចប្រើការដោះសោតាមទម្រង់មុខបានទេ។"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"ព្យាយាម​ដោះសោ​ច្រើនដងពេក។ សូមបញ្ចូល​ការចាក់សោ​អេក្រង់​ជំនួសវិញ​។"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"មិន​អាច​ផ្ទៀងផ្ទាត់​មុខ​បាន​ទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"អ្នក​មិនបាន​រៀបចំ​ការដោះសោតាមទម្រង់មុខ​ទេ"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ខ្លឹមសារនេះ​មិនអាចបើក​តាមរយៈ​កម្មវិធី​ការងារ​បានទេ"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ខ្លឹមសារនេះ​មិនអាចចែករំលែក​តាមរយៈ​កម្មវិធី​ផ្ទាល់ខ្លួន​បានទេ"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ខ្លឹមសារនេះ​មិនអាចបើក​តាមរយៈ​កម្មវិធី​ផ្ទាល់ខ្លួន​បានទេ"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"កម្រងព័ត៌មានការងារត្រូវបាន​ផ្អាក"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ចុច​ដើម្បី​បើក"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"គ្មាន​កម្មវិធី​ការងារ​ទេ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"គ្មាន​កម្មវិធី​ផ្ទាល់ខ្លួន​ទេ"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"បើក <xliff:g id="APP">%s</xliff:g> ផ្ទាល់ខ្លួន"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"បើក <xliff:g id="APP">%s</xliff:g> សម្រាប់ការងារ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ប្រើ​កម្មវិធីរុករក​តាមអ៊ីនធឺណិត​ផ្ទាល់ខ្លួន"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ប្រើ​កម្មវិធីរុករក​តាមអ៊ីនធឺណិត​សម្រាប់​ការងារ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"កូដ PIN ដោះ​សោ​បណ្ដាញ​ស៊ីម"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 2faf699..7af2f5a 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -446,9 +446,9 @@
     <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ಪ್ರಸಾರವು ಮುಕ್ತಾಯಗೊಂಡ ನಂತರ ಉಳಿದಿರುವ ಜಿಗುಟಾದ ಪ್ರಸಾರಗಳನ್ನು ಕಳುಹಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದರ ಹೆಚ್ಚಿನ ಬಳಕೆಯು Android TV ಸಾಧನವನ್ನು ನಿಧಾನಗೊಳಿಸುತ್ತದೆ ಅಥವಾ ಅತಿಯಾಗಿ ಮೆಮೊರಿಯನ್ನು ಬಳಸುವಂತೆ ಮಾಡುವ ಮೂಲಕ ಅಸ್ಥಿರಗೊಳಿಸುತ್ತದೆ."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ಪ್ರಸಾರ ಕೊನೆಗೊಂಡ ನಂತರ ಹಾಗೆಯೇ ಉಳಿಯುವ ಸ್ಟಿಕಿ ಪ್ರಸಾರಗಳನ್ನು ಕಳುಹಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಮಿತಿಮೀರಿದ ಬಳಕೆಯು ಫೋನ್‍ ಅನ್ನು ನಿಧಾನಗೊಳಿಸಬಹುದು ಅಥವಾ ಅತಿಯಾದ ಮೆಮೊರಿ ಬಳಕೆಯು ಅಸ್ಥಿರತೆಯನ್ನು ಉಂಟುಮಾಡಬಹುದು."</string>
     <string name="permlab_readContacts" msgid="8776395111787429099">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಓದಿರಿ"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಂಪರ್ಕಗಳನ್ನು ರಚಿಸಿದ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿನ ಖಾತೆಗಳಿಗೂ ಸಹ ಆ್ಯಪ್‌ಗಳು ಪ್ರವೇಶ ಹೊಂದಿರುತ್ತವೆ. ಇದರಲ್ಲಿ ನೀವು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್‌ಗಳು ರಚಿಸಿದ ಖಾತೆಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಆದರೆ ದುರುದ್ದೇಶಪೂರಿತ ಆ್ಯಪ್‌ಗಳಿಗೆ ನಿಮ್ಮ ಗಮನಕ್ಕೆ ಬಾರದೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಂಪರ್ಕಗಳನ್ನು ರಚಿಸಿದ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿನ ಖಾತೆಗಳಿಗೂ ಸಹ ಆ್ಯಪ್‌ಗಳು ಆ್ಯಕ್ಸೆಸ್ ಹೊಂದಿರುತ್ತವೆ. ಇದರಲ್ಲಿ ನೀವು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್‌ಗಳು ರಚಿಸಿದ ಖಾತೆಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಆದರೆ ದುರುದ್ದೇಶಪೂರಿತ ಆ್ಯಪ್‌ಗಳಿಗೆ ನಿಮ್ಮ ಗಮನಕ್ಕೆ ಬಾರದೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
     <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ರಚಿಸಲಾದ ಸಂಪರ್ಕಗಳಿಗೆ ಖಾತೆಗಳಿಗೆ ಆ್ಯಪ್‌ಗಳು ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಇದರಲ್ಲಿ ನೀವು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್‌ಗಳು ರಚಿಸಿದ ಖಾತೆಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಆದರೆ ದುರುದ್ದೇಶಪೂರಿತ ಆ್ಯಪ್‌ಗಳಿಗೆ ನಿಮ್ಮ ಗಮನಕ್ಕೆ ಬಾರದೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
-    <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಂಪರ್ಕಗಳನ್ನು ರಚಿಸಿದ ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿನ ಖಾತೆಗಳಿಗೂ ಸಹ ಆ್ಯಪ್‌ಗಳು ಪ್ರವೇಶ ಹೊಂದಿರುತ್ತವೆ. ಇದರಲ್ಲಿ ನೀವು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್‌ಗಳು ರಚಿಸಿದ ಖಾತೆಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಆದರೆ ದುರುದ್ದೇಶಪೂರಿತ ಆ್ಯಪ್‌ಗಳಿಗೆ ನಿಮ್ಮ ಗಮನಕ್ಕೆ ಬಾರದೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
+    <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಂಪರ್ಕಗಳನ್ನು ರಚಿಸಿದ ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿನ ಖಾತೆಗಳಿಗೂ ಸಹ ಆ್ಯಪ್‌ಗಳು ಆ್ಯಕ್ಸೆಸ್ ಹೊಂದಿರುತ್ತವೆ. ಇದರಲ್ಲಿ ನೀವು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್‌ಗಳು ರಚಿಸಿದ ಖಾತೆಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಆದರೆ ದುರುದ್ದೇಶಪೂರಿತ ಆ್ಯಪ್‌ಗಳಿಗೆ ನಿಮ್ಮ ಗಮನಕ್ಕೆ ಬಾರದೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
     <string name="permlab_writeContacts" msgid="8919430536404830430">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಮಾರ್ಪಡಿಸಿ"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ಮಾರ್ಪಡಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಆ್ಯಪ್‌ಗಳಿಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ಮಾರ್ಪಡಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಆ್ಯಪ್‌ಗಳಿಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ವೈಬ್ರೇಟರ್‌ ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ವೈಬ್ರೇಟರ್ ಸ್ಥಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ಫೋನ್ ಸಂಖ್ಯೆಗಳಿಗೆ ನೇರವಾಗಿ ಕರೆ ಮಾಡಿ"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"ನಿಮ್ಮ ಹಸ್ತಕ್ಷೇಪ ಇಲ್ಲದೆಯೇ ಫೋನ್‍ ಸಂಖ್ಯೆಗಳಿಗೆ ಕರೆ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ಅನಿರೀಕ್ಷಿತ ಶುಲ್ಕಗಳು ಅಥವಾ ಕರೆಗಳಿಗೆ ಕಾರಣವಾಗಬಹುದು. ತುರ್ತು ಸಂಖ್ಯೆಗಳಿಗೆ ಕರೆಮಾಡಲು ಈ ಅಪ್ಲಿಕೇಶನ್‍ ಅನುಮತಿಸುವುದಿಲ್ಲ ಎಂಬುದು ಗಮನದಲ್ಲಿರಲಿ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್‍‍ಗಳು ನಿಮ್ಮ ಖಾತರಿ ಇಲ್ಲದೆಯೇ ಕರೆಗಳನ್ನು ಮಾಡುವುದರ ಮೂಲಕ ನಿಮ್ಮ ಹಣ ಖರ್ಚಾಗಬಹುದು."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ಕರೆ ಸೇವೆಯನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"ನಿಮ್ಮ ಮಧ್ಯಸ್ಥಿಕೆ ಇಲ್ಲದೆಯೇ ಕರೆಗಳನ್ನು ಮಾಡಲು IMS ಸೇವೆಯನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ಫೋನ್ ಸ್ಥಿತಿ ಮತ್ತು ಗುರುತಿಸುವಿಕೆಯನ್ನು ಓದಿ"</string>
@@ -519,7 +520,7 @@
     <string name="permlab_acceptHandover" msgid="2925523073573116523">"ಮತ್ತೊಂದು ಅಪ್ಲಿಕೇಶನ್‌ ಮೂಲಕ ಕರೆಯನ್ನು ಮುಂದುವರಿಸಿ"</string>
     <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"ಮತ್ತೊಂದು ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ ಪ್ರಾರಂಭವಾದ ಕರೆಯನ್ನು ಮುಂದುವರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡಿ."</string>
     <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"ಫೋನ್‌ ಸಂಖ್ಯೆಗಳನ್ನು ಓದಿ"</string>
-    <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"ಸಾಧನದ ಫೋನ್ ಸಂಖ್ಯೆಗಳಿಗೆ ಪ್ರವೇಶ ಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."</string>
+    <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"ಸಾಧನದ ಫೋನ್ ಸಂಖ್ಯೆಗಳಿಗೆ ಆ್ಯಕ್ಸೆಸ್ ಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."</string>
     <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"ಕಾರ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆನ್‌ನಲ್ಲೇ ಇರಿಸಿ"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"ಟ್ಯಾಬ್ಲೆಟ್ ನಿದ್ರಾವಸ್ಥೆಯನ್ನು ತಡೆಯಿರಿ"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"ನಿಮ್ಮ Android TV ಸಾಧನವು ನಿದ್ರಾವಸ್ಥೆಗೆ ಹೋಗುವುದನ್ನು ತಡೆಯಿರಿ"</string>
@@ -555,7 +556,7 @@
     <string name="permlab_accessWifiState" msgid="5552488500317911052">"ವೈ-ಫೈ ಸಂಪರ್ಕಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="permdesc_accessWifiState" msgid="6913641669259483363">"ವೈ-ಫೈ ಸಕ್ರಿಯಗೊಂಡಿದೆಯೇ ಮತ್ತು ಸಂಪರ್ಕಿಸಲಾದ ವೈ-ಫೈ ಸಾಧನಗಳ ಹೆಸರಿನ ಮಾಹಿತಿ ರೀತಿಯ, ವೈ-ಫೈ ನೆಟ್‍‍ವರ್ಕ್ ಕುರಿತು ಮಾಹಿತಿಯನ್ನು ವೀಕ್ಷಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
     <string name="permlab_changeWifiState" msgid="7947824109713181554">"ವೈ-ಫೈ ನಿಂದ ಸಂಪರ್ಕಗೊಳಿಸಿ ಮತ್ತು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿ"</string>
-    <string name="permdesc_changeWifiState" msgid="7170350070554505384">"ವೈ-ಫೈ ಪ್ರವೇಶ ಕೇಂದ್ರಗಳಿಂದ ಸಂಪರ್ಕ ಹೊಂದಲು ಮತ್ತು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲು, ಹಾಗೆಯೇ ವೈ-ಫೈ ನೆಟ್‍‍ವರ್ಕ್‌ಗಳಿಗೆ ಸಾಧನದ ಕನ್ಫಿಗರೇಶನ್‍ ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
+    <string name="permdesc_changeWifiState" msgid="7170350070554505384">"ವೈ-ಫೈ ಆ್ಯಕ್ಸೆಸ್ ಕೇಂದ್ರಗಳಿಂದ ಸಂಪರ್ಕ ಹೊಂದಲು ಮತ್ತು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲು, ಹಾಗೆಯೇ ವೈ-ಫೈ ನೆಟ್‍‍ವರ್ಕ್‌ಗಳಿಗೆ ಸಾಧನದ ಕನ್ಫಿಗರೇಶನ್‍ ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
     <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"ವೈ-ಫೈ ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಸ್ವೀಕಾರಕ್ಕೆ ಅನುಮತಿಸಿ"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಮಾತ್ರವಲ್ಲದೇ, ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ವಿಳಾಸಗಳನ್ನು ಬಳಸಿಕೊಂಡು ವೈ-ಫೈ ನೆಟ್‍‍ವರ್ಕ್‌ನಲ್ಲಿ ಎಲ್ಲಾ ಸಾಧನಗಳಿಗೆ ಕಳುಹಿಸಲಾಗಿರುವ ಪ್ಯಾಕೆಟ್‍‍ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಅಲ್ಲದ ಮೋಡ್ ಬಳಸುವ ಶಕ್ತಿಗಿಂತಲೂ ಹೆಚ್ಚಿನ ಶಕ್ತಿಯನ್ನು ಬಳಸುತ್ತದೆ."</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿ ನಿಮ್ಮ Android TV ಮಾತ್ರವಲ್ಲದೆ, ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ವಿಳಾಸಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಎಲ್ಲಾ ಸಾಧನಗಳಿಗೆ ಕಳುಹಿಸಲಾದ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಅಲ್ಲದ ಮೋಡ್‌ಗಿಂತಲೂ ಹೆಚ್ಚು ಪವರ್ ಬಳಸುತ್ತದೆ."</string>
@@ -623,11 +624,11 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"ದೃಢೀಕರಿಸುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ಮುಂದುವರಿಯಲು ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ ಅನ್ನು ನಮೂದಿಸಿ"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ಸೆನ್ಸರ್ ಮೇಲೆ ದೃಢವಾಗಿ ಒತ್ತಿರಿ"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ಸೆನ್ಸರ್ ಮೇಲೆ ಗಟ್ಟಿಯಾಗಿ ಒತ್ತಿರಿ"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಸ್ವಚ್ಛಗೊಳಿಸಿ ಹಾಗೂ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ಸೆನ್ಸರ್‌‌ ಸ್ವಚ್ಛಗೊಳಿಸಿ ಹಾಗೂ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"ಸೆನ್ಸರ್ ಮೇಲೆ ದೃಢವಾಗಿ ಒತ್ತಿರಿ"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"ಸೆನ್ಸರ್ ಮೇಲೆ ಗಟ್ಟಿಯಾಗಿ ಒತ್ತಿರಿ"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ಬೆರಳನ್ನು ತುಂಬಾ ನಿಧಾನವಾಗಿ ಸರಿಸಲಾಗಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ಮತ್ತೊಂದು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"ಮುಖದ ಕಾರ್ಯಚರಣೆಯನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಬಳಕೆದಾರರು ರದ್ದುಗೊಳಿಸಿದ್ದಾರೆ"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಲಭ್ಯವಿಲ್ಲ."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಬದಲಾಗಿ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ನಮೂದಿಸಿ."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"ನೀವು ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಿಲ್ಲ"</string>
@@ -1188,7 +1188,7 @@
     <string name="whichOpenLinksWith" msgid="1120936181362907258">"ಇವುಗಳ ಮೂಲಕ ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"<xliff:g id="APPLICATION">%1$s</xliff:g> ಮೂಲಕ ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"<xliff:g id="APPLICATION">%2$s</xliff:g> ಮೂಲಕ <xliff:g id="HOST">%1$s</xliff:g> ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
-    <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"ಪ್ರವೇಶ ಅನುಮತಿಸಿ"</string>
+    <string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"ಆ್ಯಕ್ಸೆಸ್ ಅನುಮತಿಸಿ"</string>
     <string name="whichEditApplication" msgid="6191568491456092812">"ಇವರ ಜೊತೆಗೆ ಎಡಿಟ್ ಮಾಡಿ"</string>
     <string name="whichEditApplicationNamed" msgid="8096494987978521514">"%1$s ಜೊತೆಗೆ ಎಡಿಟ್ ಮಾಡಿ"</string>
     <string name="whichEditApplicationLabel" msgid="1463288652070140285">"ಎಡಿಟ್"</string>
@@ -1272,7 +1272,7 @@
     <string name="dump_heap_ready_notification" msgid="2302452262927390268">"<xliff:g id="PROC">%1$s</xliff:g> ಹೀಪ್ ಡಂಪ್ ಸಿದ್ಧವಾಗಿದೆ"</string>
     <string name="dump_heap_notification_detail" msgid="8431586843001054050">"ಹೀಪ್ ಡಂಪ್ ಅನ್ನು ಸಂಗ್ರಹಿಸಲಾಗಿದೆ; ಹಂಚಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="dump_heap_title" msgid="4367128917229233901">"ಹೀಪ್ ಡಂಪ್ ಹಂಚಿಕೊಳ್ಳುವುದೇ?"</string>
-    <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g> ಪ್ರಕ್ರಿಯೆಯು ತನ್ನ <xliff:g id="SIZE">%2$s</xliff:g> ಮೆಮೊರಿ ಮಿತಿಯನ್ನು ಮೀರಿದೆ. ಅದರ ಡೆವಲಪರ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲು ನಿಮಗಾಗಿ ಹೀಪ್ ಡಂಪ್ ಲಭ್ಯವಿದೆ. ಎಚ್ಚರಿಕೆ: ಈ ಹೀಪ್ ಡಂಪ್, ಅಪ್ಲಿಕೇಶನ್ ಪ್ರವೇಶ ಹೊಂದಿರುವ ನಿಮ್ಮ ಯಾವುದೇ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು."</string>
+    <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g> ಪ್ರಕ್ರಿಯೆಯು ತನ್ನ <xliff:g id="SIZE">%2$s</xliff:g> ಮೆಮೊರಿ ಮಿತಿಯನ್ನು ಮೀರಿದೆ. ಅದರ ಡೆವಲಪರ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲು ನಿಮಗಾಗಿ ಹೀಪ್ ಡಂಪ್ ಲಭ್ಯವಿದೆ. ಎಚ್ಚರಿಕೆ: ಈ ಹೀಪ್ ಡಂಪ್, ಅಪ್ಲಿಕೇಶನ್ ಆ್ಯಕ್ಸೆಸ್ ಹೊಂದಿರುವ ನಿಮ್ಮ ಯಾವುದೇ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು."</string>
     <string name="dump_heap_system_text" msgid="6805155514925350849">"<xliff:g id="PROC">%1$s</xliff:g> ಪ್ರಕ್ರಿಯೆಯು ತನ್ನ <xliff:g id="SIZE">%2$s</xliff:g> ಮೆಮೊರಿ ಮಿತಿಯನ್ನು ಮೀರಿದೆ. ಹಂಚಿಕೊಳ್ಳಲು ನಿಮಗಾಗಿ ಹೀಪ್ ಡಂಪ್ ಲಭ್ಯವಿದೆ. ಎಚ್ಚರಿಕೆ: ಈ ಹೀಪ್ ಡಂಪ್, ಪ್ರಕ್ರಿಯೆಯು ಯಾವುದೇ ಸೂಕ್ಷ್ಮ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರಬಹುದು, ಇದು ನೀವು ಟೈಪ್ ಮಾಡಿದ ವಿಷಯಗಳನ್ನು ಸಹ ಒಳಗೊಂಡಿರಬಹುದು."</string>
     <string name="dump_heap_ready_text" msgid="5849618132123045516">"<xliff:g id="PROC">%1$s</xliff:g> ನ ಪ್ರಕ್ರಿಯೆಯ ಹೀಪ್ ಡಂಪ್ ನಿಮಗಾಗಿ ಹಂಚಿಕೊಳ್ಳಲು ಲಭ್ಯವಿದೆ. ಎಚ್ಚರಿಕೆ: ಈ ಹೀಪ್ ಡಂಪ್, ಪ್ರಕ್ರಿಯೆಯು ಯಾವುದೇ ಸೂಕ್ಷ್ಮ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರಬಹುದು, ಇದು ನೀವು ಟೈಪ್ ಮಾಡಿದ ವಿಷಯಗಳನ್ನು ಸಹ ಒಳಗೊಂಡಿರಬಹುದು."</string>
     <string name="sendText" msgid="493003724401350724">"ಪಠ್ಯಕ್ಕೆ ಕ್ರಿಯೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
@@ -1309,7 +1309,7 @@
     <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ಸೀಮಿತ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿದೆ"</string>
     <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ಹೇಗಾದರೂ ಸಂಪರ್ಕಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
-    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ ಹೊಂದಿಲ್ಲದಿರುವಾಗ, ಸಾಧನವು <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ಬಳಸುತ್ತದೆ. ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು."</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ಇಂಟರ್ನೆಟ್ ಆ್ಯಕ್ಸೆಸ್ ಹೊಂದಿಲ್ಲದಿರುವಾಗ, ಸಾಧನವು <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ಬಳಸುತ್ತದೆ. ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು."</string>
     <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ರಿಂದ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
   <string-array name="network_switch_type_name">
     <item msgid="2255670471736226365">"ಮೊಬೈಲ್ ಡೇಟಾ"</item>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳ ಈ ವಿಷಯವನ್ನು ತೆರೆಯಲಾಗುವುದಿಲ್ಲ"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ಗಳ ಮೂಲಕ ಈ ವಿಷಯವನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುವುದಿಲ್ಲ"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ಗಳ ಮೂಲಕ ಈ ವಿಷಯವನ್ನು ತೆರೆಯಲಾಗುವುದಿಲ್ಲ"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ಆನ್‌‌‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ಯಾವುದೇ ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಲ್ಲ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ಯಾವುದೇ ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ಗಳಿಲ್ಲ"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"ವೈಯಕ್ತಿಕ <xliff:g id="APP">%s</xliff:g> ತೆರೆಯಿರಿ"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"ಕೆಲಸದ <xliff:g id="APP">%s</xliff:g> ತೆರೆಯಿರಿ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ವೈಯಕ್ತಿಕ ಬ್ರೌಸರ್ ಬಳಸಿ"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ಉದ್ಯೋಗ ಬ್ರೌಸರ್ ಬಳಸಿ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ನೆಟ್‌ವರ್ಕ್‌ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index b4c0599..84ec310 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"앱이 진동을 제어할 수 있도록 허용합니다."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"앱이 진동 상태에 액세스하도록 허용합니다."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"전화번호 자동 연결"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"앱이 사용자의 조작 없이 전화번호로 전화를 걸 수 있도록 허용합니다. 이 경우 예상치 못한 통화 요금이 부과될 수 있습니다. 앱이 비상 전화를 걸도록 하는 권한은 주어지지 않습니다. 악성 앱이 사용자의 확인 없이 전화를 걸어 요금이 부과될 수 있습니다."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS 통화 서비스에 접근"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"앱이 IMS 서비스를 사용하여 자동으로 전화를 걸 수 있도록 허용합니다."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"휴대전화 상태 및 ID 읽기"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"얼굴 인식 작업이 취소되었습니다."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"사용자가 얼굴 인식 잠금 해제를 취소했습니다."</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"시도 횟수가 너무 많습니다. 나중에 다시 시도하세요."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"시도 횟수가 너무 많습니다. 얼굴 인식 잠금 해제를 사용할 수 없습니다."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"시도 횟수가 너무 많습니다. 화면 잠금을 대신 사용하세요."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"얼굴을 확인할 수 없습니다. 다시 시도하세요."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"얼굴 인식 잠금 해제를 설정하지 않았습니다."</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"이 콘텐츠는 직장 앱으로 열 수 없습니다."</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"이 콘텐츠는 개인 앱을 통해 공유할 수 없습니다."</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"이 콘텐츠는 개인 앱으로 열 수 없습니다."</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"직장 프로필이 일시중지됨"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"탭하여 사용 설정"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"직장 앱 없음"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"개인 앱 없음"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"개인 <xliff:g id="APP">%s</xliff:g> 열기"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"직장 <xliff:g id="APP">%s</xliff:g> 앱 열기"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"개인 브라우저 사용"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"직장 브라우저 사용"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 네트워크 잠금 해제 PIN"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 7b87b83..6207e5e 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Колдонмого дирилдегичти көзөмөлдөө мүмкүнчүлүгүн берет."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Колдонмого дирилдөө абалына кирүүгө уруксат берет."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"телефон номерлерине түз чалуу"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Колдонмого сиздин катышууңузсуз телефон номурларга чалуу уруксатын берет. Бул сиз күтпөгөн чыгымдарга же чалууларга алып келиши мүмкүн. Бул куткаруучулардын номурларына чалууга уруксат бербей тургандыгын эске алыңыз. Зыяндуу колдонмолор, сиздин ырастооңузсуз чалууларды аткарып, көп чыгымдарга себепкер болушу мүмкүн."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS чалуу кызматына мүмкүнчүлүк алуу"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Колдонмого сизди катыштырбай туруп, IMS кызматынын жардамы менен, чалууларды жасоо мүмкүнчүлүгүн берет."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"телефондун абалын жана аныктыгын окуу"</string>
@@ -610,7 +611,7 @@
     <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Колдонмого сүрөт жыйнагыңызды өзгөртүүгө мүмкүнчүлүк берет."</string>
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"медиа жыйнагыңыз сакталган жерлерди окуу"</string>
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"Колдонмого медиа жыйнагыңыз сакталган жерлерди окууга мүмкүнчүлүк берет."</string>
-    <string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометрикалык жөндөөлөрдү колдонуу"</string>
+    <string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометрикалык параметрлерди колдонуу"</string>
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометрикалык жөндөөнү же экрандын кулпусун колдонуу"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Өзүңүздү ырастаңыз"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Улантуу үчүн биометрикалык жөндөөнү колдонуу"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Жүздүн аныктыгын текшерүү жокко чыгарылды."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Жүзүнөн таанып ачуу функциясын колдонуучу өчүрүп салды"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Өтө көп жолу аракет жасадыңыз. Бир аздан кийин кайталап көрүңүз."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Өтө көп жолу аракет кылдыңыз. \"Жүзүнөн таанып ачуу\" жеткиликсиз."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Өтө көп жолу аракет кылдыңыз. Эрканды кулпулоо функциясын колдонуңуз."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Жүз ырасталбай жатат. Кайталап көрүңүз."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Жүзүнөн таанып ачуу функциясын жөндөй элексиз"</string>
@@ -1161,7 +1161,7 @@
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Киргизүү ыкмасын өзгөртүү"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Сактагычта орун калбай баратат"</string>
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Айрым функциялар иштебеши мүмкүн"</string>
-    <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Тутумда сактагыч жетишсиз. 250МБ бош орун бар экенин текшерип туруп, өчүрүп күйгүзүңүз."</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Системада сактагыч жетишсиз. 250МБ бош орун бар экенин текшерип туруп, өчүрүп күйгүзүңүз."</string>
     <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> иштөөдө"</string>
     <string name="app_running_notification_text" msgid="5120815883400228566">"Көбүрөөк маалымат үчүн же колдонмону токтотуш үчүн таптап коюңуз."</string>
     <string name="ok" msgid="2646370155170753815">"Жарайт"</string>
@@ -1401,7 +1401,7 @@
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Башка колдонмолордун үстүнөн көрсөтүү"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> колдонмосун башка терезелердин үстүнөн көрсөтүү"</string>
     <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g>: башка колдонмолордун үстүнөн"</string>
-    <string name="alert_windows_notification_message" msgid="6538171456970725333">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, жөндөөлөрдү ачып туруп, аны өчүрүп коюңуз."</string>
+    <string name="alert_windows_notification_message" msgid="6538171456970725333">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, параметрлерди ачып туруп, аны өчүрүп коюңуз."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Өчүрүү"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> текшерилүүдө…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Учурдагы мазмун каралып жатат"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Бул мазмунду жумуш колдонмолору менен ачуу мүмкүн эмес"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Бул мазмунду жеке колдонмолор менен бөлүшүү мүмкүн эмес"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Бул мазмунду жеке колдонмолор менен ачуу мүмкүн эмес"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Жумуш профили тындырылган"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Күйгүзүү үчүн таптап коюңуз"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Жумуш колдонмолору жок"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Жеке колдонмолор жок"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Жеке <xliff:g id="APP">%s</xliff:g> колдонмосун ачуу"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Жумуш үчүн <xliff:g id="APP">%s</xliff:g> колдонмосун ачуу"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Жеке серепчини колдонуу"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Жумуш серепчисин колдонуу"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM карта тармагынын кулпусун ачуучу PIN код"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 49b7732..80e6009 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມໂຕສັ່ນ."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງສະຖານະການສັ່ນໄດ້."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ໂທຫາເບີໂທລະສັບໂດຍກົງ"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"ອະນຸຍາດໃຫ້ແອັບຯໂທຫາເບີໂທລະສັບໄດ້ ໂດຍບໍ່ຕ້ອງຖ້າການດຳເນີນການໃດໆຈາກທ່ານ. ຄຸນສົມບັດນີ້ອາດກໍ່ໃຫ້ເກີດຄ່າໃຊ້ຈ່າຍໃນການໂທທີ່ບໍ່ຄາດຄິດໄດ້. ໝາຍເຫດ: ຄຸນສົມບັດນີ້ບໍ່ໄດ້ເປັນການອະນຸຍາດໃຫ້ແອັບຯ ສາມາດໂທຫາເບີສຸກເສີນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດເຮັດໃຫ້ທ່ານ ຕ້ອງເສຍຄ່າໂທໂດຍທີ່ບໍ່ໄດ້ຄາດຄິດ."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"ເຂົ້າ​ຫາ​ການ​ບໍ​ລິ​ການ​ໂທ IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ໃຊ້​ການ​ບໍ​ລິ​ການ IMS ເພື່ອ​ໂທ​ໂດຍ​ບໍ່​ມີ​ການ​ຊ່ວຍ​ເຫຼືອ​ຂອງ​ທ່ານ."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ອ່ານສະຖານະ ແລະຂໍ້ມູນລະບຸໂຕຕົນຂອງໂທລະສັບ"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"ຍົກເລີກການດຳເນີນການກັບໃບໜ້າແລ້ວ."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"ຜູ້ໃຊ້ຍົກເລີກການປົດລັອກດ້ວຍໜ້າແລ້ວ"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"ມີຄວາມພະຍາຍາມຫຼາຍຄັ້ງເກີນໄປ. ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"ພະຍາຍາມຫຼາຍເທື່ອເກີນໄປ. ໃຊ້ການປົດລັອກດ້ວຍໜ້າບໍ່ໄດ້."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"ພະຍາຍາມຫຼາຍເທື່ອເກີນໄປ. ກະລຸນາເຂົ້າການລັອກໜ້າຈໍແທນ."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ບໍ່ສາມາດຢັ້ງຢືນໃບໜ້າໄດ້. ກະລຸນາລອງໃໝ່."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"ທ່ານຍັງບໍ່ໄດ້ຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າເທື່ອ"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ເນື້ອຫານີ້ບໍ່ສາມາດຖືກເປີດໄດ້ດ້ວຍແອັບບ່ອນເຮັດວຽກ"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ເນື້ອຫານີ້ບໍ່ສາມາດຖືກແບ່ງປັນກັບແອັບສ່ວນຕົວໄດ້"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ເນື້ອຫານີ້ບໍ່ສາມາດຖືກເປີດໄດ້ດ້ວຍແອັບສ່ວນຕົວ"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ຢຸດໂປຣໄຟລ໌ວຽກໄວ້ຊົ່ວຄາວແລ້ວ"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ແຕະເພື່ອເປີດໃຊ້"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ບໍ່ມີແອັບບ່ອນເຮັດວຽກ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ບໍ່ມີແອັບສ່ວນຕົວ"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"ເປີດ <xliff:g id="APP">%s</xliff:g> ແບບສ່ວນຕົວ"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"ເປີດ <xliff:g id="APP">%s</xliff:g> ສຳລັບວຽກ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ໃຊ້ໂປຣແກຣມທ່ອງເວັບສ່ວນຕົວ"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ໃຊ້ໂປຣແກຣມທ່ອງເວັບບ່ອນເຮັດວຽກ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ປົດລັອກເຄືອຂ່າຍຊິມ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 11cd09d..864cdc6 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -505,7 +505,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Leidžiama programai valdyti vibravimą."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Programai leidžiama pasiekti vibratoriaus būseną."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"skambinti tiesiogiai telefono numeriais"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Leidžiama programai skambinti telefonų numeriais be jūsų įsikišimo. Dėl to gali atsirasti nenumatytų apmokestinimų ar skambučių. Atminkite, kad programai neleidžiama skambinti pagalbos telefonų numeriais. Kenkėjiškos programos gali skambinti be jūsų patvirtinimo, o dėl to jums gali būti taikomi mokesčiai."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pasiekti IMS skambučių paslaugą"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Programai leidžiama naudoti IMS paslaugą, kad būtų galima atlikti skambučius be jūsų įsikišimo."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"skaityti telefono būseną ir tapatybę"</string>
@@ -711,8 +712,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Veido atpažinimo operacija atšaukta."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Atrakinimą pagal veidą atšaukė naudotojas"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Per daug bandymų. Vėliau bandykite dar kartą."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Per daug bandymų. Atrakinimo pagal veidą funkcija nepasiekiama."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Per daug bandymų. Geriau naudokite ekrano užraktą."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nepavyko patvirtinti veido. Bandykite dar kartą."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Nenustatėte atrakinimo pagal veidą"</string>
@@ -2161,14 +2161,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Šio turinio negalima atidaryti naudojant darbo programas"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Šio turinio negalima bendrinti su asmeninėmis programomis"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Šio turinio negalima atidaryti naudojant asmenines programas"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Darbo profilis pristabdytas"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Paliesti, norint įjungti"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nėra darbo programų"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nėra asmeninių programų"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Asmeninės programos „<xliff:g id="APP">%s</xliff:g>“ atidarymas"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Darbo programos „<xliff:g id="APP">%s</xliff:g>“ atidarymas"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Naudoti asmeninę naršyklę"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Naudoti darbo naršyklę"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM tinklo operatoriaus pasirinkimo ribojimo panaikinimo PIN kodas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index b72502e..f293a2f 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Ļauj lietotnei kontrolēt vibrosignālu."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ļauj lietotnei piekļūt vibrosignāla statusam."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"tieši zvanīt uz tālruņa numuriem"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Ļauj lietotnei zvanīt uz tālruņa numuriem bez jūsu iejaukšanās. Tas var radīt neparedzētas izmaksas vai zvanus. Ņemiet vērā, ka lietotnei nav atļauts zvanīt uz tālruņa numuriem ārkārtas situācijām. Ļaunprātīgas lietotnes var radīt jums izmaksas, veicot zvanus bez jūsu apstiprinājuma."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"piekļūt tūlītējās ziņojumapmaiņas pakalpojumam, lai veiktu zvanus"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Ļauj lietotnei izmantot tūlītējās ziņojumapmaiņas pakalpojumu, lai veiktu zvanus bez jūsu ziņas."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"lasīt tālruņa statusu un identitāti"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Darbība ar sejas datiem atcelta."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Lietotājs atcēla autorizāciju pēc sejas."</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Pārāk daudz mēģinājumu. Vēlāk mēģiniet vēlreiz."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Pārāk daudz mēģinājumu. Autorizācija pēc sejas nav pieejama."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Pārāk daudz mēģinājumu. Tā vietā ievadiet ekrāna bloķēšanas akreditācijas datus."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nevar verificēt seju. Mēģiniet vēlreiz."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Autorizācija pēc sejas nav iestatīta."</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Šo saturu nevar atvērt darba lietotnēs"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Šo saturu nevar kopīgot ar personīgajām lietotnēm"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Šo saturu nevar atvērt personīgajās lietotnēs"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Darba profila darbība ir apturēta."</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Lai ieslēgtu, pieskarieties"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nav darba lietotņu"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nav personīgu lietotņu"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Lietotnes <xliff:g id="APP">%s</xliff:g> atvēršana personīgajā profilā"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Lietotnes <xliff:g id="APP">%s</xliff:g> atvēršana darba profilā"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Izmantot personīgo pārlūku"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Izmantot darba pārlūku"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM tīkla atbloķēšanas PIN"</string>
diff --git a/core/res/res/values-mcc310/config.xml b/core/res/res/values-mcc310/config.xml
index df398f9..76abcee 100644
--- a/core/res/res/values-mcc310/config.xml
+++ b/core/res/res/values-mcc310/config.xml
@@ -22,4 +22,7 @@
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
     <bool name="config_safe_media_volume_enabled">false</bool>
 
+    <!-- Whether safe headphone sound dosage warning is enabled or not (country specific). -->
+    <bool name="config_safe_sound_dosage_mcc_enabled">false</bool>
+
 </resources>
diff --git a/core/res/res/values-mcc311/config.xml b/core/res/res/values-mcc311/config.xml
index df398f9..6e0b678 100644
--- a/core/res/res/values-mcc311/config.xml
+++ b/core/res/res/values-mcc311/config.xml
@@ -22,4 +22,7 @@
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
     <bool name="config_safe_media_volume_enabled">false</bool>
 
+    <!-- Whether safe headphone sound dosage warning is enabled or not (country specific). -->
+    <bool name="config_safe_sound_dosage_enabled">false</bool>
+
 </resources>
diff --git a/core/res/res/values-mcc312/config.xml b/core/res/res/values-mcc312/config.xml
index df398f9..6e0b678 100644
--- a/core/res/res/values-mcc312/config.xml
+++ b/core/res/res/values-mcc312/config.xml
@@ -22,4 +22,7 @@
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
     <bool name="config_safe_media_volume_enabled">false</bool>
 
+    <!-- Whether safe headphone sound dosage warning is enabled or not (country specific). -->
+    <bool name="config_safe_sound_dosage_enabled">false</bool>
+
 </resources>
diff --git a/core/res/res/values-mcc313/config.xml b/core/res/res/values-mcc313/config.xml
index df398f9..6e0b678 100644
--- a/core/res/res/values-mcc313/config.xml
+++ b/core/res/res/values-mcc313/config.xml
@@ -22,4 +22,7 @@
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
     <bool name="config_safe_media_volume_enabled">false</bool>
 
+    <!-- Whether safe headphone sound dosage warning is enabled or not (country specific). -->
+    <bool name="config_safe_sound_dosage_enabled">false</bool>
+
 </resources>
diff --git a/core/res/res/values-mcc314/config.xml b/core/res/res/values-mcc314/config.xml
index df398f9..6e0b678 100644
--- a/core/res/res/values-mcc314/config.xml
+++ b/core/res/res/values-mcc314/config.xml
@@ -22,4 +22,7 @@
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
     <bool name="config_safe_media_volume_enabled">false</bool>
 
+    <!-- Whether safe headphone sound dosage warning is enabled or not (country specific). -->
+    <bool name="config_safe_sound_dosage_enabled">false</bool>
+
 </resources>
diff --git a/core/res/res/values-mcc315/config.xml b/core/res/res/values-mcc315/config.xml
index df398f9..6e0b678 100644
--- a/core/res/res/values-mcc315/config.xml
+++ b/core/res/res/values-mcc315/config.xml
@@ -22,4 +22,7 @@
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
     <bool name="config_safe_media_volume_enabled">false</bool>
 
+    <!-- Whether safe headphone sound dosage warning is enabled or not (country specific). -->
+    <bool name="config_safe_sound_dosage_enabled">false</bool>
+
 </resources>
diff --git a/core/res/res/values-mcc316/config.xml b/core/res/res/values-mcc316/config.xml
index df398f9..6e0b678 100644
--- a/core/res/res/values-mcc316/config.xml
+++ b/core/res/res/values-mcc316/config.xml
@@ -22,4 +22,7 @@
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
     <bool name="config_safe_media_volume_enabled">false</bool>
 
+    <!-- Whether safe headphone sound dosage warning is enabled or not (country specific). -->
+    <bool name="config_safe_sound_dosage_enabled">false</bool>
+
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 8c0cf6d..0a0ed8a 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Дозволува апликацијата да ги контролира вибрациите."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ѝ дозволува на апликацијата да пристапи до состојбата на вибрации."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"директно избирај телефонски броеви"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Овозможува апликацијата да повикува телефонски броеви без ваша интервенција. Ова може да предизвика неочекувани трошоци или повици. Имајте на ум дека ова не дозволува апликацијата да повикува броеви на служби за итна помош. Злонамерните апликации може да ве чинат пари поради повици без ваша потврда."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"пристапи до услугата за повици IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Дозволува апликацијата да ја користи услугата IMS за повици без ваша интервенција."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"прочитај ги статусот и идентитетот  на телефонот"</string>
@@ -665,7 +666,7 @@
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона за отпечатоци"</string>
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Отклучување со лик"</string>
     <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Проблем со „Отклучување со лик“"</string>
-    <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Допрете за да го избришете вашиот модел на лице, а потоа повторно додајте го лицето"</string>
+    <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Допрете за да го избришете вашиот модел на лик, а потоа повторно додајте го ликот"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"Поставете „Отклучување со лик“"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Отклучете го телефонот со гледање во него"</string>
     <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"За да користите „Отклучување со лик“, вклучете "<b>"Пристап до камерата"</b>" во „Поставки &gt; Приватност“"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Операцијата со лице се откажа."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Корисникот го откажа „Отклучувањето со лик“"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Премногу обиди. Обидете се повторно подоцна."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Премногу обиди. „Отклучување со лик“ е недостапна."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Премногу обиди. Наместо тоа, користете го заклучувањето на екранот."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ликот не може да се потврди. Обидете се повторно."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Не сте поставиле „Отклучување со лик“"</string>
@@ -1283,13 +1283,13 @@
     <string name="volume_call" msgid="7625321655265747433">"Јачина на звук на дојдовен повик"</string>
     <string name="volume_bluetooth_call" msgid="2930204618610115061">"Јачина на звук на дојдовен повик преку Bluetooth"</string>
     <string name="volume_alarm" msgid="4486241060751798448">"Јачина на звук за аларм"</string>
-    <string name="volume_notification" msgid="6864412249031660057">"Јачина на звук на известување"</string>
+    <string name="volume_notification" msgid="6864412249031660057">"Јачина на звук за известување"</string>
     <string name="volume_unknown" msgid="4041914008166576293">"Јачина на звук"</string>
     <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Јачина на звук на Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Јачина на звук на мелодија"</string>
     <string name="volume_icon_description_incall" msgid="4491255105381227919">"Јачина на звук на повик"</string>
     <string name="volume_icon_description_media" msgid="4997633254078171233">"Јачина на аудио/видео звук"</string>
-    <string name="volume_icon_description_notification" msgid="579091344110747279">"Јачина на звук на известување"</string>
+    <string name="volume_icon_description_notification" msgid="579091344110747279">"Јачина на звук за известување"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"Стандардна мелодија"</string>
     <string name="ringtone_default_with_actual" msgid="2709686194556159773">"Стандардна (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="397111123930141876">"Ниедна"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Овие содржини не може да се отвораат со работни апликации"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Овие содржини не може да се споделуваат со лични апликации"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Овие содржини не може да се отвораат со лични апликации"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Работниот профил е паузиран"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Допрете за да вклучите"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Нема работни апликации"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Нема лични апликации"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Отворање лична <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Отворање работна <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Користи личен прелистувач"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Користи работен прелистувач"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN за отклучување на мрежата на SIM-картичката"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 7ba5181..b6dcf69 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -503,7 +503,7 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"വൈബ്രേറ്റർ നിയന്ത്രിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"വൈബ്രേറ്റ് ചെയ്യൽ ആക്‌സസ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ഫോൺ നമ്പറുകളിലേക്ക് നേരിട്ട് വിളിക്കുക"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"നിങ്ങളുടെ ഇടപെടൽ ഇല്ലാതെ ഫോൺ നമ്പറുകളിലേക്ക് കോൾ ചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് അപ്രതീക്ഷിത നിരക്കുകൾക്കോ കോളുകൾക്കോ ഇടയാക്കാം. ഇത് അടിയന്തര നമ്പറുകളിലേക്ക് വിളിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കില്ലെന്ന കാര്യം ശ്രദ്ധിക്കുക. ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ സ്ഥിരീകരണമില്ലാതെ കോളുകൾ ചെയ്യുന്നത് പണച്ചെലവിനിടയാക്കാം."</string>
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"നിങ്ങളുടെ ഇടപെടലില്ലാതെ ഫോൺ നമ്പറുകളിലേക്ക് വിളിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. ഇത് അപ്രതീക്ഷിതമായ കോളുകൾക്കോ നിരക്കുകൾ നൽകേണ്ട സാഹചര്യത്തിനോ കാരണമായേക്കാം. അടിയന്തര നമ്പറുകളിലേക്ക് വിളിക്കാൻ ഇത് ആപ്പിനെ അനുവദിക്കുന്നില്ലെന്ന കാര്യം ശ്രദ്ധിക്കുക. നിങ്ങളുടെ സ്ഥിരീകരണമില്ലാതെ കോളുകൾ വിളിക്കുന്നതിലൂടെ ദോഷകരമായ ആപ്പുകൾ നിങ്ങൾക്ക് ധനനഷ്ടം ഉണ്ടാക്കിയേക്കാം, അല്ലെങ്കിൽ ഇൻകമിംഗ് കോളുകൾ സ്വയമേവ മറ്റൊരു നമ്പറിലേക്ക് കൈമാറാൻ കാരണമാകുന്ന കാരിയർ കോഡുകൾ ഡയൽ ചെയ്തേക്കാം."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS കോൾ സേവനം ആക്സസ് ചെയ്യുക"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"നിങ്ങളുടെ ഇടപെടൽ ഇല്ലാതെ കോളുകൾ ചെയ്യാൻ IMS സേവനം ഉപയോഗിക്കുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ഫോൺ നിലയും ഐഡന്റിറ്റിയും റീഡുചെയ്യുക"</string>
@@ -709,8 +709,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"മുഖത്തിന്റെ പ്രവർത്തനം റദ്ദാക്കി."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"ഉപയോക്താവ് ഫെയ്‌സ് അൺലോക്ക് റദ്ദാക്കി"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"നിരവധി തവണ ശ്രമിച്ചു. പിന്നീട് വീണ്ടും ശ്രമിക്കുക."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"നിരവധി ശ്രമങ്ങൾ. ഫെയ്‌സ് അൺലോക്ക് ലഭ്യമല്ല."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"നിരവധി ശ്രമങ്ങൾ. പകരം സ്‌ക്രീൻ ലോക്ക് നൽകുക."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"മുഖം പരിശോധിക്കാൻ കഴിയില്ല. വീണ്ടും ശ്രമിക്കൂ."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"നിങ്ങൾ ഫെയ്‌സ് അൺലോക്ക് സജ്ജീകരിച്ചിട്ടില്ല"</string>
@@ -2159,14 +2158,12 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ഔദ്യോഗിക ആപ്പുകൾ ഉപയോഗിച്ച് ഈ ഉള്ളടക്കം തുറക്കാനാകില്ല"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"വ്യക്തിപര ആപ്പുകൾ ഉപയോഗിച്ച് ഈ ഉള്ളടക്കം പങ്കിടാനാകില്ല"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"വ്യക്തിപര ആപ്പുകൾ ഉപയോഗിച്ച് ഈ ഉള്ളടക്കം തുറക്കാനാകില്ല"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ഔദ്യോഗിക പ്രൊഫൈൽ തൽക്കാലം നിർത്തിയിരിക്കുന്നു"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ഓണാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"ഔദ്യോഗിക ആപ്പുകൾ തൽക്കാലം നിർത്തിയിരിക്കുന്നു"</string>
+    <string name="resolver_switch_on_work" msgid="4527096360772311894">"താൽക്കാലികമായി നിർത്തിയത് മാറ്റുക"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ഔദ്യോഗിക ആപ്പുകൾ ഇല്ല"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"വ്യക്തിപര ആപ്പുകൾ ഇല്ല"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"<xliff:g id="APP">%s</xliff:g> എന്ന വ്യക്തിപര ആപ്പ് തുറക്കുക"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"<xliff:g id="APP">%s</xliff:g> എന്ന ഔദ്യോഗിക ആപ്പ് തുറക്കുക"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"വ്യക്തിപരമായ ബ്രൗസർ ഉപയോഗിക്കുക"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ഔദ്യോഗിക ബ്രൗസർ ഉപയോഗിക്കുക"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"സിം നെറ്റ്‌വർക്ക് അൺലോക്ക് ചെയ്യാനുള്ള പിൻ"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index f5f7851..2917fb6 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Апп нь чичиргээг удирдах боломжтой."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Аппыг чичиргээний төлөвт хандахыг зөвшөөрдөг."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"утасны дугаарт шууд дуудлага хийх"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Апп нь таны оролцоогүйгээр дуудлага хийх боломжтой. Энэ нь төлөвлөгдөөгүй төлбөрт оруулах эсвэл дуудлага хийнэ. Энэ нь апп-г яаралтай дугаарт дуудлага хийхйг зөвшөөрөхгүй. Хортой апп нь таны зөвшөөрөлгүйгээр дуудлага хийж таныг төлбөрт оруулж болзошгүй"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS дуудлагын үйлчилгээнд хандах"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Апп нь дуудлага хийхдээ таны оролцоогүйгээр IMS үйлчилгээг ашиглах боломжтой."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"утасны статус ба таниулбарыг унших"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Царайны үйл ажиллагааг цуцаллаа."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Хэрэглэгч Царайгаар түгжээ тайлахыг цуцалсан"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Хэт олон удаа оролдлоо. Дараа дахин оролдоно уу."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Хэт олон удаа оролдлоо. Царайгаар түгжээ тайлах боломжгүй."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Хэт олон удаа оролдлоо. Оронд нь дэлгэцийн түгжээ оруулна уу."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Царайг бататгаж чадсангүй. Дахин оролдоно уу."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Та Царайгаар түгжээ тайлахыг тохируулаагүй байна"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Энэ контентыг ажлын аппуудаар нээх боломжгүй"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Энэ контентыг хувийн аппуудаар хуваалцах боломжгүй"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Энэ контентыг хувийн аппуудаар нээх боломжгүй"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Ажлын профайлыг түр зогсоосон"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Асаахын тулд товших"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ямар ч ажлын апп байхгүй байна"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ямар ч хувийн апп байхгүй байна"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Хувийн <xliff:g id="APP">%s</xliff:g>-г нээх"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Ажлын <xliff:g id="APP">%s</xliff:g>-г нээх"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Хувийн хөтөч ашиглах"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Ажлын хөтөч ашиглах"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Сүлжээний SIM-н түгжээг тайлах ПИН"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index eeba652..640f5d940 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"अ‍ॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"अ‍ॅपला व्हायब्रेटर स्थितीचा अ‍ॅक्सेस करण्याची अनुमती देते."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"फोन नंबरवर प्रत्यक्ष कॉल करा"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"आपल्या हस्तक्षेपाशिवाय फोन नंबरवर कॉल करण्यासाठी अ‍ॅप ला अनुमती देते. यामुळे अनपेक्षित शुल्क किंवा कॉल लागू शकतात. लक्षात ठेवा की हे आणीबाणीच्या नंबरवर कॉल करण्यासाठी अ‍ॅप ला अनुमती देत नाही. दुर्भावनापूर्ण अ‍ॅप्स नी आपल्या पुष्टिकरणाशिवाय कॉल केल्यामुळे तुमचे पैसे खर्च होऊ शकतात."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS कॉल सेवा अ‍ॅक्सेस करा"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"आपल्‍या हस्तक्षेपाशिवाय अ‍ॅपला कॉल करण्‍यासाठी IMS सेवा वापरण्याची अनुमती देते."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"फोन स्थिती आणि ओळख वाचा"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"चेहरा ऑपरेशन रद्द केले गेले."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"वापरकर्त्याने फेस अनलॉक रद्द केले आहे"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"खूप जास्त प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"खूप वेळा प्रयत्न केले आहेत. फेस अनलॉक उपलब्ध नाही."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"बरेच प्रयत्न. त्याऐवजी स्क्रीन लॉक वापरा."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"चेहरा पडताळणी करू शकत नाही. पुन्हा प्रयत्न करा."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"तुम्ही फेस अनलॉक सेट केले नाही"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"हा आशय कार्य ॲप्स वापरून उघडला जाऊ शकत नाही"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"हा आशय वैयक्तिक ॲप्ससह शेअर केला जाऊ शकत नाही"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"हा आशय वैयक्तिक ॲप्स वापरून उघडला जाऊ शकत नाही"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"कार्य प्रोफाइल थांबवली आहे"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"सुरू करण्यासाठी टॅप करा"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"कोणतीही कार्य ॲप्स सपोर्ट करत नाहीत"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"कोणतीही वैयक्तिक ॲप्स सपोर्ट करत नाहीत"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"वैयक्तिक <xliff:g id="APP">%s</xliff:g> उघडा"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"ऑफिसचे <xliff:g id="APP">%s</xliff:g> उघडा"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"वैयक्तिक ब्राउझर वापरा"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"कार्य ब्राउझर वापरा"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"सिम नेटवर्क अनलॉक पिन"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 9ec0483..04d4478 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Membenarkan apl mengawal penggetar."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Membenarkan apl mengakses keadaan penggetar."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"panggil terus nombor telefon"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Membenarkan apl memanggil nombor telefon tanpa campur tangan anda. Ini mungkin menyebabkan caj atau panggilan yang di luar jangkaan. Apl hasad boleh menyebabkan anda kerugian wang dengan membuat panggilan tanpa pengesahan anda."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"akses perkhidmatan panggilan IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Membenarkan apl menggunakan perkhidmatan IMS untuk membuat panggilan tanpa campur tangan anda."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"baca status dan identiti telefon"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Pengendalian wajah dibatalkan."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Buka Kunci Wajah dibatalkan oleh pengguna"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Terlalu banyak percubaan. Cuba sebentar lagi."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Terlalu banyak percubaan. Buka Kunci Wajah tidak tersedia."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Terlalu banyak percubaan. Sebaliknya, masukkan kunci skrin."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Tidak dapat mengesahkan wajah. Cuba lagi."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Anda belum menyediakan Buka Kunci Wajah"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Kandungan ini tidak boleh dibuka dengan apl kerja"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Kandungan ini tidak boleh dikongsi dengan apl peribadi"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Kandungan ini tidak boleh dibuka dengan apl peribadi"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Profil kerja dijeda"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Ketik untuk menghidupkan profil"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Tiada apl kerja"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Tiada apl peribadi"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Buka <xliff:g id="APP">%s</xliff:g> peribadi"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Buka <xliff:g id="APP">%s</xliff:g> kerja"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Gunakan penyemak imbas peribadi"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Gunakan penyemak imbas kerja"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN buka kunci rangkaian SIM"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index a94bc70..e54ebd7 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"အက်ပ်အား တုန်ခါစက်ကို ထိန်းချုပ်ခွင့် ပြုသည်။"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"အက်ပ်ကို တုန်ခါမှုအခြေအနေအား သုံးခွင့်ပေးပါ။"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ဖုန်းနံပါတ်များကိုတိုက်ရိုက်ခေါ်ဆိုခြင်း"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"အပလီကေးရှင်းအား အလိုအလျောက် ဖုန်းခေါ်ခွင့် ပြုပါ။ မလိုအပ်သော ဖုန်းခ များ ဖြစ်ပေါ်နိုင်ပါသည်။ ဒီခွင့်ပြုခြင်းမှာ အရေးပေါ်ဖုန်းခေါ်ခြင်း မပါဝင်ပါ။ သံသယဖြစ်စရာ အပလီကေးရှင်းများက သင့်မသိပဲ ဖုန်းခေါ်ခြင်းဖြင့် ဖုန်းခ ပိုမိုကျနိုင်ပါသည်။"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ဖုန်းခေါ်ဆိုမှု ဝန်ဆောင်ဌာန ဝင်ကြည့်ပါ"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"သင့်ရဲ့ဝင်ရောက်စွက်ဖက်မှုမပါဘဲ IMS ဝန်ဆောင်မှုကိုအသုံးပြုပြီး ဖုန်းခေါ်ဆိုနိုင်ရန် အပ်ဖ်ကို ခွင့်ပြုထားပါ။"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ဖုန်းရဲ့ အခြေအနေ နှင့် အမှတ်သညာအား ဖတ်ခြင်း"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"မျက်နှာ ဆောင်ရွက်ခြင်းကို ပယ်ဖျက်လိုက်ပါပြီ။"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"အသုံးပြုသူက မျက်နှာပြ လော့ခ်ဖွင့်ခြင်းကို ပယ်ဖျက်ထားသည်"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"အကြိမ်များစွာ စမ်းပြီးပါပြီ။ နောက်မှထပ်စမ်းပါ။"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"ကြိုးပမ်းမှုအကြိမ်ရေ များလွန်းသည်။ မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း မရနိုင်ပါ။"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"ကြိုးပမ်းမှုအကြိမ်ရေ များလွန်းသည်။ ဖန်သားပြင် လော့ခ်ကို အစားထိုးထည့်သွင်းပါ။"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"မျက်နှာကို အတည်ပြု၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"မျက်နှာပြ လော့ခ်ဖွင့်ခြင်းကို ထည့်သွင်းမထားပါ"</string>
@@ -1283,13 +1283,13 @@
     <string name="volume_call" msgid="7625321655265747433">"ခေါ်ဆိုနေခြင်းအသံအတိုးအကျယ်"</string>
     <string name="volume_bluetooth_call" msgid="2930204618610115061">"ဘလူးတုသ်ဖြင့် ခေါ်ဆိုနေခြင်းအသံအတိုးအကျယ်"</string>
     <string name="volume_alarm" msgid="4486241060751798448">"နှိုးစက်သံအတိုးအကျယ်"</string>
-    <string name="volume_notification" msgid="6864412249031660057">"အကြောင်းကြားသံအတိုးအကျယ်"</string>
+    <string name="volume_notification" msgid="6864412249031660057">"အကြောင်းကြားသံ အတိုးအကျယ်"</string>
     <string name="volume_unknown" msgid="4041914008166576293">"အသံအတိုးအကျယ်"</string>
     <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"ဘလူးတုသ်သံအတိုးအကျယ်"</string>
     <string name="volume_icon_description_ringer" msgid="2187800636867423459">"ဖုန်းမြည်သံအတိုးအကျယ်"</string>
     <string name="volume_icon_description_incall" msgid="4491255105381227919">"ဖုန်းခေါ်သံအတိုးအကျယ်"</string>
     <string name="volume_icon_description_media" msgid="4997633254078171233">"မီဒီယာအသံအတိုးအကျယ်"</string>
-    <string name="volume_icon_description_notification" msgid="579091344110747279">"အကြောင်းကြားသံအတိုးအကျယ်"</string>
+    <string name="volume_icon_description_notification" msgid="579091344110747279">"အကြောင်းကြားသံ အတိုးအကျယ်"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"မူရင်းမြည်သံ"</string>
     <string name="ringtone_default_with_actual" msgid="2709686194556159773">"မူရင်း (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="397111123930141876">"မရှိ"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ဤအကြောင်းအရာကို အလုပ်သုံးအက်ပ်များဖြင့် မဖွင့်နိုင်ပါ"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ဤအကြောင်းအရာကို ကိုယ်ပိုင်အက်ပ်များဖြင့် မမျှဝေနိုင်ပါ"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ဤအကြောင်းအရာကို ကိုယ်ပိုင်အက်ပ်များဖြင့် မဖွင့်နိုင်ပါ"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"အလုပ်ပရိုဖိုင် ခဏရပ်ထားသည်"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ဖွင့်ရန်တို့ပါ"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"အလုပ်သုံးအက်ပ်များ မရှိပါ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ကိုယ်ပိုင်အက်ပ်များ မရှိပါ"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"ကိုယ်ရေးကိုယ်တာသုံး <xliff:g id="APP">%s</xliff:g> ဖွင့်ခြင်း"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"အလုပ်သုံး <xliff:g id="APP">%s</xliff:g> ဖွင့်ခြင်း"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ကိုယ်ပိုင်ဘရောင်ဇာ သုံးရန်"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"အလုပ်သုံးဘရောင်ဇာ သုံးရန်"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ဆင်းမ်ကွန်ရက် လော့ခ်ဖွင့်ရန် ပင်နံပါတ်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index a52c9b8..56c191e 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Lar appen kontrollere vibreringsfunksjonen."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Gir appen tilgang til vibreringstilstanden."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ringe telefonnummer direkte"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Lar appen ringe telefonnumre uten at du gjør noe. Dette kan resultere i uventede oppringninger og kostnader. Appen kan imidlertid ikke ringe nødnumre. Merk at skadelige apper kan påføre deg kostnader ved å ringe uten bekreftelse fra deg."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"få tilgang til nettprattjenesten for ringing"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Lar appen bruke nettprattjenesten til å ringe uten at du gjør noe."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"lese telefonstatus og -identitet"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Ansikt-operasjonen ble avbrutt."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Ansiktslås ble avbrutt av brukeren"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"For mange forsøk. Prøv på nytt senere."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"For mange forsøk Ansiktslås er utilgjengelig."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"For mange forsøk. Skriv inn skjermlås i stedet."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kan ikke bekrefte ansiktet. Prøv på nytt."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Du har ikke konfigurert ansiktslås"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Dette innholdet kan ikke åpnes med jobbapper"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Dette innholdet kan ikke deles med personlige apper"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Dette innholdet kan ikke åpnes med personlige apper"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Jobbprofilen er satt på pause"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Trykk for å slå på"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ingen jobbapper"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ingen personlige apper"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Åpne <xliff:g id="APP">%s</xliff:g> personlig"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Åpne <xliff:g id="APP">%s</xliff:g> for jobb"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Bruk den personlige nettleseren"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Bruk jobbnettleseren"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-kode for å fjerne operatørlåser"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index f94646e..b11d76a 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -503,7 +503,7 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"एपलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"यो एपलाई कम्पनको स्थितिमाथि पहुँच राख्न दिनुहोस्।"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"फोन नम्बरहरूमा सीधै कल गर्नुहोस्"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"तपाईँको हस्तक्षेप बेगरै फोन नम्बर कल गर्न एपलाई अनुमति दिन्छ। यसले अनपेक्षित शुल्क वा कलहरू गराउन सक्छ। यसले एपलाई आपत्‌कालीन नम्बरहरू कल गर्न अनुमति दिँदैन विचार गर्नुहोस्। खराब एपहरूले तपाईँको स्वीकार बिना कलहरू गरेर तपाईँलाई बढी पैसा तिराउन सक्छ।"</string>
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"यो एपले तपाईंको अनुमतिविनै कसैको फोन नम्बरमा कल गर्न सक्छ। यसको परिणामस्वरूप अनपेक्षित शुल्क लाग्न वा तपाईंलाई जानकारी नगराइकन कलहरू गरिन सक्छ। यसले एपलाई आपत्‍कालीन नम्बरहरूमा कल गर्ने अनुमति दिँदैन भन्ने कुरा ख्याल गर्नुहोस्। हानिकारक एपहरूले तपाईंको अनुमतिविनै कलहरू गरेर वा अन्य नम्बरमा आगमन कलहरू स्वतः फर्वार्ड गर्ने सेवा प्रदायकका कोडहरू डायल गरेर तपाईंको पैसा खर्च गराउन सक्छ।"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS कल सेवा पहुँच गर्नुहोस्"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"तपाईँको हस्तक्षेप बिना नै कल गर्न IMS सेवा प्रयोग गर्न एपलाई अनुमति दिन्छ।"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"फोन स्थिति र पहिचान पढ्नुहोस्"</string>
@@ -709,8 +709,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"अनुहार पहिचान रद्द गरियो।"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"प्रयोगकर्ताले फेस अनलक सेटअप गर्ने कार्य रद्द गर्नुभयो"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"धेरैपटक प्रयासहरू भए। पछि फेरि प्रयास गर्नुहोस्‌।"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"अत्यन्तै धेरै पटक प्रयास गरिसकियो। फेस अनलक उपलब्ध छैन।"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"निकै धेरै प्रयासहरू भए। यसको साटो स्क्रिन लक प्रयोग गर्नुहोस्।"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"अनुहार पुष्टि गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"तपाईंले फेस अनलक सेटअप गर्नुभएको छैन"</string>
@@ -2159,14 +2158,12 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"यो सामग्री कामसम्बन्धी एपहरूमार्फत खोल्न मिल्दैन"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"यो सामग्री व्यक्तिगत एपहरूमार्फत सेयर गर्न मिल्दैन"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"यो सामग्री व्यक्तिगत एपहरूमार्फत खोल्न मिल्दैन"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"कार्य प्रोफाइल पज गरिएको छ"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"अन गर्न ट्याप गर्नुहोस्"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"कामसम्बन्धी एपहरू पज गरिएका छन्"</string>
+    <string name="resolver_switch_on_work" msgid="4527096360772311894">"अनपज गर्नुहोस्"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"यो सामग्री खोल्न मिल्ने कुनै पनि कामसम्बन्धी एप छैन"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"यो सामग्री खोल्न मिल्ने कुनै पनि व्यक्तिगत एप छैन"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"व्यक्तिगत <xliff:g id="APP">%s</xliff:g> खोल्नुहोस्"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"कामसम्बन्धी <xliff:g id="APP">%s</xliff:g> खोल्नुहोस्"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"व्यक्तिगत ब्राउजर प्रयोग गर्नुहोस्"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"कार्य ब्राउजर प्रयोग गर्नुहोस्"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM को नेटवर्क अनलक गर्ने PIN"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 40ec59e..9605db1 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Hiermee kan de app de trilstand beheren."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Hiermee heeft de app toegang tot de status van de trilstand."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefoonnummers rechtstreeks bellen"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Hiermee kan de app zonder je tussenkomst telefoonnummers bellen. Dit kan tot onverwachte kosten of gesprekken leiden. De app kan hiermee geen noodnummers bellen. Schadelijke apps kunnen u geld kosten door nummers te bellen zonder om je bevestiging te vragen."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"toegang tot IMS-service voor bellen"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Hiermee kan de app de IMS-service gebruiken om te bellen zonder je tussenkomst."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"telefoonstatus en -identiteit lezen"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Bewerking voor gezichtsherkenning geannuleerd."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Ontgrendelen via gezichtsherkenning geannuleerd door gebruiker"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Te veel pogingen. Probeer het later opnieuw."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Te veel pogingen. Ontgrendelen via gezichtsherkenning is niet beschikbaar."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Te veel pogingen. Gebruik schermvergrendeling."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kan gezicht niet verifiëren. Probeer het nog eens."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Je hebt Ontgrendelen via gezichtsherkenning niet ingesteld."</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Deze content kan niet worden geopend met werk-apps"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Deze content kan niet worden gedeeld met persoonlijke apps"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Deze content kan niet worden geopend met persoonlijke apps"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Werkprofiel is onderbroken"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tik om aan te zetten"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Geen werk-apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Geen persoonlijke apps"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Persoonlijke <xliff:g id="APP">%s</xliff:g> openen"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"<xliff:g id="APP">%s</xliff:g> voor het werk openen"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Persoonlijke browser gebruiken"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Werkbrowser gebruiken"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Ontgrendelingspincode voor SIM-netwerk"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index f9842d7..69cfaae 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -262,7 +262,7 @@
     <string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"ସାଇଲେଣ୍ଟ ମୋଡ୍"</string>
     <string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"ସାଉଣ୍ଡ ଅଫ୍ ଅଛି"</string>
     <string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"ସାଉଣ୍ଡ ଚାଲୁ ଅଛି"</string>
-    <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="6911684460146916206">"ଏରୋପ୍ଲେନ ମୋଡ"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="5508025516695361936">"ଏୟାରପ୍ଲେନ୍ ମୋଡ୍ ଚାଲୁ ଅଛି"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="8522219771500505475">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍ ଅଫ୍ ଅଛି"</string>
     <string name="global_action_settings" msgid="4671878836947494217">"ସେଟିଂସ୍"</string>
@@ -316,7 +316,7 @@
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ଅଡିଓ ରେକର୍ଡ କରେ"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ଶାରୀରିକ କାର୍ଯ୍ୟକଳାପ"</string>
     <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ଆପଣଙ୍କ ଶାରୀରିକ କାର୍ଯ୍ୟକଳାପ ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
-    <string name="permgrouplab_camera" msgid="9090413408963547706">"କ୍ୟାମେରା"</string>
+    <string name="permgrouplab_camera" msgid="9090413408963547706">"କେମେରା"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"ଫଟୋ ନିଏ ଓ ଭିଡିଓ ରେକର୍ଡ କରେ"</string>
     <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକ"</string>
     <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକୁ ଖୋଜି ସଂଯୋଗ କରନ୍ତୁ"</string>
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ଆପ୍‍କୁ, ଭାଇବ୍ରେଟର୍‍ ନିୟନ୍ତ୍ରଣ କରିବାକୁ ଦେଇଥାଏ।"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ଭାଇବ୍ରେଟର୍ ସ୍ଥିତି ଆକ୍ସେସ୍ କରିବାକୁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ସିଧାସଳଖ ଫୋନ୍ ନମ୍ବରଗୁଡ଼ିକୁ କଲ୍ କରନ୍ତୁ"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"ଆପଣଙ୍କ ହସ୍ତକ୍ଷେପ ବିନା ଫୋନ୍‌ ନମ୍ଵରକୁ କଲ୍ କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହାଦ୍ୱାରା ଅପ୍ରତ୍ୟାଶିତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ କିମ୍ବା କଲ୍ ହୋଇପାରେ। ଧ୍ୟାନଦିଅନ୍ତୁ ଯେ, ଏହା ଆପ୍‌କୁ କୌଣସି ଜରୁରୀକାଳୀନ ନମ୍ବରରେ କଲ୍ କରିବାକୁ ଅନୁମତି ଦିଏନାହିଁ। ହାନୀକାରକ ଆପ୍‌ ଆପଣଙ୍କ ବିନା ସ୍ୱୀକୃତିରେ କଲ୍ କରି ଆପଣଙ୍କ ପଇସା ଖର୍ଚ୍ଚ କରାଇପାରେ।"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS କଲ୍‍ ସେବା ଆକ୍ସେସ୍‍ କରେ"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"ଆପଣଙ୍କ ହସ୍ତକ୍ଷେପ ବିନା କଲ୍‍ କରିପାରିବା ପାଇଁ ଆପ୍‌କୁ IMS ସେବା ବ୍ୟବହାର କରିବାକୁ ଦିଏ।"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ଫୋନ୍‍ ସ୍ଥିତି ଓ ପରିଚୟ ପଢ଼ନ୍ତୁ"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"ଫେସ୍‍ର ଅପରେଶନ୍‍ କ୍ୟାନ୍ସଲ୍‍ ହୋ‍ଇଗଲା"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ଦ୍ୱାରା ଫେସ୍ ଅନଲକ୍ ବାତିଲ୍ କରାଯାଇଛି"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"ବାରମ୍ବାର ଚେଷ୍ଟା। ପରେ ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"ଅନେକଗୁଡ଼ିଏ ପ୍ରଚେଷ୍ଟା। ଫେସ ଅନଲକ ଉପଲବ୍ଧ ନାହିଁ।"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"ଅନେକଗୁଡ଼ିଏ ପ୍ରଚେଷ୍ଟା। ଏହା ପରିବର୍ତ୍ତେ ସ୍କ୍ରିନ୍ ଲକ୍ ଏଣ୍ଟର୍ କରନ୍ତୁ।"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ମୁହଁ ଚିହ୍ନଟ କରିପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"ଆପଣ ଫେସ୍ ଅନଲକ୍ ସେଟ୍ ଅପ୍ କରିନାହାଁନ୍ତି"</string>
@@ -986,7 +986,7 @@
     <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"ପଛକୁ ନିଅନ୍ତୁ"</string>
     <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"ଫାଷ୍ଟ ଫ‌ର୍‌ୱାର୍ଡ"</string>
-    <string name="emergency_calls_only" msgid="3057351206678279851">"କେବଳ ଜରୁରୀକାଳୀନ କଲ୍‌"</string>
+    <string name="emergency_calls_only" msgid="3057351206678279851">"କେବଳ ଜରୁରୀକାଳୀନ କଲ"</string>
     <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"ନେଟ୍‌ୱର୍କକୁ ଲକ୍‌ କରାଯାଇଛି"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="2867953953604224166">"SIMକୁ PUK-ଲକ କରାଯାଇଛି।"</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"ୟୁଜର ଗାଇଡ ଦେଖନ୍ତୁ କିମ୍ବା ଗ୍ରାହକ ସେବା କେନ୍ଦ୍ର ସହ କଣ୍ଟାକ୍ଟ କରନ୍ତୁ।"</string>
@@ -1032,7 +1032,7 @@
     <string name="keyguard_accessibility_widget" msgid="6776892679715699875">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ୱିଜେଟ୍‍।"</string>
     <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"ୟୁଜର୍‌ ଚୟନକାରୀ"</string>
     <string name="keyguard_accessibility_status" msgid="6792745049712397237">"ଷ୍ଟାଟସ୍"</string>
-    <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"କ୍ୟାମେରା"</string>
+    <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"କେମେରା"</string>
     <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"ମିଡିଆ ନିୟନ୍ତ୍ରଣ"</string>
     <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"ୱିଜେଟ୍‍ ପୁନଃ ସଜାଇବା ଆରମ୍ଭ ହେଲା।"</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"ୱିଜେଟ୍‍ ପୁନଃ ସଜାଇବା ଶେଷ ହେଲା।"</string>
@@ -2079,7 +2079,7 @@
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ଖାରଜ କରନ୍ତୁ"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ସିଷ୍ଟମ"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ସେଟିଂସ୍"</string>
-    <string name="notification_appops_camera_active" msgid="8177643089272352083">"କ୍ୟାମେରା"</string>
+    <string name="notification_appops_camera_active" msgid="8177643089272352083">"କେମେରା"</string>
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"ମାଇକ୍ରୋଫୋନ"</string>
     <string name="notification_appops_overlay_active" msgid="5571732753262836481">"ଆପଣଙ୍କ ସ୍କ୍ରୀନ୍ ଉପରେ ଥିବା ଅନ୍ୟ ଆପ୍‌ ଉପରେ ଦେଖାଦେବ"</string>
     <string name="notification_feedback_indicator" msgid="663476517711323016">"ମତାମତ ଦିଅନ୍ତୁ"</string>
@@ -2094,7 +2094,7 @@
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
     <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12ରେ Android ଆଡେପ୍ଟିଭ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଉନ୍ନତ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକରେ ପରିବର୍ତ୍ତନ କରାଯାଇଛି। ଏହି ଫିଚର ପ୍ରସ୍ତାବିତ କାର୍ଯ୍ୟ ଏବଂ ପ୍ରତ୍ୟୁତ୍ତରଗୁଡ଼ିକୁ ଦେଖାଏ ଏବଂ ଆପଣଙ୍କ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବ୍ୟବସ୍ଥିତ କରେ।\n\nଉନ୍ନତ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ କଣ୍ଟାକ୍ଟ ନାମ ଏବଂ ମେସେଜଗୁଡ଼ିକ ପରି ବ୍ୟକ୍ତିଗତ ସୂଚନା ସମେତ ବିଜ୍ଞପ୍ତିର ବିଷୟବସ୍ତୁକୁ ଆକ୍ସେସ କରିପାରିବ। ଏହି ଫିଚର ଫୋନ କଲଗୁଡ଼ିକର ଉତ୍ତର ଦେବା ଏବଂ \'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\'କୁ ନିୟନ୍ତ୍ରଣ କରିବା ପରି, ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ମଧ୍ୟ ଖାରଜ କରିପାରିବ କିମ୍ବା ସେଗୁଡ଼ିକର ଉତ୍ତର ଦେଇପାରିବ।"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ନିୟମିତ ମୋଡ୍‍ ସୂଚନା ବିଜ୍ଞପ୍ତି"</string>
-    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ବ୍ୟାଟେରୀ ସେଭର ଚାଲୁ କରାଯାଇଛି"</string>
+    <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ବେଟେରୀ ସେଭର ଚାଲୁ କରାଯାଇଛି"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ବ୍ୟାଟେରୀ ଲାଇଫ ବଢ଼ାଇବା ପାଇଁ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କମ୍ କରିବା"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ବ୍ୟାଟେରୀ ସେଭର୍"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"ବ୍ୟାଟେରୀ ସେଭର୍ ବନ୍ଦ ଅଛି"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ଏହି ବିଷୟବସ୍ତୁ ୱାର୍କ ଆପଗୁଡ଼ିକରେ ଖୋଲାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ଏହି ବିଷୟବସ୍ତୁ ବ୍ୟକ୍ତିଗତ ଆପଗୁଡ଼ିକରେ ସେୟାର୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ଏହି ବିଷୟବସ୍ତୁ ବ୍ୟକ୍ତିଗତ ଆପଗୁଡ଼ିକରେ ଖୋଲାଯାଇପାରିବ ନାହିଁ"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ୱାର୍କ ପ୍ରୋଫାଇଲକୁ ବିରତ କରାଯାଇଛି"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ଚାଲୁ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"କୌଣସି ୱାର୍କ ଆପ୍ ନାହିଁ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"କୌଣସି ବ୍ୟକ୍ତିଗତ ଆପ୍ ନାହିଁ"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"ବ୍ୟକ୍ତିଗତ <xliff:g id="APP">%s</xliff:g> ଖୋଲନ୍ତୁ"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"ୱାର୍କ <xliff:g id="APP">%s</xliff:g> ଖୋଲନ୍ତୁ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ବ୍ୟକ୍ତିଗତ ବ୍ରାଉଜର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ୱାର୍କ ବ୍ରାଉଜର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ନେଟୱାର୍କ ଅନଲକ୍ PIN"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 0b09f9f..3c58842 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ਐਪ ਨੂੰ ਵਾਈਬ੍ਰੇਟਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ਐਪ ਨੂੰ ਥਰਥਰਾਹਟ ਸਥਿਤੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ਫ਼ੋਨ ਨੰਬਰਾਂ ਤੇ ਸਿੱਧੇ ਕਾਲ ਕਰੋ"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਦਖਲ ਤੋਂ ਬਿਨਾਂ ਫ਼ੋਨ ਨੰਬਰਾਂ ਤੇ ਕਾਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦੇ ਸਿੱਟੇ ਵਜੋਂ ਅਕਲਪਿਤ ਖਰਚੇ ਜਾਂ ਕਾਲਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਧਿਆਨ ਦਿਓ ਕਿ ਇਹ ਐਪ ਨੂੰ ਸੰਕਟਕਾਲੀਨ ਨੰਬਰਾਂ ਤੇ ਕਾਲ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੰਦਾ। ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੀ ਪੁਸ਼ਟੀ ਤੋਂ ਬਿਨਾਂ ਕਾਲਾਂ ਕਰਕੇ ਤੁਹਾਨੂੰ ਖਰਚੇ ਪਾ ਸਕਦੀਆਂ ਹਨ।"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ਕਾਲ ਸੇਵਾ ਤੱਕ ਪਹੁੰਚ"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਕਾਲਾਂ ਕਰਨ ਲਈ IMS ਸੇਵਾ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ਫ਼ੋਨ ਸਥਿਤੀ ਅਤੇ ਪਛਾਣ ਪੜ੍ਹੋ"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"ਚਿਹਰਾ ਪਛਾਣਨ ਦੀ ਪ੍ਰਕਿਰਿਆ ਰੱਦ ਕੀਤੀ ਗਈ।"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"ਵਰਤੋਂਕਾਰ ਨੇ ਫ਼ੇਸ ਅਣਲਾਕ ਰੱਦ ਕੀਤਾ"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"ਹੱਦੋਂ ਵੱਧ ਕੋਸ਼ਿਸ਼ਾਂ। ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ। ਫ਼ੇਸ ਅਣਲਾਕ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸਦੀ ਬਜਾਏ ਸਕ੍ਰੀਨ ਲਾਕ ਦਾਖਲ ਕਰੋ।"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ਚਿਹਰੇ ਦੀ ਪੁਸ਼ਟੀ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"ਤੁਸੀਂ ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਸੈੱਟਅੱਪ ਨਹੀਂ ਕੀਤਾ ਹੈ।"</string>
@@ -2092,7 +2092,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ਠੀਕ ਹੈ"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ਬੰਦ ਕਰੋ"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ਹੋਰ ਜਾਣੋ"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 ਵਿੱਚ ਵਿਸਤ੍ਰਿਤ ਸੂਚਨਾਵਾਂ ਨੇ Android ਅਡੈਪਟਿਵ ਸੂਚਨਾਵਾਂ ਦੀ ਜਗ੍ਹਾ ਲੈ ਲਈ ਹੈ। ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਕਾਰਵਾਈਆਂ ਅਤੇ ਜਵਾਬਾਂ ਵਾਲੇ ਸੁਝਾਅ ਦਿਖਾਉਂਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰਦੀ ਹੈ।\n\nਵਿਸਤ੍ਰਿਤ ਸੂਚਨਾਵਾਂ ਸੂਚਨਾ ਸਮੱਗਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀਆਂ ਹਨ, ਜਿਸ ਵਿੱਚ ਸੰਪਰਕ ਦੇ ਨਾਮ ਅਤੇ ਸੁਨੇਹੇ ਵਰਗੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਵੀ ਸ਼ਾਮਲ ਹੈ। ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਸੂਚਨਾਵਾਂ ਨੂੰ ਖਾਰਜ ਵੀ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਸੂਚਨਾਵਾਂ ਦਾ ਜਵਾਬ ਵੀ ਦੇ ਸਕਦੀ ਹੈ, ਜਿਵੇਂ ਕਿ ਫ਼ੋਨ ਕਾਲਾਂ ਦਾ ਜਵਾਬ ਦੇਣਾ ਅਤੇ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਨੂੰ ਕੰਟਰੋਲ ਕਰਨਾ।"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 ਵਿੱਚ ਵਿਸਤ੍ਰਿਤ ਸੂਚਨਾਵਾਂ ਨੇ Android ਅਡੈਪਟਿਵ ਸੂਚਨਾਵਾਂ ਦੀ ਜਗ੍ਹਾ ਲੈ ਲਈ ਹੈ। ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਕਾਰਵਾਈਆਂ ਅਤੇ ਜਵਾਬਾਂ ਵਾਲੇ ਸੁਝਾਅ ਦਿਖਾਉਂਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰਦੀ ਹੈ।\n\nਵਿਸਤ੍ਰਿਤ ਸੂਚਨਾਵਾਂ ਸੂਚਨਾ ਸਮੱਗਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀਆਂ ਹਨ, ਜਿਸ ਵਿੱਚ ਸੰਪਰਕ ਦੇ ਨਾਮ ਅਤੇ ਸੁਨੇਹਿਆਂ ਵਰਗੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਵੀ ਸ਼ਾਮਲ ਹੈ। ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਸੂਚਨਾਵਾਂ ਨੂੰ ਖਾਰਜ ਵੀ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਸੂਚਨਾਵਾਂ ਦਾ ਜਵਾਬ ਵੀ ਦੇ ਸਕਦੀ ਹੈ, ਜਿਵੇਂ ਕਿ ਫ਼ੋਨ ਕਾਲਾਂ ਦਾ ਜਵਾਬ ਦੇਣਾ ਅਤੇ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਨੂੰ ਕੰਟਰੋਲ ਕਰਨਾ।"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ਨਿਯਮਬੱਧ ਮੋਡ ਦੀ ਜਾਣਕਾਰੀ ਵਾਲੀ ਸੂਚਨਾ"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਲੂ ਹੈ"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ਬੈਟਰੀ ਲਾਈਫ਼ ਵਧਾਉਣ ਲਈ ਬੈਟਰੀ ਵਰਤੋਂ ਨੂੰ ਘਟਾਉਣਾ"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨਾਲ ਨਹੀਂ ਖੋਲ੍ਹਿਆ ਜਾ ਸਕਦਾ"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਨਿੱਜੀ ਐਪਾਂ ਨਾਲ ਸਾਂਝਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਨਿੱਜੀ ਐਪਾਂ ਨਾਲ ਨਹੀਂ ਖੋਲ੍ਹਿਆ ਜਾ ਸਕਦਾ"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਨੂੰ ਰੋਕਿਆ ਗਿਆ ਹੈ"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ਚਾਲੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ਕੋਈ ਕੰਮ ਸੰਬੰਧੀ ਐਪ ਨਹੀਂ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ਕੋਈ ਨਿੱਜੀ ਐਪ ਨਹੀਂ"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"ਨਿੱਜੀ <xliff:g id="APP">%s</xliff:g> ਖੋਲ੍ਹੋ"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"ਕਾਰਜ <xliff:g id="APP">%s</xliff:g> ਖੋਲ੍ਹੋ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ਨਿੱਜੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ਕੰਮ ਸੰਬੰਧੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ਸਿਮ ਨੈੱਟਵਰਕ ਅਣਲਾਕ ਪਿੰਨ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 7965830..c247254 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -247,7 +247,7 @@
     <string name="global_action_lock" msgid="6949357274257655383">"Blokada ekranu"</string>
     <string name="global_action_power_off" msgid="4404936470711393203">"Wyłącz"</string>
     <string name="global_action_power_options" msgid="1185286119330160073">"Przycisk zasilania"</string>
-    <string name="global_action_restart" msgid="4678451019561687074">"Uruchom ponownie"</string>
+    <string name="global_action_restart" msgid="4678451019561687074">"Zrestartuj"</string>
     <string name="global_action_emergency" msgid="1387617624177105088">"Połączenie alarmowe"</string>
     <string name="global_action_bug_report" msgid="5127867163044170003">"Zgłoś błąd"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"Zakończ sesję"</string>
@@ -505,7 +505,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Pozwala aplikacji na sterowanie wibracjami."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Zezwala aplikacji na dostęp do stanu wibracji"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"bezpośrednie wybieranie numerów telefonów"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Pozwala aplikacji na dzwonienie pod numery telefonów bez Twojej wiedzy. Może to skutkować nieoczekiwanymi opłatami lub połączeniami. Aplikacja nie może dzwonić pod numery alarmowe. Złośliwe aplikacje mogą generować koszty, wykonując połączenia bez Twojego potwierdzenia."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"usługa telefoniczna z dostępem do komunikatora"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Zezwala aplikacji na korzystanie z usługi komunikatora, by nawiązywać połączenia bez Twojego udziału."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"odczytywanie stanu i informacji o telefonie"</string>
@@ -711,8 +712,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Analiza twarzy została anulowana."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Użytkownik anulował rozpoznawanie twarzy"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Zbyt wiele prób. Spróbuj ponownie później."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Zbyt wiele prób. Rozpoznawanie twarzy niedostępne."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Zbyt wiele prób. Użyj blokady ekranu."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nie można zweryfikować twarzy. Spróbuj ponownie."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Rozpoznawanie twarzy nie zostało skonfigurowane"</string>
@@ -2161,14 +2161,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Tych treści nie można otworzyć w aplikacjach służbowych"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Tych treści nie można udostępniać w aplikacjach osobistych"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Tych treści nie można otworzyć w aplikacjach osobistych"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Działanie profilu służbowego jest wstrzymane"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Kliknij, aby włączyć"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Brak aplikacji służbowych"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Brak aplikacji osobistych"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Otwórz aplikację osobistą <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Otwórz aplikację służbową <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Użyj przeglądarki osobistej"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Użyj przeglądarki służbowej"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Kod PIN do karty SIM odblokowujący sieć"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 4256bfa..ff9b8c6 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite que o app controle a vibração."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que o app acesse o estado da vibração."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ligar diretamente para números de telefone"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que o app ligue para números de telefone sem sua intervenção. Isso pode resultar em cobranças ou chamadas inesperadas. Esta opção não permite que o app ligue para números de emergência. Apps maliciosos podem gerar custos com chamadas feitas sem sua confirmação."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acessar serviço de mensagens instantâneas para chamadas"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permite que o app use o serviço de mensagens instantâneas para fazer chamadas sem sua intervenção."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ler status e identidade do telefone"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Operação facial cancelada."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Desbloqueio facial cancelado pelo usuário"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Excesso de tentativas. Tente novamente mais tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Muitas tentativas. Desbloqueio facial indisponível."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Muitas tentativas. Como alternativa, use o bloqueio de tela."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Não é possível verificar o rosto. Tente novamente."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"O Desbloqueio facial não foi configurado"</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Não é possível abrir esse conteúdo com apps de trabalho"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Não é possível compartilhar esse conteúdo com apps pessoais"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Não é possível abrir esse conteúdo com apps pessoais"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"O perfil de trabalho está pausado"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Toque para ativar"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nenhum app de trabalho"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nenhum app pessoal"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Abrir <xliff:g id="APP">%s</xliff:g> no perfil pessoal"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Abrir <xliff:g id="APP">%s</xliff:g> no perfil do trabalho"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar o navegador pessoal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar o navegador de trabalho"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN para desbloqueio da rede do chip"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 06c8183..b252551 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite à app controlar o vibrador."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que a app aceda ao estado de vibração."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"marcar números de telefone diretamente"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que a app ligue para números de telefone sem a intervenção do utilizador. Esta ação pode resultar em cobranças ou chamadas inesperadas. Tenha em atenção que isto não permite que a app ligue para números de emergência. As aplicações maliciosas podem fazer com que incorra em custos, fazendo chamadas sem a sua confirmação."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"aceder ao serviço de chamadas IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permite que a app utilize o serviço IMS para fazer chamadas sem a sua intervenção."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ler o estado e a identidade do telemóvel"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Operação de rosto cancelada."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Desbloqueio facial cancelado pelo utilizador"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Demasiadas tentativas. Tente mais tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Demasiadas tentativas. Desbloqueio facial indisponível."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Demasiadas tentativas. Em alternativa, introduza o bloqueio de ecrã."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Não é possível validar o rosto. Tente novamente."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Não configurou o Desbloqueio facial"</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Não é possível abrir este conteúdo com apps de trabalho"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Não é possível partilhar este conteúdo com apps pessoais"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Não é possível abrir este conteúdo com apps pessoais"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Perfil de trabalho em pausa"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tocar para ativar"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Sem apps de trabalho"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Sem apps pessoais"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Abra a app <xliff:g id="APP">%s</xliff:g> pessoal"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Abra a app <xliff:g id="APP">%s</xliff:g> de trabalho"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar navegador pessoal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar navegador de trabalho"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN para desbloqueio de rede do cartão SIM"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4256bfa..ff9b8c6 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite que o app controle a vibração."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que o app acesse o estado da vibração."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ligar diretamente para números de telefone"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que o app ligue para números de telefone sem sua intervenção. Isso pode resultar em cobranças ou chamadas inesperadas. Esta opção não permite que o app ligue para números de emergência. Apps maliciosos podem gerar custos com chamadas feitas sem sua confirmação."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acessar serviço de mensagens instantâneas para chamadas"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permite que o app use o serviço de mensagens instantâneas para fazer chamadas sem sua intervenção."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ler status e identidade do telefone"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Operação facial cancelada."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Desbloqueio facial cancelado pelo usuário"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Excesso de tentativas. Tente novamente mais tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Muitas tentativas. Desbloqueio facial indisponível."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Muitas tentativas. Como alternativa, use o bloqueio de tela."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Não é possível verificar o rosto. Tente novamente."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"O Desbloqueio facial não foi configurado"</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Não é possível abrir esse conteúdo com apps de trabalho"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Não é possível compartilhar esse conteúdo com apps pessoais"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Não é possível abrir esse conteúdo com apps pessoais"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"O perfil de trabalho está pausado"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Toque para ativar"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nenhum app de trabalho"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nenhum app pessoal"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Abrir <xliff:g id="APP">%s</xliff:g> no perfil pessoal"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Abrir <xliff:g id="APP">%s</xliff:g> no perfil do trabalho"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar o navegador pessoal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar o navegador de trabalho"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN para desbloqueio da rede do chip"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7405f22..8646da4 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite aplicației să controleze mecanismul de vibrare."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite aplicației să acceseze modul de vibrații."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"să sune direct la numere de telefon"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite aplicației să apeleze numere de telefon fără intervenția ta. Acest lucru poate determina apariția unor taxe sau a unor apeluri neașteptate. Cu această permisiune aplicația nu poate apela numerele de urgență. Aplicațiile rău intenționate pot acumula costuri prin efectuarea unor apeluri fără confirmare."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accesează serviciul de apelare IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permite aplicației să folosească serviciul IMS pentru apeluri, fără intervenția ta."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"citește starea și identitatea telefonului"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Operațiunea privind chipul a fost anulată."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Deblocarea facială a fost anulată de utilizator"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Prea multe încercări. Reîncearcă mai târziu."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Prea multe încercări. Deblocarea facială nu este disponibilă."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Prea multe încercări. Folosește blocarea ecranului."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nu se poate confirma fața. Încearcă din nou."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Nu ai configurat Deblocarea facială"</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Acest conținut nu poate fi deschis cu aplicații pentru lucru"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Acest conținut nu poate fi trimis cu aplicații personale"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Acest conținut nu poate fi deschis cu aplicații personale"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Profilul de serviciu este întrerupt"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Atinge pentru a activa"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nicio aplicație pentru lucru"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nicio aplicație personală"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Deschide <xliff:g id="APP">%s</xliff:g> personal"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Deschide <xliff:g id="APP">%s</xliff:g> de serviciu"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Folosește browserul personal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Folosește browserul de serviciu"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Codul PIN de deblocare SIM privind rețeaua"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index e3262f5..39a4a65 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -505,7 +505,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Приложение сможет контролировать вибросигналы."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Приложение сможет получать доступ к состоянию виброотклика."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"Осуществление телефонных вызовов"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Приложение сможет без вашего участия звонить на любой номер телефона. Это не относится к номерам экстренных служб. Вредоносные программы смогут совершать вызовы без вашего разрешения, что может привести к непредвиденным расходам."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"совершение звонков с помощью службы IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Позволяет приложению совершать звонки с помощью службы IMS без вашего вмешательства."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"Получение данных о статусе телефона"</string>
@@ -711,8 +712,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Распознавание отменено"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Фейсконтроль: операция отменена пользователем."</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Слишком много попыток. Повторите позже."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Слишком много попыток. Фейсконтроль недоступен."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Слишком много попыток. Используйте другой способ разблокировки экрана."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Не удалось распознать лицо. Повторите попытку."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Вы не настроили фейсконтроль."</string>
@@ -2161,14 +2161,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Этот контент нельзя открыть в рабочем приложении."</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Этот контент нельзя открывать через личные приложения."</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Этот контент нельзя открыть в личном приложении."</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Действие рабочего профиля приостановлено."</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Нажмите, чтобы включить"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Не поддерживается рабочими приложениями."</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Не поддерживается личными приложениями."</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Откройте приложение \"<xliff:g id="APP">%s</xliff:g>\" в личном профиле"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Откройте приложение \"<xliff:g id="APP">%s</xliff:g>\" в рабочем профиле"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Использовать личный браузер"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Использовать рабочий браузер"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-код для разблокировки сети SIM-карты"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index f01cfab..c8a8b4c 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"කම්පකය පාලනයට යෙදුමට අවසර දෙන්න."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"යෙදුමට කම්පන තත්ත්වයට ප්‍රවේශ වීමට ඉඩ දෙන්න."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"දුරකථන අංක වෙත ඍජුවම අමතන්න"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"ඔබගේ මැදිහත් වීමක් නොමැතිව දුරකථන අංක ඇමතීමට යෙදුමට අවසර දෙන්න. මෙහි ප්‍රතිඑලය වන්නේ අනපේක්ෂිත අයකිරීම් හෝ ඇමතුම් ඇතිවීමයි. මෙයන් හදිසි අංක වලට ඇමතුම් ගැනීමට යෙදුමට අවසර නොදෙන බවට සටහන් කරගන්න. ඔබගේ අනුදැනුමක් නොමැතිව ඇමතුම් ගැනීමෙන් අනිෂ්ට යෙදුම් ඔබගේ මුදල් නිකරුණේ වැය කරයි."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ඇමතුම් සේවාවට පිවිසෙන්න"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"ඔබේ මැදිහත්වීමකින් තොරව ඇමතුම් සිදු කිරීමට  IMS සේවාව භාවිතයට යෙදුමට ඉඩ දෙන්න."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"දුරකථනයේ තත්වය සහ අනන්‍යතාවය කියවීම"</string>
@@ -2159,8 +2160,10 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"මෙම අන්තර්ගතය කාර්යාල යෙදුම් සමඟ විවෘත කළ නොහැකිය"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"මෙම අන්තර්ගතය පුද්ගලික යෙදුම් සමඟ බෙදා ගත නොහැකිය"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"මෙම අන්තර්ගතය පුද්ගලික යෙදුම් සමඟ විවෘත කළ නොහැකිය"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"කාර්යාල පැතිකඩ විරාම කර ඇත"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ක්‍රියාත්මක කිරීමට තට්ටු කරන්න"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"කාර්යාල යෙදුම් නැත"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"පුද්ගලික යෙදුම් නැත"</string>
     <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 64ec9ae..8ea8936 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -318,7 +318,7 @@
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"nahrávanie zvuku"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fyzická aktivita"</string>
     <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"prístup k vašej fyzickej aktivite"</string>
-    <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
+    <string name="permgrouplab_camera" msgid="9090413408963547706">"Fotoaparát"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"fotenie a natáčanie videí"</string>
     <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Zariadenia v okolí"</string>
     <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"objavovať a pripájať zariadenia v okolí"</string>
@@ -505,7 +505,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Umožňuje aplikácii ovládať vibrácie."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Povoľuje aplikácii prístup k stavu vibrátora."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"priamo volať na telefónne čísla"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Umožňuje aplikácii volať telefónne čísla bez vášho zásahu. V dôsledku toho sa môžu účtovať neočakávané poplatky alebo sa môžu uskutočniť neočakávané hovory. Toto povolenie neumožňuje aplikácii volať na tiesňovú linku."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"prístup k službe volania IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Umožňuje aplikácii používať službu okamžitých správ (IMS) na volanie bez intervencie používateľa."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"čítať stav a identitu telefónu"</string>
@@ -711,8 +712,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Operácia týkajúca sa tváre bola zrušená"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Odomknutie tvárou zrušil používateľ"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Príliš veľa pokusov. Skúste to neskôr."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Priveľa pokusov. Odomknutie tvárou nie je k dispozícii."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Príliš veľa pokusov. Zadajte namiesto toho zámku obrazovky."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nedá sa overiť tvár. Skúste to znova."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Nenastavili ste odomknutie tvárou"</string>
@@ -2161,14 +2161,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Tento obsah sa nedá otvoriť pomocou pracovných aplikácií"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Tento obsah sa nedá zdieľať pomocou osobných aplikácií"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Tento obsah sa nedá otvoriť pomocou osobných aplikácií"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Pracovný profil je pozastavený"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Zapnúť klepnutím"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Žiadne pracovné aplikácie"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Žiadne osobné aplikácie"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Otvorte osobnú aplikáciu <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Otvorte pracovnú aplikáciu <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Použiť osobný prehliadač"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Použiť pracovný prehliadač"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN na odomknutie siete pre SIM kartu"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index b8692d7..223fa0a 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -505,7 +505,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Aplikaciji omogoča nadzor vibriranja."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Aplikaciji dovoljuje dostop do stanja vibriranja."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"neposredno klicanje telefonskih številk"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Aplikaciji omogoča klicanje telefonskih številk brez vašega posredovanja. Zaradi tega lahko pride do nepričakovanih stroškov ali klicev. Aplikaciji to ne dovoljuje opravljanja klicev v sili. Zlonamerne aplikacije lahko kličejo brez vaše potrditve, kar vas lahko drago stane."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"dostop do storitve za klicanje IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Aplikaciji dovoljuje uporabo storitev IMS za opravljanje klicev brez vašega posredovanja."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"branje stanja in identitete telefona"</string>
@@ -711,8 +712,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Dejanje z obrazom je bilo preklicano."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Odklepanje z obrazom je preklical uporabnik."</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Preveč poskusov. Poskusite znova pozneje."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Preveč poskusov. Odklepanje z obrazom ni na voljo."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Preveč poskusov. Uporabite odklepanje zaslona s poverilnico."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Obraza ni mogoče preveriti. Poskusite znova."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Odklepanja z obrazom niste nastavili."</string>
@@ -2161,14 +2161,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Te vsebine ni mogoče odpreti z delovnimi aplikacijami."</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Te vsebine ni mogoče deliti z osebnimi aplikacijami."</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Te vsebine ni mogoče odpreti z osebnimi aplikacijami."</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Delovni profil je začasno zaustavljen"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Dotaknite se za vklop"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nobena delovna aplikacija ni na voljo"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nobena osebna aplikacija"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Odpri aplikacijo <xliff:g id="APP">%s</xliff:g> v osebnem profilu"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Odpri aplikacijo <xliff:g id="APP">%s</xliff:g> v delovnem profilu"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Uporabi osebni brskalnik"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Uporabi delovni brskalnik"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Koda PIN za odklepanje omrežja kartice SIM"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 78e1d89..c01da3e 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Lejon aplikacionin të kontrollojë dridhësin."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Lejon që aplikacioni të ketë qasje te gjendja e dridhësit."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefono drejtpërdrejt numrat e telefonit"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Lejon aplikacionin të telefonojë numra pa ndërhyrjen tënde. Kjo mund të rezultojë në tarifa ose telefonata të papritura. Ki parasysh se kjo nuk e lejon aplikacionin të telefonojë numra urgjence. Aplikacione keqdashëse mund të të kushtojnë para duke kryer telefonata pa konfirmimin tënd."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"qasje në shërbimin e telefonatave IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Lejon aplikacionin të përdorë shërbimin IMS për të kryer telefonata pa ndërhyrjen tënde."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"lexo statusin e telefonit dhe identitetin"</string>
@@ -684,7 +685,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Lëvize telefonin në të majtën tënde"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Lëvize telefonin në të djathtën tënde"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Shiko më drejt në pajisjen tënde."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Fytyra jote nuk mund të shihet. Mbaje telefonin në nivelin e syve."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Fytyra s\'mund të shihet. Mbaje telefonin në nivelin e syve."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Ka shumë lëvizje. Mbaje telefonin të palëvizur."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Regjistroje përsëri fytyrën tënde."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Fytyra nuk mund të njihet. Provo sërish."</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Veprimi me fytyrën u anulua."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"\"Shkyçja me fytyrë\" u anulua nga përdoruesi"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Shumë përpjekje. Provo sërish më vonë."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Shumë përpjekje. Shkyçja me fytyrë nuk ofrohet."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Shumë përpjekje. Fut më mirë kyçjen e ekranit."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Fytyra nuk mund të verifikohet. Provo përsëri."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Nuk e ke konfiguruar \"Shkyçjen me fytyrë\""</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Kjo përmbajtje nuk mund të hapet me aplikacione pune"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Kjo përmbajtje nuk mund të shpërndahet me aplikacione personale"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Kjo përmbajtje nuk mund të hapet me aplikacione personale"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Profili i punës është në pauzë"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Trokit për ta aktivizuar"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nuk ka aplikacione pune"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nuk ka aplikacione personale"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Hap <xliff:g id="APP">%s</xliff:g> personal"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Hap <xliff:g id="APP">%s</xliff:g> të punës"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Përdor shfletuesin personal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Përdor shfletuesin e punës"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Kodi PIN i shkyçjes së rrjetit të kartës SIM"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 5807e1e..15d18a6 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -248,10 +248,10 @@
     <string name="global_action_power_options" msgid="1185286119330160073">"Напајање"</string>
     <string name="global_action_restart" msgid="4678451019561687074">"Рестартуј"</string>
     <string name="global_action_emergency" msgid="1387617624177105088">"Хитан позив"</string>
-    <string name="global_action_bug_report" msgid="5127867163044170003">"Извештај о грешци"</string>
+    <string name="global_action_bug_report" msgid="5127867163044170003">"Јави грешку"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"Заврши сесију"</string>
     <string name="global_action_screenshot" msgid="2610053466156478564">"Снимак екрана"</string>
-    <string name="bugreport_title" msgid="8549990811777373050">"Извештај о грешци"</string>
+    <string name="bugreport_title" msgid="8549990811777373050">"Јави грешку"</string>
     <string name="bugreport_message" msgid="5212529146119624326">"Овим ће се прикупити информације о тренутном стању уређаја како би биле послате у поруци е-поште. Од започињања извештаја о грешци до тренутка за његово слање проћи ће неко време; будите стрпљиви."</string>
     <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Интерактив. извештај"</string>
     <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Користите ово у већини случајева. То вам омогућава да пратите напредак извештаја, да уносите додатне детаље о проблему и да снимате снимке екрана. Вероватно ће изоставити неке мање коришћене одељке за које прављење извештаја дуго траје."</string>
@@ -504,7 +504,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Дозвољава апликацији да контролише вибрацију."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Дозвољава апликацији да приступа стању вибрирања."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"директно позивање бројева телефона"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Дозвољава апликацији да позива бројеве телефона без ваше дозволе. Ово може да доведе до неочекиваних трошкова или позива. Имајте на уму да ово не дозвољава апликацији да позива бројеве за хитне случајеве. Злонамерне апликације могу да позивају без ваше потврде, што може да доведе до трошкова."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"приступ услузи позива помоћу размене тренутних порука"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Дозвољава апликацији да користи услугу размене тренутних порука да би упућивала позиве без ваше интервенције."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"читање статуса и идентитета телефона"</string>
@@ -710,8 +711,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Обрада лица је отказана."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Корисник је отказао откључавање лицем"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Превише покушаја. Пробајте поново касније."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Превише покушаја. Откључавање лицем није доступно."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Превише покушаја. Користите закључавање екрана за то."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Провера лица није успела. Пробајте поново."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Нисте подесили откључавање лицем"</string>
@@ -1716,7 +1716,7 @@
     <string name="color_inversion_feature_name" msgid="2672824491933264951">"Инверзија боја"</string>
     <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>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додатно затамни"</string>
     <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слушни апарати"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
@@ -2160,14 +2160,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Овај садржај не може да се отвара помоћу пословних апликација"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Овај садржај не може да се дели помоћу личних апликација"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Овај садржај не може да се отвара помоћу личних апликација"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Пословни профил је паузиран"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Додирните да бисте укључили"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Нема пословних апликација"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Нема личних апликација"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Отворите личну апликацију <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Отворите пословну апликацију <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Користи лични прегледач"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Користи пословни прегледач"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN за откључавање SIM мреже"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index fbb4ff4..d59d2d7 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -300,7 +300,7 @@
     <string name="managed_profile_label" msgid="7316778766973512382">"Byt till jobbprofilen"</string>
     <string name="permgrouplab_contacts" msgid="4254143639307316920">"Kontakter"</string>
     <string name="permgroupdesc_contacts" msgid="9163927941244182567">"få tillgång till dina kontakter"</string>
-    <string name="permgrouplab_location" msgid="1858277002233964394">"plats"</string>
+    <string name="permgrouplab_location" msgid="1858277002233964394">"Plats"</string>
     <string name="permgroupdesc_location" msgid="1995955142118450685">"komma åt enhetens platsuppgifter"</string>
     <string name="permgrouplab_calendar" msgid="6426860926123033230">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"få tillgång till din kalender"</string>
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Tillåter att appen styr vibrationen."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Appen beviljas åtkomst till vibrationsstatus."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ringa telefonnummer direkt"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Tillåter att appen ringer telefonnummer utan någon aktiv åtgärd från dig. Detta kan leda till oväntade avgifter och samtal. Observera att appen inte tillåts ringa nödsamtal. Skadliga appar kan ringa utan ditt godkännande och detta kan kosta pengar."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"tillgång till tjänsten för snabbmeddelanden vid samtal"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Tillåter att appen använder tjänsten för snabbmeddelanden för att ringa samtal utan åtgärd från dig."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"läsa telefonens status och identitet"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Ansiktsåtgärden har avbrutits."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Ansiktslås avbröts av användaren"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Du har gjort för många försök. Försök igen senare."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"För många försök. Ansiktslås är otillgängligt."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"För många försök. Ange skärmlås i stället."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Det gick inte att verifiera ansiktet. Försök igen."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Du har inte konfigurerat ansiktslås"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Det här innehållet kan inte öppnas med jobbappar"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Det här innehållet kan inte delas med privata appar"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Det här innehållet kan inte öppnas med privata appar"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Jobbprofilen är pausad"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Tryck för att aktivera"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Inga jobbappar"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Inga privata appar"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Öppna <xliff:g id="APP">%s</xliff:g> med privat profil"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Öppna <xliff:g id="APP">%s</xliff:g> med jobbprofil"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Använd privat webbläsare"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Använd jobbwebbläsare"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Pinkod för upplåsning av nätverk för SIM-kort"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index ce28bd7..6449588 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Inaruhusu programu kudhibiti kitingishi."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Huruhusu programu kufikia hali ya kitetemeshaji."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"piga simu moja kwa moja kwa nambari za simu"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Inaruhusu programu kupiga nambari za simu bila ya wewe kuingilia kati. Hii inaweza kusababisha gharama zisizotarajiwa au simu. Kumbuka kuwa hii hairuhusu programu kupiga nambari za dharura. Programu hasidi zinaweza kukugharimu pesa kwa kupiga simu bila uthibitisho wako."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"fikia huduma ya simu ya IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Huruhusu programu kutumia huduma ya IMS kupiga simu bila udhibiti wako."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"kusoma hali na kitambulisho cha simu"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Utendaji wa kitambulisho umeghairiwa."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Hatua ya Kufungua kwa Uso imeghairiwa na mtumiaji"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Umejaribu mara nyingi mno. Jaribu tena baadaye."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Umejaribu mara nyingi mno. Kipengele cha Kufungua kwa Uso hakipatikani."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Umejaribu mara nyingi mno. Weka mbinu ya kufunga skrini badala yake."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Imeshindwa kuthibitisha uso. Jaribu tena."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Hujaweka mipangilio ya kipengele cha Kufungua kwa Uso"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Huwezi kufungua maudhui haya ukitumia programu za kazini"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Huwezi kushiriki maudhui haya na programu za binafsi"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Huwezi kufungua maudhui haya ukitumia programu za binafsi"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Wasifu wa kazini umesimamishwa"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Gusa ili uwashe"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Hakuna programu za kazini"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Hakuna programu za binafsi"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Fungua <xliff:g id="APP">%s</xliff:g> ukitumia wasifu binafsi"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Fungua <xliff:g id="APP">%s</xliff:g> ukitumia wasifu wa kazini"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Tumia kivinjari cha binafsi"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Tumia kivinjari cha kazini"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ya kufungua mtandao wa SIM"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 26121c2..4709706 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"அதிர்வைக் கட்டுப்படுத்தப் ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"அதிர்வு நிலையை அணுக ஆப்ஸை அனுமதிக்கும்."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"தொலைபேசி எண்களை நேரடியாக அழைத்தல்"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"உங்கள் தலையீட்டின்றி மொபைல் எண்களை அழைக்கப் ஆப்ஸை அனுமதிக்கிறது. இதன் விளைவாக எதிர்பாராத கட்டணங்களோ அழைப்புகளோ ஏற்படலாம். அவசரகால எண்களை அழைக்க இது ஆப்ஸை அனுமதிக்காது என்பதை நினைவில்கொள்ளவும். தீங்கிழைக்கும் ஆப்ஸ், உங்கள் உறுதிப்படுத்தல் இன்றி அழைப்புகளைச் செய்வதால் உங்களுக்குச் செலவு ஏற்படக்கூடும்."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS அழைப்புச் சேவையை அணுகுதல்"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"உங்கள் குறுக்கீடின்றி IMS சேவையைப் பயன்படுத்தி அழைப்பதற்கு, ஆப்ஸை அனுமதிக்கும்."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"மொபைல் நிலை மற்றும் அடையாளத்தைப் படித்தல்"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"முக அங்கீகாரச் செயல்பாடு ரத்துசெய்யப்பட்டது."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"பயனரால் \'முகம் காட்டித் திறத்தல்\' ரத்துசெய்யப்பட்டது"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"பலமுறை முயன்றுவிட்டீர்கள். பிறகு முயலவும்."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"பலமுறை முயன்றுவிட்டீர்கள். முகம் காட்டித் திறத்தல் இல்லை."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"பலமுறை முயன்றுவிட்டீர்கள். இதற்குப் பதிலாக, திரைப் பூட்டைப் பயன்படுத்தவும்."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"முகத்தைச் சரிபார்க்க இயலவில்லை. மீண்டும் முயலவும்."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"\'முகம் காட்டித் திறத்தல்\' அம்சத்தை அமைக்கவில்லை."</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"பணி ஆப்ஸ் மூலம் இந்த உள்ளடக்கத்தைத் திறக்க முடியாது"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"தனிப்பட்ட ஆப்ஸுடன் இந்த உள்ளடக்கத்தைப் பகிர முடியாது"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"தனிப்பட்ட ஆப்ஸ் மூலம் இந்த உள்ளடக்கத்தைத் திறக்க முடியாது"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"பணிக் கணக்கு இடைநிறுத்தப்பட்டுள்ளது"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ஆன் செய்யத் தட்டுக"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"பணி ஆப்ஸ் எதுவுமில்லை"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"தனிப்பட்ட ஆப்ஸ் எதுவுமில்லை"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"தனிப்பட்ட கணக்கில் <xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் திறங்கள்"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"பணிக் கணக்கில் <xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் திறங்கள்"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"தனிப்பட்ட உலாவியைப் பயன்படுத்து"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"பணி உலாவியைப் பயன்படுத்து"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"சிம் நெட்வொர்க் அன்லாக் பின்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index fbac1c4..22f1d1a 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -219,7 +219,7 @@
     <string name="turn_on_radio" msgid="2961717788170634233">"వైర్‌లెస్‌ను ప్రారంభించండి"</string>
     <string name="turn_off_radio" msgid="7222573978109933360">"వైర్‌లెస్‌ను ఆపివేయండి"</string>
     <string name="screen_lock" msgid="2072642720826409809">"స్క్రీన్ లాక్"</string>
-    <string name="power_off" msgid="4111692782492232778">"పవర్ ఆఫ్ చేయండి"</string>
+    <string name="power_off" msgid="4111692782492232778">"పవర్ ఆఫ్"</string>
     <string name="silent_mode_silent" msgid="5079789070221150912">"రింగర్ ఆఫ్‌లో ఉంది"</string>
     <string name="silent_mode_vibrate" msgid="8821830448369552678">"రింగర్ వైబ్రేట్‌లో ఉంది"</string>
     <string name="silent_mode_ring" msgid="6039011004781526678">"రింగర్ ఆన్‌లో ఉంది"</string>
@@ -243,7 +243,7 @@
     <string name="global_actions" product="tv" msgid="3871763739487450369">"Android TV ఎంపికలు"</string>
     <string name="global_actions" product="default" msgid="6410072189971495460">"ఫోన్ ఎంపికలు"</string>
     <string name="global_action_lock" msgid="6949357274257655383">"స్క్రీన్ లాక్"</string>
-    <string name="global_action_power_off" msgid="4404936470711393203">"పవర్ ఆఫ్ చేయండి"</string>
+    <string name="global_action_power_off" msgid="4404936470711393203">"పవర్ ఆఫ్"</string>
     <string name="global_action_power_options" msgid="1185286119330160073">"పవర్"</string>
     <string name="global_action_restart" msgid="4678451019561687074">"రీస్టార్ట్ చేయండి"</string>
     <string name="global_action_emergency" msgid="1387617624177105088">"ఎమర్జెన్సీ"</string>
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"వైబ్రేటర్‌ను నియంత్రించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"వైబ్రేటర్ స్థితిని యాక్సెస్ చేసేందుకు యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"నేరుగా కాల్ చేసే ఫోన్ నంబర్‌లు"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"మీ ప్రమేయం లేకుండా ఫోన్ నంబర్‌లకు కాల్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. దీని వలన అనుకోని ఛార్జీలు విధించబడవచ్చు లేదా కాల్స్‌ రావచ్చు. ఇది అత్యవసర నంబర్‌లకు కాల్ చేయడానికి యాప్‌ను అనుమతించదని గుర్తుంచుకోండి. హానికరమైన యాప్‌లు మీ నిర్ధారణ లేకుండానే కాల్స్‌ చేయడం ద్వారా మీకు డబ్బు ఖర్చయ్యేలా చేయవచ్చు."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS కాల్ సేవ యాక్సెస్ అనుమతి"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"మీ ప్రమేయం లేకుండా కాల్స్‌ చేయడం కోసం IMS సేవను ఉపయోగించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"ఫోన్ స్టేటస్‌ మరియు గుర్తింపుని చదవడం"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"ముఖ యాక్టివిటీ రద్దయింది."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"ఫేస్ అన్‌లాక్‌ను యూజర్ రద్దు చేశారు"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"చాలా ఎక్కువ ప్రయత్నాలు చేశారు. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"ఎక్కువ సార్లు ట్రై చేశారు. ఫేస్ అన్‌లాక్ అందుబాటులో లేదు."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"చాలా ఎక్కువ సార్లు ప్రయత్నించారు. బదులుగా స్క్రీన్ లాక్‌ను ఎంటర్ చేయండి."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ముఖం ధృవీకరించలేకపోయింది. మళ్లీ ప్రయత్నించండి."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"మీరు ఫేస్ అన్‌లాక్‌ను సెటప్ చేయలేదు"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ఈ కంటెంట్ వర్క్ యాప్‌తో తెరవడం సాధ్యం కాదు"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ఈ కంటెంట్ వ్యక్తిగత యాప్‌తో షేర్ చేయడం సాధ్యం కాదు"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ఈ కంటెంట్ వ్యక్తిగత యాప్‌తో తెరవడం సాధ్యం కాదు"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"వర్క్ ప్రొఫైల్ పాజ్ చేయబడింది"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"ఆన్ చేయడానికి ట్యాప్ చేయండి"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"వర్క్ యాప్‌లు లేవు"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"వ్యక్తిగత యాప్‌లు లేవు"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"వ్యక్తిగత <xliff:g id="APP">%s</xliff:g> యాప్‌ను తెరవండి"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"వర్క్ <xliff:g id="APP">%s</xliff:g> యాప్‌ను తెరవండి"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"వ్యక్తిగత బ్రౌజర్‌ను ఉపయోగించండి"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"వర్క్ బ్రౌజర్‌ను ఉపయోగించండి"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM నెట్‌వర్క్ అన్‌లాక్ పిన్‌"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f0340c3..e33938f 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"อนุญาตให้แอปพลิเคชันควบคุมการสั่นเตือน"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"อนุญาตให้แอปเข้าถึงสถานะการสั่น"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"โทรติดต่อหมายเลขโทรศัพท์โดยตรง"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"อนุญาตให้แอปพลิเคชันโทรเข้าโทรศัพท์โดยไม่ต้องให้คุณจัดการ ซึ่งอาจทำให้มีการเรียกเก็บเงินหรือการโทรที่ไม่คาดคิด โปรดทราบว่าการทำงานนี้ไม่ได้อนุญาตให้แอปพลิเคชันโทรไปหมายเลขฉุกเฉิน แอปพลิเคชันที่เป็นอันตรายอาจทำให้คุณต้องเสียค่าบริการด้วยการโทรโดยไม่ขอการยืนยันจากคุณ"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"เข้าถึงบริการโทร IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"อนุญาตให้แอปใช้บริการ IMS เพื่อโทรออกโดยคุณไม่ต้องดำเนินการใดๆ เลย"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"อ่านสถานะและข้อมูลระบุตัวตนของโทรศัพท์"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"ยกเลิกการดำเนินการกับใบหน้าแล้ว"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"ผู้ใช้ยกเลิกการใช้การปลดล็อกด้วยใบหน้า"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"ดำเนินการหลายครั้งเกินไป ลองอีกครั้งในภายหลัง"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"ลองหลายครั้งเกินไป การปลดล็อกด้วยใบหน้าไม่พร้อมใช้งาน"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"ลองหลายครั้งเกินไป ใช้การล็อกหน้าจอแทน"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ยืนยันใบหน้าไม่ได้ ลองอีกครั้ง"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"คุณยังไม่ได้ตั้งค่าการปลดล็อกด้วยใบหน้า"</string>
@@ -1283,13 +1283,13 @@
     <string name="volume_call" msgid="7625321655265747433">"ระดับเสียงขณะโทร"</string>
     <string name="volume_bluetooth_call" msgid="2930204618610115061">"ระดับเสียงบลูทูธขณะโทร"</string>
     <string name="volume_alarm" msgid="4486241060751798448">"ระดับเสียงปลุก"</string>
-    <string name="volume_notification" msgid="6864412249031660057">"ระดับเสียงของการแจ้งเตือน"</string>
+    <string name="volume_notification" msgid="6864412249031660057">"ระดับเสียงการแจ้งเตือน"</string>
     <string name="volume_unknown" msgid="4041914008166576293">"ระดับเสียง"</string>
     <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"ระดับบลูทูธ"</string>
     <string name="volume_icon_description_ringer" msgid="2187800636867423459">"ระดับเสียงเรียกเข้า"</string>
     <string name="volume_icon_description_incall" msgid="4491255105381227919">"ระดับเสียงการโทร"</string>
     <string name="volume_icon_description_media" msgid="4997633254078171233">"ระดับเสียงของสื่อ"</string>
-    <string name="volume_icon_description_notification" msgid="579091344110747279">"ระดับเสียงของการแจ้งเตือน"</string>
+    <string name="volume_icon_description_notification" msgid="579091344110747279">"ระดับเสียงการแจ้งเตือน"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"เสียงเรียกเข้าเริ่มต้น"</string>
     <string name="ringtone_default_with_actual" msgid="2709686194556159773">"ค่าเริ่มต้น (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="397111123930141876">"ไม่มี"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"เปิดเนื้อหานี้โดยใช้แอปงานไม่ได้"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"แชร์เนื้อหานี้โดยใช้แอปส่วนตัวไม่ได้"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"เปิดเนื้อหานี้โดยใช้แอปส่วนตัวไม่ได้"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"โปรไฟล์งานหยุดชั่วคราว"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"แตะเพื่อเปิด"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ไม่มีแอปงาน"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ไม่มีแอปส่วนตัว"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"เปิด <xliff:g id="APP">%s</xliff:g> ในโปรไฟล์ส่วนตัว"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"เปิด <xliff:g id="APP">%s</xliff:g> ในโปรไฟล์งาน"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ใช้เบราว์เซอร์ส่วนตัว"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ใช้เบราว์เซอร์งาน"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ปลดล็อกเครือข่ายที่ใช้กับ SIM"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index d993981..6402f14 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Pinapayagan ang app na kontrolin ang vibrator."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Pinapayagan ang app na ma-access ang naka-vibrate na status."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"direktang tawagan ang mga numero ng telepono"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Pinapayagan ang app na tumawag sa mga numero ng telepono nang wala ng iyong panghihimasok. Maaari itong magresulta sa mga hindi inaasahang pagsingil o tawag. Tandaan na hindi nito pinapayagan ang app na tumawag sa mga numerong pang-emergency. Maaaring magpagastos sa iyo ng pera ang nakakahamak na apps sa pamamagitan ng pagtawag nang wala ng iyong kumpirmasyon."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"i-access ang serbisyo sa tawag ng IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Pinapahintulutan ang app na gamitin ang serbisyo ng IMS upang tumawag nang walang pahintulot mo."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"basahin ang katayuan at pagkakakilanlan ng telepono"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Nakansela ang operation kaugnay ng mukha."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Kinansela ng user ang Pag-unlock Gamit ang Mukha"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Masyadong maraming pagsubok. Subukang muli mamaya."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Masyadong maraming pagsubok. Hindi available ang Face Unlock."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Masyado nang maraming beses sinubukan. Ilagay na lang ang lock ng screen."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Hindi ma-verify ang mukha. Subukang muli."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Hindi mo pa nase-set up ang Pag-unlock Gamit ang Mukha"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Hindi puwedeng buksan sa mga app para sa trabaho ang content na ito"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Hindi puwedeng ibahagi sa mga personal na app ang content na ito"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Hindi puwedeng buksan sa mga personal na app ang content na ito"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Naka-pause ang profile sa trabaho"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"I-tap para i-on"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Walang app para sa trabaho"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Walang personal na app"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Buksan ang <xliff:g id="APP">%s</xliff:g> na personal"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Buksan ang <xliff:g id="APP">%s</xliff:g> na para sa trabaho"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Gamitin ang personal na browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Gamitin ang browser sa trabaho"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN para sa pag-unlock ng network ng SIM"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 1ec3682..a1c49ed 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Uygulamaya, titreşimi denetleme izni verir."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Uygulamanın titreşim durumuna erişimesine izni verir."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefon numaralarına doğrudan çağrı yap"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Uygulamaya sizin müdahaleniz olmadan telefon numaralarını arama izni verir. Bu durum beklenmeyen ödemelere veya aramalara neden olabilir. Ancak bu iznin, uygulamanın acil numaraları aramasına olanak sağlamadığını unutmayın. Kötü amaçlı uygulamalar onayınız olmadan aramalar yaparak sizi zarara sokabilir."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS çağrı hizmetine erişme"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Uygulamanın, sizin müdahaleniz olmadan telefon etmek için IMS hizmetini kullanmasına izin verir."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"telefonun durumunu ve kimliğini okuma"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Yüz işlemi iptal edildi."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Yüz Tanıma Kilidi kullanıcı tarafından iptal edildi"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Çok fazla deneme yapıldı. Daha sonra tekrar deneyin."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Çok deneme yapıldı. Yüz Tanıma Kilidi kullanılamıyor."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Çok fazla deneme yapıldı. Bunun yerine ekran kilidini girin."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Yüz doğrulanamıyor. Tekrar deneyin."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Yüz Tanıma Kilidi ayarlamadınız"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Bu içerik, iş uygulamalarıyla açılamaz"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Bu içerik, kişisel uygulamalarla paylaşılamaz"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Bu içerik, kişisel uygulamalarla açılamaz"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"İş profili duraklatıldı"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Açmak için dokunun"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"İş uygulaması yok"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Kişisel uygulama yok"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Kişisel uygulamayı (<xliff:g id="APP">%s</xliff:g>) aç"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"İş uygulamasını (<xliff:g id="APP">%s</xliff:g>) aç"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Kişisel tarayıcıyı kullan"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"İş tarayıcısını kullan"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ağ kilidi açma PIN kodu"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 235e538b..517730c 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -505,7 +505,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Дозволяє програмі контролювати вібросигнал."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Надає додатку доступ до стану вібрації."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"прямо набирати номери тел."</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Дозволяє програмі набирати номери телефону без вашого відома. Це може спричинити неочікуване стягнення плати чи здійснення дзвінків. Зауважте, що це не дозволяє програмі набирати екстрені номери. Шкідливі програми можуть здійснювати дзвінки без вашого підтвердження, за що з вас стягуватимуться кошти."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"отримувати доступ до телефонної служби IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Додаток зможе телефонувати за допомогою служби IMS без вашого відома."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"читати статус та ідентифікаційну інформацію телефону"</string>
@@ -668,7 +669,7 @@
     <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Фейс-контроль"</string>
     <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Сталася помилка з фейсконтролем"</string>
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Натисніть, щоб видалити свою модель обличчя, а потім знову додайте її"</string>
-    <string name="face_setup_notification_title" msgid="8843461561970741790">"Налаштування фейсконтролю"</string>
+    <string name="face_setup_notification_title" msgid="8843461561970741790">"Налаштування фейс-контролю"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Ви зможете розблоковувати телефон, подивившись на нього"</string>
     <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Щоб використовувати фейсконтроль, увімкніть "<b>"Доступ до камери"</b>" в розділі \"Налаштування\" &gt; \"Конфіденційність\""</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Налаштуйте більше способів розблокування"</string>
@@ -711,8 +712,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Дію з обличчям скасовано."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Користувач скасував операцію фейсконтролю"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Забагато спроб. Повторіть пізніше."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Забагато спроб. Фейс-контроль недоступний."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Забагато спроб. Розблокуйте екран іншим способом."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Не вдається перевірити обличчя. Повторіть спробу."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Ви не налаштували фейсконтроль"</string>
@@ -2161,14 +2161,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Цей контент не можна відкривати в робочих додатках"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Цим контентом не можна ділитися в особистих додатках"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Цей контент не можна відкривати в особистих додатках"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Робочий профіль призупинено"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Торкніться, щоб увімкнути"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Немає робочих додатків"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Немає особистих додатків"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Відкрити особистий додаток <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Відкрити робочий додаток <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Використати особистий веб-переглядач"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Використати робочий веб-переглядач"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-код розблокування мережі SIM-карти"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index cafa9d2..9941797 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -76,18 +76,18 @@
     <string name="auto_data_switch_title" msgid="3286350716870518297">"ڈیٹا <xliff:g id="CARRIERDISPLAY">%s</xliff:g> پر سوئچ کیا گیا"</string>
     <string name="auto_data_switch_content" msgid="803557715007110959">"آپ اسے ترتیبات میں کسی بھی وقت تبدیل کر سکتے ہیں"</string>
     <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"کوئی موبائل ڈیٹا سروس دستیاب نہیں ہے"</string>
-    <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"ہنگامی کالنگ دستیاب نہیں ہے"</string>
+    <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"ایمرجنسی کالنگ دستیاب نہیں ہے"</string>
     <string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"کوئی صوتی سروس نہیں"</string>
-    <string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"کوئی صوتی سروس یا ہنگامی کالنگ دستیاب نہیں ہے"</string>
+    <string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"کوئی صوتی سروس یا ایمرجنسی کالنگ دستیاب نہیں ہے"</string>
     <string name="RestrictedStateContent" msgid="7693575344608618926">"آپ کے کیریئر نے عارضی طور پر آف کر دیا ہے"</string>
     <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"‏SIM <xliff:g id="SIMNUMBER">%d</xliff:g> کے لئے آپ کے کیریئر نے عارضی طور پر آف کر دیا ہے"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"موبائل نیٹ ورک تک رسائی نہیں ہو سکتی"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ترجیحی نیٹ ورک تبدیل کر کے دیکھیں۔ تبدیل کرنے کے لیے تھپتھپائیں۔"</string>
-    <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ہنگامی کالنگ دستیاب نہیں ہے"</string>
-    <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"‏Wi‑Fi کے ذریعے ہنگامی کالز نہیں کر سکتے"</string>
+    <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ایمرجنسی کالنگ دستیاب نہیں ہے"</string>
+    <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"‏Wi‑Fi کے ذریعے ایمرجنسی کالز نہیں کر سکتے"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"الرٹس"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"کال فارورڈنگ"</string>
-    <string name="notification_channel_emergency_callback" msgid="54074839059123159">"ہنگامی کال بیک وضع"</string>
+    <string name="notification_channel_emergency_callback" msgid="54074839059123159">"ایمرجنسی کال بیک وضع"</string>
     <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"موبائل ڈیٹا کی صورت حال"</string>
     <string name="notification_channel_sms" msgid="1243384981025535724">"‏SMS پیغامات"</string>
     <string name="notification_channel_voice_mail" msgid="8457433203106654172">"صوتی میل پیغامات"</string>
@@ -364,11 +364,11 @@
     <string name="permlab_receiveMms" msgid="4000650116674380275">"‏متنی پیغامات (MMS) حاصل کریں"</string>
     <string name="permdesc_receiveMms" msgid="958102423732219710">"‏ایپ کو MMS پیغامات حاصل اور ان پر کارروائی کرنے کی اجازت دیتا ہے۔ اس کا مطلب ہے کہ ایپ آپ کے آلے پر مرسلہ پیغامات آپ کو دکھائے بغیر ان پر نگاہ رکھ یا انہیں حذف کرسکتی ہے۔"</string>
     <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"سیل کے نشریاتی پیغامات فارورڈ کریں"</string>
-    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"سیل کی نشریاتی پیغامات کے موصول ہوتے ہی فارورڈ کرنے کے لیے ایپ کو سیل کے نشریاتی ماڈیول میں پابندی لگانے کی اجازت دیں۔ سیل کی نشریاتی الرٹس آپ کو ہنگامی حالات سے مطلع کرنے کیلئے کچھ مقامات میں مہیا کی جاتی ہیں۔ نقصان دہ ایپس کوئی ہنگامی سیل براڈ کاسٹ موصول ہونے پر آپ کے آلے کی کارکردگی یا عمل میں مداخلت کر سکتی ہیں۔"</string>
+    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"سیل کی نشریاتی پیغامات کے موصول ہوتے ہی فارورڈ کرنے کے لیے ایپ کو سیل کے نشریاتی ماڈیول میں پابندی لگانے کی اجازت دیں۔ سیل کی نشریاتی الرٹس آپ کو ایمرجنسی حالات سے مطلع کرنے کیلئے کچھ مقامات میں مہیا کی جاتی ہیں۔ نقصان دہ ایپس کوئی ایمرجنسی سیل براڈ کاسٹ موصول ہونے پر آپ کے آلے کی کارکردگی یا عمل میں مداخلت کر سکتی ہیں۔"</string>
     <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"جاری کالز کا نظم کریں"</string>
     <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"اس سے ایپ کو آپ کے آلے پر جاری کالز کے بارے میں تفصیلات دیکھنے اور ان کالز کو کنٹرول کرنے کی اجازت ملتی ہے۔"</string>
     <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"سیل کے نشریاتی پیغامات پڑھیں"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"ایپ کو آپ کے آلے کو موصولہ سیل کے نشریاتی پیغامات پڑھنے کی اجازت دیتا ہے۔ سیل کی نشریاتی الرٹس آپ کو ہنگامی حالات سے مطلع کرنے کیلئے کچھ مقامات میں مہیا کی جاتی ہیں۔ نقصان دہ ایپس کوئی ہنگامی سیل کا نشریہ موصول ہونے پر آپ کے آلے کی کارکردگی یا عمل میں خلل ڈال سکتی ہیں۔"</string>
+    <string name="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>
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ایپ کو وائبریٹر کنٹرول کرنے کی اجازت دیتا ہے۔"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ایپ کو وائبریٹر اسٹیٹ تک رسائی حاصل کرنے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"براہ راست فون نمبرز پر کال کریں"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"ایپ کو آپ کی مداخلت کے بغیر فون نمبروں پر کال کرنے کی اجازت دیتا ہے۔ اس کے نتیجے میں غیر متوقع چارجز یا کالیں ہوسکتی ہیں۔ نوٹ کرلیں کہ یہ ایپ کو ہنگامی نمبروں پر کال کرنے کی اجازت نہیں دیتا ہے۔ نقصان دہ ایپس آپ کی تصدیق کے بغیر کالیں کرکے آپ کی رقم صرف کروا سکتے ہیں۔"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"‏IMS کال سروس تک رسائی حاصل کریں"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"‏آپ کی مداخلت کے بغیر کالیں کرنے کیلئے ایپ کو IMS سروس استعمال کرنے کی اجازت دیتی ہے۔"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"فون کے اسٹیٹس اور شناخت کو پڑھیں"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"چہرے پر ہونے والی کارروائی منسوخ ہو گئی۔"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"صارف نے فیس اَنلاک کو منسوخ کر دیا"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"کافی زیادہ کوششیں کی گئیں۔ دوبارہ کوشش کریں۔"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"کافی زیادہ کوششیں۔ فیس اَنلاک دستیاب نہیں ہے۔"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"کافی زیادہ کوششیں۔ اس کے بجائے اسکرین لاک درج کریں۔"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"چہرے کی توثیق نہیں کی جا سکی۔ پھر آزمائيں۔"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"آپ نے فیس اَنلاک کو سیٹ نہیں کیا ہے"</string>
@@ -958,13 +958,13 @@
     <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"‏غیر مقفل کرنے کیلئے PIN ٹائپ کریں"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"‏غلط PIN کوڈ۔"</string>
     <string name="keyguard_label_text" msgid="3841953694564168384">"غیر مقفل کرنے کیلئے، مینیو پھر 0 دبائیں۔"</string>
-    <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"ہنگامی نمبر"</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"ایمرجنسی نمبر"</string>
     <string name="lockscreen_carrier_default" msgid="6192313772955399160">"کوئی سروس نہیں ہے"</string>
     <string name="lockscreen_screen_locked" msgid="7364905540516041817">"اسکرین مقفل ہے۔"</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"غیر مقفل کرنے کیلئے مینیو دبائیں یا ہنگامی کال کریں۔"</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"غیر مقفل کرنے کیلئے مینیو دبائیں یا ایمرجنسی کال کریں۔"</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"غیر مقفل کرنے کیلئے مینیو دبائیں۔"</string>
     <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"غیر مقفل کرنے کیلئے پیٹرن کو ڈرا کریں"</string>
-    <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ہنگامی"</string>
+    <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ایمرجنسی"</string>
     <string name="lockscreen_return_to_call" msgid="3156883574692006382">"کال پر واپس جائیں"</string>
     <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"صحیح!"</string>
     <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"دوبارہ کوشش کریں"</string>
@@ -986,7 +986,7 @@
     <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"روکیں"</string>
     <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"ریوائینڈ کریں"</string>
     <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"تیزی سے فارورڈ کریں"</string>
-    <string name="emergency_calls_only" msgid="3057351206678279851">"صرف ہنگامی کالز"</string>
+    <string name="emergency_calls_only" msgid="3057351206678279851">"صرف ایمرجنسی کالز"</string>
     <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"نیٹ ورک مقفل ہو گیا"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="2867953953604224166">"‏آپ کا SIM ‏PUK مقفل ہے۔"</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"رہنمائے صارف دیکھیں یا کسٹمر کیئر سے رابطہ کریں۔"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"اس مواد کو ورک ایپس کے ساتھ نہیں کھولا جا سکتا"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"اس مواد کا اشتراک ذاتی ایپس کے ساتھ نہیں کیا جا سکتا"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"اس مواد کو ذاتی ایپس کے ساتھ نہیں کھولا جا سکتا"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"دفتری پروفائل روک دی گئی ہے"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"آن کرنے کیلئے تھپتھپائیں"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"کوئی ورک ایپ نہیں"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"کوئی ذاتی ایپ نہیں"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"ذاتی <xliff:g id="APP">%s</xliff:g> کھولیں"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"دفتری <xliff:g id="APP">%s</xliff:g> کھولیں"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ذاتی براؤزر استعمال کریں"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ورک براؤزر استعمال کریں"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‏SIM نیٹ ورک غیر مقفل کرنے کا PIN"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 6104446..5e227d3 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Ilova tebranishli signallarni boshqarishi mumkin."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ilovaga tebranish holatini aniqlash ruxsatini beradi."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefon raqamlariga tog‘ridan to‘g‘ri qo‘ng‘iroq qilish"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Ilovaga sizning yordamingizsiz telefonga qo‘ng‘iroq qilish imkonini beradi. Bu kutilmagan qo‘ng‘iroqlarni amalga oshirishi yoki ortiqcha to‘lovlarni yuzaga keltirishi mumkin. Shunga e’tibor qilinki, u favqulodda telefon raqamlariga qo‘ng‘iroqlar qilishga ruxsat bermaydi. Zararli ilovalar sizdan so‘ramasdan qo‘ng‘iroqlarni amalga oshirib, pulingizni sarflashi mumkin."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS qo‘ng‘iroq xizmatiga kirish"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Ilovaga sizning ishtirokingizsiz qo‘ng‘iroqlarni amalga oshirish uchun IMS xizmatidan foydalanishga ruxsat beradi."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"telefon holati haqidagi ma’lumotlarni olish"</string>
@@ -684,7 +685,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Telefonni chaproq tuting"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Telefonni oʻngroq tuting"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Qurilmaga tik qarang."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Yuzingiz koʻrinmayapti. Telefonni koʻz balandligida tuting."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Yuz koʻrinmayapti. Telefonni koʻz darajasida tuting."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Ortiqcha harakatlanmoqda. Qimirlatmasdan ushlang."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Yuzingizni qaytadan qayd qildiring."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Yuz aniqlanmadi. Qayta urining."</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Yuzni aniqlash bekor qilindi."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Yuz bilan ochishni foydalanuvchi bekor qildi"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Juda ko‘p urinildi. Keyinroq qaytadan urining."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Urinishlar soni oshib ketdi. Yuz bilan ochilmaydi."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Juda koʻp urinildi. Ekran qulfi bilan oching."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Yuzingiz tasdiqlanmadi. Qaytadan urining."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Hali yuz bilan ochishni sozlamagansiz"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Bu kontent ishga oid ilovalar bilan ochilmaydi"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Bu kontent shaxsiy ilovalar bilan ulashilmaydi"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Bu kontent shaxsiy ilovalar bilan ochilmaydi"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Ish profili pauzada"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Yoqish uchun bosing"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ishga oid ilovalar topilmadi"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Shaxsiy ilovalar topilmadi"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Shaxsiy <xliff:g id="APP">%s</xliff:g> ochish"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Ishdagi <xliff:g id="APP">%s</xliff:g> ochish"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Shaxsiy brauzerdan foydalanish"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Ishga oid brauzerdan foydalanish"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM kartaning tarmoqdagi qulfini ochish uchun PIN kod"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index eba580c..c206b68 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Cho phép ứng dụng kiểm soát bộ rung."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Cho phép ứng dụng truy cập vào trạng thái bộ rung."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"gọi trực tiếp số điện thoại"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Cho phép ứng dụng gọi các số điện thoại mà không cần sự can thiệp của bạn. Việc này có thể dẫn đến các khoản phí hoặc cuộc gọi không mong muốn. Lưu ý rằng quyền này không cho phép ứng dụng gọi các số khẩn cấp. Các ứng dụng độc hại có thể khiến bạn tốn tiền do thực hiện cuộc gọi mà không cần sự xác nhận của bạn."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"truy cập dịch vụ gọi điện qua IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Cho phép ứng dụng sử dụng dịch vụ IMS để thực hiện cuộc gọi mà không có sự can thiệp của bạn."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"đọc trạng thái và nhận dạng của điện thoại"</string>
@@ -623,7 +624,7 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"Lỗi khi xác thực"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Dùng phương thức khóa màn hình"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Hãy nhập phương thức khóa màn hình của bạn để tiếp tục"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Nhấn chắc trên cảm biến"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Nhấn chắc chắn trên cảm biến"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Không nhận dạng được vân tay. Hãy thử lại."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hãy vệ sinh cảm biến vân tay rồi thử lại"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vệ sinh cảm biến rồi thử lại"</string>
@@ -684,7 +685,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Đưa điện thoại sang bên trái"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Đưa điện thoại sang bên phải"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Vui lòng nhìn thẳng vào thiết bị."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Không phát hiện thấy khuôn mặt của bạn. Hãy cầm điện thoại ngang tầm mắt"</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Không thấy khuôn mặt. Hãy cầm điện thoại ngang tầm mắt"</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Thiết bị di chuyển quá nhiều. Giữ yên thiết bị."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Vui lòng đăng ký lại khuôn mặt của bạn."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Không thể nhận dạng khuôn mặt. Hãy thử lại."</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Đã hủy thao tác dùng khuôn mặt."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Người dùng đã hủy thao tác Mở khóa bằng khuôn mặt"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Bạn đã thử quá nhiều lần. Hãy thử lại sau."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Bạn đã thử quá nhiều lần. Không dùng được tính năng Mở khoá bằng khuôn mặt."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Bạn đã thử quá nhiều lần. Hãy nhập phương thức khóa màn hình."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Không thể xác minh khuôn mặt. Hãy thử lại."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Bạn chưa thiết lập tính năng Mở khóa bằng khuôn mặt"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Bạn không thể mở nội dung này bằng ứng dụng công việc"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Bạn không thể chia sẻ nội dung này bằng ứng dụng cá nhân"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Bạn không thể mở nội dung này bằng ứng dụng cá nhân"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Hồ sơ công việc đã bị tạm dừng"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Nhấn để bật"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Không có ứng dụng công việc"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Không có ứng dụng cá nhân"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Mở <xliff:g id="APP">%s</xliff:g> cá nhân"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Mở <xliff:g id="APP">%s</xliff:g> công việc"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Dùng trình duyệt cá nhân"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Dùng trình duyệt công việc"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Mã PIN mở khóa mạng SIM"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1e25289..99203d5 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"允许应用控制振动器。"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"允许该应用访问振动器状态。"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"拨打电话"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"允许该应用在您未执行操作的情况下拨打电话号码。此权限可能会导致意外收费或呼叫。请注意,此权限不允许该应用拨打紧急电话号码。恶意应用可通过拨打电话产生相关费用,而无需您的确认。"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"使用即时通讯通话服务"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"允许应用自行使用即时通讯服务拨打电话。"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"读取手机状态和身份"</string>
@@ -684,7 +685,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"请将手机向左移动"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"请将手机向右移动"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"请直视您的设备。"</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"看不清您的脸部,请将手机举到与眼睛齐平的位置。"</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"看不到人脸,请将手机举到与眼睛齐平的位置。"</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"摄像头过于晃动。请将手机拿稳。"</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"请重新注册您的面孔。"</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"无法识别人脸,请重试。"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"面孔处理操作已取消。"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"用户已取消人脸解锁"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"尝试次数过多,请稍后重试。"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"尝试次数过多。无法使用人脸解锁功能。"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"尝试次数过多,请改为通过解除屏幕锁定来验证身份。"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"无法验证人脸,请重试。"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"您尚未设置人脸解锁"</string>
@@ -2092,7 +2092,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"确定"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"关闭"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"了解详情"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"在 Android 12 中,增强型通知功能取代了 Android 自适应通知功能。增强型通知功能可以显示建议的操作和回复,并可将通知整理得井井有条。\n\n增强型通知功能可以读取通知内容,包括联系人名称和消息等个人信息。该功能还可以关闭通知或对通知做出回应,例如接听来电以及控制勿扰模式。"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"在 Android 12 中,增强型通知功能取代了 Android 自适应通知功能。增强型通知功能可以显示建议的操作和回复,并可将通知整理得井井有条。\n\n增强型通知功能可以读取通知内容,包括联系人姓名、消息等个人信息。该功能还可以关闭通知或对通知做出回应,例如接听来电以及控制勿扰模式。"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"日常安排模式信息通知"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"省电模式已开启"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"降低电池用量以延长电池续航时间"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"无法使用工作应用打开该内容"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"无法使用个人应用分享该内容"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"无法使用个人应用打开该内容"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"工作资料已被暂停"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"点按即可开启"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"没有支持该内容的工作应用"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"没有支持该内容的个人应用"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"打开个人 <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"打开工作 <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"使用个人浏览器"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"使用工作浏览器"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 网络解锁 PIN 码"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 74e44a6..a3704c7 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -38,17 +38,17 @@
     <string name="serviceErased" msgid="997354043770513494">"已成功清除。"</string>
     <string name="passwordIncorrect" msgid="917087532676155877">"密碼有誤。"</string>
     <string name="mmiComplete" msgid="6341884570892520140">"已完成 MMI。"</string>
-    <string name="badPin" msgid="888372071306274355">"您所輸入的舊 PIN 碼不正確。"</string>
-    <string name="badPuk" msgid="4232069163733147376">"您輸入的 PUK 不正確。"</string>
-    <string name="mismatchPin" msgid="2929611853228707473">"您輸入的 PIN 碼不符。"</string>
+    <string name="badPin" msgid="888372071306274355">"你所輸入的舊 PIN 碼不正確。"</string>
+    <string name="badPuk" msgid="4232069163733147376">"你輸入的 PUK 不正確。"</string>
+    <string name="mismatchPin" msgid="2929611853228707473">"你輸入的 PIN 碼不符。"</string>
     <string name="invalidPin" msgid="7542498253319440408">"請輸入一個 4 至 8 位數的 PIN。"</string>
     <string name="invalidPuk" msgid="8831151490931907083">"輸入 8 位數以上的 PUK。"</string>
     <string name="needPuk" msgid="3503414069503752211">"SIM 卡已使用 PUK 鎖定,請輸入 PUK 解鎖。"</string>
     <string name="needPuk2" msgid="3910763547447344963">"請輸入 PUK2 解鎖 SIM 卡。"</string>
     <string name="enablePin" msgid="2543771964137091212">"操作失敗,請啟用「SIM/RUIM 鎖定」。"</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
-      <item quantity="other">您還有 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會輸入。如果仍然輸入錯誤,SIM 卡將會被鎖定。</item>
-      <item quantity="one">您還有 <xliff:g id="NUMBER_0">%d</xliff:g> 次機會輸入。如果仍然輸入錯誤,SIM 卡將會被鎖定。</item>
+      <item quantity="other">你還有 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會輸入。如果仍然輸入錯誤,SIM 卡將會被鎖定。</item>
+      <item quantity="one">你還有 <xliff:g id="NUMBER_0">%d</xliff:g> 次機會輸入。如果仍然輸入錯誤,SIM 卡將會被鎖定。</item>
     </plurals>
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
     <string name="meid" msgid="3291227361605924674">"MEID"</string>
@@ -72,9 +72,9 @@
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"預設顯示來電號碼,但下一通電話不顯示。"</string>
     <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"預設顯示來電號碼,下一通電話也繼續顯示。"</string>
     <string name="serviceNotProvisioned" msgid="8289333510236766193">"未提供此服務。"</string>
-    <string name="CLIRPermanent" msgid="166443681876381118">"您無法更改來電顯示設定。"</string>
+    <string name="CLIRPermanent" msgid="166443681876381118">"你無法更改來電顯示設定。"</string>
     <string name="auto_data_switch_title" msgid="3286350716870518297">"流動數據已切換至「<xliff:g id="CARRIERDISPLAY">%s</xliff:g>」"</string>
-    <string name="auto_data_switch_content" msgid="803557715007110959">"您隨時可在「設定」中變更此設定"</string>
+    <string name="auto_data_switch_content" msgid="803557715007110959">"你隨時可在「設定」中變更此設定"</string>
     <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"無法使用流動數據服務"</string>
     <string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"無法撥打緊急電話"</string>
     <string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"沒有語音服務"</string>
@@ -125,7 +125,7 @@
     <item msgid="468830943567116703">"如要透過 Wi-Fi 撥打電話和傳送訊息,請先向流動網絡供應商要求設定此服務,然後再次在「設定」中開啟「Wi-Fi 通話」。(錯誤代碼:<xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="4795145070505729156">"向您的流動網絡供應商註冊 Wi-Fi 通話時發生問題:<xliff:g id="CODE">%1$s</xliff:g>"</item>
+    <item msgid="4795145070505729156">"向你的流動網絡供應商註冊 Wi-Fi 通話時發生問題:<xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
     <!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
     <skip />
@@ -181,17 +181,17 @@
     <string name="low_memory" product="default" msgid="2539532364144025569">"手機的儲存空間已滿。請刪除一些檔案,以騰出可用空間。"</string>
     <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{已安裝憑證機構}other{已安裝憑證機構}}"</string>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"由不明的第三方監管"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"由您的工作設定檔管理員監控"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"由你的工作設定檔管理員監控"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"由 <xliff:g id="MANAGING_DOMAIN">%s</xliff:g> 監管"</string>
     <string name="work_profile_deleted" msgid="5891181538182009328">"工作設定檔已被刪除"</string>
-    <string name="work_profile_deleted_details" msgid="3773706828364418016">"工作設定檔管理員應用程式已遺失或損毀。因此,您的工作設定檔和相關資料已刪除。請聯絡您的管理員以取得協助。"</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"您的工作設定檔無法再在此裝置上使用"</string>
+    <string name="work_profile_deleted_details" msgid="3773706828364418016">"工作設定檔管理員應用程式已遺失或損毀。因此,你的工作設定檔和相關資料已刪除。請聯絡你的管理員以取得協助。"</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"你的工作設定檔無法再在此裝置上使用"</string>
     <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密碼輸入錯誤的次數過多"</string>
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"管理員已開放裝置供個人使用"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"裝置已受管理"</string>
-    <string name="network_logging_notification_text" msgid="1327373071132562512">"您的機構會管理此裝置,並可能會監控網絡流量。輕按即可瞭解詳情。"</string>
-    <string name="location_changed_notification_title" msgid="3620158742816699316">"應用程式可存取您的位置"</string>
-    <string name="location_changed_notification_text" msgid="7158423339982706912">"請聯絡您的 IT 管理員以瞭解詳情"</string>
+    <string name="network_logging_notification_text" msgid="1327373071132562512">"你的機構會管理此裝置,並可能會監控網絡流量。輕按即可瞭解詳情。"</string>
+    <string name="location_changed_notification_title" msgid="3620158742816699316">"應用程式可存取你的位置"</string>
+    <string name="location_changed_notification_text" msgid="7158423339982706912">"請聯絡你的 IT 管理員以瞭解詳情"</string>
     <string name="geofencing_service" msgid="3826902410740315456">"地理圍欄服務"</string>
     <string name="country_detector" msgid="7023275114706088854">"國家/地區偵測器"</string>
     <string name="location_service" msgid="2439187616018455546">"定位服務"</string>
@@ -201,15 +201,15 @@
     <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS 時間更新服務"</string>
     <string name="device_policy_manager_service" msgid="5085762851388850332">"裝置政策管理中心服務"</string>
     <string name="music_recognition_manager_service" msgid="7481956037950276359">"音樂識別管理員服務"</string>
-    <string name="factory_reset_warning" msgid="6858705527798047809">"您的裝置將被清除"</string>
-    <string name="factory_reset_message" msgid="2657049595153992213">"無法使用管理員應用程式。系統會現在清除您的裝置。\n\n如有任何疑問,請聯絡您的機構管理員。"</string>
+    <string name="factory_reset_warning" msgid="6858705527798047809">"你的裝置將被清除"</string>
+    <string name="factory_reset_message" msgid="2657049595153992213">"無法使用管理員應用程式。系統會現在清除你的裝置。\n\n如有任何疑問,請聯絡你的機構管理員。"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」暫停了列印。"</string>
     <string name="personal_apps_suspension_title" msgid="7561416677884286600">"開啟工作設定檔"</string>
-    <string name="personal_apps_suspension_text" msgid="6115455688932935597">"系統會封鎖您的個人應用程式,直至您開啟工作設定檔為止"</string>
-    <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"個人應用程式將於 <xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> 封鎖。IT 管理員不允許您的工作設定檔保持關閉狀態超過 <xliff:g id="NUMBER">%3$d</xliff:g> 天。"</string>
+    <string name="personal_apps_suspension_text" msgid="6115455688932935597">"系統會封鎖你的個人應用程式,直至你開啟工作設定檔為止"</string>
+    <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"個人應用程式將於 <xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> 封鎖。IT 管理員不允許你的工作設定檔保持關閉狀態超過 <xliff:g id="NUMBER">%3$d</xliff:g> 天。"</string>
     <string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"開啟"</string>
     <string name="work_profile_telephony_paused_title" msgid="7690804479291839519">"通話和訊息功能已關閉"</string>
-    <string name="work_profile_telephony_paused_text" msgid="8065762301100978221">"您已暫停工作應用程式,因此無法接聽電話或接收訊息。"</string>
+    <string name="work_profile_telephony_paused_text" msgid="8065762301100978221">"你已暫停工作應用程式,因此無法接聽電話或接收訊息。"</string>
     <string name="work_profile_telephony_paused_turn_on_button" msgid="7542632318337068821">"取消暫停工作應用程式"</string>
     <string name="me" msgid="6207584824693813140">"我本人"</string>
     <string name="power_dialog" product="tablet" msgid="8333207765671417261">"平板電腦選項"</string>
@@ -230,13 +230,13 @@
     <string name="reboot_to_reset_title" msgid="2226229680017882787">"回復原廠設定"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"正在重新啟動…"</string>
     <string name="shutdown_progress" msgid="5017145516412657345">"正在關機..."</string>
-    <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"您的平板電腦將會關機。"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"你的平板電腦將會關機。"</string>
     <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Android TV 裝置將會關機。"</string>
-    <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"您的手錶即將關機。"</string>
-    <string name="shutdown_confirm" product="default" msgid="136816458966692315">"您的手機即將關機。"</string>
-    <string name="shutdown_confirm_question" msgid="796151167261608447">"您要關機嗎?"</string>
+    <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"你的手錶即將關機。"</string>
+    <string name="shutdown_confirm" product="default" msgid="136816458966692315">"你的手機即將關機。"</string>
+    <string name="shutdown_confirm_question" msgid="796151167261608447">"你要關機嗎?"</string>
     <string name="reboot_safemode_title" msgid="5853949122655346734">"重新啟動進入安全模式"</string>
-    <string name="reboot_safemode_confirm" msgid="1658357874737219624">"您要重新啟動來進入安全模式嗎?這會停用您安裝的所有第三方應用程式。您只要再次重新啟動,系統便會還原這些應用程式。"</string>
+    <string name="reboot_safemode_confirm" msgid="1658357874737219624">"你要重新啟動來進入安全模式嗎?這會停用你安裝的所有第三方應用程式。你只要再次重新啟動,系統便會還原這些應用程式。"</string>
     <string name="recent_tasks_title" msgid="8183172372995396653">"近期活動"</string>
     <string name="no_recent_tasks" msgid="9063946524312275906">"沒有最近用過的應用程式。"</string>
     <string name="global_actions" product="tablet" msgid="4412132498517933867">"平板電腦選項"</string>
@@ -251,11 +251,11 @@
     <string name="global_action_logout" msgid="6093581310002476511">"結束工作階段"</string>
     <string name="global_action_screenshot" msgid="2610053466156478564">"螢幕截圖"</string>
     <string name="bugreport_title" msgid="8549990811777373050">"錯誤報告"</string>
-    <string name="bugreport_message" msgid="5212529146119624326">"這會收集您目前裝置狀態的相關資訊,並以電郵傳送給您。從開始建立錯誤報告到準備傳送需要一段時間,請耐心等候。"</string>
+    <string name="bugreport_message" msgid="5212529146119624326">"這會收集你目前裝置狀態的相關資訊,並以電郵傳送給你。從開始建立錯誤報告到準備傳送需要一段時間,請耐心等候。"</string>
     <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"互動報告"</string>
-    <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"在大部分情況下,建議您使用此選項,以便追蹤報告進度、輸入更多與問題相關的詳細資料,以及擷取螢幕畫面。系統可能會省略一些不常用的部分,以縮短產生報告的時間。"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"在大部分情況下,建議你使用此選項,以便追蹤報告進度、輸入更多與問題相關的詳細資料,以及擷取螢幕畫面。系統可能會省略一些不常用的部分,以縮短產生報告的時間。"</string>
     <string name="bugreport_option_full_title" msgid="7681035745950045690">"完整報告"</string>
-    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"如果裝置沒有反應或運作速度較慢,或您需要完整的報告時,建議使用此選項將系統的干擾程度降至最低。此選項不允許您輸入更多詳細資料,或擷取更多螢幕畫面。"</string>
+    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"如果裝置沒有反應或運作速度較慢,或你需要完整的報告時,建議使用此選項將系統的干擾程度降至最低。此選項不允許你輸入更多詳細資料,或擷取更多螢幕畫面。"</string>
     <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{系統將在 # 秒後擷取錯誤報告的螢幕畫面。}other{系統將在 # 秒後擷取錯誤報告的螢幕畫面。}}"</string>
     <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"已為錯誤報告擷取螢幕截圖"</string>
     <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"無法為錯誤報告擷取螢幕截圖"</string>
@@ -299,11 +299,11 @@
     <string name="user_owner_label" msgid="8628726904184471211">"切換至個人設定檔"</string>
     <string name="managed_profile_label" msgid="7316778766973512382">"切換至工作設定檔"</string>
     <string name="permgrouplab_contacts" msgid="4254143639307316920">"通訊錄"</string>
-    <string name="permgroupdesc_contacts" msgid="9163927941244182567">"存取您的通訊錄"</string>
+    <string name="permgroupdesc_contacts" msgid="9163927941244182567">"存取你的通訊錄"</string>
     <string name="permgrouplab_location" msgid="1858277002233964394">"位置"</string>
     <string name="permgroupdesc_location" msgid="1995955142118450685">"存取此裝置的位置"</string>
     <string name="permgrouplab_calendar" msgid="6426860926123033230">"日曆"</string>
-    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取您的日曆"</string>
+    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取你的日曆"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"短訊"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"傳送和查看短訊"</string>
     <string name="permgrouplab_storage" msgid="17339216290379241">"檔案"</string>
@@ -325,14 +325,14 @@
     <string name="permgrouplab_phone" msgid="570318944091926620">"電話"</string>
     <string name="permgroupdesc_phone" msgid="270048070781478204">"撥打電話及管理通話"</string>
     <string name="permgrouplab_sensors" msgid="9134046949784064495">"人體感應器"</string>
-    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"存取與您生命體徵相關的感應器資料"</string>
+    <string name="permgroupdesc_sensors" msgid="2610631290633747752">"存取與你生命體徵相關的感應器資料"</string>
     <string name="permgrouplab_notifications" msgid="5472972361980668884">"通知"</string>
     <string name="permgroupdesc_notifications" msgid="4608679556801506580">"顯示通知"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"擷取視窗內容"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"檢查您使用中的視窗內容。"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"檢查你使用中的視窗內容。"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"開啟「輕觸探索」功能"</string>
-    <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"朗讀您輕按的項目,並可讓您使用手勢探索螢幕。"</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"記錄您輸入的文字"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"朗讀你輕按的項目,並可讓你使用手勢探索螢幕。"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"記錄你輸入的文字"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"包括個人資料,如信用卡號碼和密碼。"</string>
     <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"控制顯示屏的放大功能"</string>
     <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"控制顯示屏的縮放程度和位置。"</string>
@@ -360,31 +360,31 @@
     <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"接聽來電"</string>
     <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"允許應用程式接聽來電。"</string>
     <string name="permlab_receiveSms" msgid="505961632050451881">"接收短訊 (SMS)"</string>
-    <string name="permdesc_receiveSms" msgid="1797345626687832285">"允許應用程式接收和處理短訊。這表示應用程式可監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
+    <string name="permdesc_receiveSms" msgid="1797345626687832285">"允許應用程式接收和處理短訊。這表示應用程式可監控傳送至你裝置的訊息,或在你閱讀訊息前擅自刪除訊息。"</string>
     <string name="permlab_receiveMms" msgid="4000650116674380275">"接收短訊 (MMS)"</string>
-    <string name="permdesc_receiveMms" msgid="958102423732219710">"允許應用程式接收和處理 MMS 訊息。這表示應用程式可監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
+    <string name="permdesc_receiveMms" msgid="958102423732219710">"允許應用程式接收和處理 MMS 訊息。這表示應用程式可監控傳送至你裝置的訊息,或在你閱讀訊息前擅自刪除訊息。"</string>
     <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"轉寄區域廣播訊息"</string>
-    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"允許應用程式繫結至區域廣播模組,以在收到區域廣播訊息時轉寄訊息。在某些地點,系統會發出區域廣播通知,提示您有緊急狀況發生。惡意應用程式可能會在裝置收到緊急區域廣播時,干擾裝置的效能或運作。"</string>
+    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"允許應用程式繫結至區域廣播模組,以在收到區域廣播訊息時轉寄訊息。在某些地點,系統會發出區域廣播通知,提示你有緊急狀況發生。惡意應用程式可能會在裝置收到緊急區域廣播時,干擾裝置的效能或運作。"</string>
     <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"管理正在進行的通話"</string>
     <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"允許應用程式查看裝置上正在進行的通話詳情並控制通話。"</string>
     <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"讀取區域廣播訊息"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"允許應用程式讀取您裝置接收的區域廣播訊息。某些地點會發出區域廣播警報,警告您發生緊急狀況。惡意應用程式可能會在裝置收到緊急區域廣播時,干擾裝置的性能或運作。"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"允許應用程式讀取你裝置接收的區域廣播訊息。某些地點會發出區域廣播警報,警告你發生緊急狀況。惡意應用程式可能會在裝置收到緊急區域廣播時,干擾裝置的性能或運作。"</string>
     <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"讀取訂閱的資訊提供"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"允許應用程式取得目前已同步的資訊提供的詳細資料。"</string>
     <string name="permlab_sendSms" msgid="7757368721742014252">"傳送和查看 SMS 短訊"</string>
-    <string name="permdesc_sendSms" msgid="6757089798435130769">"允許應用程式傳送短訊,但可能產生未預期的費用。惡意應用程式可能會未經您確認擅自傳送短訊,增加您的支出。"</string>
-    <string name="permlab_readSms" msgid="5164176626258800297">"讀取您的短訊 (SMS 或 MMS)"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"此應用程式可以讀取所有儲存在您的平板電腦中的短訊。"</string>
+    <string name="permdesc_sendSms" msgid="6757089798435130769">"允許應用程式傳送短訊,但可能產生未預期的費用。惡意應用程式可能會未經你確認擅自傳送短訊,增加你的支出。"</string>
+    <string name="permlab_readSms" msgid="5164176626258800297">"讀取你的短訊 (SMS 或 MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"此應用程式可以讀取所有儲存在你的平板電腦中的短訊。"</string>
     <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"此應用程式可以讀取所有儲存在 Android TV 裝置中的短訊。"</string>
-    <string name="permdesc_readSms" product="default" msgid="774753371111699782">"此應用程式可以讀取所有儲存在您的手機中的短訊。"</string>
+    <string name="permdesc_readSms" product="default" msgid="774753371111699782">"此應用程式可以讀取所有儲存在你的手機中的短訊。"</string>
     <string name="permlab_receiveWapPush" msgid="4223747702856929056">"接收短訊 (WAP)"</string>
-    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"允許應用程式接收和處理 WAP 訊息。這項權限也能讓應用程式監控訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
+    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"允許應用程式接收和處理 WAP 訊息。這項權限也能讓應用程式監控訊息,或在你閱讀訊息前擅自刪除訊息。"</string>
     <string name="permlab_getTasks" msgid="7460048811831750262">"擷取執行中的應用程式"</string>
     <string name="permdesc_getTasks" msgid="7388138607018233726">"允許應用程式擷取有關目前和最近執行的工作的資訊。如此一來,應用程式或可找出裝置上所使用應用程式的相關資訊。"</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"管理個人檔案和裝置擁有者"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"允許應用程式設定檔案擁有者和裝置擁有者。"</string>
     <string name="permlab_reorderTasks" msgid="7598562301992923804">"為執行中的應用程式重新排序"</string>
-    <string name="permdesc_reorderTasks" msgid="8796089937352344183">"允許應用程式將工作移至前景或背景。應用程式可以自行處理,您無須操作。"</string>
+    <string name="permdesc_reorderTasks" msgid="8796089937352344183">"允許應用程式將工作移至前景或背景。應用程式可以自行處理,你無須操作。"</string>
     <string name="permlab_enableCarMode" msgid="893019409519325311">"啟用行車模式"</string>
     <string name="permdesc_enableCarMode" msgid="56419168820473508">"允許應用程式啟用車用模式。"</string>
     <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"關閉其他應用程式"</string>
@@ -398,7 +398,7 @@
     <string name="permlab_useDataInBackground" msgid="783415807623038947">"在背景中使用數據"</string>
     <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"此應用程式可在背景中使用數據,這可能會增加數據用量。"</string>
     <string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"排定精準時間的動作"</string>
-    <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"此應用程式可以預先安排系統在指定的未來時間執行工作。這也表示,即使您沒有積極使用裝置,應用程式仍可運作。"</string>
+    <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"此應用程式可以預先安排系統在指定的未來時間執行工作。這也表示,即使你沒有積極使用裝置,應用程式仍可運作。"</string>
     <string name="permlab_use_exact_alarm" msgid="348045139777131552">"預先安排鬧鐘或活動提醒"</string>
     <string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"此應用程式可以預先安排鬧鐘和提醒等動作,讓系統在指定的未來時間發出通知。"</string>
     <string name="permlab_persistentActivity" msgid="464970041740567970">"一律執行應用程式"</string>
@@ -445,40 +445,40 @@
     <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"允許應用程式傳送在廣播結束後仍繼續存在的記憶廣播。過度使用可能會促使平板電腦過度使用記憶體,因而拖慢速度或造成不穩定。"</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"允許應用程式傳送置頂廣播,並在廣播結束後仍然繼續。過度使用會佔用大量記憶體,可能會令 Android TV 減慢運行速度或無法穩定運行。"</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"允許應用程式傳送在廣播結束後仍繼續存在的記憶廣播。過度使用可能會促使手機過度使用記憶體,因而拖慢運行速度或造成不穩定。"</string>
-    <string name="permlab_readContacts" msgid="8776395111787429099">"讀取您的通訊錄"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"允許應用程式讀取儲存在平板電腦上的聯絡人資料。應用程式亦可存取平板電腦上已建立聯絡人的帳戶,其中可能包括已安裝應用程式所建立的帳戶。這項權限允許應用程式儲存您的聯絡人資料,而惡意應用程式也可能在您不知情時擅自共用聯絡資料。"</string>
-    <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"允許應用程式讀取儲存在 Android TV 裝置上的聯絡人資料。應用程式亦可存取 Android TV 裝置上已建立聯絡人的帳戶,其中可能包括已安裝應用程式所建立的帳戶。這項權限允許應用程式儲存您的聯絡人資料,而惡意應用程式也可能在您不知情時擅自共用聯絡資料。"</string>
-    <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"允許應用程式讀取儲存在手機上的聯絡人資料。應用程式亦可存取手機上已建立聯絡人的帳戶,其中可能包括已安裝應用程式所建立的帳戶。這項權限允許應用程式儲存您的聯絡人資料,而惡意應用程式也可能在您不知情時擅自共用聯絡資料。"</string>
-    <string name="permlab_writeContacts" msgid="8919430536404830430">"修改您的通訊錄"</string>
+    <string name="permlab_readContacts" msgid="8776395111787429099">"讀取你的通訊錄"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"允許應用程式讀取儲存在平板電腦上的聯絡人資料。應用程式亦可存取平板電腦上已建立聯絡人的帳戶,其中可能包括已安裝應用程式所建立的帳戶。這項權限允許應用程式儲存你的聯絡人資料,而惡意應用程式也可能在你不知情時擅自共用聯絡資料。"</string>
+    <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"允許應用程式讀取儲存在 Android TV 裝置上的聯絡人資料。應用程式亦可存取 Android TV 裝置上已建立聯絡人的帳戶,其中可能包括已安裝應用程式所建立的帳戶。這項權限允許應用程式儲存你的聯絡人資料,而惡意應用程式也可能在你不知情時擅自共用聯絡資料。"</string>
+    <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"允許應用程式讀取儲存在手機上的聯絡人資料。應用程式亦可存取手機上已建立聯絡人的帳戶,其中可能包括已安裝應用程式所建立的帳戶。這項權限允許應用程式儲存你的聯絡人資料,而惡意應用程式也可能在你不知情時擅自共用聯絡資料。"</string>
+    <string name="permlab_writeContacts" msgid="8919430536404830430">"修改你的通訊錄"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"允許應用程式修改儲存在平板電腦上的聯絡人資料。這項權限允許應用程式刪除聯絡人資料。"</string>
     <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"允許應用程式修改儲存在 Android TV 裝置上的聯絡人資料。這項權限允許應用程式刪除聯絡人資料。"</string>
     <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"允許應用程式修改儲存在手機上的聯絡人資料。這項權限允許應用程式刪除聯絡人資料。"</string>
     <string name="permlab_readCallLog" msgid="1739990210293505948">"讀取通話記錄"</string>
-    <string name="permdesc_readCallLog" msgid="8964770895425873433">"此應用程式可以讀取您的通話記錄。"</string>
+    <string name="permdesc_readCallLog" msgid="8964770895425873433">"此應用程式可以讀取你的通話記錄。"</string>
     <string name="permlab_writeCallLog" msgid="670292975137658895">"寫入通話記錄"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"允許應用程式修改平板電腦的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改您的通話記錄。"</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"允許應用程式修改 Android TV 裝置的通話記錄,包括來電和撥出電話的相關資料。惡意應用程式可能會藉此清除或修改您的通話記錄。"</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"允許應用程式修改手機的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改您的通話記錄。"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"允許應用程式修改平板電腦的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改你的通話記錄。"</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"允許應用程式修改 Android TV 裝置的通話記錄,包括來電和撥出電話的相關資料。惡意應用程式可能會藉此清除或修改你的通話記錄。"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"允許應用程式修改手機的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改你的通話記錄。"</string>
     <string name="permlab_bodySensors" msgid="662918578601619569">"在使用時存取人體感應器資料,例如心率"</string>
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允許應用程式在使用時存取人體感應器資料,例如心率、體溫、血氧百分比等。"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在背景執行時存取人體感應器資料,例如心率"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允許應用程式在背景執行時存取人體感應器資料,例如心率、體溫、血氧百分比等。"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"讀取日曆活動和詳情"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"此應用程式可以讀取所有儲存在您的平板電腦的日曆活動,並分享或儲存您的日曆資料。"</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"此應用程式可以讀取所有儲存在 Android TV 裝置上的日曆活動,並分享或儲存您的日曆資料。"</string>
-    <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"此應用程式可以讀取所有儲存在您的手機中的日曆活動,並分享或儲存您的日曆資料。"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"此應用程式可以讀取所有儲存在你的平板電腦的日曆活動,並分享或儲存你的日曆資料。"</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"此應用程式可以讀取所有儲存在 Android TV 裝置上的日曆活動,並分享或儲存你的日曆資料。"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"此應用程式可以讀取所有儲存在你的手機中的日曆活動,並分享或儲存你的日曆資料。"</string>
     <string name="permlab_writeCalendar" msgid="6422137308329578076">"在機主不知情下,新增或修改日曆活動,以及發送電郵給嘉賓"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"此應用程式可以加入、移除或變更您的平板電腦中的日曆活動。此應用程式可以傳送看似來自日曆擁有者的訊息,或變更活動而不通知其擁有者。"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"此應用程式可以加入、移除或變更你的平板電腦中的日曆活動。此應用程式可以傳送看似來自日曆擁有者的訊息,或變更活動而不通知其擁有者。"</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"此應用程式可以加入、移除或變更 Android TV 裝置中的日曆活動。此應用程式可以傳送看似來自日曆擁有者的訊息,或變更活動而不通知其擁有者。"</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"此應用程式可以加入、移除或變更您的手機中的日曆活動。此應用程式可以傳送看似來自日曆擁有者的訊息,或變更活動而不通知其擁有者。"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"此應用程式可以加入、移除或變更你的手機中的日曆活動。此應用程式可以傳送看似來自日曆擁有者的訊息,或變更活動而不通知其擁有者。"</string>
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"接收額外的位置提供者指令"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"允許應用程式存取額外的位置提供者指令。這項設定可能會使應用程式干擾 GPS 或其他位置來源的運作。"</string>
     <string name="permlab_accessFineLocation" msgid="6426318438195622966">"只在前景存取精確位置"</string>
-    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"使用此應用程式時,應用程式可透過定位服務獲取您的精確位置。您的裝置必須開啟定位服務,才能讓應用程式獲取位置。這可能會增加電池用量。"</string>
+    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"使用此應用程式時,應用程式可透過定位服務獲取你的精確位置。你的裝置必須開啟定位服務,才能讓應用程式獲取位置。這可能會增加電池用量。"</string>
     <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"只在前景存取概略位置"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"使用此應用程式時,應用程式可透過定位服務獲取您的概略位置。您的裝置必須開啟定位服務,才能讓應用程式獲取位置。"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"使用此應用程式時,應用程式可透過定位服務獲取你的概略位置。你的裝置必須開啟定位服務,才能讓應用程式獲取位置。"</string>
     <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"在背景存取位置資訊"</string>
-    <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"即使您不使用此應用程式,它仍可隨時存取位置。"</string>
+    <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"即使你不使用此應用程式,它仍可隨時存取位置。"</string>
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"更改音效設定"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"允許應用程式修改全域音頻設定,例如音量和用於輸出的喇叭。"</string>
     <string name="permlab_recordAudio" msgid="1208457423054219147">"錄音"</string>
@@ -490,7 +490,7 @@
     <string name="permlab_sim_communication" msgid="176788115994050692">"發送指令至 SIM 卡"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"允許應用程式傳送指令到 SIM 卡。這項操作具有高危險性。"</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"識別體能活動"</string>
-    <string name="permdesc_activityRecognition" msgid="8667484762991357519">"此應用程式可識別您的體能活動。"</string>
+    <string name="permdesc_activityRecognition" msgid="8667484762991357519">"此應用程式可識別你的體能活動。"</string>
     <string name="permlab_camera" msgid="6320282492904119413">"拍照和拍攝影片"</string>
     <string name="permdesc_camera" msgid="5240801376168647151">"此應用程式在使用期間可使用相機拍照及錄影。"</string>
     <string name="permlab_backgroundCamera" msgid="7549917926079731681">"在背景拍照及錄影"</string>
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"允許應用程式控制震動。"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"允許應用程式存取震動狀態。"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"直接撥打電話號碼"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"允許應用程式繞過您自行撥打電話號碼,但可能會產生未預期的費用或撥打未預期的電話。注意:這項權限不允許應用程式撥打緊急電話。惡意應用程式可能未經您確認擅自撥打電話,增加您的支出。"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"使用 IMS 通話服務"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"允許應用程式自行使用 IMS 服務撥打電話。"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"讀取手機狀態和識別碼"</string>
@@ -541,9 +542,9 @@
     <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"允許應用程式變更 Android TV 裝置的時區。"</string>
     <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"允許應用程式更改手機的時區。"</string>
     <string name="permlab_getAccounts" msgid="5304317160463582791">"找出裝置上的帳戶"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"允許應用程式取得平板電腦已知的帳戶清單,其中可能包括您安裝的應用程式所建立的任何帳戶。"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"允許應用程式取得平板電腦已知的帳戶清單,其中可能包括你安裝的應用程式所建立的任何帳戶。"</string>
     <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"允許應用程式取得 Android TV 裝置已知的帳戶清單,其中可能包括已安裝應用程式所建立的任何帳戶。"</string>
-    <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"允許應用程式取得手機已知的帳戶清單,其中可能包括您安裝的應用程式所建立的任何帳戶。"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"允許應用程式取得手機已知的帳戶清單,其中可能包括你安裝的應用程式所建立的任何帳戶。"</string>
     <string name="permlab_accessNetworkState" msgid="2349126720783633918">"查看網絡連線"</string>
     <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"允許應用程式查看網絡連線相關資訊,例如有哪些網絡和已連接哪些網絡。"</string>
     <string name="permlab_createNetworkSockets" msgid="3224420491603590541">"擁有全面網絡存取權"</string>
@@ -557,9 +558,9 @@
     <string name="permlab_changeWifiState" msgid="7947824109713181554">"與 Wi-Fi 網絡建立和中斷連線"</string>
     <string name="permdesc_changeWifiState" msgid="7170350070554505384">"允許應用程式建立或中斷與 Wi-Fi 接入點的連線,並可更改 Wi-Fi 網絡的裝置設定。"</string>
     <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"允許接收 Wi-Fi 多點傳播封包"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"允許應用程式接收透過多點傳播位址傳送給 Wi-Fi 網絡上所有裝置 (而不只是傳送給您的平板電腦) 的封包。這樣會比非多點傳播模式耗用更多電力。"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"允許應用程式接收由多點傳播位址向 Wi-Fi 網絡上所有裝置 (不只限於您的 Android TV 裝置) 傳送的數據包。這樣會比非多點傳播模式消耗更多電力。"</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"允許應用程式接收透過多點傳播位址傳送給 Wi-Fi 網絡上所有裝置 (而不只是傳送給您的手機) 的封包。這樣會比非多點傳播模式耗用更多電力。"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"允許應用程式接收透過多點傳播位址傳送給 Wi-Fi 網絡上所有裝置 (而不只是傳送給你的平板電腦) 的封包。這樣會比非多點傳播模式耗用更多電力。"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"允許應用程式接收由多點傳播位址向 Wi-Fi 網絡上所有裝置 (不只限於你的 Android TV 裝置) 傳送的數據包。這樣會比非多點傳播模式消耗更多電力。"</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"允許應用程式接收透過多點傳播位址傳送給 Wi-Fi 網絡上所有裝置 (而不只是傳送給你的手機) 的封包。這樣會比非多點傳播模式耗用更多電力。"</string>
     <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"存取藍牙設定"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"允許應用程式設定本機藍牙平板電腦,以及與偵測到的遠端裝置配對。"</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"允許應用程式設定 Android TV 裝置上的藍牙,以及與偵測到的遙距裝置配對。"</string>
@@ -602,12 +603,12 @@
     <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"允許應用程式調用加入和刪除指紋模板的方法以供使用。"</string>
     <string name="permlab_useFingerprint" msgid="1001421069766751922">"使用指紋硬件"</string>
     <string name="permdesc_useFingerprint" msgid="412463055059323742">"允許應用程式使用指紋硬件驗證"</string>
-    <string name="permlab_audioWrite" msgid="8501705294265669405">"修改您的音樂收藏"</string>
-    <string name="permdesc_audioWrite" msgid="8057399517013412431">"允許應用程式修改您的音樂收藏。"</string>
-    <string name="permlab_videoWrite" msgid="5940738769586451318">"修改您的影片集"</string>
-    <string name="permdesc_videoWrite" msgid="6124731210613317051">"允許應用程式修改您的影片集。"</string>
-    <string name="permlab_imagesWrite" msgid="1774555086984985578">"修改您的相片集"</string>
-    <string name="permdesc_imagesWrite" msgid="5195054463269193317">"允許應用程式修改您的相片集。"</string>
+    <string name="permlab_audioWrite" msgid="8501705294265669405">"修改你的音樂收藏"</string>
+    <string name="permdesc_audioWrite" msgid="8057399517013412431">"允許應用程式修改你的音樂收藏。"</string>
+    <string name="permlab_videoWrite" msgid="5940738769586451318">"修改你的影片集"</string>
+    <string name="permdesc_videoWrite" msgid="6124731210613317051">"允許應用程式修改你的影片集。"</string>
+    <string name="permlab_imagesWrite" msgid="1774555086984985578">"修改你的相片集"</string>
+    <string name="permdesc_imagesWrite" msgid="5195054463269193317">"允許應用程式修改你的相片集。"</string>
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"讀取媒體集的位置"</string>
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"允許應用程式讀取媒體集的位置。"</string>
     <string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物識別"</string>
@@ -657,7 +658,7 @@
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
-    <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"請使用您的指紋繼續"</string>
+    <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"請使用你的指紋繼續"</string>
     <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"請使用指紋解鎖或螢幕鎖定功能驗證身分,才能繼續操作"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -699,8 +700,8 @@
     <!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"無法建立面部模型,請再試一次。"</string>
-    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"偵測到深色眼鏡。您必須展示整個面孔。"</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"偵測到面部遮蓋物。您必須展示整個面孔。"</string>
+    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"偵測到深色眼鏡。你必須展示整個面孔。"</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"偵測到面部遮蓋物。你必須展示整個面孔。"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"無法驗證面孔,硬件無法使用。"</string>
@@ -709,17 +710,16 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"面孔操作已取消。"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"使用者已取消「面孔解鎖」"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"嘗試次數過多,請稍後再試。"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"嘗試次數過多,無法使用面孔解鎖。"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"嘗試次數過多,請改為解除螢幕鎖定來驗證身分。"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"無法驗證面孔。請再試一次。"</string>
-    <string name="face_error_not_enrolled" msgid="1134739108536328412">"您尚未設定「面孔解鎖」"</string>
+    <string name="face_error_not_enrolled" msgid="1134739108536328412">"你尚未設定「面孔解鎖」"</string>
     <string name="face_error_hw_not_present" msgid="7940978724978763011">"此裝置不支援「面孔解鎖」"</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"感應器已暫時停用。"</string>
     <string name="face_name_template" msgid="3877037340223318119">"面孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
     <string name="face_app_setting_name" msgid="5854024256907828015">"使用「面孔解鎖」"</string>
     <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用面孔或螢幕鎖定"</string>
-    <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"如要繼續操作,請使用您的面孔驗證身分"</string>
+    <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"如要繼續操作,請使用你的面孔驗證身分"</string>
     <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"請使用面孔解鎖或螢幕鎖定功能驗證身分,才能繼續操作"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -731,8 +731,8 @@
     <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"允許應用程式修改帳戶的同步設定,例如讓「通訊錄」應用程式與某個帳戶保持同步。"</string>
     <string name="permlab_readSyncStats" msgid="3747407238320105332">"讀取同步處理統計資料"</string>
     <string name="permdesc_readSyncStats" msgid="3867809926567379434">"允許應用程式讀取帳戶的同步統計資料,包括同步活動記錄,以及保持同步的資料量。"</string>
-    <string name="permlab_sdcardRead" msgid="5791467020950064920">"讀取您共用儲存空間的內容"</string>
-    <string name="permdesc_sdcardRead" msgid="6872973242228240382">"允許應用程式讀取您共用儲存空間的內容。"</string>
+    <string name="permlab_sdcardRead" msgid="5791467020950064920">"讀取你共用儲存空間的內容"</string>
+    <string name="permdesc_sdcardRead" msgid="6872973242228240382">"允許應用程式讀取你共用儲存空間的內容。"</string>
     <string name="permlab_readMediaAudio" msgid="8723513075731763810">"讀取共用儲存空間中的音訊檔案"</string>
     <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"允許應用程式讀取共用儲存空間中的音訊檔案。"</string>
     <string name="permlab_readMediaVideo" msgid="7768003311260655007">"讀取共用儲存空間中的影片檔案"</string>
@@ -740,9 +740,9 @@
     <string name="permlab_readMediaImages" msgid="4057590631020986789">"讀取共用儲存空間中的圖片檔案"</string>
     <string name="permdesc_readMediaImages" msgid="5836219373138469259">"允許應用程式讀取共用儲存空間中的圖片檔案。"</string>
     <string name="permlab_readVisualUserSelect" msgid="5516204215354667586">"讀取使用者在共用儲存空間中選取的圖片和影片檔案"</string>
-    <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"允許應用程式讀取您在共用儲存空間中選取的圖片和影片檔案。"</string>
-    <string name="permlab_sdcardWrite" msgid="4863021819671416668">"修改或刪除您共用儲存空間的內容"</string>
-    <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"允許應用程式寫入您共用儲存空間的內容。"</string>
+    <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"允許應用程式讀取你在共用儲存空間中選取的圖片和影片檔案。"</string>
+    <string name="permlab_sdcardWrite" msgid="4863021819671416668">"修改或刪除你共用儲存空間的內容"</string>
+    <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"允許應用程式寫入你共用儲存空間的內容。"</string>
     <string name="permlab_use_sip" msgid="8250774565189337477">"撥打/接聽 SIP 電話"</string>
     <string name="permdesc_use_sip" msgid="3590270893253204451">"允許應用程式撥打及接聽 SIP 電話。"</string>
     <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"註冊新的電訊 SIM 卡連接"</string>
@@ -986,24 +986,24 @@
     <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"停止"</string>
     <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"倒帶"</string>
     <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"向前快轉"</string>
-    <string name="emergency_calls_only" msgid="3057351206678279851">"只可撥打緊急電話"</string>
+    <string name="emergency_calls_only" msgid="3057351206678279851">"只可致電緊急電話"</string>
     <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"網絡已鎖定"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="2867953953604224166">"SIM 卡已使用 PUK 鎖定。"</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"請參閱使用者指南或與客戶服務中心聯絡。"</string>
     <string name="lockscreen_sim_locked_message" msgid="5911944931911850164">"SIM 卡已鎖定。"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"正在解鎖 SIM 卡…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用 Google 登入資料將 Android TV 裝置解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"您嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,平板電腦將恢復原廠設定,所有使用者資料均會遺失。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"您嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,手機將恢復原廠設定,所有使用者資料均會遺失。"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"您嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。平板電腦現在會重設為原廠預設值。"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次無法解鎖 Android TV 裝置,Android TV 裝置現在將回復原廠設定。"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"您嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。手機現在會重設為原廠預設值。"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"你已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"你已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你使用你的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你使用 Google 登入資料將 Android TV 裝置解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你使用你的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"你嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,平板電腦將恢復原廠設定,所有使用者資料均會遺失。"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"你已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"你嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,手機將恢復原廠設定,所有使用者資料均會遺失。"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"你嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。平板電腦現在會重設為原廠預設值。"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"你已 <xliff:g id="NUMBER">%d</xliff:g> 次無法解鎖 Android TV 裝置,Android TV 裝置現在將回復原廠設定。"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"你嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。手機現在會重設為原廠預設值。"</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"<xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"忘記圖案?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"帳戶解鎖"</string>
@@ -1063,12 +1063,12 @@
     <string name="js_dialog_before_unload_title" msgid="7012587995876771246">"確認瀏覽"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"離開這一頁"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"停留在這一頁"</string>
-    <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\n您確定要離開這個網頁嗎?"</string>
+    <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\n你確定要離開這個網頁嗎?"</string>
     <string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> 的自動填入功能"</string>
     <string name="permlab_setAlarm" msgid="1158001610254173567">"設定鬧鐘"</string>
     <string name="permdesc_setAlarm" msgid="2185033720060109640">"允許應用程式在安裝的鬧鐘應用程式中設定鬧鐘,某些鬧鐘應用程式可能沒有這項功能。"</string>
     <string name="permlab_addVoicemail" msgid="4770245808840814471">"新增留言"</string>
-    <string name="permdesc_addVoicemail" msgid="5470312139820074324">"允許應用程式將訊息加到您的留言信箱收件箱。"</string>
+    <string name="permdesc_addVoicemail" msgid="5470312139820074324">"允許應用程式將訊息加到你的留言信箱收件箱。"</string>
     <string name="pasted_from_clipboard" msgid="7355790625710831847">"「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」已貼上剪貼簿內容"</string>
     <string name="more_item_label" msgid="7419249600215749115">"更多"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"選單鍵 +"</string>
@@ -1089,8 +1089,8 @@
     <string name="searchview_description_submit" msgid="6771060386117334686">"提交查詢"</string>
     <string name="searchview_description_voice" msgid="42360159504884679">"語音搜尋"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"啟用輕觸探索?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> 需要啟用「輕觸探索」。開啟這項功能時,系統會在您的手指輕觸螢幕上的物件時顯示或朗讀說明,您也可以執行手勢來與平板電腦互動。"</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> 需要啟用「輕觸探索」。開啟這項功能時,系統會在您的手指輕觸螢幕上的物件時顯示或朗讀說明,您也可以執行手勢來與手機互動。"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> 需要啟用「輕觸探索」。開啟這項功能時,系統會在你的手指輕觸螢幕上的物件時顯示或朗讀說明,你也可以執行手勢來與平板電腦互動。"</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> 需要啟用「輕觸探索」。開啟這項功能時,系統會在你的手指輕觸螢幕上的物件時顯示或朗讀說明,你也可以執行手勢來與手機互動。"</string>
     <string name="oneMonthDurationPast" msgid="4538030857114635777">"1 個月前"</string>
     <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"1 個月前"</string>
     <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{過去 # 天}other{過去 # 天}}"</string>
@@ -1228,7 +1228,7 @@
     <string name="force_close" msgid="9035203496368973803">"確定"</string>
     <string name="report" msgid="2149194372340349521">"報告"</string>
     <string name="wait" msgid="7765985809494033348">"等待"</string>
-    <string name="webpage_unresponsive" msgid="7850879412195273433">"網頁沒有反應。 \n \n您要關閉嗎?"</string>
+    <string name="webpage_unresponsive" msgid="7850879412195273433">"網頁沒有反應。 \n \n你要關閉嗎?"</string>
     <string name="launch_warning_title" msgid="6725456009564953595">"應用程式已重新導向"</string>
     <string name="launch_warning_replace" msgid="3073392976283203402">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」現在正在執行。"</string>
     <string name="launch_warning_original" msgid="3332206576800169626">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」原先已啟動。"</string>
@@ -1237,7 +1237,7 @@
     <string name="screen_compat_mode_hint" msgid="4032272159093750908">"前往 [系統設定] &gt; [應用程式] &gt; [下載] 重新啟用這個模式。"</string>
     <string name="unsupported_display_size_message" msgid="7265211375269394699">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援目前的「螢幕」尺寸設定,畫面可能無法如預期顯示。"</string>
     <string name="unsupported_display_size_show" msgid="980129850974919375">"永遠顯示"</string>
-    <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」是專為不兼容 Android OS 版本所打造的應用程式,因此可能無法正常運作。您可能可以使用該應用程式的更新版本。"</string>
+    <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」是專為不兼容 Android OS 版本所打造的應用程式,因此可能無法正常運作。你可能可以使用該應用程式的更新版本。"</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"一律顯示"</string>
     <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"檢查更新"</string>
     <string name="smv_application" msgid="3775183542777792638">"應用程式 <xliff:g id="APPLICATION">%1$s</xliff:g> (處理程序 <xliff:g id="PROCESS">%2$s</xliff:g>) 已違反其自行強制實施的嚴格模式 (StrictMode) 政策。"</string>
@@ -1254,11 +1254,11 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"正在準備 <xliff:g id="APPNAME">%1$s</xliff:g>。"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"正在啟動應用程式。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"啟動完成。"</string>
-    <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"您已按下開關按鈕,這麼做通常會關閉螢幕。\n\n設定指紋時請嘗試輕按開關按鈕。"</string>
+    <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"你已按下開關按鈕,這麼做通常會關閉螢幕。\n\n設定指紋時請嘗試輕按開關按鈕。"</string>
     <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"如要結束設定,請關閉螢幕"</string>
     <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"關閉"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"要繼續驗證指紋嗎?"</string>
-    <string name="fp_power_button_bp_message" msgid="2983163038168903393">"您已按下開關按鈕,這麼做通常會關閉螢幕。\n\n嘗試輕按開關按鈕以驗證指紋。"</string>
+    <string name="fp_power_button_bp_message" msgid="2983163038168903393">"你已按下開關按鈕,這麼做通常會關閉螢幕。\n\n嘗試輕按開關按鈕以驗證指紋。"</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"關閉螢幕"</string>
     <string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"繼續"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"正在執行 <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -1272,9 +1272,9 @@
     <string name="dump_heap_ready_notification" msgid="2302452262927390268">"<xliff:g id="PROC">%1$s</xliff:g> 堆轉儲已準備就緒"</string>
     <string name="dump_heap_notification_detail" msgid="8431586843001054050">"已收集堆轉儲,輕按即可分享。"</string>
     <string name="dump_heap_title" msgid="4367128917229233901">"分享堆轉儲?"</string>
-    <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g> 處理程序的記憶體用量已超過上限 (<xliff:g id="SIZE">%2$s</xliff:g>),您可以將堆轉儲分享給相關開發人員。請注意:此堆轉儲可包含應用程式能夠存取您的任何個人資料。"</string>
-    <string name="dump_heap_system_text" msgid="6805155514925350849">"<xliff:g id="PROC">%1$s</xliff:g>處理程序的記憶體用量已超出上限 (<xliff:g id="SIZE">%2$s</xliff:g>),您可以分享已收集的堆轉儲。請注意:此堆轉儲或會包含該處理程序有權存取的任何敏感個人資料,當中可能包括您所輸入的內容。"</string>
-    <string name="dump_heap_ready_text" msgid="5849618132123045516">"您可以分享 <xliff:g id="PROC">%1$s</xliff:g> 處理程序的堆轉儲。請注意:此堆轉儲或會包含該處理程序有權存取的任何敏感個人資料,當中可能包括您所輸入的內容。"</string>
+    <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g> 處理程序的記憶體用量已超過上限 (<xliff:g id="SIZE">%2$s</xliff:g>),你可以將堆轉儲分享給相關開發人員。請注意:此堆轉儲可包含應用程式能夠存取你的任何個人資料。"</string>
+    <string name="dump_heap_system_text" msgid="6805155514925350849">"<xliff:g id="PROC">%1$s</xliff:g>處理程序的記憶體用量已超出上限 (<xliff:g id="SIZE">%2$s</xliff:g>),你可以分享已收集的堆轉儲。請注意:此堆轉儲或會包含該處理程序有權存取的任何敏感個人資料,當中可能包括你所輸入的內容。"</string>
+    <string name="dump_heap_ready_text" msgid="5849618132123045516">"你可以分享 <xliff:g id="PROC">%1$s</xliff:g> 處理程序的堆轉儲。請注意:此堆轉儲或會包含該處理程序有權存取的任何敏感個人資料,當中可能包括你所輸入的內容。"</string>
     <string name="sendText" msgid="493003724401350724">"選擇處理文字的操作"</string>
     <string name="volume_ringtone" msgid="134784084629229029">"鈴聲音量"</string>
     <string name="volume_music" msgid="7727274216734955095">"媒體音量"</string>
@@ -1323,20 +1323,20 @@
     <string name="decline" msgid="6490507610282145874">"拒絕"</string>
     <string name="select_character" msgid="3352797107930786979">"插入字元"</string>
     <string name="sms_control_title" msgid="4748684259903148341">"正在傳送 SMS 短訊"</string>
-    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;/b&gt;正在傳送大量短訊。您要允許這個應用程式繼續傳送短訊嗎?"</string>
+    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;/b&gt;正在傳送大量短訊。你要允許這個應用程式繼續傳送短訊嗎?"</string>
     <string name="sms_control_yes" msgid="4858845109269524622">"允許"</string>
     <string name="sms_control_no" msgid="4845717880040355570">"拒絕"</string>
     <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; 要求將訊息傳送至 &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;。"</string>
-    <string name="sms_short_code_details" msgid="2723725738333388351">"您的流動服務帳戶"<b>"可能因此繳付費用"</b>"。"</string>
-    <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"您的流動服務帳戶將因此繳付費用。"</b></string>
+    <string name="sms_short_code_details" msgid="2723725738333388351">"你的流動服務帳戶"<b>"可能因此繳付費用"</b>"。"</string>
+    <string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>"你的流動服務帳戶將因此繳付費用。"</b></string>
     <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"發送"</string>
     <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"取消"</string>
     <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"記住我的選擇"</string>
-    <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"您日後可以在 [設定] &gt; [應用程式] 中更改這項設定"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"你日後可以在 [設定] &gt; [應用程式] 中更改這項設定"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"一律允許"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"絕不允許"</string>
     <string name="sim_removed_title" msgid="1349026474932481037">"已移除 SIM 卡"</string>
-    <string name="sim_removed_message" msgid="8469588437451533845">"您必須重新啟動並新增有效的 SIM 卡,才能使用流動網絡。"</string>
+    <string name="sim_removed_message" msgid="8469588437451533845">"你必須重新啟動並新增有效的 SIM 卡,才能使用流動網絡。"</string>
     <string name="sim_done_button" msgid="6464250841528410598">"完成"</string>
     <string name="sim_added_title" msgid="2976783426741012468">"已新增 SIM 卡"</string>
     <string name="sim_added_message" msgid="6602906609509958680">"重新啟動裝置,才能使用流動網絡。"</string>
@@ -1387,7 +1387,7 @@
     <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"正在取得錯誤報告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"要分享錯誤報告嗎?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"正在分享錯誤報告…"</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"您的管理員要求您提供錯誤報告,以協助解決此裝置的問題。報告可能包含應用程式和相關資料。"</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"你的管理員要求你提供錯誤報告,以協助解決此裝置的問題。報告可能包含應用程式和相關資料。"</string>
     <string name="share_remote_bugreport_action" msgid="7630880678785123682">"分享"</string>
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"拒絕"</string>
     <string name="select_input_method" msgid="3971267998568587025">"選擇輸入法"</string>
@@ -1401,7 +1401,7 @@
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"顯示在其他應用程式上層"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"「<xliff:g id="NAME">%s</xliff:g>」目前可顯示在其他應用程式上面"</string>
     <string name="alert_windows_notification_title" msgid="6331662751095228536">"「<xliff:g id="NAME">%s</xliff:g>」正在其他應用程式上顯示內容"</string>
-    <string name="alert_windows_notification_message" msgid="6538171456970725333">"如果您不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string>
+    <string name="alert_windows_notification_message" msgid="6538171456970725333">"如果你不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string>
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"關閉"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"正在檢查 <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"正在檢查目前的內容"</string>
@@ -1410,19 +1410,19 @@
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"「<xliff:g id="NAME">%s</xliff:g>」無法運作"</string>
     <string name="ext_media_new_notification_message" msgid="6095403121990786986">"輕按即可設定"</string>
     <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"選取即可設定"</string>
-    <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"您可能需要將裝置重新格式化。輕按即可退出。"</string>
+    <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"你可能需要將裝置重新格式化。輕按即可退出。"</string>
     <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"用於儲存相片、影片、音樂等"</string>
     <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"瀏覽媒體檔案"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"<xliff:g id="NAME">%s</xliff:g>發生問題"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"「<xliff:g id="NAME">%s</xliff:g>」無法運作"</string>
     <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"輕按即可修正問題"</string>
     <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"<xliff:g id="NAME">%s</xliff:g>已損毀。選取即可修正。"</string>
-    <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"您可能需要將裝置重新格式化。輕按即可退出。"</string>
+    <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"你可能需要將裝置重新格式化。輕按即可退出。"</string>
     <string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"已偵測到「<xliff:g id="NAME">%s</xliff:g>」"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"「<xliff:g id="NAME">%s</xliff:g>」無法運作"</string>
     <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"輕按即可設定。"</string>
     <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"選取即可使用支援的格式設定 <xliff:g id="NAME">%s</xliff:g>。"</string>
-    <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"您可能需要將裝置重新格式化"</string>
+    <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"你可能需要將裝置重新格式化"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g>被意外移除"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"請先退出媒體,再將其移除,以免內容遺失。"</string>
     <string name="ext_media_nomedia_notification_title" msgid="742671636376975890">"已移除 <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1476,16 +1476,16 @@
     <string name="ime_action_default" msgid="8265027027659800121">"執行"</string>
     <string name="dial_number_using" msgid="6060769078933953531">"使用 <xliff:g id="NUMBER">%s</xliff:g>\n 撥號"</string>
     <string name="create_contact_using" msgid="6200708808003692594">"建立號碼為 <xliff:g id="NUMBER">%s</xliff:g>\n的聯絡人"</string>
-    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"下列一個或多個應用程式要求授予現在和今後存取您帳戶的權限。"</string>
-    <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"您要允許這個要求嗎?"</string>
+    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"下列一個或多個應用程式要求授予現在和今後存取你帳戶的權限。"</string>
+    <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"你要允許這個要求嗎?"</string>
     <string name="grant_permissions_header_text" msgid="3420736827804657201">"存取權要求"</string>
     <string name="allow" msgid="6195617008611933762">"允許"</string>
     <string name="deny" msgid="6632259981847676572">"拒絕"</string>
     <string name="permission_request_notification_title" msgid="1810025922441048273">"已要求權限"</string>
     <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"<xliff:g id="ACCOUNT">%s</xliff:g> 帳戶的\n權限要求。"</string>
     <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"「<xliff:g id="APP">%1$s</xliff:g>」要求帳戶 <xliff:g id="ACCOUNT">%2$s</xliff:g>\n的權限"</string>
-    <string name="forward_intent_to_owner" msgid="4620359037192871015">"您目前並未透過公司檔案使用這個應用程式"</string>
-    <string name="forward_intent_to_work" msgid="3620262405636021151">"您目前透過公司檔案使用這個應用程式"</string>
+    <string name="forward_intent_to_owner" msgid="4620359037192871015">"你目前並未透過公司檔案使用這個應用程式"</string>
+    <string name="forward_intent_to_work" msgid="3620262405636021151">"你目前透過公司檔案使用這個應用程式"</string>
     <string name="input_method_binding_label" msgid="1166731601721983656">"輸入法"</string>
     <string name="sync_binding_label" msgid="469249309424662147">"同步處理"</string>
     <string name="accessibility_binding_label" msgid="1974602776545801715">"無障礙功能"</string>
@@ -1529,7 +1529,7 @@
     <string name="gpsVerifYes" msgid="3719843080744112940">"是"</string>
     <string name="gpsVerifNo" msgid="1671201856091564741">"否"</string>
     <string name="sync_too_many_deletes" msgid="6999440774578705300">"已超過刪除上限"</string>
-    <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"帳戶 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 的 <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> 操作會刪除 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 項。您要如何處理呢?"</string>
+    <string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"帳戶 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 的 <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> 操作會刪除 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 項。你要如何處理呢?"</string>
     <string name="sync_really_delete" msgid="5657871730315579051">"刪除這些項目"</string>
     <string name="sync_undo_deletes" msgid="5786033331266418896">"復原刪除"</string>
     <string name="sync_do_nothing" msgid="4528734662446469646">"暫不執行"</string>
@@ -1580,17 +1580,17 @@
     <string name="storage_usb" msgid="2391213347883616886">"USB 儲存裝置"</string>
     <string name="extract_edit_menu_button" msgid="63954536535863040">"編輯"</string>
     <string name="data_usage_warning_title" msgid="9034893717078325845">"數據用量警告"</string>
-    <string name="data_usage_warning_body" msgid="1669325367188029454">"您已使用 <xliff:g id="APP">%s</xliff:g> 流動數據"</string>
+    <string name="data_usage_warning_body" msgid="1669325367188029454">"你已使用 <xliff:g id="APP">%s</xliff:g> 流動數據"</string>
     <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"已達流動數據用量上限"</string>
     <string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"已達到 Wi-Fi 數據流量上限"</string>
     <string name="data_usage_limit_body" msgid="3567699582000085710">"已暫停使用數據連線,直至此週期結束為止"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"已超過流動數據用量上限"</string>
-    <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"已超出您的 Wi-Fi 數據用量上限"</string>
-    <string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"您已比設定上限使用多 <xliff:g id="SIZE">%s</xliff:g>"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"已超出你的 Wi-Fi 數據用量上限"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"你已比設定上限使用多 <xliff:g id="SIZE">%s</xliff:g>"</string>
     <string name="data_usage_restricted_title" msgid="126711424380051268">"已限制背景資料"</string>
     <string name="data_usage_restricted_body" msgid="5338694433686077733">"輕按即可移除限制。"</string>
     <string name="data_usage_rapid_title" msgid="2950192123248740375">"高流動數據用量"</string>
-    <string name="data_usage_rapid_body" msgid="3886676853263693432">"您的應用程式數據用量比平常多"</string>
+    <string name="data_usage_rapid_body" msgid="3886676853263693432">"你的應用程式數據用量比平常多"</string>
     <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"「<xliff:g id="APP">%s</xliff:g>」的數據用量比平常多"</string>
     <string name="ssl_certificate" msgid="5690020361307261997">"安全性憑證"</string>
     <string name="ssl_certificate_is_valid" msgid="7293675884598527081">"憑證有效。"</string>
@@ -1666,42 +1666,42 @@
     <string name="kg_login_invalid_input" msgid="8292367491901220210">"無效的使用者名稱或密碼。"</string>
     <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"忘記使用者名稱或密碼?\n請瀏覽 "<b>"google.com/accounts/recovery"</b>"。"</string>
     <string name="kg_login_checking_password" msgid="4676010303243317253">"正在檢查帳戶…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"您嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有使用者資料均會失去。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"您嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,手機將回復原廠設定,所有使用者資料均會失去。"</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。平板電腦現在將回復原廠設定。"</string>
-    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次無法解鎖 Android TV 裝置,Android TV 裝置現在將回復原廠設定。"</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。手機現在將回復原廠設定。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用電郵帳戶解鎖 Android TV 裝置。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"你已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"你已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"你嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有使用者資料均會失去。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"你已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"你嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,手機將回復原廠設定,所有使用者資料均會失去。"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"你嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。平板電腦現在將回復原廠設定。"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"你已 <xliff:g id="NUMBER">%d</xliff:g> 次無法解鎖 Android TV 裝置,Android TV 裝置現在將回復原廠設定。"</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"你嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。手機現在將回復原廠設定。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你使用電郵帳戶解鎖 Android TV 裝置。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"移除"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量 (比建議的音量更大聲) 嗎?\n\n長時間聆聽高分貝音量可能會導致您的聽力受損。"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"警告:\n您於一週內使用耳機聆聽的高分貝音訊量已超過安全範圍\n\n繼續此行為將導致聽力永久受損。"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"警告:\n您於一週內使用耳機聆聽的高分貝音訊量已超過安全範圍 5 倍。\n\n為保護您的聽力,系統已調低音量。"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量 (比建議的音量更大聲) 嗎?\n\n長時間聆聽高分貝音量可能會導致你的聽力受損。"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"警告:\n你於一週內使用耳機聆聽的高分貝音訊量已超過安全範圍\n\n繼續此行為將導致聽力永久受損。"</string>
+    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"警告:\n你於一週內使用耳機聆聽的高分貝音訊量已超過安全範圍 5 倍。\n\n為保護你的聽力,系統已調低音量。"</string>
     <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"目前的媒體播放音量在長時間聆聽下可能會損害聽力。\n\n如繼續以此音量播放內容,長時間可能導致聽力受損。"</string>
     <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"警告:\n目前的內容播放音量已超過安全聆聽範圍。\n\n繼續聆聽此音量將導致聽力永久受損。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙功能快速鍵嗎?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"啟用快速鍵後,同時按住音量按鈕 3 秒便可啟用無障礙功能。"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"要開啟無障礙功能捷徑嗎?"</string>
-    <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"同時按下兩個音量鍵幾秒,以開啟無障礙功能。這可能會變更裝置的運作。\n\n目前功能:\n<xliff:g id="SERVICE">%1$s</xliff:g>\n您可在「設定」&gt;「無障礙功能」中變更所選功能。"</string>
+    <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"同時按下兩個音量鍵幾秒,以開啟無障礙功能。這可能會變更裝置的運作。\n\n目前功能:\n<xliff:g id="SERVICE">%1$s</xliff:g>\n你可在「設定」&gt;「無障礙功能」中變更所選功能。"</string>
     <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
     <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"要開啟 <xliff:g id="SERVICE">%1$s</xliff:g> 捷徑嗎?"</string>
-    <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"同時按下兩個音量鍵幾秒,以開啟 <xliff:g id="SERVICE">%1$s</xliff:g> 無障礙功能。這可能會變更裝置的運作。\n\n您可在「設定」&gt;「無障礙功能」中變更此快速鍵。"</string>
+    <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"同時按下兩個音量鍵幾秒,以開啟 <xliff:g id="SERVICE">%1$s</xliff:g> 無障礙功能。這可能會變更裝置的運作。\n\n你可在「設定」&gt;「無障礙功能」中變更此快速鍵。"</string>
     <string name="accessibility_shortcut_on" msgid="5463618449556111344">"開啟"</string>
     <string name="accessibility_shortcut_off" msgid="3651336255403648739">"不要開啟"</string>
     <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"開啟"</string>
     <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"關閉"</string>
     <string name="accessibility_enable_service_title" msgid="3931558336268541484">"要授予「<xliff:g id="SERVICE">%1$s</xliff:g>」裝置的完整控制權?"</string>
-    <string name="accessibility_service_warning_description" msgid="291674995220940133">"對於為您提供無障礙功能的應用程式,您可授予完整控制權,但大部分應用程式都不應獲授予此權限。"</string>
+    <string name="accessibility_service_warning_description" msgid="291674995220940133">"對於為你提供無障礙功能的應用程式,你可授予完整控制權,但大部分應用程式都不應獲授予此權限。"</string>
     <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"查看和控制螢幕"</string>
     <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"這項功能可以讀出螢幕上的所有內容,並透過其他應用程式顯示內容。"</string>
     <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"查看和執行動作"</string>
-    <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"這項功能會追蹤您與應用程式或硬件感應器的互動,並代表您直接與應用程式互動。"</string>
+    <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"這項功能會追蹤你與應用程式或硬件感應器的互動,並代表你直接與應用程式互動。"</string>
     <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"允許"</string>
     <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"拒絕"</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"輕按即可開始使用所需功能:"</string>
@@ -1733,7 +1733,7 @@
     <string name="owner_name" msgid="8713560351570795743">"擁有者"</string>
     <string name="guest_name" msgid="8502103277839834324">"訪客"</string>
     <string name="error_message_title" msgid="4082495589294631966">"錯誤"</string>
-    <string name="error_message_change_not_allowed" msgid="843159705042381454">"您的管理員不允許這項變更"</string>
+    <string name="error_message_change_not_allowed" msgid="843159705042381454">"你的管理員不允許這項變更"</string>
     <string name="app_not_found" msgid="3429506115332341800">"找不到處理這項操作的應用程式"</string>
     <string name="revoke" msgid="5526857743819590458">"撤銷"</string>
     <string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string>
@@ -1867,13 +1867,13 @@
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"取消固定時必須輸入 PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須提供解鎖圖案"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string>
-    <string name="package_installed_device_owner" msgid="7035926868974878525">"已由您的管理員安裝"</string>
-    <string name="package_updated_device_owner" msgid="7560272363805506941">"已由您的管理員更新"</string>
-    <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由您的管理員刪除"</string>
+    <string name="package_installed_device_owner" msgid="7035926868974878525">"已由你的管理員安裝"</string>
+    <string name="package_updated_device_owner" msgid="7560272363805506941">"已由你的管理員更新"</string>
+    <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"好"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"「慳電模式」會開啟深色主題背景,並限制或關閉背景活動、部分視覺效果、特定功能和部分網絡連線。"</string>
     <string name="battery_saver_description" msgid="8518809702138617167">"「慳電模式」會開啟深色主題背景,並限制或關閉背景活動、部分視覺效果、特定功能和部分網絡連線。"</string>
-    <string name="data_saver_description" msgid="4995164271550590517">"「數據節省模式」可防止部分應用程式在背景收發資料,以節省數據用量。您正在使用的應用程式可存取資料,但次數可能會減少。例如,圖片可能需要輕按才會顯示。"</string>
+    <string name="data_saver_description" msgid="4995164271550590517">"「數據節省模式」可防止部分應用程式在背景收發資料,以節省數據用量。你正在使用的應用程式可存取資料,但次數可能會減少。例如,圖片可能需要輕按才會顯示。"</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"要開啟「數據節省模式」嗎?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"開啟"</string>
     <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{一分鐘 (直至{formattedTime})}other{# 分鐘 (直至{formattedTime})}}"</string>
@@ -1887,8 +1887,8 @@
     <string name="zen_mode_until_next_day" msgid="1403042784161725038">"直至<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_until" msgid="2250286190237669079">"完成時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"直至<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (下一次響鬧)"</string>
-    <string name="zen_mode_forever" msgid="740585666364912448">"直至您關閉為止"</string>
-    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"直至您關閉「請勿騷擾」功能"</string>
+    <string name="zen_mode_forever" msgid="740585666364912448">"直至你關閉為止"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"直至你關閉「請勿騷擾」功能"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"收合"</string>
     <string name="zen_mode_feature_name" msgid="3785547207263754500">"請勿騷擾"</string>
@@ -1898,8 +1898,8 @@
     <string name="zen_mode_default_events_name" msgid="2280682960128512257">"活動"</string>
     <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"睡眠"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>正將某些音效設為靜音"</string>
-    <string name="system_error_wipe_data" msgid="5910572292172208493">"您裝置的系統發生問題,回復原廠設定後即可解決該問題。"</string>
-    <string name="system_error_manufacturer" msgid="703545241070116315">"您裝置的系統發生問題,請聯絡您的製造商瞭解詳情。"</string>
+    <string name="system_error_wipe_data" msgid="5910572292172208493">"你裝置的系統發生問題,回復原廠設定後即可解決該問題。"</string>
+    <string name="system_error_manufacturer" msgid="703545241070116315">"你裝置的系統發生問題,請聯絡你的製造商瞭解詳情。"</string>
     <string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"USSD 要求已變更為一般通話"</string>
     <string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"USSD 要求已變更為 SS 要求"</string>
     <string name="stk_cc_ussd_to_ussd" msgid="8343001461299302472">"已變更為新的 USSD 要求"</string>
@@ -1931,7 +1931,7 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"未分類"</string>
-    <string name="importance_from_user" msgid="2782756722448800447">"您可以設定這些通知的重要性。"</string>
+    <string name="importance_from_user" msgid="2782756722448800447">"你可以設定這些通知的重要性。"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"列為重要的原因:涉及的人。"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"自訂應用程式通知"</string>
     <string name="user_creation_account_exists" msgid="2239146360099708035">"要允許 <xliff:g id="APP">%1$s</xliff:g> 使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者 (此帳戶目前已有此使用者) 嗎?"</string>
@@ -1976,7 +1976,7 @@
     <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用手機。"</string>
     <string name="deprecated_target_sdk_message" msgid="5246906284426844596">"此應用程式專為舊版 Android 而設。因此可能無法正常運作,且不提供最新的安全性和私隱保護。請檢查是否有更新版本,或聯絡應用程式開發人員。"</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
-    <string name="new_sms_notification_title" msgid="6528758221319927107">"您有新的訊息"</string>
+    <string name="new_sms_notification_title" msgid="6528758221319927107">"你有新的訊息"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"開啟短訊應用程式查看內容"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"部分功能可能會受到限制"</string>
     <string name="profile_encrypted_detail" msgid="5279730442756849055">"工作設定檔已上鎖"</string>
@@ -2013,7 +2013,7 @@
     <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"切換至文字輸入模式即可輸入時間。"</string>
     <string name="time_picker_radial_mode_description" msgid="1222342577115016953">"切換至時鐘模式即可輸入時間。"</string>
     <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"自動填入選項"</string>
-    <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"儲存資料,方便您自動填入"</string>
+    <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"儲存資料,方便你自動填入"</string>
     <string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"無法自動填入內容"</string>
     <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"冇任何自動填入建議"</string>
     <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{一個自動填入建議}other{# 個自動填入建議}}"</string>
@@ -2074,7 +2074,7 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"請勿騷擾已變更"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"輕按即可查看封鎖內容。"</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"查看通知設定"</string>
-    <string name="review_notification_settings_text" msgid="5916244866751849279">"由 Android 13 開始,您安裝的應用程式須獲得授權才能傳送通知。輕按即可變更現有應用程式的這項權限。"</string>
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"由 Android 13 開始,你安裝的應用程式須獲得授權才能傳送通知。輕按即可變更現有應用程式的這項權限。"</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"稍後提醒我"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"關閉"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"系統"</string>
@@ -2092,7 +2092,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"確定"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"關閉"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"瞭解詳情"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"加強版通知在 Android 12 取代了 Android 自動調整通知。此功能會顯示建議的操作和回覆,更可為您整理通知。\n\n加強版通知功能可存取您的通知內容 (包括聯絡人姓名和訊息等個人資料),亦可以關閉或回應通知,例如接聽來電和控制「請勿騷擾」功能。"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"加強版通知在 Android 12 取代了 Android 自動調整通知。此功能會顯示建議的操作和回覆,更可為你整理通知。\n\n加強版通知功能可存取你的通知內容 (包括聯絡人姓名和訊息等個人資料),亦可以關閉或回應通知,例如接聽來電和控制「請勿騷擾」功能。"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"「日常安排模式」資料通知"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"已開啟「慳電模式」"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"減少用電可延長電池壽命"</string>
@@ -2154,19 +2154,19 @@
     <string name="resolver_work_tab" msgid="2690019516263167035">"工作"</string>
     <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"個人檢視模式"</string>
     <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"工作檢視模式"</string>
-    <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"已被您的 IT 管理員封鎖"</string>
+    <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"已被你的 IT 管理員封鎖"</string>
     <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"無法使用工作應用程式分享此內容"</string>
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"無法使用工作應用程式開啟此內容"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"無法使用個人應用程式分享此內容"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"無法使用個人應用程式開啟此內容"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"工作設定檔已暫停使用"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"輕按即可啟用"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"沒有適用的工作應用程式"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"沒有適用的個人應用程式"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"開啟個人用 <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"開啟工作用 <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"使用個人瀏覽器"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"使用工作瀏覽器"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 網絡解鎖 PIN"</string>
@@ -2282,7 +2282,7 @@
     <string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
     <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
     <string name="window_magnification_prompt_title" msgid="2876703640772778215">"放大功能推出新設定"</string>
-    <string name="window_magnification_prompt_content" msgid="8159173903032344891">"您現在可以放大部分畫面"</string>
+    <string name="window_magnification_prompt_content" msgid="8159173903032344891">"你現在可以放大部分畫面"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在「設定」中開啟"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"關閉"</string>
     <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"解除封鎖裝置麥克風"</string>
@@ -2293,7 +2293,7 @@
     <string name="splash_screen_view_icon_description" msgid="180638751260598187">"應用程式圖示"</string>
     <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"應用程式品牌形象"</string>
     <string name="view_and_control_notification_title" msgid="4300765399209912240">"檢查存取權設定"</string>
-    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> 可以查看及控制您的螢幕。輕按即可查看。"</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> 可以查看及控制你的螢幕。輕按即可查看。"</string>
     <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"翻譯咗「<xliff:g id="MESSAGE">%1$s</xliff:g>」。"</string>
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"已經將訊息由<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>翻譯成<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>。"</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"背景活動"</string>
@@ -2324,7 +2324,7 @@
     <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"裝置過熱"</string>
     <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"由於手機過熱,雙螢幕功能無法使用"</string>
     <string name="concurrent_display_notification_power_save_title" msgid="1794569070730736281">"無法使用雙螢幕功能"</string>
-    <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"由於「慳電模式」已開啟,因此無法使用雙螢幕功能。您可以前往「設定」中關閉此模式。"</string>
+    <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"由於「慳電模式」已開啟,因此無法使用雙螢幕功能。你可以前往「設定」中關閉此模式。"</string>
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"前往「設定」"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"關閉"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"已設定「<xliff:g id="DEVICE_NAME">%s</xliff:g>」"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 7a036bf..e6b7380 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"允許應用程式控制震動。"</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"允許應用程式存取震動功能狀態。"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"直接撥打電話號碼"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"允許應用程式自行撥打電話,但可能產生非預期的費用或撥打非預期的電話。注意:這項權限不允許應用程式撥打緊急電話。惡意應用程式可能利用此功能擅自撥打電話,增加你不必要的額外支出。"</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"存取 IMS 撥號服務"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"允許應用程式自動使用 IMS 服務撥打電話。"</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"讀取手機狀態和識別碼"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"臉孔處理作業已取消。"</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"使用者已取消人臉解鎖作業"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"嘗試次數過多,請稍後再試。"</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"嘗試次數過多,人臉解鎖功能無法使用。"</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"嘗試次數過多,請改用螢幕鎖定功能驗證身分。"</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"無法驗證臉孔,請再試一次。"</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"你尚未設定人臉解鎖功能"</string>
@@ -1686,7 +1686,7 @@
     <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"目前的媒體播放音量在長時間聆聽下可能會損害聽力。\n\n如果繼續以這個音量播放內容,長時間可能導致聽力受損。"</string>
     <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"警告:\n目前的內容播放音量已超過安全聆聽範圍。\n\n繼續聆聽這個音量將導致聽力永久受損。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙捷徑嗎?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"啟用捷徑功能,只要同時按下兩個音量按鈕 3 秒,就能啟動無障礙功能。"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"啟用捷徑功能,只要同時按下兩個音量鍵 3 秒,就能啟動無障礙功能。"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"要開啟無障礙功能快速鍵嗎?"</string>
     <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"同時按住音量調高鍵和調低鍵數秒,即可開啟無障礙功能。這麼做可能會改變裝置的運作方式。\n\n目前的功能:\n<xliff:g id="SERVICE">%1$s</xliff:g>\n你可以在 [設定] &gt; [無障礙設定] 中變更選取的功能。"</string>
     <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"無法使用工作應用程式開啟這項內容"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"無法透過個人應用程式分享這項內容"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"無法使用個人應用程式開啟這項內容"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"工作資料夾已暫停使用"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"輕觸即可啟用"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"沒有適用的工作應用程式"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"沒有適用的個人應用程式"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"開啟個人用「<xliff:g id="APP">%s</xliff:g>」"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"開啟工作用「<xliff:g id="APP">%s</xliff:g>」"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"使用個人瀏覽器"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"使用工作瀏覽器"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 卡網路解鎖 PIN 碼"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 1bd0d80..355d70d 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -503,7 +503,8 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Ivumela uhlelo lokusebenza ukulawula isidlidlizi."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ivumela uhlelo lokusebenza ukuthi lufinyelele kusimo sesidlidlizeli."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ngokuqondile shayela izinombolo zocingo"</string>
-    <string name="permdesc_callPhone" msgid="5439809516131609109">"Ivumela uhlelo lokusebenza ukushayela izinombolo zefoni ngaphandle kokuhlanganyela kwakho. Lokhu kungaholela emashajini noma amakholi angalindelekile. Qaphela ukuthi lokhu akuvumeli uhlelo lokusebenza ukushayela izinombolo zesimo esiphuthumayo. Izinhlelo zokusebenza ezingalungile zingabiza imali ngokwenze amakholi ngaphandle kokuqinisekisa kwakho."</string>
+    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
+    <skip />
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"finyelela kusevisi yekholi ye-IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Ivumela uhlelo lokusebenza ukuthi lusebenzise isevisi ye-IMS ukuze yenze amakholi ngaphandle kokungenelela kwakho."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"funda isimo sefoni kanye nesazisi"</string>
@@ -623,11 +624,11 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"Iphutha lokufakazela ubuqiniso"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Sebenzisa isikhiya sesikrini"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Faka ukukhiya isikrini kwakho ukuze uqhubeke"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Cindezela ngokuqinile kunzwa"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Cindezela inzwa uqinise"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Ayisazi isigxivizo somunwe. Zama futhi."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hlanza inzwa yesigxivizo somunwe bese uzame futhi"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Hlanza inzwa bese uzame futhi"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Cindezela ngokuqinile kunzwa"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Cindezela inzwa uqinise"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Umnwe uhanjiswe kancane kakhulu. Sicela uzame futhi."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zama ezinye izigxivizo zeminwe"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Kukhanya kakhulu"</string>
@@ -709,8 +710,7 @@
     <string name="face_error_canceled" msgid="2164434737103802131">"Umsebenzi wobuso ukhanselwe."</string>
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Ukuvula ngobuso kukhanselwe umsebenzisi."</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Imizamo eminingi kakhulu. Zama futhi emuva kwesikhathi."</string>
-    <!-- no translation found for face_error_lockout_permanent (8533257333130473422) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Imizamo eminingi kakhulu. Ukuvula Ngobuso akutholakali."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Imizamo eminingi kakhulu. Kunalokho faka ukukhiya isikrini."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ayikwazi ukuqinisekisa ubuso. Zama futhi."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Awukakusethi Ukuvula ngobuso."</string>
@@ -2159,14 +2159,14 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Lokhu okuqukethwe akukwazi ukukopishwa ngama-app womsebenzi"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Lokhu okuqukethwe akukwazi ukwabiwa nama-app womuntu siqu"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Lokhu okuqukethwe akukwazi ukukopishwa ngama-app womuntu siqu"</string>
-    <string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Iphrofayela yomsebenzi iphunyuziwe"</string>
-    <string name="resolver_switch_on_work" msgid="463709043650610420">"Thepha ukuze uvule"</string>
+    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
+    <skip />
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Awekho ama-app womsebenzi"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Awekho ama-app womuntu siqu"</string>
-    <!-- no translation found for miniresolver_open_in_personal (6499100403307136696) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (7138659785478630639) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="6499100403307136696">"Vula i-<xliff:g id="APP">%s</xliff:g> yomuntu siqu"</string>
+    <string name="miniresolver_open_in_work" msgid="7138659785478630639">"Vula i-<xliff:g id="APP">%s</xliff:g> yomsebenzi"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Sebenzisa isiphequluli somuntu siqu"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Sebenzisa isiphequluli somsebenzi"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Iphinikhodi yokuvula inethiwekhi ye-SIM"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c5f7ea6..7bc3ab8 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -558,6 +558,9 @@
          docked if the dock is configured to enable the accelerometer. -->
     <bool name="config_supportAutoRotation">true</bool>
 
+    <!-- If true, allows rotation resolver service to help resolve screen rotation. -->
+    <bool name="config_allowRotationResolver">true</bool>
+
     <!-- If true, the screen can be rotated via the accelerometer in all 4
          rotations as the default behavior. -->
     <bool name="config_allowAllRotations">false</bool>
@@ -2102,9 +2105,6 @@
     <!-- The default volume for the ring stream -->
     <integer name="config_audio_ring_vol_default">5</integer>
 
-    <!-- Enable sound dose computation and warnings -->
-    <bool name="config_audio_csd_enabled_default">true</bool>
-
     <!-- The default value for whether head tracking for
          spatial audio is enabled for a newly connected audio device -->
     <bool name="config_spatial_audio_head_tracking_enabled_default">false</bool>
@@ -2936,6 +2936,9 @@
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
     <bool name="config_safe_media_volume_enabled">true</bool>
 
+    <!-- Whether safe headphone sound dosage warning is enabled or not (country specific). -->
+    <bool name="config_safe_sound_dosage_enabled">true</bool>
+
     <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
     <bool name="config_safe_media_disable_on_volume_up">true</bool>
 
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index a57a051..fd74185 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -133,6 +133,10 @@
     <string name="config_pointing_ui_package" translatable="false"></string>
     <java-symbol type="string" name="config_pointing_ui_package" />
 
+    <!-- Telephony pointing UI class name to be launched. -->
+    <string name="config_pointing_ui_class" translatable="false"></string>
+    <java-symbol type="string" name="config_pointing_ui_class" />
+
     <!-- Telephony resends received satellite datagram to listener
          if ack is not received within this timeout -->
     <integer name="config_timeout_to_receive_delivered_ack_millis">300000</integer>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index b1b1edf..ad864b1 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -96,12 +96,12 @@
     <!-- Width of the navigation bar when it is placed vertically on the screen in car mode -->
     <dimen name="navigation_bar_width_car_mode">96dp</dimen>
     <!-- Height of notification icons in the status bar -->
-    <dimen name="status_bar_icon_size">22dip</dimen>
+    <dimen name="status_bar_icon_size">18sp</dimen>
     <!-- Desired size of system icons in status bar. -->
-    <dimen name="status_bar_system_icon_size">15dp</dimen>
+    <dimen name="status_bar_system_icon_size">15sp</dimen>
     <!-- Intrinsic size of most system icons in status bar. This is the default value that
          is used if a Drawable reports an intrinsic size of 0. -->
-    <dimen name="status_bar_system_icon_intrinsic_size">17dp</dimen>
+    <dimen name="status_bar_system_icon_intrinsic_size">17sp</dimen>
     <!-- Size of the giant number (unread count) in the notifications -->
     <dimen name="status_bar_content_number_size">48sp</dimen>
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
@@ -257,8 +257,8 @@
     <!-- The margin of the notification action list at the top -->
     <dimen name="notification_action_list_margin_top">0dp</dimen>
 
-    <!-- The visual height of the emphasized notification action -->
-    <dimen name="notification_action_emphasized_height">36dp</dimen>
+    <!-- The overall height of the emphasized notification action -->
+    <dimen name="notification_action_emphasized_height">48dp</dimen>
 
     <!-- The padding of the actions in non-conversation layout. For conversations, the analogous
          value is calculated in ConversationLayout#updateActionListPadding() -->
@@ -330,7 +330,7 @@
     <dimen name="notification_icon_circle_start">16dp</dimen>
 
     <!-- size (width and height) of the icon in the notification header -->
-    <dimen name="notification_header_icon_size_ambient">18dp</dimen>
+    <dimen name="notification_header_icon_size_ambient">18sp</dimen>
 
     <!-- The margin before the start of the app name in the header. -->
     <dimen name="notification_header_app_name_margin_start">3dp</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c6462f1..a49ea0b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -861,6 +861,12 @@
     <!-- "Switch" is a verb; it means to change user profile by tapping another user profile name. -->
     <string name="managed_profile_label">Switch to work profile</string>
 
+    <!-- "Switch" is a verb; it means to change user profile by tapping another user profile name. -->
+    <string name="user_owner_app_label">Switch to personal <xliff:g id="app_name" example="Gmail">%1$s</xliff:g></string>
+
+    <!-- "Switch" is a verb; it means to change user profile by tapping another user profile name. -->
+    <string name="managed_profile_app_label">Switch to work <xliff:g id="app_name" example="Gmail">%1$s</xliff:g></string>
+
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_contacts">Contacts</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b7df6a4..e25425d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -283,7 +283,6 @@
   <java-symbol type="attr" name="autofillSaveCustomSubtitleMaxHeight"/>
   <java-symbol type="bool" name="action_bar_embed_tabs" />
   <java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" />
-  <java-symbol type="bool" name="config_audio_csd_enabled_default" />
   <java-symbol type="integer" name="config_audio_notif_vol_default" />
   <java-symbol type="integer" name="config_audio_notif_vol_steps" />
   <java-symbol type="integer" name="config_audio_ring_vol_default" />
@@ -349,6 +348,7 @@
   <java-symbol type="bool" name="config_useDevInputEventForAudioJack" />
   <java-symbol type="bool" name="config_safe_media_volume_enabled" />
   <java-symbol type="bool" name="config_safe_media_disable_on_volume_up" />
+  <java-symbol type="bool" name="config_safe_sound_dosage_enabled" />
   <java-symbol type="bool" name="config_camera_sound_forced" />
   <java-symbol type="bool" name="config_dontPreferApn" />
   <java-symbol type="bool" name="config_restartRadioAfterProvisioning" />
@@ -1068,7 +1068,9 @@
   <java-symbol type="string" name="action_bar_home_subtitle_description_format" />
   <java-symbol type="string" name="wireless_display_route_description" />
   <java-symbol type="string" name="user_owner_label" />
+  <java-symbol type="string" name="user_owner_app_label" />
   <java-symbol type="string" name="managed_profile_label" />
+  <java-symbol type="string" name="managed_profile_app_label" />
   <java-symbol type="string" name="managed_profile_label_badge" />
   <java-symbol type="string" name="managed_profile_label_badge_2" />
   <java-symbol type="string" name="managed_profile_label_badge_3" />
@@ -1713,6 +1715,7 @@
   <java-symbol type="integer" name="config_motionPredictionOffsetNanos" />
   <java-symbol type="bool" name="config_showNavigationBar" />
   <java-symbol type="bool" name="config_supportAutoRotation" />
+  <java-symbol type="bool" name="config_allowRotationResolver" />
   <java-symbol type="bool" name="config_dockedStackDividerFreeSnapMode" />
   <java-symbol type="dimen" name="docked_stack_divider_thickness" />
   <java-symbol type="dimen" name="docked_stack_divider_insets" />
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java
index 3e9e992..516253b 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java
@@ -58,7 +58,7 @@
     }
 
     @Test
-    public void isCurrentUser_forCurrentUser_returnsFalse() {
+    public void isCurrentOrSystemUser_forCurrentUser_returnsFalse() {
         when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
 
         assertWithMessage("Current user")
@@ -66,7 +66,7 @@
     }
 
     @Test
-    public void isCurrentUser_forNonCurrentUser_returnsFalse() {
+    public void isCurrentOrSystemUser_forNonCurrentUser_returnsFalse() {
         when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_2);
 
         assertWithMessage("Non-current user")
@@ -74,7 +74,8 @@
     }
 
     @Test
-    public void isCurrentUser_forSystemUser_returnsTrue() {
+    public void isCurrentOrSystemUser_forSystemUser_returnsTrue() {
+        when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
         when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
 
         assertWithMessage("System user")
@@ -82,10 +83,26 @@
     }
 
     @Test
-    public void isCurrentUser_withActivityManagerFails_returnsFalse() {
-        doThrow(new RuntimeException()).when(() -> ActivityManager.getCurrentUser());
+    public void isCurrentOrSystemUser_withActivityManagerFailure_returnsFalse() {
+        when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
+        doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser);
 
         assertWithMessage("User when activity manager fails")
                 .that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse();
     }
+
+    @Test
+    public void getCurrentUser() {
+        assertWithMessage("Current user")
+                .that(RadioServiceUserController.getCurrentUser()).isEqualTo(USER_ID_1);
+    }
+
+    @Test
+    public void getCurrentUser_withActivityManagerFailure_returnsUserNull() {
+        when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
+        doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser);
+
+        assertWithMessage("Current user when activity manager fails")
+                .that(RadioServiceUserController.getCurrentUser()).isEqualTo(UserHandle.USER_NULL);
+    }
 }
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
index cce1b2b..6c70192 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
@@ -80,7 +80,7 @@
                 /* vendorIds= */ null);
     }
 
-    static android.hardware.broadcastradio.ProgramSelector makeHalFmSelector(int freq) {
+    static android.hardware.broadcastradio.ProgramSelector makeHalFmSelector(long freq) {
         ProgramIdentifier halId = makeHalIdentifier(IdentifierType.AMFM_FREQUENCY_KHZ, freq);
         return makeHalSelector(halId, /* secondaryIds= */ new ProgramIdentifier[0]);
     }
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsResultTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsResultTest.java
index df3ddfd..b54c156 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsResultTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsResultTest.java
@@ -52,6 +52,7 @@
                 {Result.INVALID_STATE, RadioTuner.TUNER_RESULT_INVALID_STATE},
                 {Result.NOT_SUPPORTED, RadioTuner.TUNER_RESULT_NOT_SUPPORTED},
                 {Result.TIMEOUT, RadioTuner.TUNER_RESULT_TIMEOUT},
+                {Result.CANCELED, RadioTuner.TUNER_RESULT_CANCELED},
                 {Result.UNKNOWN_ERROR, RadioTuner.TUNER_RESULT_UNKNOWN_ERROR}
         });
     }
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
index aea0178..2ef923d 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
@@ -27,11 +27,13 @@
 import android.hardware.broadcastradio.ProgramInfo;
 import android.hardware.broadcastradio.ProgramListChunk;
 import android.hardware.broadcastradio.Properties;
+import android.hardware.broadcastradio.Result;
 import android.hardware.broadcastradio.VendorKeyValue;
 import android.hardware.radio.Announcement;
 import android.hardware.radio.ProgramList;
 import android.hardware.radio.ProgramSelector;
 import android.hardware.radio.RadioManager;
+import android.os.ServiceSpecificException;
 
 import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
 import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
@@ -153,6 +155,16 @@
     }
 
     @Test
+    public void throwOnError_withCancelException() {
+        ServiceSpecificException halException = new ServiceSpecificException(Result.CANCELED);
+
+        RuntimeException thrown = ConversionUtils.throwOnError(halException, "tune");
+
+        expect.withMessage("Exception thrown for canceling error").that(thrown)
+                .hasMessageThat().contains("tune: CANCELED");
+    }
+
+    @Test
     public void propertiesFromHalProperties_idsMatch() {
         expect.withMessage("Properties id")
                 .that(MODULE_PROPERTIES.getId()).isEqualTo(TEST_ID);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
index 78b5a4a..84aa864 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
@@ -47,9 +47,11 @@
 import android.hardware.radio.ProgramSelector;
 import android.hardware.radio.RadioManager;
 import android.hardware.radio.RadioTuner;
+import android.os.Binder;
 import android.os.ParcelableException;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
+import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
@@ -73,6 +75,8 @@
  */
 public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
 
+    private static final int USER_ID_1 = 11;
+    private static final int USER_ID_2 = 12;
     private static final VerificationWithTimeout CALLBACK_TIMEOUT =
             timeout(/* millis= */ 200);
     private static final int SIGNAL_QUALITY = 90;
@@ -109,7 +113,10 @@
             SIGNAL_QUALITY);
 
     // Mocks
-    @Mock private IBroadcastRadio mBroadcastRadioMock;
+    @Mock
+    private UserHandle mUserHandleMock;
+    @Mock
+    private IBroadcastRadio mBroadcastRadioMock;
     private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
 
     // RadioModule under test
@@ -124,14 +131,18 @@
 
     @Override
     protected void initializeSession(StaticMockitoSessionBuilder builder) {
-        builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class);
+        builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class)
+                .spyStatic(Binder.class);
     }
 
     @Before
     public void setup() throws Exception {
+        when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
         doReturn(true).when(() -> CompatChanges.isChangeEnabled(
                 eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt()));
         doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+        doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
+        doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
 
         mRadioModule = new RadioModule(mBroadcastRadioMock,
                 AidlTestUtils.makeDefaultModuleProperties());
@@ -421,6 +432,21 @@
     }
 
     @Test
+    public void tune_forSystemUser() throws Exception {
+        when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
+        doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
+        doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+        ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
+        RadioManager.ProgramInfo tuneInfo =
+                AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
+        openAidlClients(/* numClients= */ 1);
+
+        mTunerSessions[0].tune(initialSel);
+
+        verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo);
+    }
+
+    @Test
     public void tune_withUnknownErrorFromHal_fails() throws Exception {
         openAidlClients(/* numClients= */ 1);
         ProgramSelector sel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
@@ -1136,6 +1162,35 @@
     }
 
     @Test
+    public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback()
+            throws Exception {
+        openAidlClients(1);
+        doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
+
+        mHalTunerCallback.onCurrentProgramInfoChanged(AidlTestUtils.makeHalProgramInfo(
+                AidlTestUtils.makeHalFmSelector(AM_FM_FREQUENCY_LIST[1]), SIGNAL_QUALITY));
+
+        verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+                .onCurrentProgramInfoChanged(any());
+    }
+
+    @Test
+    public void onTuneFailed_forTunerCallback() throws Exception {
+        int numSessions = 3;
+        openAidlClients(numSessions);
+        android.hardware.broadcastradio.ProgramSelector halSel = AidlTestUtils.makeHalFmSelector(
+                AM_FM_FREQUENCY_LIST[1]);
+        ProgramSelector sel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
+
+        mHalTunerCallback.onTuneFailed(Result.CANCELED, halSel);
+
+        for (int index = 0; index < numSessions; index++) {
+            verify(mAidlTunerCallbackMocks[index], CALLBACK_TIMEOUT)
+                    .onTuneFailed(RadioTuner.TUNER_RESULT_CANCELED, sel);
+        }
+    }
+
+    @Test
     public void onAntennaStateChange_forTunerCallback() throws Exception {
         int numSessions = 3;
         openAidlClients(numSessions);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
index 3815008..fac9eaa 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
@@ -46,8 +46,10 @@
 import android.hardware.radio.ProgramSelector;
 import android.hardware.radio.RadioManager;
 import android.hardware.radio.RadioTuner;
+import android.os.Binder;
 import android.os.ParcelableException;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
@@ -74,6 +76,8 @@
 @RunWith(MockitoJUnitRunner.class)
 public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase {
 
+    private static final int USER_ID_1 = 11;
+    private static final int USER_ID_2 = 12;
     private static final VerificationWithTimeout CALLBACK_TIMEOUT =
             timeout(/* millis= */ 200);
     private static final int SIGNAL_QUALITY = 1;
@@ -94,18 +98,25 @@
     private ProgramInfo mHalCurrentInfo;
     private TunerSession[] mTunerSessions;
 
-    @Mock private IBroadcastRadio mBroadcastRadioMock;
-    @Mock ITunerSession mHalTunerSessionMock;
+    @Mock
+    private UserHandle mUserHandleMock;
+    @Mock
+    private IBroadcastRadio mBroadcastRadioMock;
+    @Mock
+    ITunerSession mHalTunerSessionMock;
     private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
 
     @Override
     protected void initializeSession(StaticMockitoSessionBuilder builder) {
-        builder.spyStatic(RadioServiceUserController.class);
+        builder.spyStatic(RadioServiceUserController.class).spyStatic(Binder.class);
     }
 
     @Before
     public void setup() throws Exception {
+        when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
+        doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
         doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+        doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
 
         mRadioModule = new RadioModule(mBroadcastRadioMock,
                 TestUtils.makeDefaultModuleProperties());
@@ -387,6 +398,20 @@
     }
 
     @Test
+    public void tune_forSystemUser() throws Exception {
+        when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
+        doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
+        doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+        ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
+        RadioManager.ProgramInfo tuneInfo = TestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
+        openAidlClients(/* numClients= */ 1);
+
+        mTunerSessions[0].tune(initialSel);
+
+        verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo);
+    }
+
+    @Test
     public void step_withDirectionUp() throws Exception {
         long initFreq = AM_FM_FREQUENCY_LIST[1];
         ProgramSelector initialSel = TestUtils.makeFmSelector(initFreq);
@@ -858,6 +883,19 @@
     }
 
     @Test
+    public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback()
+            throws Exception {
+        openAidlClients(1);
+        doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
+
+        mHalTunerCallback.onCurrentProgramInfoChanged(TestUtils.makeHalProgramInfo(
+                TestUtils.makeHalFmSelector(/* freq= */ 97300), SIGNAL_QUALITY));
+
+        verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+                .onCurrentProgramInfoChanged(any());
+    }
+
+    @Test
     public void onConfigFlagUpdated_forTunerCallback() throws Exception {
         int numSessions = 3;
         openAidlClients(numSessions);
diff --git a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
index bf8c7c6..72969f7 100644
--- a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
+++ b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
@@ -112,6 +112,7 @@
             Paths.get("/data/misc/wmtrace/layers_trace.winscope"),
             Paths.get("/data/misc/wmtrace/transactions_trace.winscope"),
             Paths.get("/data/misc/wmtrace/transition_trace.winscope"),
+            Paths.get("/data/misc/wmtrace/shell_transition_trace.winscope"),
     };
     private static final Path[] UI_TRACES_GENERATED_DURING_BUGREPORT = {
             Paths.get("/data/misc/wmtrace/layers_trace_from_transactions.winscope"),
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 34b4c51..ab500f7 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -59,6 +59,7 @@
         "print-test-util-lib",
         "testng",
         "servicestests-utils",
+        "device-time-shell-utils",
     ],
 
     libs: [
@@ -73,6 +74,7 @@
     ],
     jni_libs: [
         "libpowermanagertest_jni",
+        "libworksourceparceltest_jni",
     ],
 
     sdk_version: "core_platform",
diff --git a/core/tests/coretests/jni/Android.bp b/core/tests/coretests/jni/Android.bp
index edac8ef..7cc844a 100644
--- a/core/tests/coretests/jni/Android.bp
+++ b/core/tests/coretests/jni/Android.bp
@@ -43,3 +43,27 @@
     ],
     gtest: false,
 }
+
+cc_test_library {
+    name: "libworksourceparceltest_jni",
+    srcs: [
+        "NativeWorkSourceParcelTest.cpp",
+    ],
+    shared_libs: [
+        "libandroid",
+        "libandroid_runtime_lazy",
+        "libbase",
+        "libbinder",
+        "liblog",
+        "libnativehelper",
+        "libpowermanager",
+        "libutils",
+    ],
+    header_libs: ["jni_headers"],
+    stl: "libc++_static",
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+    gtest: false,
+}
diff --git a/core/tests/coretests/jni/NativePowerManagerTest.cpp b/core/tests/coretests/jni/NativePowerManagerTest.cpp
index 5f20e4f..c15c0ce 100644
--- a/core/tests/coretests/jni/NativePowerManagerTest.cpp
+++ b/core/tests/coretests/jni/NativePowerManagerTest.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "NativePowerManagerTest"
 
 #include "jni.h"
+#include "ParcelHelper.h"
 
 #include <android_util_Binder.h>
 #include <binder/IServiceManager.h>
@@ -36,21 +37,6 @@
 
 namespace android {
 
-#define FIND_CLASS(var, className) \
-    var = env->FindClass(className); \
-    LOG_FATAL_IF(!(var), "Unable to find class %s", className);
-
-#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
-    var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
-    LOG_FATAL_IF(!(var), "Unable to find field %s", fieldName);
-
-#define GET_STATIC_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
-    var = env->GetStaticMethodID(clazz, fieldName, fieldDescriptor); \
-    LOG_FATAL_IF(!(var), "Unable to find method %s", fieldName);
-
-static jclass gParcelClazz;
-static jfieldID gParcelDataFieldID;
-static jmethodID gParcelObtainMethodID;
 static struct BatterySaverPolicyConfigFieldId {
     jfieldID adjustBrightnessFactor;
     jfieldID advertiseIsEnabled;
@@ -73,102 +59,6 @@
     jfieldID soundTriggerMode;
 } gBSPCFieldIds;
 
-static jobject nativeObtainParcel(JNIEnv* env) {
-    jobject parcel = env->CallStaticObjectMethod(gParcelClazz, gParcelObtainMethodID);
-    if (parcel == nullptr) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "Obtain parcel failed.");
-    }
-    return parcel;
-}
-
-static Parcel* nativeGetParcelData(JNIEnv* env, jobject obj) {
-    Parcel* parcel = reinterpret_cast<Parcel*>(env->GetLongField(obj, gParcelDataFieldID));
-    if (parcel && parcel->objectsCount() != 0) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid parcel object.");
-    }
-    parcel->setDataPosition(0);
-    return parcel;
-}
-
-static jobject nativeObtainWorkSourceParcel(JNIEnv* env, jobject /* obj */, jintArray uidArray,
-            jobjectArray nameArray) {
-    std::vector<int32_t> uids;
-    std::optional<std::vector<std::optional<String16>>> names = std::nullopt;
-
-    if (uidArray != nullptr) {
-        jint *ptr = env->GetIntArrayElements(uidArray, 0);
-        for (jint i = 0; i < env->GetArrayLength(uidArray); i++) {
-            uids.push_back(static_cast<int32_t>(ptr[i]));
-        }
-    }
-
-    if (nameArray != nullptr) {
-        std::vector<std::optional<String16>> namesVec;
-        for (jint i = 0; i < env->GetArrayLength(nameArray); i++) {
-            jstring string = (jstring) (env->GetObjectArrayElement(nameArray, i));
-            const char *rawString = env->GetStringUTFChars(string, 0);
-            namesVec.push_back(std::make_optional<String16>(String16(rawString)));
-        }
-        names = std::make_optional(std::move(namesVec));
-    }
-
-    WorkSource ws = WorkSource(uids, names);
-    jobject wsParcel = nativeObtainParcel(env);
-    Parcel* parcel = nativeGetParcelData(env, wsParcel);
-    status_t err = ws.writeToParcel(parcel);
-    if (err != OK) {
-        jniThrowException(env, "java/lang/IllegalArgumentException",
-                            StringPrintf("WorkSource writeToParcel failed %d", err).c_str());
-    }
-    parcel->setDataPosition(0);
-    return wsParcel;
-}
-
-static void nativeUnparcelAndVerifyWorkSource(JNIEnv* env, jobject /* obj */, jobject wsParcel,
-        jintArray uidArray, jobjectArray nameArray) {
-    WorkSource ws = {};
-    Parcel* parcel = nativeGetParcelData(env, wsParcel);
-
-    status_t err = ws.readFromParcel(parcel);
-    if (err != OK) {
-        ALOGE("WorkSource writeToParcel failed %d", err);
-    }
-
-    // Now we have a native WorkSource object, verify it.
-    if (uidArray != nullptr) {
-        jint *ptr = env->GetIntArrayElements(uidArray, 0);
-        for (jint i = 0; i < env->GetArrayLength(uidArray); i++) {
-            if (ws.getUids().at(i) != static_cast<int32_t>(ptr[i])) {
-                jniThrowException(env, "java/lang/IllegalArgumentException",
-                            StringPrintf("WorkSource uid not equal %d %d",
-                            ws.getUids().at(i), static_cast<int32_t>(ptr[i])).c_str());
-            }
-        }
-    } else {
-        if (ws.getUids().size() != 0) {
-            jniThrowException(env, "java/lang/IllegalArgumentException",
-                    StringPrintf("WorkSource parcel size not 0").c_str());
-        }
-    }
-
-    if (nameArray != nullptr) {
-        std::vector<std::optional<String16>> namesVec;
-        for (jint i = 0; i < env->GetArrayLength(nameArray); i++) {
-            jstring string = (jstring) (env->GetObjectArrayElement(nameArray, i));
-            const char *rawString = env->GetStringUTFChars(string, 0);
-            if (String16(rawString) != ws.getNames()->at(i)) {
-                jniThrowException(env, "java/lang/IllegalArgumentException",
-                            StringPrintf("WorkSource uid not equal %s", rawString).c_str());
-            }
-        }
-    } else {
-        if (ws.getNames() != std::nullopt) {
-            jniThrowException(env, "java/lang/IllegalArgumentException",
-                    StringPrintf("WorkSource parcel name not empty").c_str());
-        }
-    }
-}
-
 static jobject nativeObtainPowerSaveStateParcel(JNIEnv* env, jobject /* obj */,
         jboolean batterySaverEnabled, jboolean globalBatterySaverEnabled,
         jint locationMode, jint soundTriggerMode, jfloat brightnessFactor) {
@@ -305,10 +195,6 @@
     JNIEnv* env;
     const JNINativeMethod methodTable[] = {
         /* name, signature, funcPtr */
-        { "nativeObtainWorkSourceParcel", "([I[Ljava/lang/String;)Landroid/os/Parcel;",
-                (void*) nativeObtainWorkSourceParcel },
-        { "nativeUnparcelAndVerifyWorkSource", "(Landroid/os/Parcel;[I[Ljava/lang/String;)V",
-                (void*) nativeUnparcelAndVerifyWorkSource },
         { "nativeObtainPowerSaveStateParcel", "(ZZIIF)Landroid/os/Parcel;",
                 (void*) nativeObtainPowerSaveStateParcel },
         { "nativeUnparcelAndVerifyPowerSaveState", "(Landroid/os/Parcel;ZZIIF)V",
@@ -327,34 +213,40 @@
         return JNI_ERR;
     }
 
-    jclass bspcClazz;
-    FIND_CLASS(gParcelClazz, "android/os/Parcel");
-    GET_FIELD_ID(gParcelDataFieldID, gParcelClazz, "mNativePtr", "J");
-    GET_STATIC_METHOD_ID(gParcelObtainMethodID, gParcelClazz, "obtain", "()Landroid/os/Parcel;");
-    FIND_CLASS(bspcClazz, "android/os/BatterySaverPolicyConfig");
-    GET_FIELD_ID(gBSPCFieldIds.adjustBrightnessFactor, bspcClazz, "mAdjustBrightnessFactor", "F");
-    GET_FIELD_ID(gBSPCFieldIds.advertiseIsEnabled, bspcClazz, "mAdvertiseIsEnabled", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.deferFullBackup, bspcClazz, "mDeferFullBackup", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.deferKeyValueBackup, bspcClazz, "mDeferKeyValueBackup", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.deviceSpecificSettings, bspcClazz, "mDeviceSpecificSettings",
-                    "Ljava/util/Map;");
-    GET_FIELD_ID(gBSPCFieldIds.disableAnimation, bspcClazz, "mDisableAnimation", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.disableAod, bspcClazz, "mDisableAod", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.disableLaunchBoost, bspcClazz, "mDisableLaunchBoost", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.disableOptionalSensors, bspcClazz, "mDisableOptionalSensors", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.disableVibration, bspcClazz, "mDisableVibration", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.enableAdjustBrightness, bspcClazz, "mEnableAdjustBrightness", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.enableDataSaver, bspcClazz, "mEnableDataSaver", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.enableFirewall, bspcClazz, "mEnableFirewall", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.enableNightMode, bspcClazz, "mEnableNightMode", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.enableQuickDoze, bspcClazz, "mEnableQuickDoze", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.forceAllAppsStandby, bspcClazz, "mForceAllAppsStandby", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.forceBackgroundCheck, bspcClazz, "mForceBackgroundCheck", "Z");
-    GET_FIELD_ID(gBSPCFieldIds.locationMode, bspcClazz, "mLocationMode", "I");
-    GET_FIELD_ID(gBSPCFieldIds.soundTriggerMode, bspcClazz, "mSoundTriggerMode", "I");
+    loadParcelClass(env);
+
+    jclass bspcClazz = FindClassOrDie(env, "android/os/BatterySaverPolicyConfig");
+
+    gBSPCFieldIds.adjustBrightnessFactor =
+            GetFieldIDOrDie(env, bspcClazz, "mAdjustBrightnessFactor", "F");
+    gBSPCFieldIds.advertiseIsEnabled = GetFieldIDOrDie(env, bspcClazz, "mAdvertiseIsEnabled", "Z");
+    gBSPCFieldIds.deferFullBackup = GetFieldIDOrDie(env, bspcClazz, "mDeferFullBackup", "Z");
+    gBSPCFieldIds.deferKeyValueBackup =
+            GetFieldIDOrDie(env, bspcClazz, "mDeferKeyValueBackup", "Z");
+    gBSPCFieldIds.deviceSpecificSettings =
+            GetFieldIDOrDie(env, bspcClazz, "mDeviceSpecificSettings", "Ljava/util/Map;");
+    gBSPCFieldIds.disableAnimation = GetFieldIDOrDie(env, bspcClazz, "mDisableAnimation", "Z");
+    gBSPCFieldIds.disableAod = GetFieldIDOrDie(env, bspcClazz, "mDisableAod", "Z");
+    gBSPCFieldIds.disableLaunchBoost = GetFieldIDOrDie(env, bspcClazz, "mDisableLaunchBoost", "Z");
+    gBSPCFieldIds.disableOptionalSensors =
+            GetFieldIDOrDie(env, bspcClazz, "mDisableOptionalSensors", "Z");
+    gBSPCFieldIds.disableVibration = GetFieldIDOrDie(env, bspcClazz, "mDisableVibration", "Z");
+    gBSPCFieldIds.enableAdjustBrightness =
+            GetFieldIDOrDie(env, bspcClazz, "mEnableAdjustBrightness", "Z");
+    gBSPCFieldIds.enableDataSaver = GetFieldIDOrDie(env, bspcClazz, "mEnableDataSaver", "Z");
+    gBSPCFieldIds.enableFirewall = GetFieldIDOrDie(env, bspcClazz, "mEnableFirewall", "Z");
+    gBSPCFieldIds.enableNightMode = GetFieldIDOrDie(env, bspcClazz, "mEnableNightMode", "Z");
+    gBSPCFieldIds.enableQuickDoze = GetFieldIDOrDie(env, bspcClazz, "mEnableQuickDoze", "Z");
+    gBSPCFieldIds.forceAllAppsStandby =
+            GetFieldIDOrDie(env, bspcClazz, "mForceAllAppsStandby", "Z");
+    gBSPCFieldIds.forceBackgroundCheck =
+            GetFieldIDOrDie(env, bspcClazz, "mForceBackgroundCheck", "Z");
+    gBSPCFieldIds.locationMode = GetFieldIDOrDie(env, bspcClazz, "mLocationMode", "I");
+    gBSPCFieldIds.soundTriggerMode = GetFieldIDOrDie(env, bspcClazz, "mSoundTriggerMode", "I");
 
     jniRegisterNativeMethods(env, "android/os/PowerManagerTest", methodTable,
                 sizeof(methodTable) / sizeof(JNINativeMethod));
+
     return JNI_VERSION_1_6;
 }
 
diff --git a/core/tests/coretests/jni/NativeWorkSourceParcelTest.cpp b/core/tests/coretests/jni/NativeWorkSourceParcelTest.cpp
new file mode 100644
index 0000000..db1f7bd
--- /dev/null
+++ b/core/tests/coretests/jni/NativeWorkSourceParcelTest.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NativeWorkSourceParcelTest"
+
+#include "jni.h"
+#include "ParcelHelper.h"
+
+#include <android_util_Binder.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+#include <utils/Log.h>
+
+#include <android/WorkSource.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+using namespace android::os;
+using android::base::StringPrintf;
+
+namespace android {
+
+static jobject nativeObtainWorkSourceParcel(JNIEnv* env, jobject /* obj */, jintArray uidArray,
+            jobjectArray nameArray, jint parcelEndMarker) {
+    std::vector<int32_t> uids;
+    std::optional<std::vector<std::optional<String16>>> names = std::nullopt;
+
+    if (uidArray != nullptr) {
+        ScopedIntArrayRO workSourceUids(env, uidArray);
+        for (int i = 0; i < workSourceUids.size(); i++) {
+            uids.push_back(static_cast<int32_t>(workSourceUids[i]));
+        }
+    }
+
+    if (nameArray != nullptr) {
+        std::vector<std::optional<String16>> namesVec;
+        for (jint i = 0; i < env->GetArrayLength(nameArray); i++) {
+            jstring string = static_cast<jstring>(env->GetObjectArrayElement(nameArray, i));
+            const char *rawString = env->GetStringUTFChars(string, 0);
+            namesVec.push_back(std::make_optional<String16>(String16(rawString)));
+        }
+        names = std::make_optional(std::move(namesVec));
+    }
+
+    WorkSource ws = WorkSource(uids, names);
+    jobject wsParcel = nativeObtainParcel(env);
+    Parcel* parcel = nativeGetParcelData(env, wsParcel);
+
+    // write WorkSource and if no error write end marker
+    status_t err = ws.writeToParcel(parcel) ?: parcel->writeInt32(parcelEndMarker);
+
+    if (err != OK) {
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                            StringPrintf("WorkSource writeToParcel failed %d", err).c_str());
+    }
+    parcel->setDataPosition(0);
+    return wsParcel;
+}
+
+static void nativeUnparcelAndVerifyWorkSource(JNIEnv* env, jobject /* obj */, jobject wsParcel,
+        jintArray uidArray, jobjectArray nameArray, jint parcelEndMarker) {
+    WorkSource ws = {};
+    Parcel* parcel = nativeGetParcelData(env, wsParcel);
+    int32_t endMarker;
+
+    // read WorkSource and if no error read end marker
+    status_t err = ws.readFromParcel(parcel) ?: parcel->readInt32(&endMarker);
+    int32_t dataAvailable = parcel->dataAvail();
+
+    if (err != OK) {
+        ALOGE("WorkSource readFromParcel failed %d", err);
+    }
+
+    // Now we have a native WorkSource object, verify it.
+    if (dataAvailable > 0) { // not all data read from the parcel
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                StringPrintf("WorkSource contains more data than native read (%d)",
+                dataAvailable).c_str());
+    } else if (endMarker != parcelEndMarker) { // more date than available read from parcel
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                StringPrintf("WorkSource contains less data than native read").c_str());
+    }
+
+    if (uidArray != nullptr) {
+        ScopedIntArrayRO workSourceUids(env, uidArray);
+        for (int i = 0; i < workSourceUids.size(); i++) {
+            if (ws.getUids().at(i) != static_cast<int32_t>(workSourceUids[i])) {
+                jniThrowException(env, "java/lang/IllegalArgumentException",
+                            StringPrintf("WorkSource uid not equal %d %d",
+                            ws.getUids().at(i), static_cast<int32_t>(workSourceUids[i])).c_str());
+            }
+        }
+    } else {
+        if (ws.getUids().size() != 0) {
+            jniThrowException(env, "java/lang/IllegalArgumentException",
+                    StringPrintf("WorkSource parcel size not 0").c_str());
+        }
+    }
+
+    if (nameArray != nullptr) {
+        std::vector<std::optional<String16>> namesVec;
+        for (jint i = 0; i < env->GetArrayLength(nameArray); i++) {
+            jstring string = (jstring) (env->GetObjectArrayElement(nameArray, i));
+            const char *rawString = env->GetStringUTFChars(string, 0);
+            if (String16(rawString) != ws.getNames()->at(i)) {
+                jniThrowException(env, "java/lang/IllegalArgumentException",
+                            StringPrintf("WorkSource uid not equal %s", rawString).c_str());
+            }
+        }
+    } else {
+        if (ws.getNames() != std::nullopt) {
+            jniThrowException(env, "java/lang/IllegalArgumentException",
+                    StringPrintf("WorkSource parcel name not empty").c_str());
+        }
+    }
+}
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
+{
+    JNIEnv* env;
+
+    const JNINativeMethod workSourceMethodTable[] = {
+        /* name, signature, funcPtr */
+        { "nativeObtainWorkSourceParcel", "([I[Ljava/lang/String;I)Landroid/os/Parcel;",
+                (void*) nativeObtainWorkSourceParcel },
+        { "nativeUnparcelAndVerifyWorkSource", "(Landroid/os/Parcel;[I[Ljava/lang/String;I)V",
+                (void*) nativeUnparcelAndVerifyWorkSource },
+    };
+
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        return JNI_ERR;
+    }
+
+    loadParcelClass(env);
+
+    jniRegisterNativeMethods(env, "android/os/WorkSourceParcelTest", workSourceMethodTable,
+                sizeof(workSourceMethodTable) / sizeof(JNINativeMethod));
+
+    return JNI_VERSION_1_6;
+}
+
+} /* namespace android */
diff --git a/core/tests/coretests/jni/ParcelHelper.h b/core/tests/coretests/jni/ParcelHelper.h
new file mode 100644
index 0000000..1485a2a
--- /dev/null
+++ b/core/tests/coretests/jni/ParcelHelper.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <nativehelper/JNIHelp.h>
+#include <binder/Parcel.h>
+
+namespace android {
+    static jclass gParcelClazz;
+    static jfieldID gParcelDataFieldID;
+    static jmethodID gParcelObtainMethodID;
+
+    static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
+        jclass clazz = env->FindClass(class_name);
+        LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
+        return clazz;
+    }
+
+    static inline jfieldID GetFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
+                                           const char* field_signature) {
+        jfieldID res = env->GetFieldID(clazz, field_name, field_signature);
+        LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find field %s with signature %s", field_name,
+                            field_signature);
+        return res;
+    }
+
+    static inline jmethodID GetStaticMethodIDOrDie(JNIEnv* env, jclass clazz,
+                                                   const char* method_name,
+                                                   const char* method_signature) {
+        jmethodID res = env->GetStaticMethodID(clazz, method_name, method_signature);
+        LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find method %s with signature %s", method_name,
+                            method_signature);
+        return res;
+    }
+
+    static jobject nativeObtainParcel(JNIEnv* env) {
+        jobject parcel = env->CallStaticObjectMethod(gParcelClazz, gParcelObtainMethodID);
+        if (parcel == nullptr) {
+            jniThrowException(env, "java/lang/IllegalArgumentException", "Obtain parcel failed.");
+        }
+        return parcel;
+    }
+
+    static Parcel* nativeGetParcelData(JNIEnv* env, jobject obj) {
+        Parcel* parcel = reinterpret_cast<Parcel*>(env->GetLongField(obj, gParcelDataFieldID));
+        if (parcel && parcel->objectsCount() != 0) {
+            jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid parcel object.");
+        }
+        parcel->setDataPosition(0);
+        return parcel;
+    }
+
+    static void loadParcelClass(JNIEnv* env) {
+        gParcelClazz = FindClassOrDie(env, "android/os/Parcel");
+        gParcelDataFieldID = GetFieldIDOrDie(env, gParcelClazz, "mNativePtr", "J");
+        gParcelObtainMethodID =
+                GetStaticMethodIDOrDie(env, gParcelClazz, "obtain", "()Landroid/os/Parcel;");
+    }
+
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index fb0f3d4..af81957 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -62,7 +62,6 @@
 import android.view.Display;
 import android.view.View;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
@@ -616,7 +615,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 176134235)
     public void testHandleConfigurationChanged_DoesntOverrideActivityConfig() {
         final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
 
diff --git a/core/tests/coretests/src/android/app/time/TimeManagerTest.java b/core/tests/coretests/src/android/app/time/TimeManagerTest.java
new file mode 100644
index 0000000..6370f3b
--- /dev/null
+++ b/core/tests/coretests/src/android/app/time/TimeManagerTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.time;
+
+import static android.app.time.Capabilities.CAPABILITY_NOT_ALLOWED;
+import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
+import static android.app.time.cts.shell.DeviceConfigKeys.NAMESPACE_SYSTEM_TIME;
+import static android.app.time.cts.shell.DeviceConfigKeys.TimeZoneDetector.KEY_TIME_ZONE_DETECTOR_AUTO_DETECTION_ENABLED_DEFAULT;
+import static android.app.time.cts.shell.DeviceConfigShellHelper.SYNC_DISABLED_MODE_UNTIL_REBOOT;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Instrumentation;
+import android.app.time.cts.shell.DeviceConfigShellHelper;
+import android.app.time.cts.shell.DeviceShellCommandExecutor;
+import android.app.time.cts.shell.TimeZoneDetectorShellHelper;
+import android.app.time.cts.shell.device.InstrumentationShellCommandExecutor;
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.AdoptShellPermissionsRule;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Tests for non-SDK methods / internal behavior related to {@link TimeManager}.
+ * Also see {@link android.app.time.cts.TimeManagerTest}
+ */
+public class TimeManagerTest {
+
+    /**
+     * This rule adopts the Shell process permissions, needed because MANAGE_TIME_AND_ZONE_DETECTION
+     * and SUGGEST_EXTERNAL_TIME required by {@link TimeManager} are privileged permissions.
+     */
+    @Rule
+    public final AdoptShellPermissionsRule shellPermRule = new AdoptShellPermissionsRule();
+
+    private TimeZoneDetectorShellHelper mTimeZoneDetectorShellHelper;
+    private DeviceConfigShellHelper mDeviceConfigShellHelper;
+    private DeviceConfigShellHelper.PreTestState mDeviceConfigPreTestState;
+
+    private Context mContext;
+    private TimeManager mTimeManager;
+
+    @Before
+    public void before() throws Exception {
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        DeviceShellCommandExecutor shellCommandExecutor = new InstrumentationShellCommandExecutor(
+                instrumentation.getUiAutomation());
+        mTimeZoneDetectorShellHelper = new TimeZoneDetectorShellHelper(shellCommandExecutor);
+        mDeviceConfigShellHelper = new DeviceConfigShellHelper(shellCommandExecutor);
+
+        // This anticipates a future state where a generally applied target preparer may disable
+        // device_config sync for all CTS tests: only suspend syncing if it isn't already suspended,
+        // and only resume it if this test suspended it.
+        mDeviceConfigPreTestState = mDeviceConfigShellHelper.setSyncModeForTest(
+                SYNC_DISABLED_MODE_UNTIL_REBOOT, NAMESPACE_SYSTEM_TIME);
+
+        mContext = InstrumentationRegistry.getInstrumentation().getContext();
+        mTimeManager = mContext.getSystemService(TimeManager.class);
+        assertNotNull(mTimeManager);
+
+        // Avoid running tests when device policy doesn't allow user configuration. If this needs to
+        // pass then tests will become more complicated or separate cases broken out.
+        int configureAutoDetectionEnabledCapability = mTimeManager.getTimeCapabilitiesAndConfig()
+                .getCapabilities().getConfigureAutoDetectionEnabledCapability();
+        boolean userRestricted = configureAutoDetectionEnabledCapability == CAPABILITY_NOT_ALLOWED;
+        assertFalse(userRestricted);
+    }
+
+    @After
+    public void after() throws Exception {
+        mDeviceConfigShellHelper.restoreDeviceConfigStateForTest(mDeviceConfigPreTestState);
+    }
+
+    /**
+     * Tests a server flag that can be used to change the "automatic time zone enabled" value
+     * for devices where the user hasn't yet expressed a preference. The flag is only intended for
+     * use during internal testing and therefore has not been included in CTS; it could be removed
+     * in later releases. This test takes ~35s to run because the asynchronous operations involved
+     * require sleeps to allow them to complete.
+     */
+    @Test
+    public void testTimeZoneEnabledDefaultFlagBehavior() throws Exception {
+        TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
+                mTimeManager.getTimeZoneCapabilitiesAndConfig();
+
+        TimeZoneCapabilities capabilities = capabilitiesAndConfig.getCapabilities();
+
+        // Skip this test if the current user is not allowed to alter time detection settings via
+        // the TimeManager APIs.
+        assumeTrue(capabilities.getConfigureAutoDetectionEnabledCapability()
+                == CAPABILITY_POSSESSED);
+
+        // Start with the auto_time_zone_explicit setting empty, but record the value if there is
+        // one so that it can be restored.
+        boolean isAutoDetectionEnabledExplicit =
+                mTimeZoneDetectorShellHelper.isAutoTimeZoneEnabledExplicitly();
+
+        mTimeZoneDetectorShellHelper.clearAutoTimeZoneEnabledExplicitly();
+        sleepForAsyncOperation();
+
+        // Record the current time zone and auto detection setting so that it can be restored by the
+        // test afterwards.
+        boolean initialAutoTzEnabled =
+                capabilitiesAndConfig.getConfiguration().isAutoDetectionEnabled();
+        TimeZoneState initialTimeZoneState = mTimeManager.getTimeZoneState();
+
+        try {
+            // The server flag should be used to control the device's behavior initially because
+            // auto_time_zone_explicit is not set.
+            boolean newAutoTzEnabled = !initialAutoTzEnabled;
+            mDeviceConfigShellHelper.put(NAMESPACE_SYSTEM_TIME,
+                    KEY_TIME_ZONE_DETECTOR_AUTO_DETECTION_ENABLED_DEFAULT,
+                    Boolean.toString(newAutoTzEnabled));
+            sleepForAsyncOperation();
+            assertEquals(newAutoTzEnabled, mTimeZoneDetectorShellHelper.isAutoDetectionEnabled());
+
+            mDeviceConfigShellHelper.put(NAMESPACE_SYSTEM_TIME,
+                    KEY_TIME_ZONE_DETECTOR_AUTO_DETECTION_ENABLED_DEFAULT,
+                    Boolean.toString(initialAutoTzEnabled));
+            sleepForAsyncOperation();
+            assertEquals(initialAutoTzEnabled,
+                    mTimeZoneDetectorShellHelper.isAutoDetectionEnabled());
+
+            // Now simulate the user toggling the auto tz setting twice, which should cause the
+            // system to recognize the user has expressed an explicit preference.
+            TimeZoneConfiguration config1 = new TimeZoneConfiguration.Builder()
+                    .setAutoDetectionEnabled(newAutoTzEnabled)
+                    .build();
+            mTimeManager.updateTimeZoneConfiguration(config1);
+            sleepForAsyncOperation();
+            assertEquals(newAutoTzEnabled,
+                    mTimeZoneDetectorShellHelper.isAutoDetectionEnabled());
+
+            TimeZoneConfiguration config2 = new TimeZoneConfiguration.Builder()
+                    .setAutoDetectionEnabled(initialAutoTzEnabled)
+                    .build();
+            mTimeManager.updateTimeZoneConfiguration(config2);
+            sleepForAsyncOperation();
+            assertEquals(initialAutoTzEnabled,
+                    mTimeZoneDetectorShellHelper.isAutoDetectionEnabled());
+
+            // Auto tz enabled is now back to initialAutoTzEnabled.
+
+            // Repeat the flag check: Now the server flag should have no effect because they have
+            // expressed a preference.
+            mDeviceConfigShellHelper.put(NAMESPACE_SYSTEM_TIME,
+                    KEY_TIME_ZONE_DETECTOR_AUTO_DETECTION_ENABLED_DEFAULT,
+                    Boolean.toString(newAutoTzEnabled));
+            sleepForAsyncOperation();
+            assertEquals(initialAutoTzEnabled,
+                    mTimeZoneDetectorShellHelper.isAutoDetectionEnabled());
+        } finally {
+            // Restore the device's state (as much as possible).
+            if (isAutoDetectionEnabledExplicit) {
+                mTimeZoneDetectorShellHelper.setAutoTimeZoneEnabledExplicitly();
+            } else {
+                mTimeZoneDetectorShellHelper.clearAutoTimeZoneEnabledExplicitly();
+            }
+
+            // Restore auto tz and the time zone (if the device started in manual).
+            mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(initialAutoTzEnabled);
+            if (!initialAutoTzEnabled) {
+                // If the device started in "manual" we can restore the time zone to its original
+                // state, maybe not confidence exactly.
+                mTimeZoneDetectorShellHelper.setTimeZoneState(
+                        initialTimeZoneState.getId(),
+                        initialTimeZoneState.getUserShouldConfirmId());
+            }
+            sleepForAsyncOperation();
+        }
+    }
+
+    /**
+     * Sleeps for a length of time sufficient to allow async operations to complete. Many time
+     * manager APIs are or could be asynchronous and deal with time, so there are no practical
+     * alternatives.
+     */
+    private static void sleepForAsyncOperation() throws Exception {
+        Thread.sleep(5_000);
+    }
+}
diff --git a/core/tests/coretests/src/android/content/pm/CrossProfileAppsTest.java b/core/tests/coretests/src/android/content/pm/CrossProfileAppsTest.java
index 5e07607..661b210 100644
--- a/core/tests/coretests/src/android/content/pm/CrossProfileAppsTest.java
+++ b/core/tests/coretests/src/android/content/pm/CrossProfileAppsTest.java
@@ -20,15 +20,18 @@
 import static android.app.admin.DevicePolicyResources.Strings.Core.SWITCH_TO_WORK_LABEL;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyResourcesManager;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
@@ -76,15 +79,21 @@
     private Drawable mDrawable;
     @Mock
     private PackageManager mPackageManager;
+
+    @Mock private ApplicationInfo mApplicationInfo;
+
+    private Configuration mConfiguration;
+
     private CrossProfileApps mCrossProfileApps;
 
     @Before
     public void initCrossProfileApps() {
-        mCrossProfileApps = new CrossProfileApps(mContext, mService);
+        mCrossProfileApps = spy(new CrossProfileApps(mContext, mService));
     }
 
     @Before
     public void mockContext() {
+        mConfiguration = new Configuration();
         when(mContext.getPackageName()).thenReturn(MY_PACKAGE);
         when(mContext.getSystemServiceName(UserManager.class)).thenReturn(Context.USER_SERVICE);
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
@@ -94,6 +103,8 @@
                 mDevicePolicyManager);
         when(mDevicePolicyManager.getResources()).thenReturn(mDevicePolicyResourcesManager);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
+        when(mResources.getConfiguration()).thenReturn(mConfiguration);
     }
 
     @Before
@@ -115,17 +126,20 @@
     @Test
     public void getProfileSwitchingLabel_managedProfile() {
         setValidTargetProfile(MANAGED_PROFILE);
+        when(mApplicationInfo.loadSafeLabel(any(), anyFloat(), anyInt())).thenReturn("app");
 
         mCrossProfileApps.getProfileSwitchingLabel(MANAGED_PROFILE);
-        verify(mDevicePolicyResourcesManager).getString(eq(SWITCH_TO_WORK_LABEL), any());
+        verify(mDevicePolicyResourcesManager).getString(eq(SWITCH_TO_WORK_LABEL), any(), eq("app"));
     }
 
     @Test
     public void getProfileSwitchingLabel_personalProfile() {
         setValidTargetProfile(PERSONAL_PROFILE);
+        when(mApplicationInfo.loadSafeLabel(any(), anyFloat(), anyInt())).thenReturn("app");
 
         mCrossProfileApps.getProfileSwitchingLabel(PERSONAL_PROFILE);
-        verify(mDevicePolicyResourcesManager).getString(eq(SWITCH_TO_PERSONAL_LABEL), any());
+        verify(mDevicePolicyResourcesManager)
+                .getString(eq(SWITCH_TO_PERSONAL_LABEL), any(), eq("app"));
     }
 
     @Test(expected = SecurityException.class)
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index 0dfc371..9f85d6f 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -49,9 +49,6 @@
     @Mock
     private PowerManager.OnThermalStatusChangedListener mListener2;
     private static final long CALLBACK_TIMEOUT_MILLI_SEC = 5000;
-    private native Parcel nativeObtainWorkSourceParcel(int[] uids, String[] names);
-    private native void nativeUnparcelAndVerifyWorkSource(Parcel parcel, int[] uids,
-            String[] names);
     private native Parcel nativeObtainPowerSaveStateParcel(boolean batterySaverEnabled,
             boolean globalBatterySaverEnabled, int locationMode, int soundTriggerMode,
             float brightnessFactor);
@@ -300,54 +297,6 @@
     }
 
     /**
-     * Helper function to obtain a WorkSource object as parcel from native, with
-     * specified uids and names and verify the WorkSource object created from the parcel.
-     */
-    private void unparcelWorkSourceFromNativeAndVerify(int[] uids, String[] names) {
-        // Obtain WorkSource as parcel from native, with uids and names.
-        Parcel wsParcel = nativeObtainWorkSourceParcel(uids, names);
-        WorkSource ws = WorkSource.CREATOR.createFromParcel(wsParcel);
-        if (uids == null)  {
-            assertEquals(ws.size(), 0);
-        } else {
-            assertEquals(uids.length, ws.size());
-            for (int i = 0; i < ws.size(); i++) {
-                assertEquals(ws.getUid(i), uids[i]);
-            }
-        }
-        if (names != null)  {
-            for (int i = 0; i < names.length; i++) {
-                assertEquals(ws.getName(i), names[i]);
-            }
-        }
-    }
-
-    /**
-     * Helper function to send a WorkSource as parcel from java to native.
-     * Native will verify the WorkSource in native is expected.
-     */
-    private void parcelWorkSourceToNativeAndVerify(int[] uids, String[] names) {
-        WorkSource ws = new WorkSource();
-        if (uids != null) {
-            if (names == null) {
-                for (int i = 0; i < uids.length; i++) {
-                    ws.add(uids[i]);
-                }
-            } else {
-                assertEquals(uids.length, names.length);
-                for (int i = 0; i < uids.length; i++) {
-                    ws.add(uids[i], names[i]);
-                }
-            }
-        }
-        Parcel wsParcel = Parcel.obtain();
-        ws.writeToParcel(wsParcel, 0 /* flags */);
-        wsParcel.setDataPosition(0);
-        //Set the WorkSource as parcel to native and verify.
-        nativeUnparcelAndVerifyWorkSource(wsParcel, uids, names);
-    }
-
-    /**
      * Helper function to obtain a PowerSaveState as parcel from native, with
      * specified parameters, and verify the PowerSaveState object created from the parcel.
      */
@@ -422,43 +371,6 @@
     }
 
     /**
-     * Confirm that we can pass WorkSource from native to Java.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testWorkSourceNativeToJava() {
-        final int[] uids1 = {1000};
-        final int[] uids2 = {1000, 2000};
-        final String[] names1 = {"testWorkSource1"};
-        final String[] names2 = {"testWorkSource1", "testWorkSource2"};
-        unparcelWorkSourceFromNativeAndVerify(null /* uids */, null /* names */);
-        unparcelWorkSourceFromNativeAndVerify(uids1, null /* names */);
-        unparcelWorkSourceFromNativeAndVerify(uids2, null /* names */);
-        unparcelWorkSourceFromNativeAndVerify(null /* uids */, names1);
-        unparcelWorkSourceFromNativeAndVerify(uids1, names1);
-        unparcelWorkSourceFromNativeAndVerify(uids2, names2);
-    }
-
-    /**
-     * Confirm that we can pass WorkSource from Java to native.
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testWorkSourceJavaToNative() {
-        final int[] uids1 = {1000};
-        final int[] uids2 = {1000, 2000};
-        final String[] names1 = {"testGetWorkSource1"};
-        final String[] names2 = {"testGetWorkSource1", "testGetWorkSource2"};
-        parcelWorkSourceToNativeAndVerify(null /* uids */, null /* names */);
-        parcelWorkSourceToNativeAndVerify(uids1, null /* names */);
-        parcelWorkSourceToNativeAndVerify(uids2, null /* names */);
-        parcelWorkSourceToNativeAndVerify(uids1, names1);
-        parcelWorkSourceToNativeAndVerify(uids2, names2);
-    }
-
-    /**
      * Confirm that we can pass PowerSaveState from native to Java.
      *
      * @throws Exception
diff --git a/core/tests/coretests/src/android/os/WorkSourceParcelTest.java b/core/tests/coretests/src/android/os/WorkSourceParcelTest.java
new file mode 100644
index 0000000..4831606
--- /dev/null
+++ b/core/tests/coretests/src/android/os/WorkSourceParcelTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class WorkSourceParcelTest {
+    /**
+     * END_OF_PARCEL_MARKER is added at the end of Parcel on native or java side on write and
+     * then read on java or native side on read. This way we can ensure that no extra data
+     * is read from the parcel.
+     */
+    private static final int END_OF_PARCEL_MARKER = 99;
+
+    private native Parcel nativeObtainWorkSourceParcel(int[] uids, String[] names,
+            int parcelEndMarker);
+
+    private native void nativeUnparcelAndVerifyWorkSource(Parcel parcel, int[] uids,
+            String[] names, int parcelEndMarker);
+
+    static {
+        System.loadLibrary("worksourceparceltest_jni");
+    }
+    /**
+     * Confirm that we can pass WorkSource from native to Java.
+     */
+    @Test
+    public void testWorkSourceNativeToJava() {
+        final int[] uids1 = {1000};
+        final int[] uids2 = {1000, 2000};
+        final String[] names1 = {"testWorkSource1"};
+        final String[] names2 = {"testWorkSource1", "testWorkSource2"};
+        unparcelWorkSourceFromNativeAndVerify(/* uids= */ null , /* names= */ null);
+        unparcelWorkSourceFromNativeAndVerify(uids1, /* names= */ null);
+        unparcelWorkSourceFromNativeAndVerify(uids2, /* names= */ null);
+        unparcelWorkSourceFromNativeAndVerify(/* uids= */ null , names1);
+        unparcelWorkSourceFromNativeAndVerify(uids1, names1);
+        unparcelWorkSourceFromNativeAndVerify(uids2, names2);
+    }
+
+    /**
+     * Confirm that we can pass WorkSource from Java to native.
+     */
+    @Test
+    public void testWorkSourceJavaToNative() {
+        final int[] uids1 = {1000};
+        final int[] uids2 = {1000, 2000};
+        final String[] names1 = {"testGetWorkSource1"};
+        final String[] names2 = {"testGetWorkSource1", "testGetWorkSource2"};
+
+        parcelWorkSourceToNativeAndVerify(/* uids= */ null , /* names= */ null);
+        parcelWorkSourceToNativeAndVerify(uids1, /* names= */ null);
+        parcelWorkSourceToNativeAndVerify(uids2, /* names= */ null);
+        parcelWorkSourceToNativeAndVerify(uids1, names1);
+        parcelWorkSourceToNativeAndVerify(uids2, names2);
+    }
+
+    /**
+     * Helper function to obtain a WorkSource object as parcel from native, with
+     * specified uids and names and verify the WorkSource object created from the parcel.
+     */
+    private void unparcelWorkSourceFromNativeAndVerify(int[] uids, String[] names) {
+        // Obtain WorkSource as parcel from native, with uids and names.
+        // END_OF_PARCEL_MARKER is written at the end of parcel
+        Parcel wsParcel = nativeObtainWorkSourceParcel(uids, names, END_OF_PARCEL_MARKER);
+        // read WorkSource created on native side
+        WorkSource ws = WorkSource.CREATOR.createFromParcel(wsParcel);
+        // read end marker written on native side
+        int endMarker = wsParcel.readInt();
+
+        assertEquals(0, wsParcel.dataAvail()); // we have read everything
+        assertEquals(END_OF_PARCEL_MARKER, endMarker); // endMarkers match
+
+        if (uids == null) {
+            assertEquals(ws.size(), 0);
+        } else {
+            assertEquals(uids.length, ws.size());
+            for (int i = 0; i < ws.size(); i++) {
+                assertEquals(ws.getUid(i), uids[i]);
+            }
+        }
+        if (names != null) {
+            for (int i = 0; i < names.length; i++) {
+                assertEquals(ws.getPackageName(i), names[i]);
+            }
+        }
+    }
+
+    /**
+     * Helper function to send a WorkSource as parcel from java to native.
+     * Native will verify the WorkSource in native is expected.
+     */
+    private void parcelWorkSourceToNativeAndVerify(int[] uids, String[] names) {
+        WorkSource ws = new WorkSource();
+        if (uids != null) {
+            if (names == null) {
+                for (int uid : uids) {
+                    ws.add(uid);
+                }
+            } else {
+                assertEquals(uids.length, names.length);
+                for (int i = 0; i < uids.length; i++) {
+                    ws.add(uids[i], names[i]);
+                }
+            }
+        }
+        Parcel wsParcel = Parcel.obtain();
+        // write WorkSource on java side
+        ws.writeToParcel(wsParcel, 0 /* flags */);
+        // write end marker on java side
+        wsParcel.writeInt(END_OF_PARCEL_MARKER);
+        wsParcel.setDataPosition(0);
+        //Verify parcel and end marker on native side
+        nativeUnparcelAndVerifyWorkSource(wsParcel, uids, names, END_OF_PARCEL_MARKER);
+    }
+}
diff --git a/core/tests/coretests/src/android/util/RotationUtilsTest.java b/core/tests/coretests/src/android/util/RotationUtilsTest.java
index 1b1ee4f..06b28f5 100644
--- a/core/tests/coretests/src/android/util/RotationUtilsTest.java
+++ b/core/tests/coretests/src/android/util/RotationUtilsTest.java
@@ -19,6 +19,7 @@
 import static android.util.RotationUtils.rotateBounds;
 import static android.util.RotationUtils.rotatePoint;
 import static android.util.RotationUtils.rotatePointF;
+import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
@@ -103,4 +104,19 @@
         assertEquals(560f, testResult.x, .1f);
         assertEquals(60f, testResult.y, .1f);
     }
+
+    @Test
+    public void testReverseRotationDirectionAroundZAxis() {
+        assertEquals(ROTATION_90,
+                RotationUtils.reverseRotationDirectionAroundZAxis(ROTATION_270));
+        assertEquals(ROTATION_270,
+                RotationUtils.reverseRotationDirectionAroundZAxis(ROTATION_90));
+        assertEquals(ROTATION_0,
+                RotationUtils.reverseRotationDirectionAroundZAxis(ROTATION_0));
+        assertEquals(ROTATION_180,
+                RotationUtils.reverseRotationDirectionAroundZAxis(ROTATION_180));
+
+        assertEquals(-1,
+                RotationUtils.reverseRotationDirectionAroundZAxis(-1));
+    }
 }
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index a3eda8d..f45db23 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -39,7 +39,6 @@
 import android.widget.TextView;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.FlakyTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
@@ -55,7 +54,6 @@
  *  atest FrameworksCoreTests:ImeInsetsSourceConsumerTest
  */
 @Presubmit
-@FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
 public class ImeInsetsSourceConsumerTest {
 
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 549ac58..7c2759a 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -307,6 +307,12 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
+    "-1828118576": {
+      "message": "SyncGroup %d: Started %sfor listener: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_SYNC_ENGINE",
+      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
+    },
     "-1824578273": {
       "message": "Reporting new frame to %s: %s",
       "level": "VERBOSE",
@@ -1177,6 +1183,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/AppTransitionController.java"
     },
+    "-1005167552": {
+      "message": "Playing #%d in parallel on track #%d",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/TransitionController.java"
+    },
     "-1003678883": {
       "message": "Cleaning splash screen token=%s",
       "level": "VERBOSE",
@@ -1441,6 +1453,12 @@
       "group": "WM_DEBUG_TASKS",
       "at": "com\/android\/server\/wm\/RootWindowContainer.java"
     },
+    "-774908272": {
+      "message": "Marking #%d animation as SYNC.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/TransitionController.java"
+    },
     "-771177730": {
       "message": "Removing focused app token:%s displayId=%d",
       "level": "VERBOSE",
@@ -2005,6 +2023,12 @@
       "group": "WM_DEBUG_WALLPAPER",
       "at": "com\/android\/server\/wm\/WallpaperController.java"
     },
+    "-266707683": {
+      "message": "Moving #%d from collecting to waiting.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
+      "at": "com\/android\/server\/wm\/TransitionController.java"
+    },
     "-262984451": {
       "message": "Relaunch failed %s",
       "level": "INFO",
@@ -2077,6 +2101,12 @@
       "group": "WM_DEBUG_WINDOW_MOVEMENT",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-186693085": {
+      "message": "Starting a Recents transition which can be parallel.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/Transition.java"
+    },
     "-182877285": {
       "message": "Wallpaper layer changed: assigning layers + relayout",
       "level": "VERBOSE",
@@ -2893,12 +2923,6 @@
       "group": "WM_DEBUG_BOOT",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "550717438": {
-      "message": "SyncGroup %d: Started for listener: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
-    },
     "556758086": {
       "message": "Applying new update lock state '%s' for %s",
       "level": "DEBUG",
@@ -4129,6 +4153,12 @@
       "group": "WM_DEBUG_ANIM",
       "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
     },
+    "1820873642": {
+      "message": "SyncGroup %d:  Unfinished dependencies: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_SYNC_ENGINE",
+      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
+    },
     "1822314934": {
       "message": "Expected target rootTask=%s to restored behind rootTask=%s but it is behind rootTask=%s",
       "level": "WARN",
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 56c3068..dd4b58e 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -40,9 +40,9 @@
 import android.graphics.drawable.NinePatchDrawable;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
+import android.media.MediaFormat;
 import android.net.Uri;
 import android.os.Build;
-import android.os.SystemProperties;
 import android.os.Trace;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -915,8 +915,6 @@
             case "image/jpeg":
             case "image/webp":
             case "image/gif":
-            case "image/heif":
-            case "image/heic":
             case "image/bmp":
             case "image/x-ico":
             case "image/vnd.wap.wbmp":
@@ -931,6 +929,9 @@
             case "image/x-pentax-pef":
             case "image/x-samsung-srw":
                 return true;
+            case "image/heif":
+            case "image/heic":
+                return isHevcDecoderSupported();
             case "image/avif":
                 return isP010SupportedForAV1();
             default:
@@ -2068,48 +2069,90 @@
         return decodeBitmapImpl(src, null);
     }
 
+    private static boolean sIsHevcDecoderSupported = false;
+    private static boolean sIsHevcDecoderSupportedInitialized = false;
+    private static final Object sIsHevcDecoderSupportedLock = new Object();
+
+    /*
+     * Check if HEVC decoder is supported by the device.
+     */
+    @SuppressWarnings("AndroidFrameworkCompatChange")
+    private static boolean isHevcDecoderSupported() {
+        synchronized (sIsHevcDecoderSupportedLock) {
+            if (sIsHevcDecoderSupportedInitialized) {
+                return sIsHevcDecoderSupported;
+            }
+            MediaFormat format = new MediaFormat();
+            format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_HEVC);
+            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+            sIsHevcDecoderSupported = mcl.findDecoderForFormat(format) != null;
+            sIsHevcDecoderSupportedInitialized = true;
+            return sIsHevcDecoderSupported;
+        }
+    }
+
     private static boolean sIsP010SupportedForAV1 = false;
-    private static boolean sIsP010SupportedForAV1Initialized = false;
-    private static final Object sIsP010SupportedForAV1Lock = new Object();
+    private static boolean sIsP010SupportedForHEVC = false;
+    private static boolean sIsP010SupportedFlagsInitialized = false;
+    private static final Object sIsP010SupportedLock = new Object();
 
     /**
      * Checks if the device supports decoding 10-bit AV1.
      */
     @SuppressWarnings("AndroidFrameworkCompatChange")  // This is not an app-visible API.
     private static boolean isP010SupportedForAV1() {
-        synchronized (sIsP010SupportedForAV1Lock) {
-            if (sIsP010SupportedForAV1Initialized) {
+        synchronized (sIsP010SupportedLock) {
+            if (sIsP010SupportedFlagsInitialized) {
                 return sIsP010SupportedForAV1;
             }
+            checkP010SupportforAV1HEVC();
+            return sIsP010SupportedForAV1;
+        }
+    }
 
-            sIsP010SupportedForAV1Initialized = true;
-            return sIsP010SupportedForAV1 = isP010SupportedforMime("video/av01");
+    /**
+     * Checks if the device supports decoding 10-bit HEVC.
+     * This method is called by JNI.
+     */
+    @SuppressWarnings("unused")
+    private static boolean isP010SupportedForHEVC() {
+        synchronized (sIsP010SupportedLock) {
+            if (sIsP010SupportedFlagsInitialized) {
+                return sIsP010SupportedForHEVC;
+            }
+            checkP010SupportforAV1HEVC();
+            return sIsP010SupportedForHEVC;
         }
     }
 
     /**
      * Checks if the device supports decoding 10-bit for the given mime type.
      */
-    private static boolean isP010SupportedforMime(String mime) {
-        MediaCodecList codecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
+    private static void checkP010SupportforAV1HEVC() {
+        MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
         for (MediaCodecInfo mediaCodecInfo : codecList.getCodecInfos()) {
             if (mediaCodecInfo.isEncoder()) {
                 continue;
             }
             for (String mediaType : mediaCodecInfo.getSupportedTypes()) {
-                if (mediaType.equalsIgnoreCase(mime)) {
+                if (mediaType.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AV1)
+                        || mediaType.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
                     MediaCodecInfo.CodecCapabilities codecCapabilities =
                         mediaCodecInfo.getCapabilitiesForType(mediaType);
                     for (int i = 0; i < codecCapabilities.colorFormats.length; ++i) {
                         if (codecCapabilities.colorFormats[i]
                             == MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010) {
-                            return true;
+                            if (mediaType.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AV1)) {
+                                sIsP010SupportedForAV1 = true;
+                            } else {
+                                sIsP010SupportedForHEVC = true;
+                            }
                         }
                     }
                 }
             }
         }
-        return false;
+        sIsP010SupportedFlagsInitialized = true;
     }
 
     /**
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 88373e8..cb3b64c 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -261,8 +261,9 @@
     /**
      * Compressed JPEG format that includes an embedded recovery map.
      *
-     * <p>JPEG compressed main image along with XMP embedded recovery map
-     * following ISO TBD.</p>
+     * <p>JPEG compressed main image along with embedded recovery map following the
+     * <a href="https://developer.android.com/guide/topics/media/hdr-image-format">Ultra HDR
+     * Image format specification</a>.</p>
      */
     public static final int JPEG_R = 0x1005;
 
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
index b917ac8..d9b73a8 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
@@ -83,10 +83,7 @@
     }
 
     @Override
-    public void onAnimationCancelled(boolean isKeyguardOccluded) {
-        if (TaskFragmentAnimationController.DEBUG) {
-            Log.v(TAG, "onAnimationCancelled: isKeyguardOccluded=" + isKeyguardOccluded);
-        }
+    public void onAnimationCancelled() {
         mHandler.post(this::cancelAnimation);
     }
 
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 54978bd..6a79bc1 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -125,6 +125,34 @@
 
 // End ProtoLog
 
+gensrcs {
+    name: "wm-shell-protos",
+
+    tools: [
+        "aprotoc",
+        "protoc-gen-javastream",
+        "soong_zip",
+    ],
+
+    tool_files: [
+        ":libprotobuf-internal-protos",
+    ],
+
+    cmd: "mkdir -p $(genDir)/$(in) " +
+        "&& $(location aprotoc) " +
+        "  --plugin=$(location protoc-gen-javastream) " +
+        "  --javastream_out=$(genDir)/$(in) " +
+        "  -Iexternal/protobuf/src " +
+        "  -I . " +
+        "  $(in) " +
+        "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
+
+    srcs: [
+        "proto/**/*.proto",
+    ],
+    output_extension: "srcjar",
+}
+
 java_library {
     name: "WindowManager-Shell-proto",
 
@@ -142,6 +170,7 @@
         // TODO(b/168581922) protologtool do not support kotlin(*.kt)
         ":wm_shell-sources-kt",
         ":wm_shell-aidls",
+        ":wm-shell-protos",
     ],
     resource_dirs: [
         "res",
diff --git a/libs/WindowManager/Shell/proto/wm_shell_transition_trace.proto b/libs/WindowManager/Shell/proto/wm_shell_transition_trace.proto
new file mode 100644
index 0000000..6e01101
--- /dev/null
+++ b/libs/WindowManager/Shell/proto/wm_shell_transition_trace.proto
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+
+package com.android.wm.shell;
+
+option java_multiple_files = true;
+
+/* Represents a file full of transition entries.
+   Encoded, it should start with 0x09 0x57 0x4D 0x53 0x54 0x52 0x41 0x43 0x45 (.WMSTRACE), such
+   that it can be easily identified. */
+message WmShellTransitionTraceProto {
+    /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L
+   (this is needed because enums have to be 32 bits and there's no nice way to put 64bit
+    constants into .proto files. */
+    enum MagicNumber {
+        INVALID = 0;
+        MAGIC_NUMBER_L = 0x54534D57;  /* WMST (little-endian ASCII) */
+        MAGIC_NUMBER_H = 0x45434152;  /* RACE (little-endian ASCII) */
+    }
+
+    // Must be the first field, set to value in MagicNumber
+    required fixed64 magic_number = 1;
+    repeated Transition transitions = 2;
+    repeated HandlerMapping handlerMappings = 3;
+}
+
+message Transition {
+    required int32 id = 1;
+    optional int64 dispatch_time_ns = 2;
+    optional int32 handler = 3;
+    optional int64 merge_time_ns = 4;
+    optional int64 merge_request_time_ns = 5;
+    optional int32 merged_into = 6;
+    optional int64 abort_time_ns = 7;
+}
+
+message HandlerMapping {
+    required int32 id = 1;
+    required string name = 2;
+}
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml b/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml
index 96d2d7c..d2360e9 100644
--- a/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml
@@ -16,9 +16,10 @@
   -->
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
     <solid
-        android:color="@android:color/system_neutral1_800"
+        android:color="?androidprv:attr/materialColorSurfaceContainerHigh"
         />
     <corners android:radius="20dp" />
 
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml
index 4bd2f13..8fd2e68 100644
--- a/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml
@@ -17,7 +17,7 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
        android:shape="rectangle">
-    <solid android:color="?androidprv:attr/colorSurface" />
+    <solid android:color="?androidprv:attr/materialColorSurfaceBright" />
     <corners
         android:bottomLeftRadius="?android:attr/dialogCornerRadius"
         android:topLeftRadius="?android:attr/dialogCornerRadius"
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_resize_veil_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_resize_veil_background.xml
new file mode 100644
index 0000000..1f3e3a4
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_resize_veil_background.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<shape android:shape="rectangle"
+       xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@android:color/white" />
+</shape>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_flyout.xml b/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
index 7fdf290..65a07a7 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
@@ -13,7 +13,8 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
 
     <LinearLayout
         android:id="@+id/bubble_flyout_text_container"
@@ -48,6 +49,7 @@
                 android:fontFamily="@*android:string/config_bodyFontFamilyMedium"
                 android:maxLines="1"
                 android:ellipsize="end"
+                android:textColor="?androidprv:attr/materialColorOnSurface"
                 android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/>
 
             <TextView
@@ -57,6 +59,7 @@
                 android:fontFamily="@*android:string/config_bodyFontFamily"
                 android:maxLines="2"
                 android:ellipsize="end"
+                android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
                 android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/>
 
         </LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml
index 0cf6d73..f88d63d 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml
@@ -16,6 +16,7 @@
   -->
 <com.android.wm.shell.common.AlphaOptimizedButton
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     style="@android:style/Widget.DeviceDefault.Button.Borderless"
     android:id="@+id/manage_button"
     android:layout_gravity="start"
@@ -27,6 +28,6 @@
     android:focusable="true"
     android:text="@string/manage_bubbles_text"
     android:textSize="@*android:dimen/text_size_body_2_material"
-    android:textColor="@*android:color/system_neutral1_50"
+    android:textColor="?androidprv:attr/materialColorOnSurface"
     android:background="@drawable/bubble_manage_btn_bg"
     />
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
index 298ad30..10c9562 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
@@ -15,6 +15,7 @@
   ~ limitations under the License
   -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:background="@drawable/bubble_manage_menu_bg"
@@ -41,6 +42,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
+            android:textColor="?androidprv:attr/materialColorOnSurface"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault"
             android:text="@string/bubble_dismiss_text" />
 
@@ -66,6 +68,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
+            android:textColor="?androidprv:attr/materialColorOnSurface"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault"
             android:text="@string/bubbles_dont_bubble_conversation" />
 
@@ -92,6 +95,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
+            android:textColor="?androidprv:attr/materialColorOnSurface"
             android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
 
     </LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_resize_veil.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_resize_veil.xml
new file mode 100644
index 0000000..a4bbd89
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_resize_veil.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:background="@drawable/desktop_mode_resize_veil_background">
+
+    <ImageView
+        android:id="@+id/veil_application_icon"
+        android:layout_width="96dp"
+        android:layout_height="96dp"
+        android:layout_gravity="center"
+        android:contentDescription="@string/app_icon_text" />
+</FrameLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_restart_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_restart_dialog_layout.xml
index 5aff415..7f1aac3 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_restart_dialog_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_restart_dialog_layout.xml
@@ -73,11 +73,13 @@
                     android:textAlignment="center"/>
 
                 <LinearLayout
+                    android:id="@+id/letterbox_restart_dialog_checkbox_container"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
+                    android:paddingVertical="14dp"
                     android:orientation="horizontal"
                     android:layout_gravity="center_vertical"
-                    android:layout_marginVertical="32dp">
+                    android:layout_marginVertical="18dp">
 
                     <CheckBox
                         android:id="@+id/letterbox_restart_dialog_checkbox"
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 21172e2..9cb4435 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -32,23 +32,23 @@
     <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"መጠን ይቀይሩ"</string>
     <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Stash"</string>
     <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string>
-    <string name="dock_forced_resizable" msgid="7429086980048964687">"መተግበሪያ ከተከፈለ ማያ ገጽ ጋር ላይሠራ ይችላል"</string>
+    <string name="dock_forced_resizable" msgid="7429086980048964687">"መተግበሪያ ከተከፈለ ማያ ገፅ ጋር ላይሠራ ይችላል"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም"</string>
     <string name="dock_multi_instances_not_supported_text" msgid="5242868470666346929">"ይህ መተግበሪያ መከፈት የሚችለው በ1 መስኮት ብቻ ነው።"</string>
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"መተግበሪያ በሁለተኛ ማሳያ ላይ ላይሠራ ይችላል።"</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"መተግበሪያ በሁለተኛ ማሳያዎች ላይ ማስጀመርን አይደግፍም።"</string>
-    <string name="accessibility_divider" msgid="6407584574218956849">"የተከፈለ የማያ ገጽ ከፋይ"</string>
-    <string name="divider_title" msgid="1963391955593749442">"የተከፈለ የማያ ገጽ ከፋይ"</string>
-    <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"የግራ ሙሉ ማያ ገጽ"</string>
+    <string name="accessibility_divider" msgid="6407584574218956849">"የተከፈለ የማያ ገፅ ከፋይ"</string>
+    <string name="divider_title" msgid="1963391955593749442">"የተከፈለ የማያ ገፅ ከፋይ"</string>
+    <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"የግራ ሙሉ ማያ ገፅ"</string>
     <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ግራ 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ግራ 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ግራ 30%"</string>
-    <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"የቀኝ ሙሉ ማያ ገጽ"</string>
-    <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"የላይ ሙሉ ማያ ገጽ"</string>
+    <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"የቀኝ ሙሉ ማያ ገፅ"</string>
+    <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"የላይ ሙሉ ማያ ገፅ"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ከላይ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ከላይ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ከላይ 30%"</string>
-    <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"የታች ሙሉ ማያ ገጽ"</string>
+    <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"የታች ሙሉ ማያ ገፅ"</string>
     <string name="accessibility_split_left" msgid="1713683765575562458">"ወደ ግራ ከፋፍል"</string>
     <string name="accessibility_split_right" msgid="8441001008181296837">"ወደ ቀኝ ከፋፍል"</string>
     <string name="accessibility_split_top" msgid="2789329702027147146">"ወደ ላይ ከፋፍል"</string>
@@ -84,7 +84,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"አልተስተካከለም?\nለማህደር መታ ያድርጉ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ምንም የካሜራ ችግሮች የሉም? ለማሰናበት መታ ያድርጉ።"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ተጨማሪ ይመልከቱ እና ያድርጉ"</string>
-    <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ለተከፈለ ማያ ገጽ ሌላ መተግበሪያ ይጎትቱ"</string>
+    <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ለተከፈለ ማያ ገፅ ሌላ መተግበሪያ ይጎትቱ"</string>
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ቦታውን ለመቀየር ከመተግበሪያው ውጪ ሁለቴ መታ ያድርጉ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ገባኝ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ለተጨማሪ መረጃ ይዘርጉ።"</string>
@@ -102,11 +102,11 @@
     <string name="app_icon_text" msgid="2823268023931811747">"የመተግበሪያ አዶ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ሙሉ ማያ"</string>
     <string name="desktop_text" msgid="1077633567027630454">"የዴስክቶፕ ሁነታ"</string>
-    <string name="split_screen_text" msgid="1396336058129570886">"የተከፈለ ማያ ገጽ"</string>
+    <string name="split_screen_text" msgid="1396336058129570886">"የተከፈለ ማያ ገፅ"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ተጨማሪ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ተንሳፋፊ"</string>
     <string name="select_text" msgid="5139083974039906583">"ምረጥ"</string>
-    <string name="screenshot_text" msgid="1477704010087786671">"ቅጽበታዊ ገጽ እይታ"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ቅጽበታዊ ገፅ እይታ"</string>
     <string name="close_text" msgid="4986518933445178928">"ዝጋ"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
     <string name="expand_menu_text" msgid="3847736164494181168">"ምናሌን ክፈት"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings_tv.xml b/libs/WindowManager/Shell/res/values-am/strings_tv.xml
index a6be578..84c1c67 100644
--- a/libs/WindowManager/Shell/res/values-am/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings_tv.xml
@@ -20,7 +20,7 @@
     <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ሥዕል-ላይ-ሥዕል"</string>
     <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ርዕስ የሌለው ፕሮግራም)"</string>
     <string name="pip_close" msgid="2955969519031223530">"ዝጋ"</string>
-    <string name="pip_fullscreen" msgid="7278047353591302554">"ሙሉ ማያ ገጽ"</string>
+    <string name="pip_fullscreen" msgid="7278047353591302554">"ሙሉ ማያ ገፅ"</string>
     <string name="pip_move" msgid="158770205886688553">"ውሰድ"</string>
     <string name="pip_expand" msgid="1051966011679297308">"ዘርጋ"</string>
     <string name="pip_collapse" msgid="3903295106641385962">"ሰብስብ"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 6ce475a..c17f97f 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -20,7 +20,7 @@
     <string name="pip_phone_close" msgid="5783752637260411309">"Schließen"</string>
     <string name="pip_phone_expand" msgid="2579292903468287504">"Maximieren"</string>
     <string name="pip_phone_settings" msgid="5468987116750491918">"Einstellungen"</string>
-    <string name="pip_phone_enter_split" msgid="7042877263880641911">"„Geteilter Bildschirm“ aktivieren"</string>
+    <string name="pip_phone_enter_split" msgid="7042877263880641911">"Splitscreen aktivieren"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string>
     <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menü „Bild im Bild“"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ist in Bild im Bild"</string>
@@ -32,8 +32,8 @@
     <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Größe anpassen"</string>
     <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"In Stash legen"</string>
     <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Aus Stash entfernen"</string>
-    <string name="dock_forced_resizable" msgid="7429086980048964687">"Die App funktioniert bei geteiltem Bildschirm unter Umständen nicht"</string>
-    <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"„Geteilter Bildschirm“ wird in dieser App nicht unterstützt"</string>
+    <string name="dock_forced_resizable" msgid="7429086980048964687">"Die App funktioniert im Splitscreen-Modus unter Umständen nicht"</string>
+    <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Splitscreen wird in dieser App nicht unterstützt"</string>
     <string name="dock_multi_instances_not_supported_text" msgid="5242868470666346929">"Diese App kann nur in einem einzigen Fenster geöffnet werden."</string>
     <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Die App funktioniert auf einem sekundären Display möglicherweise nicht."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Die App unterstützt den Start auf sekundären Displays nicht."</string>
@@ -84,7 +84,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Das Problem ist nicht behoben?\nZum Rückgängigmachen tippen."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Keine Probleme mit der Kamera? Zum Schließen tippen."</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Mehr sehen und erledigen"</string>
-    <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Weitere App hineinziehen, um den Bildschirm zu teilen"</string>
+    <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Für Splitscreen-Modus weitere App hineinziehen"</string>
     <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>
@@ -102,13 +102,12 @@
     <string name="app_icon_text" msgid="2823268023931811747">"App-Symbol"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Vollbild"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string>
-    <string name="split_screen_text" msgid="1396336058129570886">"Geteilter Bildschirm"</string>
+    <string name="split_screen_text" msgid="1396336058129570886">"Splitscreen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mehr"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Frei schwebend"</string>
     <string name="select_text" msgid="5139083974039906583">"Auswählen"</string>
     <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
     <string name="close_text" msgid="4986518933445178928">"Schließen"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
-    <!-- no translation found for expand_menu_text (3847736164494181168) -->
-    <skip />
+    <string name="expand_menu_text" msgid="3847736164494181168">"Menü öffnen"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index f210ea2..19df267 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -24,7 +24,7 @@
     <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string>
     <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Сүрөт ичиндеги сүрөт менюсу"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> – сүрөт ичиндеги сүрөт"</string>
-    <string name="pip_notification_message" msgid="8854051911700302620">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, жөндөөлөрдү ачып туруп, аны өчүрүп коюңуз."</string>
+    <string name="pip_notification_message" msgid="8854051911700302620">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, параметрлерди ачып туруп, аны өчүрүп коюңуз."</string>
     <string name="pip_play" msgid="3496151081459417097">"Ойнотуу"</string>
     <string name="pip_pause" msgid="690688849510295232">"Тындыруу"</string>
     <string name="pip_skip_to_next" msgid="8403429188794867653">"Кийинкисине өткөрүп жиберүү"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 6f399e5..021ec46 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -24,7 +24,7 @@
     <string name="pip_menu_title" msgid="5393619322111827096">"選單"</string>
     <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"畫中畫選單"</string>
     <string name="pip_notification_title" msgid="1347104727641353453">"「<xliff:g id="NAME">%s</xliff:g>」目前在畫中畫模式"</string>
-    <string name="pip_notification_message" msgid="8854051911700302620">"如果您不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string>
+    <string name="pip_notification_message" msgid="8854051911700302620">"如果你不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string>
     <string name="pip_play" msgid="3496151081459417097">"播放"</string>
     <string name="pip_pause" msgid="690688849510295232">"暫停"</string>
     <string name="pip_skip_to_next" msgid="8403429188794867653">"跳到下一個"</string>
@@ -89,7 +89,7 @@
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展開即可查看詳情。"</string>
     <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"要重新啟動改善檢視畫面嗎?"</string>
-    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"您可重新啟動應用程式,讓系統更新檢視畫面;但系統可能不會儲存目前進度及您作出的任何變更"</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>
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index 76eb094..a3916b7 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -125,4 +125,7 @@
 
     <!-- Whether the additional education about reachability is enabled -->
     <bool name="config_letterboxIsReachabilityEducationEnabled">false</bool>
+
+    <!-- Whether DragAndDrop capability is enabled -->
+    <bool name="config_enableShellDragDrop">true</bool>
 </resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index b6fd0bb..9aac694 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -421,7 +421,7 @@
     /**
      * Removes listener.
      */
-    public void removeLocusIdListener(FocusListener listener) {
+    public void removeFocusListener(FocusListener listener) {
         synchronized (mLock) {
             mFocusListeners.remove(listener);
         }
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 22c9015..edefe9e 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
@@ -404,7 +404,7 @@
         }
 
         @Override
-        public void onAnimationCancelled(boolean isKeyguardOccluded) {
+        public void onAnimationCancelled() {
             finishAnimation();
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
index f0c5d8b2..2d6ec75 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
@@ -323,7 +323,7 @@
         }
 
         @Override
-        public void onAnimationCancelled(boolean isKeyguardOccluded) {
+        public void onAnimationCancelled() {
             finishAnimation();
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index d3f3958..24fd86b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -297,7 +297,7 @@
     public BubbleInfo asBubbleBarBubble() {
         return new BubbleInfo(getKey(),
                 getFlags(),
-                getShortcutInfo().getId(),
+                getShortcutId(),
                 getIcon(),
                 getUser().getIdentifier(),
                 getPackageName());
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 21f02b1..3eb9fa2 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
@@ -260,7 +260,7 @@
     /** One handed mode controller to register transition listener. */
     private Optional<OneHandedController> mOneHandedOptional;
     /** Drag and drop controller to register listener for onDragStarted. */
-    private DragAndDropController mDragAndDropController;
+    private Optional<DragAndDropController> mDragAndDropController;
     /** Used to send bubble events to launcher. */
     private Bubbles.BubbleStateListener mBubbleStateListener;
 
@@ -286,7 +286,7 @@
             BubblePositioner positioner,
             DisplayController displayController,
             Optional<OneHandedController> oneHandedOptional,
-            DragAndDropController dragAndDropController,
+            Optional<DragAndDropController> dragAndDropController,
             @ShellMainThread ShellExecutor mainExecutor,
             @ShellMainThread Handler mainHandler,
             @ShellBackgroundThread ShellExecutor bgExecutor,
@@ -469,7 +469,7 @@
                 });
 
         mOneHandedOptional.ifPresent(this::registerOneHandedState);
-        mDragAndDropController.addListener(this::collapseStack);
+        mDragAndDropController.ifPresent(controller -> controller.addListener(this::collapseStack));
 
         // Clear out any persisted bubbles on disk that no longer have a valid user.
         List<UserInfo> users = mUserManager.getAliveUsers();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
index f878a46..6a5f785 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
@@ -177,7 +177,7 @@
 
         final TypedArray ta = mContext.obtainStyledAttributes(
                 new int[] {
-                        com.android.internal.R.attr.colorSurface,
+                        com.android.internal.R.attr.materialColorSurfaceContainer,
                         android.R.attr.dialogCornerRadius});
         mFloatingBackgroundColor = ta.getColor(0, Color.WHITE);
         mCornerRadius = ta.getDimensionPixelSize(1, 0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index c49451d..df7f5b4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -19,23 +19,21 @@
 import android.app.ActivityTaskManager.INVALID_TASK_ID
 import android.content.Context
 import android.graphics.Bitmap
+import android.graphics.Color
 import android.graphics.Matrix
 import android.graphics.Path
 import android.graphics.drawable.AdaptiveIconDrawable
 import android.graphics.drawable.ColorDrawable
 import android.graphics.drawable.InsetDrawable
 import android.util.PathParser
-import android.util.TypedValue
 import android.view.LayoutInflater
 import android.widget.FrameLayout
 import com.android.launcher3.icons.BubbleIconFactory
 import com.android.wm.shell.R
 import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView
 
-class BubbleOverflow(
-    private val context: Context,
-    private val positioner: BubblePositioner
-) : BubbleViewProvider {
+class BubbleOverflow(private val context: Context, private val positioner: BubblePositioner) :
+    BubbleViewProvider {
 
     private lateinit var bitmap: Bitmap
     private lateinit var dotPath: Path
@@ -54,7 +52,7 @@
         overflowBtn = null
     }
 
-    /** Call before use and again if cleanUpExpandedState was called.  */
+    /** Call before use and again if cleanUpExpandedState was called. */
     fun initialize(controller: BubbleController) {
         createExpandedView()
         getExpandedView()?.initialize(controller, controller.stackView, true /* isOverflow */)
@@ -74,10 +72,10 @@
     }
 
     fun updateResources() {
-        overflowIconInset = context.resources.getDimensionPixelSize(
-                R.dimen.bubble_overflow_icon_inset)
-        overflowBtn?.layoutParams = FrameLayout.LayoutParams(positioner.bubbleSize,
-                positioner.bubbleSize)
+        overflowIconInset =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_overflow_icon_inset)
+        overflowBtn?.layoutParams =
+            FrameLayout.LayoutParams(positioner.bubbleSize, positioner.bubbleSize)
         expandedView?.updateDimensions()
     }
 
@@ -85,36 +83,58 @@
         val res = context.resources
 
         // Set overflow button accent color, dot color
-        val typedValue = TypedValue()
-        context.theme.resolveAttribute(com.android.internal.R.attr.colorAccentPrimary,
-                typedValue, true)
-        val colorAccent = res.getColor(typedValue.resourceId, null)
-        dotColor = colorAccent
 
-        val shapeColor = res.getColor(android.R.color.system_accent1_1000)
+        val typedArray =
+            context.obtainStyledAttributes(
+                intArrayOf(
+                    com.android.internal.R.attr.materialColorPrimaryFixed,
+                    com.android.internal.R.attr.materialColorOnPrimaryFixed
+                )
+            )
+
+        val colorAccent = typedArray.getColor(0, Color.WHITE)
+        val shapeColor = typedArray.getColor(1, Color.BLACK)
+        typedArray.recycle()
+
+        dotColor = colorAccent
         overflowBtn?.iconDrawable?.setTint(shapeColor)
 
-        val iconFactory = BubbleIconFactory(context,
-                context.getResources().getDimensionPixelSize(R.dimen.bubble_size),
-                context.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size),
-                context.getResources().getColor(R.color.important_conversation),
-                context.getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.importance_ring_stroke_width))
+        val iconFactory =
+            BubbleIconFactory(
+                context,
+                res.getDimensionPixelSize(R.dimen.bubble_size),
+                res.getDimensionPixelSize(R.dimen.bubble_badge_size),
+                res.getColor(R.color.important_conversation),
+                res.getDimensionPixelSize(com.android.internal.R.dimen.importance_ring_stroke_width)
+            )
 
         // Update bitmap
         val fg = InsetDrawable(overflowBtn?.iconDrawable, overflowIconInset)
-        bitmap = iconFactory.createBadgedIconBitmap(
-                AdaptiveIconDrawable(ColorDrawable(colorAccent), fg)).icon
+        bitmap =
+            iconFactory
+                .createBadgedIconBitmap(AdaptiveIconDrawable(ColorDrawable(colorAccent), fg))
+                .icon
 
         // Update dot path
-        dotPath = PathParser.createPathFromPathData(
-            res.getString(com.android.internal.R.string.config_icon_mask))
-        val scale = iconFactory.normalizer.getScale(iconView!!.iconDrawable,
-            null /* outBounds */, null /* path */, null /* outMaskShape */)
+        dotPath =
+            PathParser.createPathFromPathData(
+                res.getString(com.android.internal.R.string.config_icon_mask)
+            )
+        val scale =
+            iconFactory.normalizer.getScale(
+                iconView!!.iconDrawable,
+                null /* outBounds */,
+                null /* path */,
+                null /* outMaskShape */
+            )
         val radius = BadgedImageView.DEFAULT_PATH_SIZE / 2f
         val matrix = Matrix()
-        matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
-            radius /* pivot y */)
+        matrix.setScale(
+            scale /* x scale */,
+            scale /* y scale */,
+            radius /* pivot x */,
+            radius /* pivot y */
+        )
         dotPath.transform(matrix)
 
         // Attach BubbleOverflow to BadgedImageView
@@ -132,8 +152,12 @@
     }
 
     fun createExpandedView(): BubbleExpandedView? {
-        expandedView = inflater.inflate(R.layout.bubble_expanded_view,
-                null /* root */, false /* attachToRoot */) as BubbleExpandedView
+        expandedView =
+            inflater.inflate(
+                R.layout.bubble_expanded_view,
+                null /* root */,
+                false /* attachToRoot */
+            ) as BubbleExpandedView
         expandedView?.applyThemeAttrs()
         updateResources()
         return expandedView
@@ -177,11 +201,15 @@
 
     override fun getIconView(): BadgedImageView? {
         if (overflowBtn == null) {
-            overflowBtn = inflater.inflate(R.layout.bubble_overflow_button,
-                    null /* root */, false /* attachToRoot */) as BadgedImageView
+            overflowBtn =
+                inflater.inflate(
+                    R.layout.bubble_overflow_button,
+                    null /* root */,
+                    false /* attachToRoot */
+                ) as BadgedImageView
             overflowBtn?.initialize(positioner)
-            overflowBtn?.contentDescription = context.resources.getString(
-                    R.string.bubble_overflow_button_content_description)
+            overflowBtn?.contentDescription =
+                context.resources.getString(R.string.bubble_overflow_button_content_description)
             val bubbleSize = positioner.bubbleSize
             overflowBtn?.layoutParams = FrameLayout.LayoutParams(bubbleSize, bubbleSize)
             updateBtnTheme()
@@ -200,4 +228,4 @@
     companion object {
         const val KEY = "Overflow"
     }
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index 9aa285f..9655470 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -220,8 +220,8 @@
                         : res.getColor(R.color.bubbles_light));
 
         final TypedArray typedArray = getContext().obtainStyledAttributes(new int[] {
-                android.R.attr.colorBackgroundFloating,
-                android.R.attr.textColorSecondary});
+                com.android.internal.R.attr.materialColorSurfaceBright,
+                com.android.internal.R.attr.materialColorOnSurface});
         int bgColor = typedArray.getColor(0, isNightMode ? Color.BLACK : Color.WHITE);
         int textColor = typedArray.getColor(1, isNightMode ? Color.WHITE : Color.BLACK);
         textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, isNightMode);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index f8f8897..b9ff5f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -282,6 +282,11 @@
     /** Whether the expanded view has been hidden, because we are dragging out a bubble. */
     private boolean mExpandedViewTemporarilyHidden = false;
 
+    /**
+     * Whether the last bubble is being removed when expanded, which impacts the collapse animation.
+     */
+    private boolean mRemovingLastBubbleWhileExpanded = false;
+
     /** Animator for animating the expanded view's alpha (including the TaskView inside it). */
     private final ValueAnimator mExpandedViewAlphaAnimator = ValueAnimator.ofFloat(0f, 1f);
 
@@ -765,7 +770,7 @@
 
                 // Update scrim
                 if (!mScrimAnimating) {
-                    showScrim(true);
+                    showScrim(true, null /* runnable */);
                 }
             }
         }
@@ -880,6 +885,7 @@
 
         final Runnable onBubbleAnimatedOut = () -> {
             if (getBubbleCount() == 0) {
+                mExpandedViewTemporarilyHidden = false;
                 mBubbleController.onAllBubblesAnimatedOut();
             }
         };
@@ -1007,6 +1013,7 @@
                         updatePointerPosition(false /* forIme */);
                         mExpandedAnimationController.expandFromStack(() -> {
                             afterExpandedViewAnimation();
+                            mExpandedViewContainer.setVisibility(VISIBLE);
                             showManageMenu(mShowingManage);
                         } /* after */);
                         PointF p = mPositioner.getExpandedBubbleXY(getBubbleIndex(mExpandedBubble),
@@ -1772,6 +1779,20 @@
         if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "removeBubble: " + bubble);
         }
+        if (isExpanded() && getBubbleCount() == 1) {
+            mRemovingLastBubbleWhileExpanded = true;
+            // We're expanded while the last bubble is being removed. Let the scrim animate away
+            // and then remove our views (removing the icon view triggers the removal of the
+            // bubble window so do that at the end of the animation so we see the scrim animate).
+            showScrim(false, () -> {
+                mRemovingLastBubbleWhileExpanded = false;
+                bubble.cleanupExpandedView();
+                mBubbleContainer.removeView(bubble.getIconView());
+                bubble.cleanupViews(); // cleans up the icon view
+                updateExpandedView(); // resets state for no expanded bubble
+            });
+            return;
+        }
         // Remove it from the views
         for (int i = 0; i < getBubbleCount(); i++) {
             View v = mBubbleContainer.getChildAt(i);
@@ -2142,7 +2163,7 @@
         mExpandedViewAlphaAnimator.start();
     }
 
-    private void showScrim(boolean show) {
+    private void showScrim(boolean show, Runnable after) {
         AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
@@ -2152,6 +2173,9 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 mScrimAnimating = false;
+                if (after != null) {
+                    after.run();
+                }
             }
         };
         if (show) {
@@ -2178,7 +2202,7 @@
         }
         beforeExpandedViewAnimation();
 
-        showScrim(true);
+        showScrim(true, null /* runnable */);
         updateZOrder();
         updateBadges(false /* setBadgeForCollapsedStack */);
         mBubbleContainer.setActiveController(mExpandedAnimationController);
@@ -2302,7 +2326,10 @@
         mIsExpanded = false;
         mIsExpansionAnimating = true;
 
-        showScrim(false);
+        if (!mRemovingLastBubbleWhileExpanded) {
+            // When we remove the last bubble it animates the scrim.
+            showScrim(false, null /* runnable */);
+        }
 
         mBubbleContainer.cancelAllAnimations();
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
index 0f9260c..9abf0f6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
@@ -38,7 +38,7 @@
 
     default void onTaskStackChanged() { }
 
-    default void onTaskProfileLocked(RunningTaskInfo taskInfo) { }
+    default void onTaskProfileLocked(RunningTaskInfo taskInfo, int userId) { }
 
     default void onTaskDisplayChanged(int taskId, int newDisplayId) { }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java
index e2106e4..d8859ba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java
@@ -150,8 +150,8 @@
     }
 
     @Override
-    public void onTaskProfileLocked(ActivityManager.RunningTaskInfo taskInfo) {
-        mMainHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, taskInfo).sendToTarget();
+    public void onTaskProfileLocked(ActivityManager.RunningTaskInfo taskInfo, int userId) {
+        mMainHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, userId, 0, taskInfo).sendToTarget();
     }
 
     @Override
@@ -348,8 +348,9 @@
                 case ON_TASK_PROFILE_LOCKED: {
                     final ActivityManager.RunningTaskInfo
                             info = (ActivityManager.RunningTaskInfo) msg.obj;
+                    final int userId = msg.arg1;
                     for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onTaskProfileLocked(info);
+                        mTaskStackListeners.get(i).onTaskProfileLocked(info, userId);
                     }
                     break;
                 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
index b0dea72..d27d05b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
@@ -35,6 +35,7 @@
 
     private String mKey; // Same key as the Notification
     private int mFlags;  // Flags from BubbleMetadata
+    @Nullable
     private String mShortcutId;
     private int mUserId;
     private String mPackageName;
@@ -46,7 +47,7 @@
     @Nullable
     private Icon mIcon;
 
-    public BubbleInfo(String key, int flags, String shortcutId, @Nullable Icon icon,
+    public BubbleInfo(String key, int flags, @Nullable String shortcutId, @Nullable Icon icon,
             int userId, String packageName) {
         mKey = key;
         mFlags = flags;
@@ -69,10 +70,12 @@
         return mKey;
     }
 
+    @Nullable
     public String getShortcutId() {
         return mShortcutId;
     }
 
+    @Nullable
     public Icon getIcon() {
         return mIcon;
     }
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 9eba5ec..e7dede7 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
@@ -738,10 +738,6 @@
         getRefBounds2(mTempRect);
         t.setPosition(leash2, mTempRect.left, mTempRect.top)
                 .setWindowCrop(leash2, mTempRect.width(), mTempRect.height());
-        // Make right or bottom side surface always higher than left or top side to avoid weird
-        // animation when dismiss split. e.g. App surface fling above on decor surface.
-        t.setLayer(leash1, 1);
-        t.setLayer(leash2, 2);
 
         if (mImePositionProcessor.adjustSurfaceLayoutForIme(
                 t, dividerLeash, leash1, leash2, dimLayer1, dimLayer2)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
index b8204d0..0bcafe5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
@@ -59,4 +59,17 @@
 
     /** Flag applied to a transition change to identify it as a divider bar for animation. */
     public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM;
+
+    public static final String splitPositionToString(@SplitPosition int pos) {
+        switch (pos) {
+            case SPLIT_POSITION_UNDEFINED:
+                return "SPLIT_POSITION_UNDEFINED";
+            case SPLIT_POSITION_TOP_OR_LEFT:
+                return "SPLIT_POSITION_TOP_OR_LEFT";
+            case SPLIT_POSITION_BOTTOM_OR_RIGHT:
+                return "SPLIT_POSITION_BOTTOM_OR_RIGHT";
+            default:
+                return "UNKNOWN";
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogLayout.java
index c53e638..05fd5f1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogLayout.java
@@ -95,6 +95,9 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
+        final View checkboxContainer = findViewById(
+                R.id.letterbox_restart_dialog_checkbox_container);
+        final CheckBox checkbox = findViewById(R.id.letterbox_restart_dialog_checkbox);
         mDialogContainer = findViewById(R.id.letterbox_restart_dialog_container);
         mDialogTitle = findViewById(R.id.letterbox_restart_dialog_title);
         mBackgroundDim = getBackground().mutate();
@@ -103,5 +106,6 @@
         // We add a no-op on-click listener to the dialog container so that clicks on it won't
         // propagate to the listener of the layout (which represents the background dim).
         mDialogContainer.setOnClickListener(view -> {});
+        checkboxContainer.setOnClickListener(view -> checkbox.performClick());
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java
index e9957fd..12d51f5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java
@@ -41,11 +41,11 @@
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
 
-import java.util.Optional;
-
 import dagger.Module;
 import dagger.Provides;
 
+import java.util.Optional;
+
 /**
  * Provides dependencies from {@link com.android.wm.shell}, these dependencies are only
  * accessible from components within the WM subcomponent (can be explicitly exposed to the
@@ -81,7 +81,7 @@
             DisplayController displayController,
             DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController,
-            DragAndDropController dragAndDropController,
+            Optional<DragAndDropController> dragAndDropController,
             Transitions transitions,
             TransactionPool transactionPool,
             IconProvider iconProvider,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 9808c59..80e920f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -186,15 +186,15 @@
 
     @WMSingleton
     @Provides
-    static DragAndDropController provideDragAndDropController(Context context,
+    static Optional<DragAndDropController> provideDragAndDropController(Context context,
             ShellInit shellInit,
             ShellController shellController,
             DisplayController displayController,
             UiEventLogger uiEventLogger,
             IconProvider iconProvider,
             @ShellMainThread ShellExecutor mainExecutor) {
-        return new DragAndDropController(context, shellInit, shellController, displayController,
-                uiEventLogger, iconProvider, mainExecutor);
+        return Optional.ofNullable(DragAndDropController.create(context, shellInit, shellController,
+                displayController, uiEventLogger, iconProvider, mainExecutor));
     }
 
     @WMSingleton
@@ -544,13 +544,14 @@
             DisplayController displayController,
             @ShellMainThread ShellExecutor mainExecutor,
             @ShellMainThread Handler mainHandler,
-            @ShellAnimationThread ShellExecutor animExecutor) {
+            @ShellAnimationThread ShellExecutor animExecutor,
+            ShellCommandHandler shellCommandHandler) {
         if (!context.getResources().getBoolean(R.bool.config_registerShellTransitionsOnInit)) {
             // TODO(b/238217847): Force override shell init if registration is disabled
             shellInit = new ShellInit(mainExecutor);
         }
         return new Transitions(context, shellInit, shellController, organizer, pool,
-                displayController, mainExecutor, mainHandler, animExecutor);
+                displayController, mainExecutor, mainHandler, animExecutor, shellCommandHandler);
     }
 
     @WMSingleton
@@ -796,7 +797,7 @@
             DisplayController displayController,
             DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController,
-            DragAndDropController dragAndDropController,
+            Optional<DragAndDropController> dragAndDropControllerOptional,
             ShellTaskOrganizer shellTaskOrganizer,
             Optional<BubbleController> bubblesOptional,
             Optional<SplitScreenController> splitScreenOptional,
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 d8e2f5c..f3130d3 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
@@ -171,7 +171,7 @@
             BubblePositioner positioner,
             DisplayController displayController,
             @DynamicOverride Optional<OneHandedController> oneHandedOptional,
-            DragAndDropController dragAndDropController,
+            Optional<DragAndDropController> dragAndDropController,
             @ShellMainThread ShellExecutor mainExecutor,
             @ShellMainThread Handler mainHandler,
             @ShellBackgroundThread ShellExecutor bgExecutor,
@@ -320,7 +320,7 @@
             DisplayController displayController,
             DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController,
-            DragAndDropController dragAndDropController,
+            Optional<DragAndDropController> dragAndDropController,
             Transitions transitions,
             TransactionPool transactionPool,
             IconProvider iconProvider,
@@ -634,14 +634,8 @@
 
     @WMSingleton
     @Provides
-    static UnfoldBackgroundController provideUnfoldBackgroundController(
-            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
-            Context context
-    ) {
-        return new UnfoldBackgroundController(
-                context,
-                rootTaskDisplayAreaOrganizer
-        );
+    static UnfoldBackgroundController provideUnfoldBackgroundController(Context context) {
+        return new UnfoldBackgroundController(context);
     }
 
     //
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 86ea725..b9d2be2 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
@@ -264,10 +264,10 @@
     /**
      * Show apps on desktop
      */
-    void showDesktopApps() {
+    void showDesktopApps(int displayId) {
         // Bring apps to front, ignoring their visibility status to always ensure they are on top.
         WindowContainerTransaction wct = new WindowContainerTransaction();
-        bringDesktopAppsToFront(wct);
+        bringDesktopAppsToFront(displayId, wct);
 
         if (!wct.isEmpty()) {
             if (Transitions.ENABLE_SHELL_TRANSITIONS) {
@@ -280,12 +280,12 @@
     }
 
     /** Get number of tasks that are marked as visible */
-    int getVisibleTaskCount() {
-        return mDesktopModeTaskRepository.getVisibleTaskCount();
+    int getVisibleTaskCount(int displayId) {
+        return mDesktopModeTaskRepository.getVisibleTaskCount(displayId);
     }
 
-    private void bringDesktopAppsToFront(WindowContainerTransaction wct) {
-        final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks();
+    private void bringDesktopAppsToFront(int displayId, WindowContainerTransaction wct) {
+        final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks(displayId);
         ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size());
 
         final List<RunningTaskInfo> taskInfos = new ArrayList<>();
@@ -386,6 +386,7 @@
     @Override
     public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
             @NonNull TransitionRequestInfo request) {
+        RunningTaskInfo triggerTask = request.getTriggerTask();
         // Only do anything if we are in desktop mode and opening/moving-to-front a task/app in
         // freeform
         if (!DesktopModeStatus.isActive(mContext)) {
@@ -399,16 +400,15 @@
                     WindowManager.transitTypeToString(request.getType()));
             return null;
         }
-        if (request.getTriggerTask() == null
-                || request.getTriggerTask().getWindowingMode() != WINDOWING_MODE_FREEFORM) {
+        if (triggerTask == null || triggerTask.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
             ProtoLog.d(WM_SHELL_DESKTOP_MODE, "skip shell transition request: not freeform task");
             return null;
         }
         ProtoLog.d(WM_SHELL_DESKTOP_MODE, "handle shell transition request: %s", request);
 
         WindowContainerTransaction wct = new WindowContainerTransaction();
-        bringDesktopAppsToFront(wct);
-        wct.reorder(request.getTriggerTask().token, true /* onTop */);
+        bringDesktopAppsToFront(triggerTask.displayId, wct);
+        wct.reorder(triggerTask.token, true /* onTop */);
 
         return wct;
     }
@@ -493,16 +493,17 @@
             mController = null;
         }
 
-        public void showDesktopApps() {
+        @Override
+        public void showDesktopApps(int displayId) {
             executeRemoteCallWithTaskPermission(mController, "showDesktopApps",
-                    DesktopModeController::showDesktopApps);
+                    controller -> controller.showDesktopApps(displayId));
         }
 
         @Override
-        public int getVisibleTaskCount() throws RemoteException {
+        public int getVisibleTaskCount(int displayId) throws RemoteException {
             int[] result = new int[1];
             executeRemoteCallWithTaskPermission(mController, "getVisibleTaskCount",
-                    controller -> result[0] = controller.getVisibleTaskCount(),
+                    controller -> result[0] = controller.getVisibleTaskCount(displayId),
                     true /* blocking */
             );
             return result[0];
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
index 055949f..d1760ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
@@ -43,6 +43,12 @@
             "persist.wm.debug.desktop_mode_2", false);
 
     /**
+     * Flag to indicate whether task resizing is veiled.
+     */
+    private static final boolean IS_VEILED_RESIZE_ENABLED = SystemProperties.getBoolean(
+            "persist.wm.debug.desktop_veiled_resizing", true);
+
+    /**
      * Return {@code true} if desktop mode support is enabled
      */
     public static boolean isProto1Enabled() {
@@ -65,6 +71,13 @@
     }
 
     /**
+     * Return {@code true} if veiled resizing is active. If false, fluid resizing is used.
+     */
+    public static boolean isVeiledResizeEnabled() {
+        return IS_VEILED_RESIZE_ENABLED;
+    }
+
+    /**
      * Check if desktop mode is active
      *
      * @return {@code true} if active
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
index 12f8ea2..00cc57f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
@@ -20,6 +20,8 @@
 import android.util.ArrayMap
 import android.util.ArraySet
 import android.util.SparseArray
+import androidx.core.util.forEach
+import androidx.core.util.keyIterator
 import androidx.core.util.valueIterator
 import java.util.concurrent.Executor
 import java.util.function.Consumer
@@ -29,14 +31,18 @@
  */
 class DesktopModeTaskRepository {
 
-    /**
-     * Set of task ids that are marked as active in desktop mode.
-     * Active tasks in desktop mode are freeform tasks that are visible or have been visible after
-     * desktop mode was activated.
-     * Task gets removed from this list when it vanishes. Or when desktop mode is turned off.
-     */
-    private val activeTasks = ArraySet<Int>()
-    private val visibleTasks = ArraySet<Int>()
+    /** Task data that is tracked per display */
+    private data class DisplayData(
+        /**
+         * Set of task ids that are marked as active in desktop mode. Active tasks in desktop mode
+         * are freeform tasks that are visible or have been visible after desktop mode was
+         * activated. Task gets removed from this list when it vanishes. Or when desktop mode is
+         * turned off.
+         */
+        val activeTasks: ArraySet<Int> = ArraySet(),
+        val visibleTasks: ArraySet<Int> = ArraySet(),
+    )
+
     // Tasks currently in freeform mode, ordered from top to bottom (top is at index 0).
     private val freeformTasksInZOrder = mutableListOf<Int>()
     private val activeTasksListeners = ArraySet<ActiveTasksListener>()
@@ -47,9 +53,22 @@
     private var desktopGestureExclusionListener: Consumer<Region>? = null
     private var desktopGestureExclusionExecutor: Executor? = null
 
-    /**
-     * Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository.
-     */
+    private val displayData =
+        object : SparseArray<DisplayData>() {
+            /**
+             * Get the [DisplayData] associated with this [displayId]
+             *
+             * Creates a new instance if one does not exist
+             */
+            fun getOrCreate(displayId: Int): DisplayData {
+                if (!contains(displayId)) {
+                    put(displayId, DisplayData())
+                }
+                return get(displayId)
+            }
+        }
+
+    /** Add a [ActiveTasksListener] to be notified of updates to active tasks in the repository. */
     fun addActiveTaskListener(activeTasksListener: ActiveTasksListener) {
         activeTasksListeners.add(activeTasksListener)
     }
@@ -57,10 +76,17 @@
     /**
      * Add a [VisibleTasksListener] to be notified when freeform tasks are visible or not.
      */
-    fun addVisibleTasksListener(visibleTasksListener: VisibleTasksListener, executor: Executor) {
-        visibleTasksListeners.put(visibleTasksListener, executor)
-        executor.execute(
-                Runnable { visibleTasksListener.onVisibilityChanged(visibleTasks.size > 0) })
+    fun addVisibleTasksListener(
+        visibleTasksListener: VisibleTasksListener,
+        executor: Executor
+    ) {
+        visibleTasksListeners[visibleTasksListener] = executor
+        displayData.keyIterator().forEach { displayId ->
+            val visibleTasks = getVisibleTaskCount(displayId)
+            executor.execute {
+                visibleTasksListener.onVisibilityChanged(displayId, visibleTasks > 0)
+            }
+        }
     }
 
     /**
@@ -100,14 +126,21 @@
     }
 
     /**
-     * Mark a task with given [taskId] as active.
+     * Mark a task with given [taskId] as active on given [displayId]
      *
-     * @return `true` if the task was not active
+     * @return `true` if the task was not active on given [displayId]
      */
-    fun addActiveTask(taskId: Int): Boolean {
-        val added = activeTasks.add(taskId)
+    fun addActiveTask(displayId: Int, taskId: Int): Boolean {
+        // Check if task is active on another display, if so, remove it
+        displayData.forEach { id, data ->
+            if (id != displayId && data.activeTasks.remove(taskId)) {
+                activeTasksListeners.onEach { it.onActiveTasksChanged(id) }
+            }
+        }
+
+        val added = displayData.getOrCreate(displayId).activeTasks.add(taskId)
         if (added) {
-            activeTasksListeners.onEach { it.onActiveTasksChanged() }
+            activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) }
         }
         return added
     }
@@ -118,65 +151,93 @@
      * @return `true` if the task was active
      */
     fun removeActiveTask(taskId: Int): Boolean {
-        val removed = activeTasks.remove(taskId)
-        if (removed) {
-            activeTasksListeners.onEach { it.onActiveTasksChanged() }
+        var result = false
+        displayData.forEach { displayId, data ->
+            if (data.activeTasks.remove(taskId)) {
+                activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) }
+                result = true
+            }
         }
-        return removed
+        return result
     }
 
     /**
      * Check if a task with the given [taskId] was marked as an active task
      */
     fun isActiveTask(taskId: Int): Boolean {
-        return activeTasks.contains(taskId)
+        return displayData.valueIterator().asSequence().any { data ->
+            data.activeTasks.contains(taskId)
+        }
     }
 
     /**
      * Whether a task is visible.
      */
     fun isVisibleTask(taskId: Int): Boolean {
-        return visibleTasks.contains(taskId)
+        return displayData.valueIterator().asSequence().any { data ->
+            data.visibleTasks.contains(taskId)
+        }
     }
 
     /**
-     * Get a set of the active tasks
+     * Get a set of the active tasks for given [displayId]
      */
-    fun getActiveTasks(): ArraySet<Int> {
-        return ArraySet(activeTasks)
+    fun getActiveTasks(displayId: Int): ArraySet<Int> {
+        return ArraySet(displayData[displayId]?.activeTasks)
     }
 
     /**
      * Get a list of freeform tasks, ordered from top-bottom (top at index 0).
      */
+     // TODO(b/278084491): pass in display id
     fun getFreeformTasksInZOrder(): List<Int> {
         return freeformTasksInZOrder
     }
 
     /**
      * Updates whether a freeform task with this id is visible or not and notifies listeners.
+     *
+     * If the task was visible on a different display with a different displayId, it is removed from
+     * the set of visible tasks on that display. Listeners will be notified.
      */
-    fun updateVisibleFreeformTasks(taskId: Int, visible: Boolean) {
-        val prevCount: Int = visibleTasks.size
+    fun updateVisibleFreeformTasks(displayId: Int, taskId: Int, visible: Boolean) {
         if (visible) {
-            visibleTasks.add(taskId)
-        } else {
-            visibleTasks.remove(taskId)
-        }
-        if (prevCount == 0 && visibleTasks.size == 1 ||
-                prevCount > 0 && visibleTasks.size == 0) {
-            for ((listener, executor) in visibleTasksListeners) {
-                executor.execute(
-                        Runnable { listener.onVisibilityChanged(visibleTasks.size > 0) })
+            // Task is visible. Check if we need to remove it from any other display.
+            val otherDisplays = displayData.keyIterator().asSequence().filter { it != displayId }
+            for (otherDisplayId in otherDisplays) {
+                if (displayData[otherDisplayId].visibleTasks.remove(taskId)) {
+                    // Task removed from other display, check if we should notify listeners
+                    if (displayData[otherDisplayId].visibleTasks.isEmpty()) {
+                        notifyVisibleTaskListeners(otherDisplayId, hasVisibleFreeformTasks = false)
+                    }
+                }
             }
         }
+
+        val prevCount = getVisibleTaskCount(displayId)
+        if (visible) {
+            displayData.getOrCreate(displayId).visibleTasks.add(taskId)
+        } else {
+            displayData[displayId]?.visibleTasks?.remove(taskId)
+        }
+        val newCount = getVisibleTaskCount(displayId)
+        // Check if count changed and if there was no tasks or this is the first task
+        if (prevCount != newCount && (prevCount == 0 || newCount == 0)) {
+            notifyVisibleTaskListeners(displayId, newCount > 0)
+        }
+    }
+
+    private fun notifyVisibleTaskListeners(displayId: Int, hasVisibleFreeformTasks: Boolean) {
+        visibleTasksListeners.forEach { (listener, executor) ->
+            executor.execute { listener.onVisibilityChanged(displayId, hasVisibleFreeformTasks) }
+        }
     }
 
     /**
-     * Get number of tasks that are marked as visible
+     * Get number of tasks that are marked as visible on given [displayId]
      */
-    fun getVisibleTaskCount(): Int {
-        return visibleTasks.size
+    fun getVisibleTaskCount(displayId: Int): Int {
+        return displayData[displayId]?.visibleTasks?.size ?: 0
     }
 
     /**
@@ -226,7 +287,7 @@
          * Called when the active tasks change in desktop mode.
          */
         @JvmDefault
-        fun onActiveTasksChanged() {}
+        fun onActiveTasksChanged(displayId: Int) {}
     }
 
     /**
@@ -237,6 +298,6 @@
          * Called when the desktop starts or stops showing freeform tasks.
          */
         @JvmDefault
-        fun onVisibilityChanged(hasVisibleFreeformTasks: Boolean) {}
+        fun onVisibilityChanged(displayId: Int, hasVisibleFreeformTasks: Boolean) {}
     }
 }
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 0d56023..c814fe5 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
@@ -97,10 +97,11 @@
     }
 
     /** Show all tasks, that are part of the desktop, on top of launcher */
-    fun showDesktopApps() {
+    fun showDesktopApps(displayId: Int) {
         ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps")
         val wct = WindowContainerTransaction()
-        bringDesktopAppsToFront(wct)
+        // TODO(b/278084491): pass in display id
+        bringDesktopAppsToFront(displayId, wct)
 
         // Execute transaction if there are pending operations
         if (!wct.isEmpty) {
@@ -114,8 +115,8 @@
     }
 
     /** Get number of tasks that are marked as visible */
-    fun getVisibleTaskCount(): Int {
-        return desktopModeTaskRepository.getVisibleTaskCount()
+    fun getVisibleTaskCount(displayId: Int): Int {
+        return desktopModeTaskRepository.getVisibleTaskCount(displayId)
     }
 
     /** Move a task with given `taskId` to desktop */
@@ -129,7 +130,7 @@
 
         val wct = WindowContainerTransaction()
         // Bring other apps to front first
-        bringDesktopAppsToFront(wct)
+        bringDesktopAppsToFront(task.displayId, wct)
         addMoveToDesktopChanges(wct, task.token)
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
             transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */)
@@ -165,7 +166,7 @@
             freeformBounds: Rect
     ) {
         val wct = WindowContainerTransaction()
-        bringDesktopAppsToFront(wct)
+        bringDesktopAppsToFront(taskInfo.displayId, wct)
         addMoveToDesktopChanges(wct, taskInfo.getToken())
         wct.setBounds(taskInfo.token, freeformBounds)
 
@@ -244,9 +245,9 @@
             ?: WINDOWING_MODE_UNDEFINED
     }
 
-    private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) {
+    private fun bringDesktopAppsToFront(displayId: Int, wct: WindowContainerTransaction) {
         ProtoLog.v(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront")
-        val activeTasks = desktopModeTaskRepository.getActiveTasks()
+        val activeTasks = desktopModeTaskRepository.getActiveTasks(displayId)
 
         // First move home to front and then other tasks on top of it
         moveHomeTaskToFront(wct)
@@ -290,18 +291,17 @@
         request: TransitionRequestInfo
     ): WindowContainerTransaction? {
         // Check if we should skip handling this transition
-        val task: RunningTaskInfo? = request.triggerTask
         val shouldHandleRequest =
             when {
                 // Only handle open or to front transitions
                 request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> false
                 // Only handle when it is a task transition
-                task == null -> false
+                request.triggerTask == null -> false
                 // Only handle standard type tasks
-                task.activityType != ACTIVITY_TYPE_STANDARD -> false
+                request.triggerTask.activityType != ACTIVITY_TYPE_STANDARD -> false
                 // Only handle fullscreen or freeform tasks
-                task.windowingMode != WINDOWING_MODE_FULLSCREEN &&
-                    task.windowingMode != WINDOWING_MODE_FREEFORM -> false
+                request.triggerTask.windowingMode != WINDOWING_MODE_FULLSCREEN &&
+                        request.triggerTask.windowingMode != WINDOWING_MODE_FREEFORM -> false
                 // Otherwise process it
                 else -> true
             }
@@ -310,10 +310,11 @@
             return null
         }
 
-        val activeTasks = desktopModeTaskRepository.getActiveTasks()
+        val task: RunningTaskInfo = request.triggerTask
+        val activeTasks = desktopModeTaskRepository.getActiveTasks(task.displayId)
 
         // Check if we should switch a fullscreen task to freeform
-        if (task?.windowingMode == WINDOWING_MODE_FULLSCREEN) {
+        if (task.windowingMode == WINDOWING_MODE_FULLSCREEN) {
             // If there are any visible desktop tasks, switch the task to freeform
             if (activeTasks.any { desktopModeTaskRepository.isVisibleTask(it) }) {
                 ProtoLog.d(
@@ -329,7 +330,7 @@
         }
 
         // CHeck if we should switch a freeform task to fullscreen
-        if (task?.windowingMode == WINDOWING_MODE_FREEFORM) {
+        if (task.windowingMode == WINDOWING_MODE_FREEFORM) {
             // If no visible desktop tasks, switch this task to freeform as the transition came
             // outside of this controller
             if (activeTasks.none { desktopModeTaskRepository.isVisibleTask(it) }) {
@@ -559,20 +560,19 @@
             controller = null
         }
 
-        override fun showDesktopApps() {
+        override fun showDesktopApps(displayId: Int) {
             ExecutorUtils.executeRemoteCallWithTaskPermission(
                 controller,
-                "showDesktopApps",
-                Consumer(DesktopTasksController::showDesktopApps)
-            )
+                "showDesktopApps"
+            ) { c -> c.showDesktopApps(displayId) }
         }
 
-        override fun getVisibleTaskCount(): Int {
+        override fun getVisibleTaskCount(displayId: Int): Int {
             val result = IntArray(1)
             ExecutorUtils.executeRemoteCallWithTaskPermission(
                 controller,
                 "getVisibleTaskCount",
-                { controller -> result[0] = controller.getVisibleTaskCount() },
+                { controller -> result[0] = controller.getVisibleTaskCount(displayId) },
                 true /* blocking */
             )
             return result[0]
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
index 27eda16..9467578 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
@@ -193,8 +193,11 @@
             // This Transition animates a task to fullscreen after being dragged from the status
             // bar and then released back into the status bar area
             final SurfaceControl sc = change.getLeash();
-            startT.setWindowCrop(sc, null);
-            startT.apply();
+            // Hide the first (fullscreen) frame because the animation will start from the smaller
+            // scale size.
+            startT.hide(sc)
+                    .setWindowCrop(sc, endBounds.width(), endBounds.height())
+                    .apply();
 
             final ValueAnimator animator = new ValueAnimator();
             animator.setFloatValues(DRAG_FREEFORM_SCALE, 1f);
@@ -202,10 +205,10 @@
             final SurfaceControl.Transaction t = mTransactionSupplier.get();
             animator.addUpdateListener(animation -> {
                 final float scale = animation.getAnimatedFraction();
-                t.setPosition(sc, mStartPosition.x * (1 - scale),
-                        mStartPosition.y * (1 - scale));
-                t.setScale(sc, scale, scale);
-                t.apply();
+                t.setPosition(sc, mStartPosition.x * (1 - scale), mStartPosition.y * (1 - scale))
+                        .setScale(sc, scale, scale)
+                        .show(sc)
+                        .apply();
             });
             animator.addListener(new AnimatorListenerAdapter() {
                 @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
index 248a5fc..fa3eee2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
@@ -129,8 +129,12 @@
             final int screenWidth = metrics.widthPixels;
             final int screenHeight = metrics.heightPixels;
             final SurfaceControl sc = change.getLeash();
-            startT.setCrop(sc, null);
-            startT.apply();
+            final Rect endBounds = change.getEndAbsBounds();
+            // Hide the first (fullscreen) frame because the animation will start from the freeform
+            // size.
+            startT.hide(sc)
+                    .setWindowCrop(sc, endBounds.width(), endBounds.height())
+                    .apply();
             final ValueAnimator animator = new ValueAnimator();
             animator.setFloatValues(0f, 1f);
             animator.setDuration(FULLSCREEN_ANIMATION_DURATION);
@@ -144,9 +148,10 @@
                 float fraction = animation.getAnimatedFraction();
                 float currentScaleX = scaleX + ((1 - scaleX) * fraction);
                 float currentScaleY = scaleY + ((1 - scaleY) * fraction);
-                t.setPosition(sc, startPos.x * (1 - fraction), startPos.y * (1 - fraction));
-                t.setScale(sc, currentScaleX, currentScaleY);
-                t.apply();
+                t.setPosition(sc, startPos.x * (1 - fraction), startPos.y * (1 - fraction))
+                        .setScale(sc, currentScaleX, currentScaleY)
+                        .show(sc)
+                        .apply();
             });
             animator.addListener(new AnimatorListenerAdapter() {
                 @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
index d0739e1..899d672 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
@@ -21,9 +21,9 @@
  */
 interface IDesktopMode {
 
-    /** Show apps on the desktop */
-    void showDesktopApps();
+    /** Show apps on the desktop on the given display */
+    void showDesktopApps(int displayId);
 
-    /** Get count of visible desktop tasks */
-    int getVisibleTaskCount();
+    /** Get count of visible desktop tasks on the given display */
+    int getVisibleTaskCount(int displayId);
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
index 4cfaae6..091de3a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
@@ -94,7 +94,24 @@
         void onDragStarted();
     }
 
-    public DragAndDropController(Context context,
+    /**
+     * Creates {@link DragAndDropController}. Returns {@code null} if the feature is disabled.
+     */
+    public static DragAndDropController create(Context context,
+            ShellInit shellInit,
+            ShellController shellController,
+            DisplayController displayController,
+            UiEventLogger uiEventLogger,
+            IconProvider iconProvider,
+            ShellExecutor mainExecutor) {
+        if (!context.getResources().getBoolean(R.bool.config_enableShellDragDrop)) {
+            return null;
+        }
+        return new DragAndDropController(context, shellInit, shellController, displayController,
+                uiEventLogger, iconProvider, mainExecutor);
+    }
+
+    DragAndDropController(Context context,
             ShellInit shellInit,
             ShellController shellController,
             DisplayController displayController,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 48487bc..22541bbd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -94,11 +94,12 @@
             mDesktopModeTaskRepository.ifPresent(repository -> {
                 repository.addOrMoveFreeformTaskToTop(taskInfo.taskId);
                 if (taskInfo.isVisible) {
-                    if (repository.addActiveTask(taskInfo.taskId)) {
+                    if (repository.addActiveTask(taskInfo.displayId, taskInfo.taskId)) {
                         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                                 "Adding active freeform task: #%d", taskInfo.taskId);
                     }
-                    repository.updateVisibleFreeformTasks(taskInfo.taskId, true);
+                    repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId,
+                            true);
                 }
             });
         }
@@ -117,7 +118,7 @@
                     ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                             "Removing active freeform task: #%d", taskInfo.taskId);
                 }
-                repository.updateVisibleFreeformTasks(taskInfo.taskId, false);
+                repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId, false);
             });
         }
 
@@ -137,12 +138,13 @@
         if (DesktopModeStatus.isAnyEnabled()) {
             mDesktopModeTaskRepository.ifPresent(repository -> {
                 if (taskInfo.isVisible) {
-                    if (repository.addActiveTask(taskInfo.taskId)) {
+                    if (repository.addActiveTask(taskInfo.displayId, taskInfo.taskId)) {
                         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                                 "Adding active freeform task: #%d", taskInfo.taskId);
                     }
                 }
-                repository.updateVisibleFreeformTasks(taskInfo.taskId, taskInfo.isVisible);
+                repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId,
+                        taskInfo.isVisible);
             });
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
index e1a56a1..6b6a7bc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
@@ -153,6 +153,8 @@
 
     @Override
     public void onTransitionMerged(@NonNull IBinder merged, @NonNull IBinder playing) {
+        mWindowDecorViewModel.onTransitionMerged(merged, playing);
+
         final List<ActivityManager.RunningTaskInfo> infoOfMerged =
                 mTransitionToTaskInfo.get(merged);
         if (infoOfMerged == null) {
@@ -169,8 +171,6 @@
         } else {
             mTransitionToTaskInfo.put(playing, infoOfMerged);
         }
-
-        mWindowDecorViewModel.onTransitionMerged(merged, playing);
     }
 
     @Override
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 566c130..d3e7f9c 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
@@ -72,7 +72,6 @@
 import android.window.TaskSnapshot;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
-import android.window.WindowContainerTransactionCallback;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
@@ -139,17 +138,6 @@
     // the runnable to execute after WindowContainerTransactions is applied to finish resizing pip
     private Runnable mPipFinishResizeWCTRunnable;
 
-    private final WindowContainerTransactionCallback mPipFinishResizeWCTCallback =
-            new WindowContainerTransactionCallback() {
-        @Override
-        public void onTransactionReady(int id, SurfaceControl.Transaction t) {
-            t.apply();
-
-            // execute the runnable if non-null after WCT is applied to finish resizing pip
-            maybePerformFinishResizeCallback();
-        }
-    };
-
     private void maybePerformFinishResizeCallback() {
         if (mPipFinishResizeWCTRunnable != null) {
             mPipFinishResizeWCTRunnable.run();
@@ -175,6 +163,7 @@
             final int direction = animator.getTransitionDirection();
             if (mIsCancelled) {
                 sendOnPipTransitionFinished(direction);
+                maybePerformFinishResizeCallback();
                 return;
             }
             final int animationType = animator.getAnimationType();
@@ -199,6 +188,10 @@
                     || isRemovePipDirection(direction);
             if (mPipTransitionState.getTransitionState() != PipTransitionState.EXITING_PIP
                     || isExitPipDirection) {
+                // execute the finish resize callback if needed after the transaction is committed
+                tx.addTransactionCommittedListener(mMainExecutor,
+                        PipTaskOrganizer.this::maybePerformFinishResizeCallback);
+
                 // Finish resize as long as we're not exiting PIP, or, if we are, only if this is
                 // the end of an exit PIP animation.
                 // This is necessary in case there was a resize animation ongoing when exit PIP
@@ -1614,12 +1607,8 @@
         if (direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
             mSplitScreenOptional.ifPresent(splitScreenController ->
                     splitScreenController.enterSplitScreen(mTaskInfo.taskId, wasPipTopLeft, wct));
-        } else if (direction == TRANSITION_DIRECTION_LEAVE_PIP) {
-            // when leaving PiP we can call the callback without sync
-            maybePerformFinishResizeCallback();
-            mTaskOrganizer.applyTransaction(wct);
         } else {
-            mTaskOrganizer.applySyncTransaction(wct, mPipFinishResizeWCTCallback);
+            mTaskOrganizer.applyTransaction(wct);
         }
     }
 
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 b0bb14b..f8e1435 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
@@ -1060,13 +1060,22 @@
     /** Save the state to restore to on re-entry. */
     public void saveReentryState(Rect pipBounds) {
         float snapFraction = mPipBoundsAlgorithm.getSnapFraction(pipBounds);
-        if (mPipBoundsState.hasUserResizedPip()) {
-            final Rect reentryBounds = mTouchHandler.getUserResizeBounds();
-            final Size reentrySize = new Size(reentryBounds.width(), reentryBounds.height());
-            mPipBoundsState.saveReentryState(reentrySize, snapFraction);
-        } else {
+
+        if (!mPipBoundsState.hasUserResizedPip()) {
             mPipBoundsState.saveReentryState(null /* bounds */, snapFraction);
+            return;
         }
+
+        Size reentrySize = new Size(pipBounds.width(), pipBounds.height());
+
+        // TODO: b/279937014 Investigate why userResizeBounds are empty with shell transitions on
+        // fallback to using the userResizeBounds if userResizeBounds are not empty
+        if (!mTouchHandler.getUserResizeBounds().isEmpty()) {
+            Rect userResizeBounds = mTouchHandler.getUserResizeBounds();
+            reentrySize = new Size(userResizeBounds.width(), userResizeBounds.height());
+        }
+
+        mPipBoundsState.saveReentryState(reentrySize, snapFraction);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index 956af70..281cae5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -104,6 +104,7 @@
     private boolean mAllowGesture;
     private boolean mIsAttached;
     private boolean mIsEnabled;
+    private boolean mEnableTouch;
     private boolean mEnablePinchResize;
     private boolean mEnableDragCornerResize;
     private boolean mIsSysUiStateValid;
@@ -138,6 +139,7 @@
         mPhonePipMenuController = menuActivityController;
         mPipUiEventLogger = pipUiEventLogger;
         mPinchResizingAlgorithm = new PipPinchResizingAlgorithm();
+        mEnableTouch = true;
 
         mUpdateResizeBoundsCallback = (rect) -> {
             mUserResizeBounds.set(rect);
@@ -248,6 +250,11 @@
             return;
         }
 
+        if (!mEnableTouch) {
+            // No need to handle anything if touches are not enabled for resizing.
+            return;
+        }
+
         // Don't allow resize when PiP is stashed.
         if (mPipBoundsState.isStashed()) {
             return;
@@ -581,14 +588,13 @@
                         mLastResizeBounds, movementBounds);
                 mPipBoundsAlgorithm.applySnapFraction(mLastResizeBounds, snapFraction);
 
-                // disable the pinch resizing until the final bounds are updated
-                final boolean prevEnablePinchResize = mEnablePinchResize;
-                mEnablePinchResize = false;
+                // disable the resizing until the final bounds are updated
+                mEnableTouch = false;
 
                 mPipTaskOrganizer.scheduleAnimateResizePip(startBounds, mLastResizeBounds,
                         PINCH_RESIZE_SNAP_DURATION, mAngle, mUpdateResizeBoundsCallback, () -> {
                             // reset the pinch resizing to its default state
-                            mEnablePinchResize = prevEnablePinchResize;
+                            mEnableTouch = true;
                         });
             } else {
                 mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
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 c5bfd87..5c9709c 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
@@ -245,7 +245,7 @@
     }
 
     @Override
-    public void onActiveTasksChanged() {
+    public void onActiveTasksChanged(int displayId) {
         notifyRecentTasksChanged();
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index bf1509a..3e568e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -552,6 +552,14 @@
                 // are in mOpening.
                 for (int i = 0; i < closingTasks.size(); ++i) {
                     final TransitionInfo.Change change = closingTasks.get(i);
+                    final int pausingIdx = TaskState.indexOf(mPausingTasks, change);
+                    if (pausingIdx >= 0) {
+                        mPausingTasks.remove(pausingIdx);
+                        didMergeThings = true;
+                        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                                "  closing pausing taskId=%d", change.getTaskInfo().taskId);
+                        continue;
+                    }
                     int openingIdx = TaskState.indexOf(mOpeningTasks, change);
                     if (openingIdx < 0) {
                         Slog.w(TAG, "Closing a task that wasn't opening, this may be split or"
@@ -604,6 +612,11 @@
                 didMergeThings = true;
                 mState = STATE_NEW_TASK;
             }
+            if (mPausingTasks.isEmpty()) {
+                // The pausing tasks may be removed by the incoming closing tasks.
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "[%d] RecentsController.merge: empty pausing tasks", mInstanceId);
+            }
             if (!hasTaskChange) {
                 // Activity only transition, so consume the merge as it doesn't affect the rest of
                 // recents.
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 498f95c..af52350 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
@@ -165,7 +165,7 @@
     private final DisplayController mDisplayController;
     private final DisplayImeController mDisplayImeController;
     private final DisplayInsetsController mDisplayInsetsController;
-    private final DragAndDropController mDragAndDropController;
+    private final Optional<DragAndDropController> mDragAndDropController;
     private final Transitions mTransitions;
     private final TransactionPool mTransactionPool;
     private final IconProvider mIconProvider;
@@ -191,7 +191,7 @@
             DisplayController displayController,
             DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController,
-            DragAndDropController dragAndDropController,
+            Optional<DragAndDropController> dragAndDropController,
             Transitions transitions,
             TransactionPool transactionPool,
             IconProvider iconProvider,
@@ -253,7 +253,7 @@
         mDisplayController = displayController;
         mDisplayImeController = displayImeController;
         mDisplayInsetsController = displayInsetsController;
-        mDragAndDropController = dragAndDropController;
+        mDragAndDropController = Optional.of(dragAndDropController);
         mTransitions = transitions;
         mTransactionPool = transactionPool;
         mIconProvider = iconProvider;
@@ -289,7 +289,7 @@
             // TODO: Multi-display
             mStageCoordinator = createStageCoordinator();
         }
-        mDragAndDropController.setSplitScreenController(this);
+        mDragAndDropController.ifPresent(controller -> controller.setSplitScreenController(this));
     }
 
     protected StageCoordinator createStageCoordinator() {
@@ -359,6 +359,9 @@
         if (task == null) {
             throw new IllegalArgumentException("Unknown taskId" + taskId);
         }
+        if (isTaskInSplitScreen(taskId)) {
+            throw new IllegalArgumentException("taskId is in split" + taskId);
+        }
         return mStageCoordinator.moveToStage(task, stagePosition, wct);
     }
 
@@ -457,7 +460,7 @@
                 }
             }
             @Override
-            public void onAnimationCancelled(boolean isKeyguardOccluded) {
+            public void onAnimationCancelled() {
                 final WindowContainerTransaction evictWct = new WindowContainerTransaction();
                 mStageCoordinator.prepareEvictInvisibleChildTasks(evictWct);
                 mSyncQueue.queue(evictWct);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index 51b8000..a2af93f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -30,8 +30,6 @@
 import static com.android.wm.shell.splitscreen.SplitScreenController.exitReasonToString;
 import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_DISMISS;
 import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_DISMISS_SNAP;
-import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE;
-import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -165,7 +163,7 @@
                 t.setLayer(leash, Integer.MAX_VALUE);
                 t.show(leash);
             }
-            boolean isOpening = isOpeningTransition(info);
+            boolean isOpening = TransitionUtil.isOpeningType(info.getType());
             if (isOpening && (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
                 // fade in
                 startExampleAnimation(leash, true /* show */);
@@ -295,14 +293,16 @@
             @Nullable RemoteTransition remoteTransition,
             Transitions.TransitionHandler handler,
             @Nullable TransitionConsumedCallback consumedCallback,
-            @Nullable TransitionFinishedCallback finishedCallback) {
+            @Nullable TransitionFinishedCallback finishedCallback,
+            int extraTransitType) {
         if (mPendingEnter != null) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  splitTransition "
                     + " skip to start enter split transition since it already exist. ");
             return null;
         }
         final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
-        setEnterTransition(transition, remoteTransition, consumedCallback, finishedCallback);
+        setEnterTransition(transition, remoteTransition, consumedCallback, finishedCallback,
+                extraTransitType);
         return transition;
     }
 
@@ -310,9 +310,10 @@
     void setEnterTransition(@NonNull IBinder transition,
             @Nullable RemoteTransition remoteTransition,
             @Nullable TransitionConsumedCallback consumedCallback,
-            @Nullable TransitionFinishedCallback finishedCallback) {
+            @Nullable TransitionFinishedCallback finishedCallback,
+            int extraTransitType) {
         mPendingEnter = new TransitSession(
-                transition, consumedCallback, finishedCallback, remoteTransition);
+                transition, consumedCallback, finishedCallback, remoteTransition, extraTransitType);
 
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  splitTransition "
                 + " deduced Enter split screen");
@@ -513,12 +514,6 @@
         mTransitions.getAnimExecutor().execute(va::start);
     }
 
-    private boolean isOpeningTransition(TransitionInfo info) {
-        return TransitionUtil.isOpeningType(info.getType())
-                || info.getType() == TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE
-                || info.getType() == TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
-    }
-
     /** Calls when the transition got consumed. */
     interface TransitionConsumedCallback {
         void onConsumed(boolean aborted);
@@ -539,16 +534,19 @@
         /** Whether the transition was canceled. */
         boolean mCanceled;
 
+        /** A note for extra transit type, to help indicate custom transition. */
+        final int mExtraTransitType;
+
         TransitSession(IBinder transition,
                 @Nullable TransitionConsumedCallback consumedCallback,
                 @Nullable TransitionFinishedCallback finishedCallback) {
-            this(transition, consumedCallback, finishedCallback, null /* remoteTransition */);
+            this(transition, consumedCallback, finishedCallback, null /* remoteTransition */, 0);
         }
 
         TransitSession(IBinder transition,
                 @Nullable TransitionConsumedCallback consumedCallback,
                 @Nullable TransitionFinishedCallback finishedCallback,
-                @Nullable RemoteTransition remoteTransition) {
+                @Nullable RemoteTransition remoteTransition, int extraTransitType) {
             mTransition = transition;
             mConsumedCallback = consumedCallback;
             mFinishedCallback = finishedCallback;
@@ -560,6 +558,7 @@
                         mTransitions.getMainExecutor(), remoteTransition);
                 mRemoteHandler.setTransition(transition);
             }
+            mExtraTransitType = extraTransitType;
         }
 
         /** Sets transition consumed callback. */
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 ceef373..e5ae10c 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
@@ -39,6 +39,7 @@
 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.SplitScreenConstants.splitPositionToString;
 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;
@@ -378,39 +379,18 @@
 
     boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition,
             WindowContainerTransaction wct) {
-        StageTaskListener targetStage;
-        int sideStagePosition;
-        if (isSplitScreenVisible()) {
-            // If the split screen is foreground, retrieves target stage based on position.
-            targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage;
-            sideStagePosition = mSideStagePosition;
+        prepareEnterSplitScreen(wct, task, stagePosition);
+        if (ENABLE_SHELL_TRANSITIONS) {
+            mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
+                    null, this, null /* consumedCallback */, null /* finishedCallback */,
+                    isSplitScreenVisible()
+                            ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
         } else {
-            targetStage = mSideStage;
-            sideStagePosition = stagePosition;
-        }
-
-        if (!isSplitActive()) {
-            mSplitLayout.init();
-            prepareEnterSplitScreen(wct, task, stagePosition);
             mSyncQueue.queue(wct);
             mSyncQueue.runInSync(t -> {
                 updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
             });
-        } else {
-            setSideStagePosition(sideStagePosition, wct);
-            targetStage.addTask(task, wct);
-            targetStage.evictAllChildren(wct);
-            if (!isSplitScreenVisible()) {
-                final StageTaskListener anotherStage = targetStage == mMainStage
-                        ? mSideStage : mMainStage;
-                anotherStage.reparentTopTask(wct);
-                anotherStage.evictAllChildren(wct);
-                wct.reorder(mRootTaskInfo.token, true);
-            }
-            setRootForceTranslucent(false, wct);
-            mSyncQueue.queue(wct);
         }
-
         // Due to drag already pip task entering split by this method so need to reset flag here.
         mIsDropEntering = false;
         return true;
@@ -445,26 +425,10 @@
                     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;
-                        }
-                    }
-                } else if (mSideStage.getChildCount() != 0) {
-                    // There are chances the entering app transition got canceled by performing
-                    // rotation transition. Checks if there is any child task existed in split
-                    // screen before fallback to cancel entering flow.
-                    openingToSide = true;
-                }
-
-                if (isEnteringSplit && !openingToSide) {
+                if (isEnteringSplit && mSideStage.getChildCount() == 0) {
                     mMainExecutor.execute(() -> exitSplitScreen(
-                            mSideStage.getChildCount() == 0 ? mMainStage : mSideStage,
-                            EXIT_REASON_UNKNOWN));
+                            null /* childrenToTop */, EXIT_REASON_UNKNOWN));
+                    mSplitUnsupportedToast.show();
                 }
 
                 if (finishedCallback != null) {
@@ -482,7 +446,7 @@
                 }
             }
             @Override
-            public void onAnimationCancelled(boolean isKeyguardOccluded) {
+            public void onAnimationCancelled() {
                 if (isEnteringSplit) {
                     mMainExecutor.execute(() -> exitSplitScreen(
                             mSideStage.getChildCount() == 0 ? mMainStage : mSideStage,
@@ -525,17 +489,17 @@
         wct.sendPendingIntent(intent, fillInIntent, options);
 
         // If split screen is not activated, we're expecting to open a pair of apps to split.
-        final int transitType = mMainStage.isActive()
+        final int extraTransitType = mMainStage.isActive()
                 ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
         prepareEnterSplitScreen(wct, null /* taskInfo */, position);
 
-        mSplitTransitions.startEnterTransition(transitType, wct, null, this,
+        mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
                 null /* consumedCallback */,
                 (finishWct, finishT) -> {
                     if (!evictWct.isEmpty()) {
                         finishWct.merge(evictWct, true);
                     }
-                } /* finishedCallback */);
+                } /* finishedCallback */, extraTransitType);
     }
 
     /** Launches an activity into split by legacy transition. */
@@ -549,26 +513,10 @@
                     RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
                     IRemoteAnimationFinishedCallback finishedCallback,
                     SurfaceControl.Transaction t) {
-                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;
-                        }
-                    }
-                } else if (mSideStage.getChildCount() != 0) {
-                    // There are chances the entering app transition got canceled by performing
-                    // rotation transition. Checks if there is any child task existed in split
-                    // screen before fallback to cancel entering flow.
-                    openingToSide = true;
-                }
-
-                if (isEnteringSplit && !openingToSide && apps != null) {
+                if (isEnteringSplit && mSideStage.getChildCount() == 0) {
                     mMainExecutor.execute(() -> exitSplitScreen(
-                            mSideStage.getChildCount() == 0 ? mMainStage : mSideStage,
-                            EXIT_REASON_UNKNOWN));
+                            null /* childrenToTop */, EXIT_REASON_UNKNOWN));
+                    mSplitUnsupportedToast.show();
                 }
 
                 if (apps != null) {
@@ -708,7 +656,8 @@
         wct.startTask(mainTaskId, mainOptions);
 
         mSplitTransitions.startEnterTransition(
-                TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this, null, null);
+                TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null,
+                TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
         setEnterInstanceId(instanceId);
     }
 
@@ -759,7 +708,8 @@
         }
 
         mSplitTransitions.startEnterTransition(
-                TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this, null, null);
+                TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null,
+                TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
         setEnterInstanceId(instanceId);
     }
 
@@ -868,7 +818,7 @@
                         onRemoteAnimationFinished(apps);
                         t.apply();
                         try {
-                            adapter.getRunner().onAnimationCancelled(mKeyguardShowing);
+                            adapter.getRunner().onAnimationCancelled();
                         } catch (RemoteException e) {
                             Slog.e(TAG, "Error starting remote animation", e);
                         }
@@ -1012,11 +962,11 @@
             }
 
             @Override
-            public void onAnimationCancelled(boolean isKeyguardOccluded) {
+            public void onAnimationCancelled() {
                 onRemoteAnimationFinishedOrCancelled(evictWct);
                 setDividerVisibility(true, null);
                 try {
-                    adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
+                    adapter.getRunner().onAnimationCancelled();
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Error starting remote animation", e);
                 }
@@ -1037,7 +987,7 @@
                         onRemoteAnimationFinished(apps);
                         t.apply();
                         try {
-                            adapter.getRunner().onAnimationCancelled(mKeyguardShowing);
+                            adapter.getRunner().onAnimationCancelled();
                         } catch (RemoteException e) {
                             Slog.e(TAG, "Error starting remote animation", e);
                         }
@@ -1087,7 +1037,7 @@
     private void onRemoteAnimationFinishedOrCancelled(WindowContainerTransaction evictWct) {
         mIsDividerRemoteAnimating = false;
         mShouldUpdateRecents = true;
-        mSplitRequest = null;
+        clearRequestIfPresented();
         // If any stage has no child after animation finished, it means that split will display
         // nothing, such status will happen if task and intent is same app but not support
         // multi-instance, we should exit split and expand that app as full screen.
@@ -1107,7 +1057,7 @@
     private void onRemoteAnimationFinished(RemoteAnimationTarget[] apps) {
         mIsDividerRemoteAnimating = false;
         mShouldUpdateRecents = true;
-        mSplitRequest = null;
+        clearRequestIfPresented();
         // If any stage has no child after finished animation, that side of the split will display
         // nothing. This might happen if starting the same app on the both sides while not
         // supporting multi-instance. Exit the split screen and expand that app to full screen.
@@ -1380,6 +1330,7 @@
         });
         mShouldUpdateRecents = false;
         mIsDividerRemoteAnimating = false;
+        mSplitRequest = null;
 
         mSplitLayout.getInvisibleBounds(mTempRect1);
         if (childrenToTop == null || childrenToTop.getTopVisibleChildTaskId() == INVALID_TASK_ID) {
@@ -1472,6 +1423,13 @@
         }
     }
 
+    private void clearRequestIfPresented() {
+        if (mSideStageListener.mVisible && mSideStageListener.mHasChildren
+                && mMainStageListener.mVisible && mSideStageListener.mHasChildren) {
+            mSplitRequest = null;
+        }
+    }
+
     /**
      * Returns whether the split pair in the recent tasks list should be broken.
      */
@@ -1530,9 +1488,51 @@
      */
     void prepareEnterSplitScreen(WindowContainerTransaction wct,
             @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
-        if (mMainStage.isActive()) return;
-
         onSplitScreenEnter();
+        if (isSplitActive()) {
+            prepareBringSplit(wct, taskInfo, startPosition);
+        } else {
+            prepareActiveSplit(wct, taskInfo, startPosition);
+        }
+    }
+
+    private void prepareBringSplit(WindowContainerTransaction wct,
+            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
+        StageTaskListener targetStage;
+        if (isSplitScreenVisible()) {
+            // If the split screen is foreground, retrieves target stage based on position.
+            targetStage = startPosition == mSideStagePosition ? mSideStage : mMainStage;
+        } else {
+            targetStage = mSideStage;
+        }
+
+        if (taskInfo != null) {
+            wct.startTask(taskInfo.taskId,
+                    resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct));
+            targetStage.evictAllChildren(wct);
+        }
+        // If running background, we need to reparent current top visible task to another stage
+        // and evict all tasks current under its.
+        if (!isSplitScreenVisible()) {
+            // Recreate so we need to reset position rather than keep position of background split.
+            mSplitLayout.resetDividerPosition();
+            updateWindowBounds(mSplitLayout, wct);
+            final StageTaskListener anotherStage = targetStage == mMainStage
+                    ? mSideStage : mMainStage;
+            anotherStage.evictAllChildren(wct);
+            anotherStage.reparentTopTask(wct);
+            wct.reorder(mRootTaskInfo.token, true);
+            setRootForceTranslucent(false, wct);
+        }
+    }
+
+    private void prepareActiveSplit(WindowContainerTransaction wct,
+            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
+        if (!ENABLE_SHELL_TRANSITIONS) {
+            // Legacy transition we need to create divider here, shell transition case we will
+            // create it on #finishEnterSplitScreen
+            mSplitLayout.init();
+        }
         if (taskInfo != null) {
             setSideStagePosition(startPosition, wct);
             mSideStage.addTask(taskInfo, wct);
@@ -1850,6 +1850,7 @@
                     true /* setReparentLeafTaskIfRelaunch */);
             setRootForceTranslucent(true, wct);
         } else {
+            clearRequestIfPresented();
             wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
                     false /* setReparentLeafTaskIfRelaunch */);
             setRootForceTranslucent(false, wct);
@@ -2009,7 +2010,7 @@
         }
         if (mMainStageListener.mHasChildren && mSideStageListener.mHasChildren) {
             mShouldUpdateRecents = true;
-            mSplitRequest = null;
+            clearRequestIfPresented();
             updateRecentTasksSplitPair();
 
             if (!mLogger.hasStartedSession()) {
@@ -2333,7 +2334,8 @@
                 out = new WindowContainerTransaction();
                 prepareEnterSplitScreen(out);
                 mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
-                        null /* consumedCallback */, null /* finishedCallback */);
+                        null /* consumedCallback */, null /* finishedCallback */,
+                        0 /* extraTransitType */);
             }
         }
         return out;
@@ -2402,7 +2404,17 @@
                 }
 
                 final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
-                if (taskInfo == null || !taskInfo.hasParentTask()) continue;
+                if (taskInfo == null) continue;
+                if (taskInfo.token.equals(mRootTaskInfo.token)) {
+                    if (isOpeningType(change.getMode())) {
+                        // Split is opened by someone so set it as visible.
+                        setSplitsVisible(true);
+                    } else if (isClosingType(change.getMode())) {
+                        // Split is closed by someone so set it as invisible.
+                        setSplitsVisible(false);
+                    }
+                    continue;
+                }
                 final StageTaskListener stage = getStageOfTask(taskInfo);
                 if (stage == null) continue;
                 if (isOpeningType(change.getMode())) {
@@ -2419,12 +2431,13 @@
                     }
                 }
             }
-            // If the size of dismissStages > 0, the task is closed without prepare pending
+            // If the size of dismissStages == 1, one of the task is closed without prepare pending
             // transition, which could happen if all activities were finished after finish top
             // activity in a task, so the trigger task is null when handleRequest.
+            // Note if the size of dismissStages == 2, it's starting a new task, so don't handle it.
             final ArraySet<StageTaskListener> dismissStages = record.getShouldDismissedStage();
             if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0
-                    || dismissStages.size() > 0) {
+                    || dismissStages.size() == 1) {
                 Log.e(TAG, "Somehow removed the last task in a stage outside of a proper "
                         + "transition.");
                 final WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -2571,7 +2584,8 @@
             }
         }
 
-        if (info.getType() == TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE) {
+        if (mSplitTransitions.mPendingEnter.mExtraTransitType
+                == TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE) {
             if (mainChild == null && sideChild == null) {
                 Log.w(TAG, "Launched a task in split, but didn't receive any task in transition.");
                 mSplitTransitions.mPendingEnter.cancel(null /* finishedCb */);
@@ -2714,6 +2728,7 @@
             }
         });
         mShouldUpdateRecents = false;
+        mSplitRequest = null;
 
         // Update local states.
         setSplitsVisible(false);
@@ -2839,12 +2854,18 @@
         final String childPrefix = innerPrefix + "  ";
         pw.println(prefix + TAG + " mDisplayId=" + mDisplayId);
         pw.println(innerPrefix + "mDividerVisible=" + mDividerVisible);
+        pw.println(innerPrefix + "isSplitActive=" + isSplitActive());
+        pw.println(innerPrefix + "isSplitVisible=" + isSplitScreenVisible());
         pw.println(innerPrefix + "MainStage");
-        pw.println(childPrefix + "stagePosition=" + getMainStagePosition());
+        pw.println(childPrefix + "stagePosition=" + splitPositionToString(getMainStagePosition()));
         pw.println(childPrefix + "isActive=" + mMainStage.isActive());
+        mMainStage.dump(pw, childPrefix);
+        pw.println(innerPrefix + "MainStageListener");
         mMainStageListener.dump(pw, childPrefix);
         pw.println(innerPrefix + "SideStage");
-        pw.println(childPrefix + "stagePosition=" + getSideStagePosition());
+        pw.println(childPrefix + "stagePosition=" + splitPositionToString(getSideStagePosition()));
+        mSideStage.dump(pw, childPrefix);
+        pw.println(innerPrefix + "SideStageListener");
         mSideStageListener.dump(pw, childPrefix);
         if (mMainStage.isActive()) {
             pw.println(innerPrefix + "SplitLayout");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index ead0bcd..18b09b0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -220,20 +220,12 @@
                 mCallbacks.onNoLongerSupportMultiWindow();
                 return;
             }
-            if (taskInfo.topActivity == null && mChildrenTaskInfo.contains(taskInfo.taskId)
-                    && mChildrenTaskInfo.get(taskInfo.taskId).topActivity != null) {
-                // If top activity become null, it means the task is about to vanish, we use this
-                // signal to remove it from children list earlier for smooth dismiss transition.
-                mChildrenTaskInfo.remove(taskInfo.taskId);
-                mChildrenLeashes.remove(taskInfo.taskId);
-            } else {
-                mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
-            }
+            mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
             mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */,
                     taskInfo.isVisible);
-            if (!ENABLE_SHELL_TRANSITIONS && mChildrenLeashes.contains(taskInfo.taskId)) {
-                updateChildTaskSurface(taskInfo, mChildrenLeashes.get(taskInfo.taskId),
-                        false /* firstAppeared */);
+            if (!ENABLE_SHELL_TRANSITIONS) {
+                updateChildTaskSurface(
+                        taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */);
             }
         } else {
             throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
@@ -267,6 +259,9 @@
                 return;
             }
             sendStatusChanged();
+        } else {
+            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
+                    + "\n mRootTaskInfo: " + mRootTaskInfo);
         }
     }
 
@@ -426,6 +421,13 @@
     public void dump(@NonNull PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         final String childPrefix = innerPrefix + "  ";
-        pw.println(prefix + this);
+        if (mChildrenTaskInfo.size() > 0) {
+            pw.println(prefix + "Children list:");
+            for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
+                final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
+                pw.println(childPrefix + "Task#" + i + " taskID=" + taskInfo.taskId
+                        + " baseActivity=" + taskInfo.baseActivity);
+            }
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java
index 46d2a5a..27d520d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitScreenController.java
@@ -72,7 +72,7 @@
             DisplayController displayController,
             DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController,
-            DragAndDropController dragAndDropController,
+            Optional<DragAndDropController> dragAndDropController,
             Transitions transitions,
             TransactionPool transactionPool,
             IconProvider iconProvider,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
index 8a4d4c2..ae72220 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
@@ -477,15 +477,15 @@
         }
 
         @Override
-        public void removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
+        public boolean removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
             if (mRootView == null) {
-                return;
+                return true;
             }
             if (mSplashView == null) {
                 // shouldn't happen, the app window may be drawn earlier than starting window?
                 Slog.e(TAG, "Found empty splash screen, remove!");
                 removeWindowInner(mRootView, false);
-                return;
+                return true;
             }
             clearSystemBarColor();
             if (immediately
@@ -503,6 +503,7 @@
                     removeWindowInner(mRootView, true);
                 }
             }
+            return true;
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index ff06db3..7cbf263 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -18,6 +18,8 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.StartingWindowRemovalInfo.DEFER_MODE_NORMAL;
+import static android.window.StartingWindowRemovalInfo.DEFER_MODE_ROTATION;
 
 import android.annotation.CallSuper;
 import android.app.TaskInfo;
@@ -216,7 +218,17 @@
     }
     abstract static class StartingWindowRecord {
         protected int mBGColor;
-        abstract void removeIfPossible(StartingWindowRemovalInfo info, boolean immediately);
+
+        /**
+         * Remove the starting window with the given {@link StartingWindowRemovalInfo} if possible.
+         * @param info The removal info sent from the task organizer controller in the WM core.
+         * @param immediately {@code true} means removing the starting window immediately,
+         *                    {@code false} otherwise.
+         * @return {@code true} means {@link StartingWindowRecordManager} can safely remove the
+         *         record itself. {@code false} means {@link StartingWindowRecordManager} requires
+         *         to manage the record reference and remove it later.
+         */
+        abstract boolean removeIfPossible(StartingWindowRemovalInfo info, boolean immediately);
         int getBGColor() {
             return mBGColor;
         }
@@ -231,6 +243,15 @@
          * {@link StartingSurfaceDrawer#onImeDrawnOnTask(int)}.
          */
         private static final long MAX_DELAY_REMOVAL_TIME_IME_VISIBLE = 600;
+
+        /**
+         * The max delay time in milliseconds for removing the task snapshot window with IME
+         * visible after the fixed rotation finished.
+         * Ideally the delay time will be shorter when receiving
+         * {@link StartingSurfaceDrawer#onImeDrawnOnTask(int)}.
+         */
+        private static final long MAX_DELAY_REMOVAL_TIME_FIXED_ROTATION = 3000;
+
         private final Runnable mScheduledRunnable = this::removeImmediately;
 
         @WindowConfiguration.ActivityType protected final int mActivityType;
@@ -242,24 +263,34 @@
         }
 
         @Override
-        public final void removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
+        public final boolean removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
             if (immediately) {
                 removeImmediately();
             } else {
-                scheduleRemove(info.deferRemoveForIme);
+                scheduleRemove(info.deferRemoveForImeMode);
+                return false;
             }
+            return true;
         }
 
-        void scheduleRemove(boolean deferRemoveForIme) {
+        void scheduleRemove(@StartingWindowRemovalInfo.DeferMode int deferRemoveForImeMode) {
             // Show the latest content as soon as possible for unlocking to home.
             if (mActivityType == ACTIVITY_TYPE_HOME) {
                 removeImmediately();
                 return;
             }
             mRemoveExecutor.removeCallbacks(mScheduledRunnable);
-            final long delayRemovalTime = hasImeSurface() && deferRemoveForIme
-                    ? MAX_DELAY_REMOVAL_TIME_IME_VISIBLE
-                    : DELAY_REMOVAL_TIME_GENERAL;
+            final long delayRemovalTime;
+            switch (deferRemoveForImeMode) {
+                case DEFER_MODE_ROTATION:
+                    delayRemovalTime = MAX_DELAY_REMOVAL_TIME_FIXED_ROTATION;
+                    break;
+                case DEFER_MODE_NORMAL:
+                    delayRemovalTime = MAX_DELAY_REMOVAL_TIME_IME_VISIBLE;
+                    break;
+                default:
+                    delayRemovalTime = DELAY_REMOVAL_TIME_GENERAL;
+            }
             mRemoveExecutor.executeDelayed(mScheduledRunnable, delayRemovalTime);
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
                     "Defer removing snapshot surface in %d", delayRemovalTime);
@@ -297,8 +328,10 @@
             final int taskId = removeInfo.taskId;
             final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
             if (record != null) {
-                record.removeIfPossible(removeInfo, immediately);
-                mStartingWindowRecords.remove(taskId);
+                final boolean canRemoveRecord = record.removeIfPossible(removeInfo, immediately);
+                if (canRemoveRecord) {
+                    mStartingWindowRecords.remove(taskId);
+                }
             }
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java
index 12a0d40..98a8031 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSplashWindowCreator.java
@@ -124,7 +124,7 @@
         }
 
         @Override
-        public void removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
+        public boolean removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
             if (!immediately) {
                 mSplashscreenContentDrawer.applyExitAnimation(mSplashView,
                         info.windowAnimationLeash, info.mainFrame,
@@ -132,6 +132,7 @@
             } else {
                 release();
             }
+            return true;
         }
 
         void release() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index 7991c52..2ab4c75 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -82,6 +82,10 @@
         mGuard.open("release");
     }
 
+    SurfaceControl getSurfaceControl() {
+        return mSurfaceControl;
+    }
+
     /**
      * Sets the provided {@link TaskViewBase}, which is used to notify the client part about the
      * task related changes and getting the current bounds.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
index 81d69a4..c7e534a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
@@ -336,6 +336,19 @@
                 tv.prepareOpenAnimation(taskIsNew, startTransaction, finishTransaction,
                         chg.getTaskInfo(), chg.getLeash(), wct);
                 changesHandled++;
+            } else if (chg.getMode() == TRANSIT_CHANGE) {
+                TaskViewTaskController tv = findTaskView(chg.getTaskInfo());
+                if (tv == null) {
+                    if (pending != null) {
+                        Slog.w(TAG, "Found a non-TaskView task in a TaskView Transition. This "
+                                + "shouldn't happen, so there may be a visual artifact: "
+                                + chg.getTaskInfo().taskId);
+                    }
+                    continue;
+                }
+                startTransaction.reparent(chg.getLeash(), tv.getSurfaceControl());
+                finishTransaction.reparent(chg.getLeash(), tv.getSurfaceControl());
+                changesHandled++;
             }
         }
         if (stillNeedsMatchingLaunch) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 7c729a4..4942932 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -73,7 +73,7 @@
         /** Pip was entered while handling an intent with its own remoteTransition. */
         static final int TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE = 3;
 
-        /** Recents transition while split-screen active. */
+        /** Recents transition while split-screen foreground. */
         static final int TYPE_RECENTS_DURING_SPLIT = 4;
 
         /** The default animation for this mixed transition. */
@@ -152,7 +152,7 @@
             @NonNull TransitionRequestInfo request) {
         if (mPipHandler.requestHasPipEnter(request) && mSplitHandler.isSplitScreenVisible()) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a PiP-enter request while "
-                    + "Split-Screen is active, so treat it as Mixed.");
+                    + "Split-Screen is foreground, so treat it as Mixed.");
             if (request.getRemoteTransition() != null) {
                 throw new IllegalStateException("Unexpected remote transition in"
                         + "pip-enter-from-split request");
@@ -183,13 +183,13 @@
             mixed.mLeftoversHandler = handler.first;
             mActiveTransitions.add(mixed);
             return handler.second;
-        } else if (mSplitHandler.isSplitActive()
+        } else if (mSplitHandler.isSplitScreenVisible()
                 && isOpeningType(request.getType())
                 && request.getTriggerTask() != null
                 && request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
                 && request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_HOME) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a going-home request while "
-                    + "Split-Screen is active, so treat it as Mixed.");
+                    + "Split-Screen is foreground, so treat it as Mixed.");
             Pair<Transitions.TransitionHandler, WindowContainerTransaction> handler =
                     mPlayer.dispatchRequest(transition, request, this);
             if (handler == null) {
@@ -211,7 +211,7 @@
 
     @Override
     public Transitions.TransitionHandler handleRecentsRequest(WindowContainerTransaction outWCT) {
-        if (mRecentsHandler != null && mSplitHandler.isSplitActive()) {
+        if (mRecentsHandler != null && mSplitHandler.isSplitScreenVisible()) {
             return this;
         }
         return null;
@@ -219,9 +219,9 @@
 
     @Override
     public void setRecentsTransition(IBinder transition) {
-        if (mSplitHandler.isSplitActive()) {
+        if (mSplitHandler.isSplitScreenVisible()) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while "
-                    + "Split-Screen is active, so treat it as Mixed.");
+                    + "Split-Screen is foreground, so treat it as Mixed.");
             final MixedTransition mixed = new MixedTransition(
                     MixedTransition.TYPE_RECENTS_DURING_SPLIT, transition);
             mixed.mLeftoversHandler = mRecentsHandler;
@@ -351,7 +351,7 @@
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animating a mixed transition for "
-                + "entering PIP while Split-Screen is active.");
+                + "entering PIP while Split-Screen is foreground.");
         TransitionInfo.Change pipChange = null;
         TransitionInfo.Change wallpaper = null;
         final TransitionInfo everythingElse = subCopy(info, TRANSIT_TO_BACK, true /* changes */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
index 61e92f3..61e11e8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
@@ -107,7 +107,7 @@
             }
 
             @Override
-            public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException {
+            public void onAnimationCancelled() throws RemoteException {
                 mCancelled = true;
                 mApps = mWallpapers = mNonApps = null;
                 checkApply();
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 5b7231c..ef2a511 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
@@ -94,9 +94,11 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        if (!Transitions.SHELL_TRANSITIONS_ROTATION && TransitionUtil.hasDisplayChange(info)) {
+        if (!Transitions.SHELL_TRANSITIONS_ROTATION && TransitionUtil.hasDisplayChange(info)
+                && !TransitionUtil.alwaysReportToKeyguard(info)) {
             // Note that if the remote doesn't have permission ACCESS_SURFACE_FLINGER, some
             // operations of the start transaction may be ignored.
+            mRequestedRemotes.remove(transition);
             return false;
         }
         RemoteTransition pendingRemote = mRequestedRemotes.get(transition);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
index d25318d..9ce2209 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
@@ -144,6 +144,7 @@
                                 .setCaptureSecureLayers(true)
                                 .setAllowProtected(true)
                                 .setSourceCrop(new Rect(0, 0, mStartWidth, mStartHeight))
+                                .setHintForSeamlessTransition(true)
                                 .build();
                 ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
                         ScreenCapture.captureLayers(args);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Tracer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Tracer.java
new file mode 100644
index 0000000..ba364f8
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Tracer.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.transition;
+
+import static android.os.Build.IS_USER;
+
+import static com.android.wm.shell.WmShellTransitionTraceProto.MAGIC_NUMBER;
+import static com.android.wm.shell.WmShellTransitionTraceProto.MAGIC_NUMBER_H;
+import static com.android.wm.shell.WmShellTransitionTraceProto.MAGIC_NUMBER_L;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.Log;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.util.TraceBuffer;
+import com.android.wm.shell.sysui.ShellCommandHandler;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Helper class to collect and dump transition traces.
+ */
+public class Tracer implements ShellCommandHandler.ShellCommandActionHandler {
+    private static final int ALWAYS_ON_TRACING_CAPACITY = 15 * 1024; // 15 KB
+    private static final int ACTIVE_TRACING_BUFFER_CAPACITY = 5000 * 1024; // 5 MB
+
+    private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
+
+    static final String WINSCOPE_EXT = ".winscope";
+    private static final String TRACE_FILE =
+            "/data/misc/wmtrace/shell_transition_trace" + WINSCOPE_EXT;
+
+    private final Object mEnabledLock = new Object();
+    private boolean mActiveTracingEnabled = false;
+
+    private final TraceBuffer mTraceBuffer = new TraceBuffer(ALWAYS_ON_TRACING_CAPACITY,
+            (proto) -> handleOnEntryRemovedFromTrace(proto));
+    private final Map<Object, Runnable> mRemovedFromTraceCallbacks = new HashMap<>();
+
+    private final Map<Transitions.TransitionHandler, Integer> mHandlerIds = new HashMap<>();
+    private final Map<Transitions.TransitionHandler, Integer> mHandlerUseCountInTrace =
+            new HashMap<>();
+
+    /**
+     * Adds an entry in the trace to log that a transition has been dispatched to a handler.
+     *
+     * @param transitionId The id of the transition being dispatched.
+     * @param handler The handler the transition is being dispatched to.
+     */
+    public void logDispatched(int transitionId, Transitions.TransitionHandler handler) {
+        final int handlerId;
+        if (mHandlerIds.containsKey(handler)) {
+            handlerId = mHandlerIds.get(handler);
+        } else {
+            // + 1 to avoid 0 ids which can be confused with missing value when dumped to proto
+            handlerId = mHandlerIds.size() + 1;
+            mHandlerIds.put(handler, handlerId);
+        }
+
+        ProtoOutputStream outputStream = new ProtoOutputStream();
+        final long protoToken =
+                outputStream.start(com.android.wm.shell.WmShellTransitionTraceProto.TRANSITIONS);
+
+        outputStream.write(com.android.wm.shell.Transition.ID, transitionId);
+        outputStream.write(com.android.wm.shell.Transition.DISPATCH_TIME_NS,
+                SystemClock.elapsedRealtimeNanos());
+        outputStream.write(com.android.wm.shell.Transition.HANDLER, handlerId);
+
+        outputStream.end(protoToken);
+
+        final int useCountAfterAdd = mHandlerUseCountInTrace.getOrDefault(handler, 0) + 1;
+        mHandlerUseCountInTrace.put(handler, useCountAfterAdd);
+
+        mRemovedFromTraceCallbacks.put(outputStream, () -> {
+            final int useCountAfterRemove = mHandlerUseCountInTrace.get(handler) - 1;
+            mHandlerUseCountInTrace.put(handler, useCountAfterRemove);
+        });
+
+        mTraceBuffer.add(outputStream);
+    }
+
+    /**
+     * Adds an entry in the trace to log that a request to merge a transition was made.
+     *
+     * @param mergeRequestedTransitionId The id of the transition we are requesting to be merged.
+     * @param playingTransitionId The id of the transition we was to merge the transition into.
+     */
+    public void logMergeRequested(int mergeRequestedTransitionId, int playingTransitionId) {
+        ProtoOutputStream outputStream = new ProtoOutputStream();
+        final long protoToken =
+                outputStream.start(com.android.wm.shell.WmShellTransitionTraceProto.TRANSITIONS);
+
+        outputStream.write(com.android.wm.shell.Transition.ID, mergeRequestedTransitionId);
+        outputStream.write(com.android.wm.shell.Transition.MERGE_REQUEST_TIME_NS,
+                SystemClock.elapsedRealtimeNanos());
+        outputStream.write(com.android.wm.shell.Transition.MERGED_INTO, playingTransitionId);
+
+        outputStream.end(protoToken);
+
+        mTraceBuffer.add(outputStream);
+    }
+
+    /**
+     * Adds an entry in the trace to log that a transition was merged by the handler.
+     *
+     * @param mergedTransitionId The id of the transition that was merged.
+     * @param playingTransitionId The id of the transition the transition was merged into.
+     */
+    public void logMerged(int mergedTransitionId, int playingTransitionId) {
+        ProtoOutputStream outputStream = new ProtoOutputStream();
+        final long protoToken =
+                outputStream.start(com.android.wm.shell.WmShellTransitionTraceProto.TRANSITIONS);
+
+        outputStream.write(com.android.wm.shell.Transition.ID, mergedTransitionId);
+        outputStream.write(
+                com.android.wm.shell.Transition.MERGE_TIME_NS, SystemClock.elapsedRealtimeNanos());
+        outputStream.write(com.android.wm.shell.Transition.MERGED_INTO, playingTransitionId);
+
+        outputStream.end(protoToken);
+
+        mTraceBuffer.add(outputStream);
+    }
+
+    /**
+     * Adds an entry in the trace to log that a transition was aborted.
+     *
+     * @param transitionId The id of the transition that was aborted.
+     */
+    public void logAborted(int transitionId) {
+        ProtoOutputStream outputStream = new ProtoOutputStream();
+        final long protoToken =
+                outputStream.start(com.android.wm.shell.WmShellTransitionTraceProto.TRANSITIONS);
+
+        outputStream.write(com.android.wm.shell.Transition.ID, transitionId);
+        outputStream.write(
+                com.android.wm.shell.Transition.ABORT_TIME_NS, SystemClock.elapsedRealtimeNanos());
+
+        outputStream.end(protoToken);
+
+        mTraceBuffer.add(outputStream);
+    }
+
+    /**
+     * Starts collecting transitions for the trace.
+     * If called while a trace is already running, this will reset the trace.
+     */
+    public void startTrace(@Nullable PrintWriter pw) {
+        if (IS_USER) {
+            LogAndPrintln.e(pw, "Tracing is not supported on user builds.");
+            return;
+        }
+        Trace.beginSection("Tracer#startTrace");
+        LogAndPrintln.i(pw, "Starting shell transition trace.");
+        synchronized (mEnabledLock) {
+            mActiveTracingEnabled = true;
+            mTraceBuffer.resetBuffer();
+            mTraceBuffer.setCapacity(ACTIVE_TRACING_BUFFER_CAPACITY);
+        }
+        Trace.endSection();
+    }
+
+    /**
+     * Stops collecting the transition trace and dump to trace to file.
+     *
+     * Dumps the trace to @link{TRACE_FILE}.
+     */
+    public void stopTrace(@Nullable PrintWriter pw) {
+        stopTrace(pw, new File(TRACE_FILE));
+    }
+
+    /**
+     * Stops collecting the transition trace and dump to trace to file.
+     * @param outputFile The file to dump the transition trace to.
+     */
+    public void stopTrace(@Nullable PrintWriter pw, File outputFile) {
+        if (IS_USER) {
+            LogAndPrintln.e(pw, "Tracing is not supported on user builds.");
+            return;
+        }
+        Trace.beginSection("Tracer#stopTrace");
+        LogAndPrintln.i(pw, "Stopping shell transition trace.");
+        synchronized (mEnabledLock) {
+            mActiveTracingEnabled = false;
+            writeTraceToFileLocked(pw, outputFile);
+            mTraceBuffer.resetBuffer();
+            mTraceBuffer.setCapacity(ALWAYS_ON_TRACING_CAPACITY);
+        }
+        Trace.endSection();
+    }
+
+    /**
+     * Being called while taking a bugreport so that tracing files can be included in the bugreport.
+     *
+     * @param pw Print writer
+     */
+    public void saveForBugreport(@Nullable PrintWriter pw) {
+        if (IS_USER) {
+            LogAndPrintln.e(pw, "Tracing is not supported on user builds.");
+            return;
+        }
+        Trace.beginSection("TransitionTracer#saveForBugreport");
+        synchronized (mEnabledLock) {
+            final File outputFile = new File(TRACE_FILE);
+            writeTraceToFileLocked(pw, outputFile);
+        }
+        Trace.endSection();
+    }
+
+    private void writeTraceToFileLocked(@Nullable PrintWriter pw, File file) {
+        Trace.beginSection("TransitionTracer#writeTraceToFileLocked");
+        try {
+            ProtoOutputStream proto = new ProtoOutputStream();
+            proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
+            writeHandlerMappingToProto(proto);
+            int pid = android.os.Process.myPid();
+            LogAndPrintln.i(pw, "Writing file to " + file.getAbsolutePath()
+                    + " from process " + pid);
+            mTraceBuffer.writeTraceToFile(file, proto);
+        } catch (IOException e) {
+            LogAndPrintln.e(pw, "Unable to write buffer to file", e);
+        }
+        Trace.endSection();
+    }
+
+    private void writeHandlerMappingToProto(ProtoOutputStream outputStream) {
+        for (Transitions.TransitionHandler handler : mHandlerUseCountInTrace.keySet()) {
+            final int count = mHandlerUseCountInTrace.get(handler);
+            if (count > 0) {
+                final long protoToken = outputStream.start(
+                        com.android.wm.shell.WmShellTransitionTraceProto.HANDLER_MAPPINGS);
+                outputStream.write(com.android.wm.shell.HandlerMapping.ID,
+                        mHandlerIds.get(handler));
+                outputStream.write(com.android.wm.shell.HandlerMapping.NAME,
+                        handler.getClass().getName());
+                outputStream.end(protoToken);
+            }
+        }
+    }
+
+    private void handleOnEntryRemovedFromTrace(Object proto) {
+        if (mRemovedFromTraceCallbacks.containsKey(proto)) {
+            mRemovedFromTraceCallbacks.get(proto).run();
+            mRemovedFromTraceCallbacks.remove(proto);
+        }
+    }
+
+    @Override
+    public boolean onShellCommand(String[] args, PrintWriter pw) {
+        switch (args[0]) {
+            case "start": {
+                startTrace(pw);
+                return true;
+            }
+            case "stop": {
+                stopTrace(pw);
+                return true;
+            }
+            case "save-for-bugreport": {
+                saveForBugreport(pw);
+                return true;
+            }
+            default: {
+                pw.println("Invalid command: " + args[0]);
+                printShellCommandHelp(pw, "");
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public void printShellCommandHelp(PrintWriter pw, String prefix) {
+        pw.println(prefix + "start");
+        pw.println(prefix + "  Start tracing the transitions.");
+        pw.println(prefix + "stop");
+        pw.println(prefix + "  Stop tracing the transitions.");
+        pw.println(prefix + "save-for-bugreport");
+        pw.println(prefix + "  Flush in memory transition trace to file.");
+    }
+
+    private static class LogAndPrintln {
+        private static final String LOG_TAG = "ShellTransitionTracer";
+
+        private static void i(@Nullable PrintWriter pw, String msg) {
+            Log.i(LOG_TAG, msg);
+            if (pw != null) {
+                pw.println(msg);
+                pw.flush();
+            }
+        }
+
+        private static void e(@Nullable PrintWriter pw, String msg) {
+            Log.e(LOG_TAG, msg);
+            if (pw != null) {
+                pw.println("ERROR: " + msg);
+                pw.flush();
+            }
+        }
+
+        private static void e(@Nullable PrintWriter pw, String msg, @NonNull Exception e) {
+            Log.e(LOG_TAG, msg, e);
+            if (pw != null) {
+                pw.println("ERROR: " + msg + " ::\n " + e);
+                pw.flush();
+            }
+        }
+    }
+}
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 5c8791e..f79f1f7 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
@@ -74,10 +74,12 @@
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.common.annotations.ExternalThread;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.util.TransitionUtil;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 
@@ -106,7 +108,8 @@
  * track, it will be marked as SYNC. This means that all currently active tracks must be flushed
  * before the SYNC transition can play.
  */
-public class Transitions implements RemoteCallable<Transitions> {
+public class Transitions implements RemoteCallable<Transitions>,
+        ShellCommandHandler.ShellCommandActionHandler {
     static final String TAG = "ShellTransitions";
 
     /** Set to {@code true} to enable shell transitions. */
@@ -165,12 +168,15 @@
     private final ShellController mShellController;
     private final ShellTransitionImpl mImpl = new ShellTransitionImpl();
     private final SleepHandler mSleepHandler = new SleepHandler();
-
+    private final Tracer mTracer = new Tracer();
     private boolean mIsRegistered = false;
 
     /** List of possible handlers. Ordered by specificity (eg. tapped back to front). */
     private final ArrayList<TransitionHandler> mHandlers = new ArrayList<>();
 
+    @Nullable
+    private final ShellCommandHandler mShellCommandHandler;
+
     private final ArrayList<TransitionObserver> mObservers = new ArrayList<>();
 
     /** List of {@link Runnable} instances to run when the last active transition has finished.  */
@@ -246,8 +252,23 @@
             @NonNull WindowOrganizer organizer,
             @NonNull TransactionPool pool,
             @NonNull DisplayController displayController,
-            @NonNull ShellExecutor mainExecutor, @NonNull Handler mainHandler,
+            @NonNull ShellExecutor mainExecutor,
+            @NonNull Handler mainHandler,
             @NonNull ShellExecutor animExecutor) {
+        this(context, shellInit, shellController, organizer, pool, displayController, mainExecutor,
+                mainHandler, animExecutor, null);
+    }
+
+    public Transitions(@NonNull Context context,
+            @NonNull ShellInit shellInit,
+            @NonNull ShellController shellController,
+            @NonNull WindowOrganizer organizer,
+            @NonNull TransactionPool pool,
+            @NonNull DisplayController displayController,
+            @NonNull ShellExecutor mainExecutor,
+            @NonNull Handler mainHandler,
+            @NonNull ShellExecutor animExecutor,
+            @Nullable ShellCommandHandler shellCommandHandler) {
         mOrganizer = organizer;
         mContext = context;
         mMainExecutor = mainExecutor;
@@ -263,6 +284,7 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "addHandler: Default");
         // Next lowest priority is remote transitions.
         mHandlers.add(mRemoteTransitionHandler);
+        mShellCommandHandler = shellCommandHandler;
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "addHandler: Remote");
         shellInit.addInitCallback(this::onInit, this);
     }
@@ -294,6 +316,10 @@
             // Pre-load the instance.
             TransitionMetrics.getInstance();
         }
+
+        if (mShellCommandHandler != null) {
+            mShellCommandHandler.addCommandCallback("transitions", this, this);
+        }
     }
 
     public boolean isRegistered() {
@@ -650,7 +676,7 @@
                     active.mToken, info, active.mStartT, active.mFinishT);
         }
 
-        if (info.getRootCount() == 0 && !alwaysReportToKeyguard(info)) {
+        if (info.getRootCount() == 0 && !TransitionUtil.alwaysReportToKeyguard(info)) {
             // No root-leashes implies that the transition is empty/no-op, so just do
             // housekeeping and return.
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "No transition roots in %s so"
@@ -699,23 +725,6 @@
         return true;
     }
 
-    /**
-     * Some transitions we always need to report to keyguard even if they are empty.
-     * TODO (b/274954192): Remove this once keyguard dispatching moves to Shell.
-     */
-    private static boolean alwaysReportToKeyguard(TransitionInfo info) {
-        // occlusion status of activities can change while screen is off so there will be no
-        // visibility change but we still need keyguardservice to be notified.
-        if (info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE) return true;
-
-        // It's possible for some activities to stop with bad timing (esp. since we can't yet
-        // queue activity transitions initiated by apps) that results in an empty transition for
-        // keyguard going-away. In general, we should should always report Keyguard-going-away.
-        if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) return true;
-
-        return false;
-    }
-
     private boolean areTracksIdle() {
         for (int i = 0; i < mTracks.size(); ++i) {
             if (!mTracks.get(i).isIdle()) return false;
@@ -783,6 +792,7 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition %s ready while"
                 + " %s is still animating. Notify the animating transition"
                 + " in case they can be merged", ready, playing);
+        mTracer.logMergeRequested(ready.mInfo.getDebugId(), playing.mInfo.getDebugId());
         playing.mHandler.mergeAnimation(ready.mToken, ready.mInfo, ready.mStartT,
                 playing.mToken, (wct, cb) -> onMerged(playing, ready));
     }
@@ -816,6 +826,7 @@
         for (int i = 0; i < mObservers.size(); ++i) {
             mObservers.get(i).onTransitionMerged(merged.mToken, playing.mToken);
         }
+        mTracer.logMerged(merged.mInfo.getDebugId(), playing.mInfo.getDebugId());
         // See if we should merge another transition.
         processReadyQueue(track);
     }
@@ -842,6 +853,8 @@
         // Otherwise give every other handler a chance
         active.mHandler = dispatchTransition(active.mToken, active.mInfo, active.mStartT,
                 active.mFinishT, (wct, cb) -> onFinish(active, wct, cb), active.mHandler);
+
+        mTracer.logDispatched(active.mInfo.getDebugId(), active.mHandler);
     }
 
     /**
@@ -893,6 +906,8 @@
         transition.mFinishT.apply();
         transition.mAborted = true;
 
+        mTracer.logAborted(transition.mInfo.getDebugId());
+
         if (transition.mHandler != null) {
             // Notifies to clean-up the aborted transition.
             transition.mHandler.onTransitionConsumed(
@@ -1367,4 +1382,26 @@
             mMainExecutor.execute(() -> dispatchAnimScaleSetting(mTransitionAnimationScaleSetting));
         }
     }
+
+
+    @Override
+    public boolean onShellCommand(String[] args, PrintWriter pw) {
+        switch (args[0]) {
+            case "tracing": {
+                mTracer.onShellCommand(Arrays.copyOfRange(args, 1, args.length), pw);
+                return true;
+            }
+            default: {
+                pw.println("Invalid command: " + args[0]);
+                printShellCommandHelp(pw, "");
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public void printShellCommandHelp(PrintWriter pw, String prefix) {
+        pw.println(prefix + "tracing");
+        mTracer.printShellCommandHelp(pw, prefix + "  ");
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
index fe0a3fb..96657af 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
@@ -19,14 +19,12 @@
 import static android.graphics.Color.blue;
 import static android.graphics.Color.green;
 import static android.graphics.Color.red;
-import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.annotation.NonNull;
 import android.content.Context;
 import android.view.SurfaceControl;
 
 import com.android.wm.shell.R;
-import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 
 /**
  * Controls background color layer for the unfold animations
@@ -34,15 +32,10 @@
 public class UnfoldBackgroundController {
 
     private static final int BACKGROUND_LAYER_Z_INDEX = -1;
-
-    private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
     private final float[] mBackgroundColor;
     private SurfaceControl mBackgroundLayer;
 
-    public UnfoldBackgroundController(
-            @NonNull Context context,
-            @NonNull RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
-        mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+    public UnfoldBackgroundController(@NonNull Context context) {
         mBackgroundColor = getBackgroundColor(context);
     }
 
@@ -57,7 +50,6 @@
                 .setName("app-unfold-background")
                 .setCallsite("AppUnfoldTransitionController")
                 .setColorLayer();
-        mRootTaskDisplayAreaOrganizer.attachToDisplayArea(DEFAULT_DISPLAY, colorLayerBuilder);
         mBackgroundLayer = colorLayerBuilder.build();
 
         transaction
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
index ce10291..c5cd2d9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
@@ -24,7 +24,9 @@
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
+import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -77,6 +79,23 @@
         return false;
     }
 
+    /**
+     * Some transitions we always need to report to keyguard even if they are empty.
+     * TODO (b/274954192): Remove this once keyguard dispatching moves to Shell.
+     */
+    public static boolean alwaysReportToKeyguard(TransitionInfo info) {
+        // occlusion status of activities can change while screen is off so there will be no
+        // visibility change but we still need keyguardservice to be notified.
+        if (info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE) return true;
+
+        // It's possible for some activities to stop with bad timing (esp. since we can't yet
+        // queue activity transitions initiated by apps) that results in an empty transition for
+        // keyguard going-away. In general, we should should always report Keyguard-going-away.
+        if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) return true;
+
+        return false;
+    }
+
     /** Returns `true` if `change` is a wallpaper. */
     public static boolean isWallpaper(TransitionInfo.Change change) {
         return (change.getTaskInfo() == null)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index e8a6a15..212ad9e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -185,8 +185,8 @@
                         mSyncQueue);
         mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
 
-        final TaskPositioner taskPositioner =
-                new TaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController);
+        final FluidResizeTaskPositioner taskPositioner =
+                new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController);
         final CaptionTouchEventListener touchEventListener =
                 new CaptionTouchEventListener(taskInfo, taskPositioner);
         windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
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 8fb56fc..4cda571 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
@@ -101,7 +101,7 @@
 
     private final SparseArray<DesktopModeWindowDecoration> mWindowDecorByTaskId =
             new SparseArray<>();
-    private final DragListenerImpl mDragStartListener = new DragListenerImpl();
+    private final DragStartListenerImpl mDragStartListener = new DragStartListenerImpl();
     private final InputMonitorFactory mInputMonitorFactory;
     private TaskOperations mTaskOperations;
     private final Supplier<SurfaceControl.Transaction> mTransactionFactory;
@@ -113,11 +113,6 @@
     private boolean mDragToDesktopAnimationStarted;
     private float mCaptionDragStartX;
 
-    // These values keep track of any transitions to freeform to stop relayout from running on
-    // changing task so that shellTransitions has a chance to animate the transition
-    private int mPauseRelayoutForTask = -1;
-    private IBinder mTransitionPausingRelayout;
-
     public DesktopModeWindowDecorViewModel(
             Context context,
             Handler mainHandler,
@@ -195,22 +190,25 @@
             @NonNull TransitionInfo info,
             @NonNull TransitionInfo.Change change) {
         if (change.getMode() == WindowManager.TRANSIT_CHANGE
-                && info.getType() == Transitions.TRANSIT_ENTER_DESKTOP_MODE) {
-            mTransitionPausingRelayout = transition;
+                && (info.getType() == Transitions.TRANSIT_ENTER_DESKTOP_MODE)) {
+            mWindowDecorByTaskId.get(change.getTaskInfo().taskId)
+                    .addTransitionPausingRelayout(transition);
         }
     }
 
     @Override
     public void onTransitionMerged(@NonNull IBinder merged, @NonNull IBinder playing) {
-        if (merged.equals(mTransitionPausingRelayout)) {
-            mTransitionPausingRelayout = playing;
+        for (int i = 0; i < mWindowDecorByTaskId.size(); i++) {
+            final DesktopModeWindowDecoration decor = mWindowDecorByTaskId.valueAt(i);
+            decor.mergeTransitionPausingRelayout(merged, playing);
         }
     }
 
     @Override
     public void onTransitionFinished(@NonNull IBinder transition) {
-        if (transition.equals(mTransitionPausingRelayout)) {
-            mPauseRelayoutForTask = -1;
+        for (int i = 0; i < mWindowDecorByTaskId.size(); i++) {
+            final DesktopModeWindowDecoration decor = mWindowDecorByTaskId.valueAt(i);
+            decor.removeTransitionPausingRelayout(transition);
         }
     }
 
@@ -225,12 +223,7 @@
             incrementEventReceiverTasks(taskInfo.displayId);
         }
 
-        // TaskListener callbacks and shell transitions aren't synchronized, so starting a shell
-        // transition can trigger an onTaskInfoChanged call that updates the task's SurfaceControl
-        // and interferes with the transition animation that is playing at the same time.
-        if (taskInfo.taskId != mPauseRelayoutForTask) {
-            decoration.relayout(taskInfo);
-        }
+        decoration.relayout(taskInfo);
     }
 
     @Override
@@ -555,8 +548,7 @@
                             relevantDecor.mTaskInfo.displayId);
                     if (ev.getY() > 2 * statusBarHeight) {
                         if (DesktopModeStatus.isProto2Enabled()) {
-                            mPauseRelayoutForTask = relevantDecor.mTaskInfo.taskId;
-                            centerAndMoveToDesktopWithAnimation(relevantDecor, ev);
+                            animateToDesktop(relevantDecor, ev);
                         } else if (DesktopModeStatus.isProto1Enabled()) {
                             mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
                         }
@@ -632,6 +624,15 @@
     }
 
     /**
+     * Blocks relayout until transition is finished and transitions to Desktop
+     */
+    private void animateToDesktop(DesktopModeWindowDecoration relevantDecor,
+            MotionEvent ev) {
+        relevantDecor.incrementRelayoutBlock();
+        centerAndMoveToDesktopWithAnimation(relevantDecor, ev);
+    }
+
+    /**
      * Animates a window to the center, grows to freeform size, and transitions to Desktop Mode.
      * @param relevantDecor the window decor of the task to be animated
      * @param ev the motion event that triggers the animation
@@ -658,10 +659,9 @@
         animator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                mDesktopTasksController.ifPresent(
-                        c -> c.onDragPositioningEndThroughStatusBar(
-                                relevantDecor.mTaskInfo,
-                                calculateFreeformBounds(FINAL_FREEFORM_SCALE)));
+                mDesktopTasksController.ifPresent(c ->
+                        c.onDragPositioningEndThroughStatusBar(relevantDecor.mTaskInfo,
+                            calculateFreeformBounds(FINAL_FREEFORM_SCALE)));
             }
         });
         animator.start();
@@ -777,21 +777,32 @@
                         mSyncQueue);
         mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
 
-        final TaskPositioner taskPositioner =
-                new TaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController,
-                        mDragStartListener);
+        final DragPositioningCallback dragPositioningCallback;
+        if (!DesktopModeStatus.isVeiledResizeEnabled()) {
+            dragPositioningCallback =
+                    new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration,
+                            mDisplayController, mDragStartListener);
+        } else {
+            windowDecoration.createResizeVeil();
+            dragPositioningCallback =
+                    new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration,
+                            mDisplayController, mDragStartListener);
+        }
         final DesktopModeTouchEventListener touchEventListener =
-                new DesktopModeTouchEventListener(taskInfo, taskPositioner);
+                new DesktopModeTouchEventListener(taskInfo, dragPositioningCallback);
+
         windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
         windowDecoration.setCornersListener(mCornersListener);
-        windowDecoration.setDragPositioningCallback(taskPositioner);
+        windowDecoration.setDragPositioningCallback(dragPositioningCallback);
         windowDecoration.setDragDetector(touchEventListener.mDragDetector);
         windowDecoration.relayout(taskInfo, startT, finishT,
                 false /* applyStartTransactionOnDraw */);
         incrementEventReceiverTasks(taskInfo.displayId);
     }
 
-    private class DragListenerImpl implements TaskPositioner.DragStartListener {
+
+    private class DragStartListenerImpl
+            implements DragPositioningCallbackUtility.DragStartListener {
         @Override
         public void onDragStart(int taskId) {
             mWindowDecorByTaskId.get(taskId).closeHandleMenu();
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 619e963..95ed42a 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
@@ -17,33 +17,26 @@
 package com.android.wm.shell.windowdecor;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 
 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.Configuration;
-import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Point;
 import android.graphics.PointF;
+import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.os.IBinder;
 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.Button;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.window.SurfaceSyncGroup;
 import android.window.WindowContainerTransaction;
 
 import com.android.launcher3.icons.IconProvider;
@@ -57,6 +50,9 @@
 import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder;
 import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
  * {@link DesktopModeWindowDecorViewModel}.
@@ -82,29 +78,17 @@
             new WindowDecoration.RelayoutResult<>();
 
     private final Point mPositionInParent = new Point();
-    private final PointF mHandleMenuAppInfoPillPosition = new PointF();
-    private final PointF mHandleMenuWindowingPillPosition = new PointF();
-    private final PointF mHandleMenuMoreActionsPillPosition = new PointF();
+    private HandleMenu mHandleMenu;
 
-    // Collection of additional windows that comprise the handle menu.
-    private AdditionalWindow mHandleMenuAppInfoPill;
-    private AdditionalWindow mHandleMenuWindowingPill;
-    private AdditionalWindow mHandleMenuMoreActionsPill;
+    private ResizeVeil mResizeVeil;
 
     private Drawable mAppIcon;
     private CharSequence mAppName;
 
     private TaskCornersListener mCornersListener;
 
-    private int mMenuWidth;
-    private int mMarginMenuTop;
-    private int mMarginMenuStart;
-    private int mMarginMenuSpacing;
-    private int mAppInfoPillHeight;
-    private int mWindowingPillHeight;
-    private int mMoreActionsPillHeight;
-    private int mShadowRadius;
-    private int mCornerRadius;
+    private final Set<IBinder> mTransitionsPausingRelayout = new HashSet<>();
+    private int mRelayoutBlock;
 
     DesktopModeWindowDecoration(
             Context context,
@@ -122,29 +106,6 @@
         mSyncQueue = syncQueue;
 
         loadAppInfo();
-        loadHandleMenuDimensions();
-    }
-
-    private void loadHandleMenuDimensions() {
-        final Resources resources = mDecorWindowContext.getResources();
-        mMenuWidth = loadDimensionPixelSize(resources,
-                R.dimen.desktop_mode_handle_menu_width);
-        mMarginMenuTop = loadDimensionPixelSize(resources,
-                R.dimen.desktop_mode_handle_menu_margin_top);
-        mMarginMenuStart = loadDimensionPixelSize(resources,
-                R.dimen.desktop_mode_handle_menu_margin_start);
-        mMarginMenuSpacing = loadDimensionPixelSize(resources,
-                R.dimen.desktop_mode_handle_menu_pill_spacing_margin);
-        mAppInfoPillHeight = loadDimensionPixelSize(resources,
-                R.dimen.desktop_mode_handle_menu_app_info_pill_height);
-        mWindowingPillHeight = loadDimensionPixelSize(resources,
-                R.dimen.desktop_mode_handle_menu_windowing_pill_height);
-        mShadowRadius = loadDimensionPixelSize(resources,
-                R.dimen.desktop_mode_handle_menu_shadow_radius);
-        mCornerRadius = loadDimensionPixelSize(resources,
-                R.dimen.desktop_mode_handle_menu_corner_radius);
-        mMoreActionsPillHeight = loadDimensionPixelSize(resources,
-                R.dimen.desktop_mode_handle_menu_more_actions_pill_height);
     }
 
     @Override
@@ -180,6 +141,13 @@
 
     @Override
     void relayout(ActivityManager.RunningTaskInfo taskInfo) {
+        // TaskListener callbacks and shell transitions aren't synchronized, so starting a shell
+        // transition can trigger an onTaskInfoChanged call that updates the task's SurfaceControl
+        // and interferes with the transition animation that is playing at the same time.
+        if (mRelayoutBlock > 0) {
+            return;
+        }
+
         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
         // Use |applyStartTransactionOnDraw| so that the transaction (that applies task crop) is
         // synced with the buffer transaction (that draws the View). Both will be shown on screen
@@ -197,20 +165,8 @@
                 taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM;
         final boolean isDragResizeable = isFreeform && taskInfo.isResizeable;
 
-        if (mHandleMenuAppInfoPill != null) {
-            updateHandleMenuPillPositions();
-            startT.setPosition(mHandleMenuAppInfoPill.mWindowSurface,
-                    mHandleMenuAppInfoPillPosition.x, mHandleMenuAppInfoPillPosition.y);
-
-            // Only show windowing buttons in proto2. Proto1 uses a system-level mode only.
-            final boolean shouldShowWindowingPill = DesktopModeStatus.isProto2Enabled();
-            if (shouldShowWindowingPill) {
-                startT.setPosition(mHandleMenuWindowingPill.mWindowSurface,
-                        mHandleMenuWindowingPillPosition.x, mHandleMenuWindowingPillPosition.y);
-            }
-
-            startT.setPosition(mHandleMenuMoreActionsPill.mWindowSurface,
-                    mHandleMenuMoreActionsPillPosition.x, mHandleMenuMoreActionsPillPosition.y);
+        if (isHandleMenuActive()) {
+            mHandleMenu.relayout(startT);
         }
 
         final WindowDecorLinearLayout oldRootView = mResult.mRootView;
@@ -226,6 +182,11 @@
         mRelayoutParams.mShadowRadiusId = shadowRadiusID;
         mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
 
+        final TypedArray ta = mContext.obtainStyledAttributes(
+                new int[]{android.R.attr.dialogCornerRadius});
+        mRelayoutParams.mCornerRadius = ta.getDimensionPixelSize(0, 0);
+        ta.recycle();
+
         relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
         // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
 
@@ -297,7 +258,7 @@
     }
 
     boolean isHandleMenuActive() {
-        return mHandleMenuAppInfoPill != null;
+        return mHandleMenu != null;
     }
 
     private void loadAppInfo() {
@@ -324,139 +285,55 @@
     }
 
     /**
-     * Create and display handle menu window
+     * Create the resize veil for this task. Note the veil's visibility is View.GONE by default
+     * until a resize event calls showResizeVeil below.
      */
-    void createHandleMenu() {
-        final SurfaceSyncGroup ssg = new SurfaceSyncGroup(TAG);
-        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
-        updateHandleMenuPillPositions();
-
-        createAppInfoPill(t, ssg);
-
-        // Only show windowing buttons in proto2. Proto1 uses a system-level mode only.
-        final boolean shouldShowWindowingPill = DesktopModeStatus.isProto2Enabled();
-        if (shouldShowWindowingPill) {
-            createWindowingPill(t, ssg);
-        }
-
-        createMoreActionsPill(t, ssg);
-
-        ssg.addTransaction(t);
-        ssg.markSyncReady();
-        setupHandleMenu(shouldShowWindowingPill);
-    }
-
-    private void createAppInfoPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
-        final int x = (int) mHandleMenuAppInfoPillPosition.x;
-        final int y = (int) mHandleMenuAppInfoPillPosition.y;
-        mHandleMenuAppInfoPill = addWindow(
-                R.layout.desktop_mode_window_decor_handle_menu_app_info_pill,
-                "Menu's app info pill",
-                t, ssg, x, y, mMenuWidth, mAppInfoPillHeight, mShadowRadius, mCornerRadius);
-    }
-
-    private void createWindowingPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
-        final int x = (int) mHandleMenuWindowingPillPosition.x;
-        final int y = (int) mHandleMenuWindowingPillPosition.y;
-        mHandleMenuWindowingPill = addWindow(
-                R.layout.desktop_mode_window_decor_handle_menu_windowing_pill,
-                "Menu's windowing pill",
-                t, ssg, x, y, mMenuWidth, mWindowingPillHeight, mShadowRadius, mCornerRadius);
-    }
-
-    private void createMoreActionsPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
-        final int x = (int) mHandleMenuMoreActionsPillPosition.x;
-        final int y = (int) mHandleMenuMoreActionsPillPosition.y;
-        mHandleMenuMoreActionsPill = addWindow(
-                R.layout.desktop_mode_window_decor_handle_menu_more_actions_pill,
-                "Menu's more actions pill",
-                t, ssg, x, y, mMenuWidth, mMoreActionsPillHeight, mShadowRadius, mCornerRadius);
-    }
-
-    private void setupHandleMenu(boolean windowingPillShown) {
-        // App Info pill setup.
-        final View appInfoPillView = mHandleMenuAppInfoPill.mWindowViewHost.getView();
-        final ImageButton collapseBtn = appInfoPillView.findViewById(R.id.collapse_menu_button);
-        final ImageView appIcon = appInfoPillView.findViewById(R.id.application_icon);
-        final TextView appName = appInfoPillView.findViewById(R.id.application_name);
-        collapseBtn.setOnClickListener(mOnCaptionButtonClickListener);
-        appInfoPillView.setOnTouchListener(mOnCaptionTouchListener);
-        appIcon.setImageDrawable(mAppIcon);
-        appName.setText(mAppName);
-
-        // Windowing pill setup.
-        if (windowingPillShown) {
-            final View windowingPillView = mHandleMenuWindowingPill.mWindowViewHost.getView();
-            final ImageButton fullscreenBtn = windowingPillView.findViewById(
-                    R.id.fullscreen_button);
-            final ImageButton splitscreenBtn = windowingPillView.findViewById(
-                    R.id.split_screen_button);
-            final ImageButton floatingBtn = windowingPillView.findViewById(R.id.floating_button);
-            final ImageButton desktopBtn = windowingPillView.findViewById(R.id.desktop_button);
-            fullscreenBtn.setOnClickListener(mOnCaptionButtonClickListener);
-            splitscreenBtn.setOnClickListener(mOnCaptionButtonClickListener);
-            floatingBtn.setOnClickListener(mOnCaptionButtonClickListener);
-            desktopBtn.setOnClickListener(mOnCaptionButtonClickListener);
-            // The button corresponding to the windowing mode that the task is currently in uses a
-            // different color than the others.
-            final ColorStateList activeColorStateList = ColorStateList.valueOf(
-                    mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_active));
-            final ColorStateList inActiveColorStateList = ColorStateList.valueOf(
-                    mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_inactive));
-            fullscreenBtn.setImageTintList(
-                    mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
-                            ? activeColorStateList : inActiveColorStateList);
-            splitscreenBtn.setImageTintList(
-                    mTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
-                            ? activeColorStateList : inActiveColorStateList);
-            floatingBtn.setImageTintList(mTaskInfo.getWindowingMode() == WINDOWING_MODE_PINNED
-                    ? activeColorStateList : inActiveColorStateList);
-            desktopBtn.setImageTintList(mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
-                    ? activeColorStateList : inActiveColorStateList);
-        }
-
-        // More Actions pill setup.
-        final View moreActionsPillView = mHandleMenuMoreActionsPill.mWindowViewHost.getView();
-        final Button closeBtn = moreActionsPillView.findViewById(R.id.close_button);
-        closeBtn.setOnClickListener(mOnCaptionButtonClickListener);
+    void createResizeVeil() {
+        mResizeVeil = new ResizeVeil(mContext, mAppIcon, mTaskInfo,
+                mSurfaceControlBuilderSupplier, mDisplay, mSurfaceControlTransactionSupplier);
     }
 
     /**
-     * Updates the handle menu pills' position variables to reflect their next positions
+     * Fade in the resize veil
      */
-    private void updateHandleMenuPillPositions() {
-        final int menuX, menuY;
-        final int captionWidth = mTaskInfo.getConfiguration()
-                .windowConfiguration.getBounds().width();
-        if (mRelayoutParams.mLayoutResId
-                == R.layout.desktop_mode_app_controls_window_decor) {
-            // Align the handle menu to the left of the caption.
-            menuX = mRelayoutParams.mCaptionX + mMarginMenuStart;
-            menuY = mRelayoutParams.mCaptionY + mMarginMenuTop;
-        } else {
-            // Position the handle menu at the center of the caption.
-            menuX = mRelayoutParams.mCaptionX + (captionWidth / 2) - (mMenuWidth / 2);
-            menuY = mRelayoutParams.mCaptionY + mMarginMenuStart;
-        }
+    void showResizeVeil() {
+        mResizeVeil.showVeil(mTaskSurface);
+    }
 
-        // App Info pill setup.
-        final int appInfoPillY = menuY;
-        mHandleMenuAppInfoPillPosition.set(menuX, appInfoPillY);
+    /**
+     * Set new bounds for the resize veil
+     */
+    void updateResizeVeil(Rect newBounds) {
+        mResizeVeil.relayout(newBounds);
+    }
 
-        // Only show windowing buttons in proto2. Proto1 uses a system-level mode only.
-        final boolean shouldShowWindowingPill = DesktopModeStatus.isProto2Enabled();
+    /**
+     * Fade the resize veil out.
+     */
+    void hideResizeVeil() {
+        mResizeVeil.hideVeil();
+    }
 
-        final int windowingPillY, moreActionsPillY;
-        if (shouldShowWindowingPill) {
-            windowingPillY = appInfoPillY + mAppInfoPillHeight + mMarginMenuSpacing;
-            mHandleMenuWindowingPillPosition.set(menuX, windowingPillY);
-            moreActionsPillY = windowingPillY + mWindowingPillHeight + mMarginMenuSpacing;
-            mHandleMenuMoreActionsPillPosition.set(menuX, moreActionsPillY);
-        } else {
-            // Just start after the end of the app info pill + margins.
-            moreActionsPillY = appInfoPillY + mAppInfoPillHeight + mMarginMenuSpacing;
-            mHandleMenuMoreActionsPillPosition.set(menuX, moreActionsPillY);
-        }
+    private void disposeResizeVeil() {
+        if (mResizeVeil == null) return;
+        mResizeVeil.dispose();
+        mResizeVeil = null;
+    }
+
+    /**
+     * Create and display handle menu window
+     */
+    void createHandleMenu() {
+        mHandleMenu = new HandleMenu.Builder(this)
+                .setAppIcon(mAppIcon)
+                .setAppName(mAppName)
+                .setOnClickListener(mOnCaptionButtonClickListener)
+                .setOnTouchListener(mOnCaptionTouchListener)
+                .setLayoutId(mRelayoutParams.mLayoutResId)
+                .setCaptionPosition(mRelayoutParams.mCaptionX, mRelayoutParams.mCaptionY)
+                .setWindowingButtonsVisible(DesktopModeStatus.isProto2Enabled())
+                .build();
+        mHandleMenu.show();
     }
 
     /**
@@ -464,14 +341,8 @@
      */
     void closeHandleMenu() {
         if (!isHandleMenuActive()) return;
-        mHandleMenuAppInfoPill.releaseView();
-        mHandleMenuAppInfoPill = null;
-        if (mHandleMenuWindowingPill != null) {
-            mHandleMenuWindowingPill.releaseView();
-            mHandleMenuWindowingPill = null;
-        }
-        mHandleMenuMoreActionsPill.releaseView();
-        mHandleMenuMoreActionsPill = null;
+        mHandleMenu.close();
+        mHandleMenu = null;
     }
 
     @Override
@@ -488,10 +359,6 @@
     void closeHandleMenuIfNeeded(MotionEvent ev) {
         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 (mHandleMenuAppInfoPill.mWindowViewHost.getView().getWidth() == 0) return;
-
         PointF inputPoint = offsetCaptionLocation(ev);
 
         // If this is called before open_menu_button's onClick, we don't want to close
@@ -501,22 +368,7 @@
                 inputPoint.x,
                 inputPoint.y);
 
-        final boolean pointInAppInfoPill = pointInView(
-                mHandleMenuAppInfoPill.mWindowViewHost.getView(),
-                inputPoint.x - mHandleMenuAppInfoPillPosition.x,
-                inputPoint.y - mHandleMenuAppInfoPillPosition.y);
-        boolean pointInWindowingPill = false;
-        if (mHandleMenuWindowingPill != null) {
-            pointInWindowingPill = pointInView(mHandleMenuWindowingPill.mWindowViewHost.getView(),
-                    inputPoint.x - mHandleMenuWindowingPillPosition.x,
-                    inputPoint.y - mHandleMenuWindowingPillPosition.y);
-        }
-        final boolean pointInMoreActionsPill = pointInView(
-                mHandleMenuMoreActionsPill.mWindowViewHost.getView(),
-                inputPoint.x - mHandleMenuMoreActionsPillPosition.x,
-                inputPoint.y - mHandleMenuMoreActionsPillPosition.y);
-        if (!pointInAppInfoPill && !pointInWindowingPill
-                && !pointInMoreActionsPill && !pointInOpenMenuButton) {
+        if (!mHandleMenu.isValidMenuInput(inputPoint) && !pointInOpenMenuButton) {
             closeHandleMenu();
         }
     }
@@ -573,13 +425,7 @@
             final View handle = caption.findViewById(R.id.caption_handle);
             clickIfPointInView(new PointF(ev.getX(), ev.getY()), handle);
         } else {
-            final View appInfoPill = mHandleMenuAppInfoPill.mWindowViewHost.getView();
-            final ImageButton collapse = appInfoPill.findViewById(R.id.collapse_menu_button);
-            // Translate the input point from display coordinates to the same space as the collapse
-            // button, meaning its parent (app info pill view).
-            final PointF inputPoint = new PointF(ev.getX() - mHandleMenuAppInfoPillPosition.x,
-                    ev.getY() - mHandleMenuAppInfoPillPosition.y);
-            clickIfPointInView(inputPoint, collapse);
+            mHandleMenu.checkClickEvent(ev);
         }
     }
 
@@ -591,7 +437,7 @@
         return false;
     }
 
-    private boolean pointInView(View v, float x, float y) {
+    boolean pointInView(View v, float x, float y) {
         return v != null && v.getLeft() <= x && v.getRight() >= x
                 && v.getTop() <= y && v.getBottom() >= y;
     }
@@ -601,6 +447,7 @@
         closeDragResizeListener();
         closeHandleMenu();
         mCornersListener.onTaskCornersRemoved(mTaskInfo.taskId);
+        disposeResizeVeil();
         super.close();
     }
 
@@ -622,6 +469,40 @@
         return cornersRegion;
     }
 
+    /**
+     * If transition exists in mTransitionsPausingRelayout, remove the transition and decrement
+     * mRelayoutBlock
+     */
+    void removeTransitionPausingRelayout(IBinder transition) {
+        if (mTransitionsPausingRelayout.remove(transition)) {
+            mRelayoutBlock--;
+        }
+    }
+
+    /**
+     * Add transition to mTransitionsPausingRelayout
+     */
+    void addTransitionPausingRelayout(IBinder transition) {
+        mTransitionsPausingRelayout.add(transition);
+    }
+
+    /**
+     * If two transitions merge and the merged transition is in mTransitionsPausingRelayout,
+     * remove the merged transition from the set and add the transition it was merged into.
+     */
+    public void mergeTransitionPausingRelayout(IBinder merged, IBinder playing) {
+        if (mTransitionsPausingRelayout.remove(merged)) {
+            mTransitionsPausingRelayout.add(playing);
+        }
+    }
+
+    /**
+     * Increase mRelayoutBlock, stopping relayout if mRelayoutBlock is now greater than 0.
+     */
+    public void incrementRelayoutBlock() {
+        mRelayoutBlock++;
+    }
+
     static class Factory {
 
         DesktopModeWindowDecoration create(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java
index 0191c60..4e98f0c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java
@@ -16,19 +16,29 @@
 
 package com.android.wm.shell.windowdecor;
 
+import android.annotation.IntDef;
+
 /**
  * Callback called when receiving drag-resize or drag-move related input events.
  */
 public interface DragPositioningCallback {
+    @IntDef({CTRL_TYPE_UNDEFINED, CTRL_TYPE_LEFT, CTRL_TYPE_RIGHT, CTRL_TYPE_TOP, CTRL_TYPE_BOTTOM})
+    @interface CtrlType {}
+
+    int CTRL_TYPE_UNDEFINED = 0;
+    int CTRL_TYPE_LEFT = 1;
+    int CTRL_TYPE_RIGHT = 2;
+    int CTRL_TYPE_TOP = 4;
+    int CTRL_TYPE_BOTTOM = 8;
     /**
      * Called when a drag-resize or drag-move starts.
      *
-     * @param ctrlType {@link TaskPositioner.CtrlType} indicating the direction of resizing, use
+     * @param ctrlType {@link CtrlType} indicating the direction of resizing, use
      *                 {@code 0} to indicate it's a move
      * @param x x coordinate in window decoration coordinate system where the drag starts
      * @param y y coordinate in window decoration coordinate system where the drag starts
      */
-    void onDragPositioningStart(@TaskPositioner.CtrlType int ctrlType, float x, float y);
+    void onDragPositioningStart(@CtrlType int ctrlType, float x, float y);
 
     /**
      * Called when the pointer moves during a drag-resize or drag-move.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
new file mode 100644
index 0000000..ae93a43
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM;
+import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT;
+import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT;
+import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP;
+import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED;
+
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+
+/**
+ * Utility class that contains logic common to classes implementing {@link DragPositioningCallback}
+ * Specifically, this class contains logic for determining changed bounds from a drag input
+ * and applying that change to the task bounds when applicable.
+ */
+public class DragPositioningCallbackUtility {
+
+    /**
+     * Determine the delta between input's current point and the input start point.
+     * @param inputX current input x coordinate
+     * @param inputY current input y coordinate
+     * @param repositionStartPoint initial input coordinate
+     * @return delta between these two points
+     */
+    static PointF calculateDelta(float inputX, float inputY, PointF repositionStartPoint) {
+        final float deltaX = inputX - repositionStartPoint.x;
+        final float deltaY = inputY - repositionStartPoint.y;
+        return new PointF(deltaX, deltaY);
+    }
+
+    /**
+     * Based on type of drag and delta provided, calculate the new bounds to display for this task.
+     * @param ctrlType type of drag being performed
+     * @param hasMoved whether the current drag has moved on a prior input event
+     * @param repositionTaskBounds the bounds the task is being repositioned to
+     * @param taskBoundsAtDragStart the bounds of the task on the first drag input event
+     * @param stableBounds bounds that represent the resize limit of this task
+     * @param delta difference between start input and current input in x/y coordinates
+     * @param displayController task's display controller
+     * @param windowDecoration window decoration of the task being dragged
+     * @return whether this method changed repositionTaskBounds
+     */
+    static boolean changeBounds(int ctrlType, boolean hasMoved,
+            Rect repositionTaskBounds, Rect taskBoundsAtDragStart, Rect stableBounds,
+            PointF delta, DisplayController displayController, WindowDecoration windowDecoration) {
+        // |mRepositionTaskBounds| is the bounds last reported if |mHasMoved| is true. If it's not
+        // true, we can compare it against |mTaskBoundsAtDragStart|.
+        final int oldLeft = hasMoved ? repositionTaskBounds.left : taskBoundsAtDragStart.left;
+        final int oldTop = hasMoved ? repositionTaskBounds.top : taskBoundsAtDragStart.top;
+        final int oldRight = hasMoved ? repositionTaskBounds.right : taskBoundsAtDragStart.right;
+        final int oldBottom =
+                hasMoved ? repositionTaskBounds.bottom : taskBoundsAtDragStart.bottom;
+
+
+        repositionTaskBounds.set(taskBoundsAtDragStart);
+
+        // Make sure the new resizing destination in any direction falls within the stable bounds.
+        // If not, set the bounds back to the old location that was valid to avoid conflicts with
+        // some regions such as the gesture area.
+        displayController.getDisplayLayout(windowDecoration.mDisplay.getDisplayId())
+                .getStableBounds(stableBounds);
+        if ((ctrlType & CTRL_TYPE_LEFT) != 0) {
+            final int candidateLeft = repositionTaskBounds.left + (int) delta.x;
+            repositionTaskBounds.left = (candidateLeft > stableBounds.left)
+                    ? candidateLeft : oldLeft;
+        }
+        if ((ctrlType & CTRL_TYPE_RIGHT) != 0) {
+            final int candidateRight = repositionTaskBounds.right + (int) delta.x;
+            repositionTaskBounds.right = (candidateRight < stableBounds.right)
+                    ? candidateRight : oldRight;
+        }
+        if ((ctrlType & CTRL_TYPE_TOP) != 0) {
+            final int candidateTop = repositionTaskBounds.top + (int) delta.y;
+            repositionTaskBounds.top = (candidateTop > stableBounds.top)
+                    ? candidateTop : oldTop;
+        }
+        if ((ctrlType & CTRL_TYPE_BOTTOM) != 0) {
+            final int candidateBottom = repositionTaskBounds.bottom + (int) delta.y;
+            repositionTaskBounds.bottom = (candidateBottom < stableBounds.bottom)
+                    ? candidateBottom : oldBottom;
+        }
+        if (ctrlType == CTRL_TYPE_UNDEFINED) {
+            repositionTaskBounds.offset((int) delta.x, (int) delta.y);
+        }
+
+        // If width or height are negative or less than the minimum width or height, revert the
+        // respective bounds to use previous bound dimensions.
+        if (repositionTaskBounds.width() < getMinWidth(displayController, windowDecoration)) {
+            repositionTaskBounds.right = oldRight;
+            repositionTaskBounds.left = oldLeft;
+        }
+        if (repositionTaskBounds.height() < getMinHeight(displayController, windowDecoration)) {
+            repositionTaskBounds.top = oldTop;
+            repositionTaskBounds.bottom = oldBottom;
+        }
+        // If there are no changes to the bounds after checking new bounds against minimum width
+        // and height, do not set bounds and return false
+        if (oldLeft == repositionTaskBounds.left && oldTop == repositionTaskBounds.top
+                && oldRight == repositionTaskBounds.right
+                && oldBottom == repositionTaskBounds.bottom) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Apply a bounds change to a task.
+     * @param wct provided {@link WindowContainerTransaction} that may contain other changes
+     * @param windowDecoration decor of task we are changing bounds for
+     * @param taskBounds new bounds of this task
+     * @param taskOrganizer applies the provided WindowContainerTransaction
+     */
+    static void applyTaskBoundsChange(WindowContainerTransaction wct,
+            WindowDecoration windowDecoration, Rect taskBounds, ShellTaskOrganizer taskOrganizer) {
+        wct.setBounds(windowDecoration.mTaskInfo.token, taskBounds);
+        taskOrganizer.applyTransaction(wct);
+    }
+
+    private static float getMinWidth(DisplayController displayController,
+            WindowDecoration windowDecoration) {
+        return windowDecoration.mTaskInfo.minWidth < 0 ? getDefaultMinSize(displayController,
+                windowDecoration)
+                : windowDecoration.mTaskInfo.minWidth;
+    }
+
+    private static float getMinHeight(DisplayController displayController,
+            WindowDecoration windowDecoration) {
+        return windowDecoration.mTaskInfo.minHeight < 0 ? getDefaultMinSize(displayController,
+                windowDecoration)
+                : windowDecoration.mTaskInfo.minHeight;
+    }
+
+    private static float getDefaultMinSize(DisplayController displayController,
+            WindowDecoration windowDecoration) {
+        float density =  displayController.getDisplayLayout(windowDecoration.mTaskInfo.displayId)
+                .densityDpi() * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+        return windowDecoration.mTaskInfo.defaultMinSize * density;
+    }
+
+    interface DragStartListener {
+        /**
+         * Inform the implementing class that a drag resize has started
+         * @param taskId id of this positioner's {@link WindowDecoration}
+         */
+        void onDragStart(int taskId);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 34c8c08..287d861 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -21,6 +21,11 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
+import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM;
+import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT;
+import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT;
+import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP;
+
 import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -367,7 +372,7 @@
             return calculateResizeHandlesCtrlType(x, y) != 0;
         }
 
-        @TaskPositioner.CtrlType
+        @DragPositioningCallback.CtrlType
         private int calculateCtrlType(boolean isTouch, float x, float y) {
             if (isTouch) {
                 return calculateCornersCtrlType(x, y);
@@ -375,62 +380,62 @@
             return calculateResizeHandlesCtrlType(x, y);
         }
 
-        @TaskPositioner.CtrlType
+        @DragPositioningCallback.CtrlType
         private int calculateResizeHandlesCtrlType(float x, float y) {
             int ctrlType = 0;
             if (x < 0) {
-                ctrlType |= TaskPositioner.CTRL_TYPE_LEFT;
+                ctrlType |= CTRL_TYPE_LEFT;
             }
             if (x > mTaskWidth) {
-                ctrlType |= TaskPositioner.CTRL_TYPE_RIGHT;
+                ctrlType |= CTRL_TYPE_RIGHT;
             }
             if (y < 0) {
-                ctrlType |= TaskPositioner.CTRL_TYPE_TOP;
+                ctrlType |= CTRL_TYPE_TOP;
             }
             if (y > mTaskHeight) {
-                ctrlType |= TaskPositioner.CTRL_TYPE_BOTTOM;
+                ctrlType |= CTRL_TYPE_BOTTOM;
             }
             return ctrlType;
         }
 
-        @TaskPositioner.CtrlType
+        @DragPositioningCallback.CtrlType
         private int calculateCornersCtrlType(float x, float y) {
             int xi = (int) x;
             int yi = (int) y;
             if (mLeftTopCornerBounds.contains(xi, yi)) {
-                return TaskPositioner.CTRL_TYPE_LEFT | TaskPositioner.CTRL_TYPE_TOP;
+                return CTRL_TYPE_LEFT | CTRL_TYPE_TOP;
             }
             if (mLeftBottomCornerBounds.contains(xi, yi)) {
-                return TaskPositioner.CTRL_TYPE_LEFT | TaskPositioner.CTRL_TYPE_BOTTOM;
+                return CTRL_TYPE_LEFT | CTRL_TYPE_BOTTOM;
             }
             if (mRightTopCornerBounds.contains(xi, yi)) {
-                return TaskPositioner.CTRL_TYPE_RIGHT | TaskPositioner.CTRL_TYPE_TOP;
+                return CTRL_TYPE_RIGHT | CTRL_TYPE_TOP;
             }
             if (mRightBottomCornerBounds.contains(xi, yi)) {
-                return TaskPositioner.CTRL_TYPE_RIGHT | TaskPositioner.CTRL_TYPE_BOTTOM;
+                return CTRL_TYPE_RIGHT | CTRL_TYPE_BOTTOM;
             }
             return 0;
         }
 
         private void updateCursorType(float x, float y) {
-            @TaskPositioner.CtrlType int ctrlType = calculateResizeHandlesCtrlType(x, y);
+            @DragPositioningCallback.CtrlType int ctrlType = calculateResizeHandlesCtrlType(x, y);
 
             int cursorType = PointerIcon.TYPE_DEFAULT;
             switch (ctrlType) {
-                case TaskPositioner.CTRL_TYPE_LEFT:
-                case TaskPositioner.CTRL_TYPE_RIGHT:
+                case CTRL_TYPE_LEFT:
+                case CTRL_TYPE_RIGHT:
                     cursorType = PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
                     break;
-                case TaskPositioner.CTRL_TYPE_TOP:
-                case TaskPositioner.CTRL_TYPE_BOTTOM:
+                case CTRL_TYPE_TOP:
+                case CTRL_TYPE_BOTTOM:
                     cursorType = PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
                     break;
-                case TaskPositioner.CTRL_TYPE_LEFT | TaskPositioner.CTRL_TYPE_TOP:
-                case TaskPositioner.CTRL_TYPE_RIGHT | TaskPositioner.CTRL_TYPE_BOTTOM:
+                case CTRL_TYPE_LEFT | CTRL_TYPE_TOP:
+                case CTRL_TYPE_RIGHT | CTRL_TYPE_BOTTOM:
                     cursorType = PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW;
                     break;
-                case TaskPositioner.CTRL_TYPE_LEFT | TaskPositioner.CTRL_TYPE_BOTTOM:
-                case TaskPositioner.CTRL_TYPE_RIGHT | TaskPositioner.CTRL_TYPE_TOP:
+                case CTRL_TYPE_LEFT | CTRL_TYPE_BOTTOM:
+                case CTRL_TYPE_RIGHT | CTRL_TYPE_TOP:
                     cursorType = PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW;
                     break;
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
new file mode 100644
index 0000000..b366c80
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.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 com.android.wm.shell.windowdecor;
+
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+
+/**
+ * A task positioner that resizes/relocates task contents as it is dragged.
+ * Utilizes {@link DragPositioningCallbackUtility} to determine new task bounds.
+ */
+class FluidResizeTaskPositioner implements DragPositioningCallback {
+    private final ShellTaskOrganizer mTaskOrganizer;
+    private final WindowDecoration mWindowDecoration;
+    private DisplayController mDisplayController;
+    private DragPositioningCallbackUtility.DragStartListener mDragStartListener;
+    private final Rect mStableBounds = new Rect();
+    private final Rect mTaskBoundsAtDragStart = new Rect();
+    private final PointF mRepositionStartPoint = new PointF();
+    private final Rect mRepositionTaskBounds = new Rect();
+    private int mCtrlType;
+    private boolean mHasMoved;
+
+    FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
+            DisplayController displayController) {
+        this(taskOrganizer, windowDecoration, displayController, dragStartListener -> {});
+    }
+
+    FluidResizeTaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
+            DisplayController displayController,
+            DragPositioningCallbackUtility.DragStartListener dragStartListener) {
+        mTaskOrganizer = taskOrganizer;
+        mWindowDecoration = windowDecoration;
+        mDisplayController = displayController;
+        mDragStartListener = dragStartListener;
+    }
+
+    @Override
+    public void onDragPositioningStart(int ctrlType, float x, float y) {
+        mCtrlType = ctrlType;
+        mTaskBoundsAtDragStart.set(
+                mWindowDecoration.mTaskInfo.configuration.windowConfiguration.getBounds());
+        mRepositionStartPoint.set(x, y);
+        mDragStartListener.onDragStart(mWindowDecoration.mTaskInfo.taskId);
+    }
+
+    @Override
+    public void onDragPositioningMove(float x, float y) {
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y, mRepositionStartPoint);
+        if (DragPositioningCallbackUtility.changeBounds(mCtrlType, mHasMoved,
+                mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta,
+                mDisplayController, mWindowDecoration)) {
+            // The task is being resized, send the |dragResizing| hint to core with the first
+            // bounds-change wct.
+            if (!mHasMoved && mCtrlType != CTRL_TYPE_UNDEFINED) {
+                // This is the first bounds change since drag resize operation started.
+                wct.setDragResizing(mWindowDecoration.mTaskInfo.token, true /* dragResizing */);
+            }
+            DragPositioningCallbackUtility.applyTaskBoundsChange(wct, mWindowDecoration,
+                    mRepositionTaskBounds, mTaskOrganizer);
+            mHasMoved = true;
+        }
+    }
+
+    @Override
+    public void onDragPositioningEnd(float x, float y) {
+        // |mHasMoved| being false means there is no real change to the task bounds in WM core, so
+        // we don't need a WCT to finish it.
+        if (mHasMoved) {
+            final WindowContainerTransaction wct = new WindowContainerTransaction();
+            wct.setDragResizing(mWindowDecoration.mTaskInfo.token, false /* dragResizing */);
+            PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y,
+                    mRepositionStartPoint);
+            if (DragPositioningCallbackUtility.changeBounds(mCtrlType, mHasMoved,
+                    mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta,
+                    mDisplayController, mWindowDecoration)) {
+                wct.setBounds(mWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
+            }
+            mTaskOrganizer.applyTransaction(wct);
+        }
+
+        mTaskBoundsAtDragStart.setEmpty();
+        mRepositionStartPoint.set(0, 0);
+        mCtrlType = CTRL_TYPE_UNDEFINED;
+        mHasMoved = false;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
new file mode 100644
index 0000000..ed3cca0
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.PointF;
+import android.graphics.drawable.Drawable;
+import android.view.MotionEvent;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.window.SurfaceSyncGroup;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.desktopmode.DesktopModeStatus;
+
+/**
+ * Handle menu opened when the appropriate button is clicked on.
+ *
+ * Displays up to 3 pills that show the following:
+ * App Info: App name, app icon, and collapse button to close the menu.
+ * Windowing Options(Proto 2 only): Buttons to change windowing modes.
+ * Additional Options: Miscellaneous functions including screenshot and closing task.
+ */
+class HandleMenu {
+    private static final String TAG = "HandleMenu";
+    private final Context mContext;
+    private final WindowDecoration mParentDecor;
+    private WindowDecoration.AdditionalWindow mAppInfoPill;
+    private WindowDecoration.AdditionalWindow mWindowingPill;
+    private WindowDecoration.AdditionalWindow mMoreActionsPill;
+    private final PointF mAppInfoPillPosition = new PointF();
+    private final PointF mWindowingPillPosition = new PointF();
+    private final PointF mMoreActionsPillPosition = new PointF();
+    private final boolean mShouldShowWindowingPill;
+    private final Drawable mAppIcon;
+    private final CharSequence mAppName;
+    private final View.OnClickListener mOnClickListener;
+    private final View.OnTouchListener mOnTouchListener;
+    private final RunningTaskInfo mTaskInfo;
+    private final int mLayoutResId;
+    private final int mCaptionX;
+    private final int mCaptionY;
+    private int mMarginMenuTop;
+    private int mMarginMenuStart;
+    private int mMarginMenuSpacing;
+    private int mMenuWidth;
+    private int mAppInfoPillHeight;
+    private int mWindowingPillHeight;
+    private int mMoreActionsPillHeight;
+    private int mShadowRadius;
+    private int mCornerRadius;
+
+
+    HandleMenu(WindowDecoration parentDecor, int layoutResId, int captionX, int captionY,
+            View.OnClickListener onClickListener, View.OnTouchListener onTouchListener,
+            Drawable appIcon, CharSequence appName, boolean shouldShowWindowingPill) {
+        mParentDecor = parentDecor;
+        mContext = mParentDecor.mDecorWindowContext;
+        mTaskInfo = mParentDecor.mTaskInfo;
+        mLayoutResId = layoutResId;
+        mCaptionX = captionX;
+        mCaptionY = captionY;
+        mOnClickListener = onClickListener;
+        mOnTouchListener = onTouchListener;
+        mAppIcon = appIcon;
+        mAppName = appName;
+        mShouldShowWindowingPill = shouldShowWindowingPill;
+        loadHandleMenuDimensions();
+        updateHandleMenuPillPositions();
+    }
+
+    void show() {
+        final SurfaceSyncGroup ssg = new SurfaceSyncGroup(TAG);
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+
+        createAppInfoPill(t, ssg);
+        if (mShouldShowWindowingPill) {
+            createWindowingPill(t, ssg);
+        }
+        createMoreActionsPill(t, ssg);
+        ssg.addTransaction(t);
+        ssg.markSyncReady();
+        setupHandleMenu();
+    }
+
+    private void createAppInfoPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
+        final int x = (int) mAppInfoPillPosition.x;
+        final int y = (int) mAppInfoPillPosition.y;
+        mAppInfoPill = mParentDecor.addWindow(
+                R.layout.desktop_mode_window_decor_handle_menu_app_info_pill,
+                "Menu's app info pill",
+                t, ssg, x, y, mMenuWidth, mAppInfoPillHeight, mShadowRadius, mCornerRadius);
+    }
+
+    private void createWindowingPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
+        final int x = (int) mWindowingPillPosition.x;
+        final int y = (int) mWindowingPillPosition.y;
+        mWindowingPill = mParentDecor.addWindow(
+                R.layout.desktop_mode_window_decor_handle_menu_windowing_pill,
+                "Menu's windowing pill",
+                t, ssg, x, y, mMenuWidth, mWindowingPillHeight, mShadowRadius, mCornerRadius);
+    }
+
+    private void createMoreActionsPill(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
+        final int x = (int) mMoreActionsPillPosition.x;
+        final int y = (int) mMoreActionsPillPosition.y;
+        mMoreActionsPill = mParentDecor.addWindow(
+                R.layout.desktop_mode_window_decor_handle_menu_more_actions_pill,
+                "Menu's more actions pill",
+                t, ssg, x, y, mMenuWidth, mMoreActionsPillHeight, mShadowRadius, mCornerRadius);
+    }
+
+    /**
+     * Set up interactive elements and color of this handle menu
+     */
+    private void setupHandleMenu() {
+        // App Info pill setup.
+        final View appInfoPillView = mAppInfoPill.mWindowViewHost.getView();
+        final ImageButton collapseBtn = appInfoPillView.findViewById(R.id.collapse_menu_button);
+        final ImageView appIcon = appInfoPillView.findViewById(R.id.application_icon);
+        final TextView appName = appInfoPillView.findViewById(R.id.application_name);
+        collapseBtn.setOnClickListener(mOnClickListener);
+        appInfoPillView.setOnTouchListener(mOnTouchListener);
+        appIcon.setImageDrawable(mAppIcon);
+        appName.setText(mAppName);
+
+        // Windowing pill setup.
+        if (mShouldShowWindowingPill) {
+            final View windowingPillView = mWindowingPill.mWindowViewHost.getView();
+            final ImageButton fullscreenBtn = windowingPillView.findViewById(
+                    R.id.fullscreen_button);
+            final ImageButton splitscreenBtn = windowingPillView.findViewById(
+                    R.id.split_screen_button);
+            final ImageButton floatingBtn = windowingPillView.findViewById(R.id.floating_button);
+            final ImageButton desktopBtn = windowingPillView.findViewById(R.id.desktop_button);
+            fullscreenBtn.setOnClickListener(mOnClickListener);
+            splitscreenBtn.setOnClickListener(mOnClickListener);
+            floatingBtn.setOnClickListener(mOnClickListener);
+            desktopBtn.setOnClickListener(mOnClickListener);
+            // The button corresponding to the windowing mode that the task is currently in uses a
+            // different color than the others.
+            final ColorStateList activeColorStateList = ColorStateList.valueOf(
+                    mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_active));
+            final ColorStateList inActiveColorStateList = ColorStateList.valueOf(
+                    mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_inactive));
+            fullscreenBtn.setImageTintList(
+                    mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+                            ? activeColorStateList : inActiveColorStateList);
+            splitscreenBtn.setImageTintList(
+                    mTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
+                            ? activeColorStateList : inActiveColorStateList);
+            floatingBtn.setImageTintList(mTaskInfo.getWindowingMode() == WINDOWING_MODE_PINNED
+                    ? activeColorStateList : inActiveColorStateList);
+            desktopBtn.setImageTintList(mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
+                    ? activeColorStateList : inActiveColorStateList);
+        }
+
+        // More Actions pill setup.
+        final View moreActionsPillView = mMoreActionsPill.mWindowViewHost.getView();
+        final Button closeBtn = moreActionsPillView.findViewById(R.id.close_button);
+        closeBtn.setOnClickListener(mOnClickListener);
+    }
+
+    /**
+     * Updates the handle menu pills' position variables to reflect their next positions
+     */
+    private void updateHandleMenuPillPositions() {
+        final int menuX, menuY;
+        final int captionWidth = mTaskInfo.getConfiguration()
+                .windowConfiguration.getBounds().width();
+        if (mLayoutResId
+                == R.layout.desktop_mode_app_controls_window_decor) {
+            // Align the handle menu to the left of the caption.
+            menuX = mCaptionX + mMarginMenuStart;
+            menuY = mCaptionY + mMarginMenuTop;
+        } else {
+            // Position the handle menu at the center of the caption.
+            menuX = mCaptionX + (captionWidth / 2) - (mMenuWidth / 2);
+            menuY = mCaptionY + mMarginMenuStart;
+        }
+
+        // App Info pill setup.
+        final int appInfoPillY = menuY;
+        mAppInfoPillPosition.set(menuX, appInfoPillY);
+
+        final int windowingPillY, moreActionsPillY;
+        if (mShouldShowWindowingPill) {
+            windowingPillY = appInfoPillY + mAppInfoPillHeight + mMarginMenuSpacing;
+            mWindowingPillPosition.set(menuX, windowingPillY);
+            moreActionsPillY = windowingPillY + mWindowingPillHeight + mMarginMenuSpacing;
+            mMoreActionsPillPosition.set(menuX, moreActionsPillY);
+        } else {
+            // Just start after the end of the app info pill + margins.
+            moreActionsPillY = appInfoPillY + mAppInfoPillHeight + mMarginMenuSpacing;
+            mMoreActionsPillPosition.set(menuX, moreActionsPillY);
+        }
+    }
+
+    /**
+     * Update pill layout, in case task changes have caused positioning to change.
+     * @param t
+     */
+    void relayout(SurfaceControl.Transaction t) {
+        if (mAppInfoPill != null) {
+            updateHandleMenuPillPositions();
+            t.setPosition(mAppInfoPill.mWindowSurface,
+                    mAppInfoPillPosition.x, mAppInfoPillPosition.y);
+            // Only show windowing buttons in proto2. Proto1 uses a system-level mode only.
+            final boolean shouldShowWindowingPill = DesktopModeStatus.isProto2Enabled();
+            if (shouldShowWindowingPill) {
+                t.setPosition(mWindowingPill.mWindowSurface,
+                        mWindowingPillPosition.x, mWindowingPillPosition.y);
+            }
+            t.setPosition(mMoreActionsPill.mWindowSurface,
+                    mMoreActionsPillPosition.x, mMoreActionsPillPosition.y);
+        }
+    }
+    /**
+     * Check a passed MotionEvent if a click has occurred on any button on this caption
+     * Note this should only be called when a regular onClick is not possible
+     * (i.e. the button was clicked through status bar layer)
+     * @param ev the MotionEvent to compare against.
+     */
+    void checkClickEvent(MotionEvent ev) {
+        final View appInfoPill = mAppInfoPill.mWindowViewHost.getView();
+        final ImageButton collapse = appInfoPill.findViewById(R.id.collapse_menu_button);
+        // Translate the input point from display coordinates to the same space as the collapse
+        // button, meaning its parent (app info pill view).
+        final PointF inputPoint = new PointF(ev.getX() - mAppInfoPillPosition.x,
+                ev.getY() - mAppInfoPillPosition.y);
+        if (pointInView(collapse, inputPoint.x, inputPoint.y)) {
+            mOnClickListener.onClick(collapse);
+        }
+    }
+
+    /**
+     * A valid menu input is one of the following:
+     * An input that happens in the menu views.
+     * Any input before the views have been laid out.
+     * @param inputPoint the input to compare against.
+     */
+    boolean isValidMenuInput(PointF inputPoint) {
+        if (!viewsLaidOut()) return true;
+        final boolean pointInAppInfoPill = pointInView(
+                mAppInfoPill.mWindowViewHost.getView(),
+                inputPoint.x - mAppInfoPillPosition.x,
+                inputPoint.y - mAppInfoPillPosition.y);
+        boolean pointInWindowingPill = false;
+        if (mWindowingPill != null) {
+            pointInWindowingPill = pointInView(
+                    mWindowingPill.mWindowViewHost.getView(),
+                    inputPoint.x - mWindowingPillPosition.x,
+                    inputPoint.y - mWindowingPillPosition.y);
+        }
+        final boolean pointInMoreActionsPill = pointInView(
+                mMoreActionsPill.mWindowViewHost.getView(),
+                inputPoint.x - mMoreActionsPillPosition.x,
+                inputPoint.y - mMoreActionsPillPosition.y);
+
+        return pointInAppInfoPill || pointInWindowingPill || pointInMoreActionsPill;
+    }
+
+    private boolean pointInView(View v, float x, float y) {
+        return v != null && v.getLeft() <= x && v.getRight() >= x
+                && v.getTop() <= y && v.getBottom() >= y;
+    }
+
+    /**
+     * Check if the views for handle menu can be seen.
+     * @return
+     */
+    private boolean viewsLaidOut() {
+        return mAppInfoPill.mWindowViewHost.getView().isLaidOut();
+    }
+
+
+    private void loadHandleMenuDimensions() {
+        final Resources resources = mContext.getResources();
+        mMenuWidth = loadDimensionPixelSize(resources,
+                R.dimen.desktop_mode_handle_menu_width);
+        mMarginMenuTop = loadDimensionPixelSize(resources,
+                R.dimen.desktop_mode_handle_menu_margin_top);
+        mMarginMenuStart = loadDimensionPixelSize(resources,
+                R.dimen.desktop_mode_handle_menu_margin_start);
+        mMarginMenuSpacing = loadDimensionPixelSize(resources,
+                R.dimen.desktop_mode_handle_menu_pill_spacing_margin);
+        mAppInfoPillHeight = loadDimensionPixelSize(resources,
+                R.dimen.desktop_mode_handle_menu_app_info_pill_height);
+        mWindowingPillHeight = loadDimensionPixelSize(resources,
+                R.dimen.desktop_mode_handle_menu_windowing_pill_height);
+        mMoreActionsPillHeight = loadDimensionPixelSize(resources,
+                R.dimen.desktop_mode_handle_menu_more_actions_pill_height);
+        mShadowRadius = loadDimensionPixelSize(resources,
+                R.dimen.desktop_mode_handle_menu_shadow_radius);
+        mCornerRadius = loadDimensionPixelSize(resources,
+                R.dimen.desktop_mode_handle_menu_corner_radius);
+    }
+
+    private int loadDimensionPixelSize(Resources resources, int resourceId) {
+        if (resourceId == Resources.ID_NULL) {
+            return 0;
+        }
+        return resources.getDimensionPixelSize(resourceId);
+    }
+
+    void close() {
+        mAppInfoPill.releaseView();
+        mAppInfoPill = null;
+        if (mWindowingPill != null) {
+            mWindowingPill.releaseView();
+            mWindowingPill = null;
+        }
+        mMoreActionsPill.releaseView();
+        mMoreActionsPill = null;
+    }
+
+    static final class Builder {
+        private final WindowDecoration mParent;
+        private CharSequence mName;
+        private Drawable mAppIcon;
+        private View.OnClickListener mOnClickListener;
+        private View.OnTouchListener mOnTouchListener;
+        private int mLayoutId;
+        private int mCaptionX;
+        private int mCaptionY;
+        private boolean mShowWindowingPill;
+
+
+        Builder(@NonNull WindowDecoration parent) {
+            mParent = parent;
+        }
+
+        Builder setAppName(@Nullable CharSequence name) {
+            mName = name;
+            return this;
+        }
+
+        Builder setAppIcon(@Nullable Drawable appIcon) {
+            mAppIcon = appIcon;
+            return this;
+        }
+
+        Builder setOnClickListener(@Nullable View.OnClickListener onClickListener) {
+            mOnClickListener = onClickListener;
+            return this;
+        }
+
+        Builder setOnTouchListener(@Nullable View.OnTouchListener onTouchListener) {
+            mOnTouchListener = onTouchListener;
+            return this;
+        }
+
+        Builder setLayoutId(int layoutId) {
+            mLayoutId = layoutId;
+            return this;
+        }
+
+        Builder setCaptionPosition(int captionX, int captionY) {
+            mCaptionX = captionX;
+            mCaptionY = captionY;
+            return this;
+        }
+
+        Builder setWindowingButtonsVisible(boolean windowingButtonsVisible) {
+            mShowWindowingPill = windowingButtonsVisible;
+            return this;
+        }
+
+        HandleMenu build() {
+            return new HandleMenu(mParent, mLayoutId, mCaptionX, mCaptionY, mOnClickListener,
+                    mOnTouchListener, mAppIcon, mName, mShowWindowingPill);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java
new file mode 100644
index 0000000..fa2d7a8
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.view.Display;
+import android.view.LayoutInflater;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowlessWindowManager;
+import android.widget.ImageView;
+import android.window.TaskConstants;
+
+import com.android.wm.shell.R;
+
+import java.util.function.Supplier;
+
+/**
+ * Creates and updates a veil that covers task contents on resize.
+ */
+public class ResizeVeil {
+    private static final int RESIZE_ALPHA_DURATION = 200;
+    private final Context mContext;
+    private final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
+    private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;
+    private final Drawable mAppIcon;
+    private SurfaceControl mParentSurface;
+    private SurfaceControl mVeilSurface;
+    private final RunningTaskInfo mTaskInfo;
+    private SurfaceControlViewHost mViewHost;
+    private final Display mDisplay;
+
+    public ResizeVeil(Context context, Drawable appIcon, RunningTaskInfo taskInfo,
+            Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, Display display,
+            Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) {
+        mContext = context;
+        mAppIcon = appIcon;
+        mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier;
+        mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier;
+        mTaskInfo = taskInfo;
+        mDisplay = display;
+        setupResizeVeil();
+    }
+
+    /**
+     * Create the veil in its default invisible state.
+     */
+    private void setupResizeVeil() {
+        SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
+        final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get();
+        mVeilSurface = builder
+                .setName("Resize veil of Task= " + mTaskInfo.taskId)
+                .setContainerLayer()
+                .build();
+        View v = LayoutInflater.from(mContext)
+                .inflate(R.layout.desktop_mode_resize_veil, null);
+
+        t.setPosition(mVeilSurface, 0, 0)
+            .setLayer(mVeilSurface, TaskConstants.TASK_CHILD_LAYER_RESIZE_VEIL)
+            .apply();
+        Rect taskBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
+        final WindowManager.LayoutParams lp =
+                new WindowManager.LayoutParams(taskBounds.width(),
+                        taskBounds.height(),
+                        WindowManager.LayoutParams.TYPE_APPLICATION,
+                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                        PixelFormat.TRANSPARENT);
+        lp.setTitle("Resize veil of Task=" + mTaskInfo.taskId);
+        lp.setTrustedOverlay();
+        WindowlessWindowManager windowManager = new WindowlessWindowManager(mTaskInfo.configuration,
+                mVeilSurface, null /* hostInputToken */);
+        mViewHost = new SurfaceControlViewHost(mContext, mDisplay, windowManager, "ResizeVeil");
+        mViewHost.setView(v, lp);
+
+        final ImageView appIcon = mViewHost.getView().findViewById(R.id.veil_application_icon);
+        appIcon.setImageDrawable(mAppIcon);
+    }
+
+    /**
+     * Animate veil's alpha to 1, fading it in.
+     */
+    public void showVeil(SurfaceControl parentSurface) {
+        // Parent surface can change, ensure it is up to date.
+        SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
+        if (!parentSurface.equals(mParentSurface)) {
+            t.reparent(mVeilSurface, parentSurface);
+            mParentSurface = parentSurface;
+        }
+        t.show(mVeilSurface)
+                .apply();
+        final ValueAnimator animator = new ValueAnimator();
+        animator.setFloatValues(0f, 1f);
+        animator.setDuration(RESIZE_ALPHA_DURATION);
+        animator.addUpdateListener(animation -> {
+            t.setAlpha(mVeilSurface, animator.getAnimatedFraction());
+            t.apply();
+        });
+        animator.start();
+    }
+
+    /**
+     * Update veil bounds to match bounds changes.
+     * @param newBounds bounds to update veil to.
+     */
+    public void relayout(Rect newBounds) {
+        SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
+        mViewHost.relayout(newBounds.width(), newBounds.height());
+        t.setWindowCrop(mVeilSurface, newBounds.width(), newBounds.height());
+        t.setPosition(mParentSurface, newBounds.left, newBounds.top);
+        t.setWindowCrop(mParentSurface, newBounds.width(), newBounds.height());
+        mViewHost.getView().getViewRootImpl().applyTransactionOnDraw(t);
+    }
+
+    /**
+     * Animate veil's alpha to 0, fading it out.
+     */
+    public void hideVeil() {
+        final View resizeVeilView = mViewHost.getView();
+        final ValueAnimator animator = new ValueAnimator();
+        animator.setFloatValues(1, 0);
+        animator.setDuration(RESIZE_ALPHA_DURATION);
+        animator.addUpdateListener(animation -> {
+            SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
+            t.setAlpha(mVeilSurface, 1 - animator.getAnimatedFraction());
+            t.apply();
+        });
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
+                t.hide(mVeilSurface);
+                t.apply();
+            }
+        });
+        animator.start();
+    }
+
+    /**
+     * Dispose of veil when it is no longer needed, likely on close of its container decor.
+     */
+    void dispose() {
+        if (mViewHost != null) {
+            mViewHost.release();
+            mViewHost = null;
+        }
+        if (mVeilSurface != null) {
+            final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
+            t.remove(mVeilSurface);
+            mVeilSurface = null;
+            t.apply();
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
deleted file mode 100644
index 0bce3ac..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.windowdecor;
-
-import android.annotation.IntDef;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.util.DisplayMetrics;
-import android.window.WindowContainerTransaction;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayController;
-
-class TaskPositioner implements DragPositioningCallback {
-
-    @IntDef({CTRL_TYPE_UNDEFINED, CTRL_TYPE_LEFT, CTRL_TYPE_RIGHT, CTRL_TYPE_TOP, CTRL_TYPE_BOTTOM})
-    @interface CtrlType {}
-
-    static final int CTRL_TYPE_UNDEFINED = 0;
-    static final int CTRL_TYPE_LEFT = 1;
-    static final int CTRL_TYPE_RIGHT = 2;
-    static final int CTRL_TYPE_TOP = 4;
-    static final int CTRL_TYPE_BOTTOM = 8;
-
-    private final ShellTaskOrganizer mTaskOrganizer;
-    private final DisplayController mDisplayController;
-    private final WindowDecoration mWindowDecoration;
-
-    private final Rect mTempBounds = new Rect();
-    private final Rect mTaskBoundsAtDragStart = new Rect();
-    private final PointF mRepositionStartPoint = new PointF();
-    private final Rect mRepositionTaskBounds = new Rect();
-    private boolean mHasMoved = false;
-
-    private int mCtrlType;
-    private DragStartListener mDragStartListener;
-
-    TaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
-            DisplayController displayController) {
-        this(taskOrganizer, windowDecoration, displayController, dragStartListener -> {});
-    }
-
-    TaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
-            DisplayController displayController, DragStartListener dragStartListener) {
-        mTaskOrganizer = taskOrganizer;
-        mWindowDecoration = windowDecoration;
-        mDisplayController = displayController;
-        mDragStartListener = dragStartListener;
-    }
-
-    @Override
-    public void onDragPositioningStart(int ctrlType, float x, float y) {
-        mHasMoved = false;
-
-        mDragStartListener.onDragStart(mWindowDecoration.mTaskInfo.taskId);
-        mCtrlType = ctrlType;
-
-        mTaskBoundsAtDragStart.set(
-                mWindowDecoration.mTaskInfo.configuration.windowConfiguration.getBounds());
-        mRepositionStartPoint.set(x, y);
-    }
-
-    @Override
-    public void onDragPositioningMove(float x, float y) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        if (changeBounds(wct, x, y)) {
-            // The task is being resized, send the |dragResizing| hint to core with the first
-            // bounds-change wct.
-            if (!mHasMoved && mCtrlType != CTRL_TYPE_UNDEFINED) {
-                // This is the first bounds change since drag resize operation started.
-                wct.setDragResizing(mWindowDecoration.mTaskInfo.token, true /* dragResizing */);
-            }
-            mTaskOrganizer.applyTransaction(wct);
-            mHasMoved = true;
-        }
-    }
-
-    @Override
-    public void onDragPositioningEnd(float x, float y) {
-        // |mHasMoved| being false means there is no real change to the task bounds in WM core, so
-        // we don't need a WCT to finish it.
-        if (mHasMoved) {
-            final WindowContainerTransaction wct = new WindowContainerTransaction();
-            wct.setDragResizing(mWindowDecoration.mTaskInfo.token, false /* dragResizing */);
-            changeBounds(wct, x, y);
-            mTaskOrganizer.applyTransaction(wct);
-        }
-
-        mCtrlType = CTRL_TYPE_UNDEFINED;
-        mTaskBoundsAtDragStart.setEmpty();
-        mRepositionStartPoint.set(0, 0);
-        mHasMoved = false;
-    }
-
-    private boolean changeBounds(WindowContainerTransaction wct, float x, float y) {
-        // |mRepositionTaskBounds| is the bounds last reported if |mHasMoved| is true. If it's not
-        // true, we can compare it against |mTaskBoundsAtDragStart|.
-        final int oldLeft = mHasMoved ? mRepositionTaskBounds.left : mTaskBoundsAtDragStart.left;
-        final int oldTop = mHasMoved ? mRepositionTaskBounds.top : mTaskBoundsAtDragStart.top;
-        final int oldRight = mHasMoved ? mRepositionTaskBounds.right : mTaskBoundsAtDragStart.right;
-        final int oldBottom =
-                mHasMoved ? mRepositionTaskBounds.bottom : mTaskBoundsAtDragStart.bottom;
-
-        final float deltaX = x - mRepositionStartPoint.x;
-        final float deltaY = y - mRepositionStartPoint.y;
-        mRepositionTaskBounds.set(mTaskBoundsAtDragStart);
-
-        final Rect stableBounds = mTempBounds;
-        // Make sure the new resizing destination in any direction falls within the stable bounds.
-        // If not, set the bounds back to the old location that was valid to avoid conflicts with
-        // some regions such as the gesture area.
-        mDisplayController.getDisplayLayout(mWindowDecoration.mDisplay.getDisplayId())
-                .getStableBounds(stableBounds);
-        if ((mCtrlType & CTRL_TYPE_LEFT) != 0) {
-            final int candidateLeft = mRepositionTaskBounds.left + (int) deltaX;
-            mRepositionTaskBounds.left = (candidateLeft > stableBounds.left)
-                    ? candidateLeft : oldLeft;
-        }
-        if ((mCtrlType & CTRL_TYPE_RIGHT) != 0) {
-            final int candidateRight = mRepositionTaskBounds.right + (int) deltaX;
-            mRepositionTaskBounds.right = (candidateRight < stableBounds.right)
-                    ? candidateRight : oldRight;
-        }
-        if ((mCtrlType & CTRL_TYPE_TOP) != 0) {
-            final int candidateTop = mRepositionTaskBounds.top + (int) deltaY;
-            mRepositionTaskBounds.top = (candidateTop > stableBounds.top)
-                    ? candidateTop : oldTop;
-        }
-        if ((mCtrlType & CTRL_TYPE_BOTTOM) != 0) {
-            final int candidateBottom = mRepositionTaskBounds.bottom + (int) deltaY;
-            mRepositionTaskBounds.bottom = (candidateBottom < stableBounds.bottom)
-                    ? candidateBottom : oldBottom;
-        }
-        if (mCtrlType == CTRL_TYPE_UNDEFINED) {
-            mRepositionTaskBounds.offset((int) deltaX, (int) deltaY);
-        }
-
-        // If width or height are negative or less than the minimum width or height, revert the
-        // respective bounds to use previous bound dimensions.
-        if (mRepositionTaskBounds.width() < getMinWidth()) {
-            mRepositionTaskBounds.right = oldRight;
-            mRepositionTaskBounds.left = oldLeft;
-        }
-        if (mRepositionTaskBounds.height() < getMinHeight()) {
-            mRepositionTaskBounds.top = oldTop;
-            mRepositionTaskBounds.bottom = oldBottom;
-        }
-        // If there are no changes to the bounds after checking new bounds against minimum width
-        // and height, do not set bounds and return false
-        if (oldLeft == mRepositionTaskBounds.left && oldTop == mRepositionTaskBounds.top
-                && oldRight == mRepositionTaskBounds.right
-                && oldBottom == mRepositionTaskBounds.bottom) {
-            return false;
-        }
-
-        wct.setBounds(mWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
-        return true;
-    }
-
-    private float getMinWidth() {
-        return mWindowDecoration.mTaskInfo.minWidth < 0 ? getDefaultMinSize()
-                : mWindowDecoration.mTaskInfo.minWidth;
-    }
-
-    private float getMinHeight() {
-        return mWindowDecoration.mTaskInfo.minHeight < 0 ? getDefaultMinSize()
-                : mWindowDecoration.mTaskInfo.minHeight;
-    }
-
-    private float getDefaultMinSize() {
-        float density =  mDisplayController.getDisplayLayout(mWindowDecoration.mTaskInfo.displayId)
-                .densityDpi() * DisplayMetrics.DENSITY_DEFAULT_SCALE;
-        return mWindowDecoration.mTaskInfo.defaultMinSize * density;
-    }
-
-    interface DragStartListener {
-        /**
-         * Inform the implementing class that a drag resize has started
-         * @param taskId id of this positioner's {@link WindowDecoration}
-         */
-        void onDragStart(int taskId);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
new file mode 100644
index 0000000..1d416c6
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.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.wm.shell.windowdecor;
+
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+
+/**
+ * A task positioner that also takes into account resizing a
+ * {@link com.android.wm.shell.windowdecor.ResizeVeil}.
+ * If the drag is resizing the task, we resize the veil instead.
+ * If the drag is repositioning, we update in the typical manner.
+ */
+public class VeiledResizeTaskPositioner implements DragPositioningCallback {
+
+    private DesktopModeWindowDecoration mDesktopWindowDecoration;
+    private ShellTaskOrganizer mTaskOrganizer;
+    private DisplayController mDisplayController;
+    private DragPositioningCallbackUtility.DragStartListener mDragStartListener;
+    private final Rect mStableBounds = new Rect();
+    private final Rect mTaskBoundsAtDragStart = new Rect();
+    private final PointF mRepositionStartPoint = new PointF();
+    private final Rect mRepositionTaskBounds = new Rect();
+    private int mCtrlType;
+    private boolean mHasMoved;
+
+
+    public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
+            DesktopModeWindowDecoration windowDecoration, DisplayController displayController,
+            DragPositioningCallbackUtility.DragStartListener dragStartListener) {
+        mTaskOrganizer = taskOrganizer;
+        mDesktopWindowDecoration = windowDecoration;
+        mDisplayController = displayController;
+        mDragStartListener = dragStartListener;
+    }
+
+    @Override
+    public void onDragPositioningStart(int ctrlType, float x, float y) {
+        mCtrlType = ctrlType;
+        mTaskBoundsAtDragStart.set(
+                mDesktopWindowDecoration.mTaskInfo.configuration.windowConfiguration.getBounds());
+        mRepositionStartPoint.set(x, y);
+        if (mCtrlType != CTRL_TYPE_UNDEFINED) {
+            mDesktopWindowDecoration.showResizeVeil();
+        }
+        mHasMoved = false;
+        mDragStartListener.onDragStart(mDesktopWindowDecoration.mTaskInfo.taskId);
+    }
+
+    @Override
+    public void onDragPositioningMove(float x, float y) {
+        PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y, mRepositionStartPoint);
+        if (DragPositioningCallbackUtility.changeBounds(mCtrlType, mHasMoved,
+                mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta,
+                mDisplayController, mDesktopWindowDecoration)) {
+            if (mCtrlType != CTRL_TYPE_UNDEFINED) {
+                mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds);
+            } else {
+                DragPositioningCallbackUtility.applyTaskBoundsChange(
+                        new WindowContainerTransaction(), mDesktopWindowDecoration,
+                        mRepositionTaskBounds, mTaskOrganizer);
+            }
+            mHasMoved = true;
+        }
+    }
+
+    @Override
+    public void onDragPositioningEnd(float x, float y) {
+        PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y,
+                mRepositionStartPoint);
+        if (mHasMoved) {
+            DragPositioningCallbackUtility.changeBounds(mCtrlType, mHasMoved,
+                    mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta,
+                    mDisplayController, mDesktopWindowDecoration);
+            DragPositioningCallbackUtility.applyTaskBoundsChange(
+                    new WindowContainerTransaction(), mDesktopWindowDecoration,
+                    mRepositionTaskBounds, mTaskOrganizer);
+        }
+        // TODO: (b/279062291) Synchronize the start of hide to the end of the draw triggered above.
+        if (mCtrlType != CTRL_TYPE_UNDEFINED) {
+            mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds);
+            mDesktopWindowDecoration.hideResizeVeil();
+        }
+        mCtrlType = CTRL_TYPE_UNDEFINED;
+        mTaskBoundsAtDragStart.setEmpty();
+        mRepositionStartPoint.set(0, 0);
+        mHasMoved = false;
+    }
+}
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 9a1b4ff..ac5ff20 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
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.windowdecor;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
 import android.app.ActivityManager.RunningTaskInfo;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -256,13 +258,17 @@
         mTmpColor[0] = (float) Color.red(backgroundColorInt) / 255.f;
         mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f;
         mTmpColor[2] = (float) Color.blue(backgroundColorInt) / 255.f;
-        Point taskPosition = mTaskInfo.positionInParent;
+        final Point taskPosition = mTaskInfo.positionInParent;
         startT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight)
                 .setShadowRadius(mTaskSurface, shadowRadius)
                 .setColor(mTaskSurface, mTmpColor)
                 .show(mTaskSurface);
         finishT.setPosition(mTaskSurface, taskPosition.x, taskPosition.y)
                 .setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight);
+        if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+            startT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+            finishT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+        }
 
         if (mCaptionWindowManager == null) {
             // Put caption under a container surface because ViewRootImpl sets the destination frame
@@ -414,6 +420,8 @@
         int mCaptionWidthId;
         int mShadowRadiusId;
 
+        int mCornerRadius;
+
         int mCaptionX;
         int mCaptionY;
 
@@ -425,6 +433,8 @@
             mCaptionWidthId = Resources.ID_NULL;
             mShadowRadiusId = Resources.ID_NULL;
 
+            mCornerRadius = 0;
+
             mCaptionX = 0;
             mCaptionY = 0;
 
@@ -458,7 +468,7 @@
         SurfaceControlViewHost mWindowViewHost;
         Supplier<SurfaceControl.Transaction> mTransactionSupplier;
 
-        private AdditionalWindow(SurfaceControl surfaceControl,
+        AdditionalWindow(SurfaceControl surfaceControl,
                 SurfaceControlViewHost surfaceControlViewHost,
                 Supplier<SurfaceControl.Transaction> transactionSupplier) {
             mWindowSurface = surfaceControl;
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseBenchmarkTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseBenchmarkTest.kt
new file mode 100644
index 0000000..e06e074
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseBenchmarkTest.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.app.Instrumentation
+import android.tools.device.flicker.junit.FlickerBuilderProvider
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+
+abstract class BaseBenchmarkTest
+@JvmOverloads
+constructor(
+    protected open val flicker: FlickerTest,
+    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
+    protected val tapl: LauncherInstrumentation = LauncherInstrumentation()
+) {
+    /** Specification of the test transition to execute */
+    abstract val transition: FlickerBuilder.() -> Unit
+
+    /**
+     * Entry point for the test runner. It will use this method to initialize and cache flicker
+     * executions
+     */
+    @FlickerBuilderProvider
+    fun buildFlicker(): FlickerBuilder {
+        return FlickerBuilder(instrumentation).apply {
+            setup { flicker.scenario.setIsTablet(tapl.isTablet) }
+            transition()
+        }
+    }
+}
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 c5ee7b7..c98c5a0 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
@@ -17,24 +17,10 @@
 package com.android.wm.shell.flicker
 
 import android.app.Instrumentation
-import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.device.flicker.junit.FlickerBuilderProvider
-import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.legacy.FlickerTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.entireScreenCovered
-import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd
-import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisibleAtStartAndEnd
-import com.android.server.wm.flicker.statusBarLayerPositionAtStartAndEnd
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.taskBarLayerIsVisibleAtStartAndEnd
-import com.android.server.wm.flicker.taskBarWindowIsAlwaysVisible
-import org.junit.Assume
-import org.junit.Test
 
 /**
  * Base test class containing common assertions for [ComponentNameMatcher.NAV_BAR],
@@ -44,124 +30,7 @@
 abstract class BaseTest
 @JvmOverloads
 constructor(
-    protected val flicker: FlickerTest,
-    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
-    protected val tapl: LauncherInstrumentation = LauncherInstrumentation()
-) {
-    /** Specification of the test transition to execute */
-    abstract val transition: FlickerBuilder.() -> Unit
-
-    /**
-     * Entry point for the test runner. It will use this method to initialize and cache flicker
-     * executions
-     */
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            setup { flicker.scenario.setIsTablet(tapl.isTablet) }
-            transition()
-        }
-    }
-
-    /** Checks that all parts of the screen are covered during the transition */
-    @Presubmit @Test open fun entireScreenCovered() = flicker.entireScreenCovered()
-
-    /**
-     * Checks that the [ComponentNameMatcher.NAV_BAR] layer is visible during the whole transition
-     */
-    @Presubmit
-    @Test
-    open fun navBarLayerIsVisibleAtStartAndEnd() {
-        Assume.assumeFalse(flicker.scenario.isTablet)
-        flicker.navBarLayerIsVisibleAtStartAndEnd()
-    }
-
-    /**
-     * Checks the position of the [ComponentNameMatcher.NAV_BAR] at the start and end of the
-     * transition
-     */
-    @Presubmit
-    @Test
-    open fun navBarLayerPositionAtStartAndEnd() {
-        Assume.assumeFalse(flicker.scenario.isTablet)
-        flicker.navBarLayerPositionAtStartAndEnd()
-    }
-
-    /**
-     * Checks that the [ComponentNameMatcher.NAV_BAR] window is visible during the whole transition
-     *
-     * Note: Phones only
-     */
-    @Presubmit
-    @Test
-    open fun navBarWindowIsAlwaysVisible() {
-        Assume.assumeFalse(flicker.scenario.isTablet)
-        flicker.navBarWindowIsAlwaysVisible()
-    }
-
-    /**
-     * Checks that the [ComponentNameMatcher.TASK_BAR] layer is visible during the whole transition
-     */
-    @Presubmit
-    @Test
-    open fun taskBarLayerIsVisibleAtStartAndEnd() {
-        Assume.assumeTrue(flicker.scenario.isTablet)
-        flicker.taskBarLayerIsVisibleAtStartAndEnd()
-    }
-
-    /**
-     * Checks that the [ComponentNameMatcher.TASK_BAR] window is visible during the whole transition
-     *
-     * Note: Large screen only
-     */
-    @Presubmit
-    @Test
-    open fun taskBarWindowIsAlwaysVisible() {
-        Assume.assumeTrue(flicker.scenario.isTablet)
-        flicker.taskBarWindowIsAlwaysVisible()
-    }
-
-    /**
-     * Checks that the [ComponentNameMatcher.STATUS_BAR] layer is visible during the whole
-     * transition
-     */
-    @Presubmit
-    @Test
-    open fun statusBarLayerIsVisibleAtStartAndEnd() = flicker.statusBarLayerIsVisibleAtStartAndEnd()
-
-    /**
-     * Checks the position of the [ComponentNameMatcher.STATUS_BAR] at the start and end of the
-     * transition
-     */
-    @Presubmit
-    @Test
-    open fun statusBarLayerPositionAtStartAndEnd() = flicker.statusBarLayerPositionAtStartAndEnd()
-
-    /**
-     * Checks that the [ComponentNameMatcher.STATUS_BAR] window is visible during the whole
-     * transition
-     */
-    @Presubmit
-    @Test
-    open fun statusBarWindowIsAlwaysVisible() = flicker.statusBarWindowIsAlwaysVisible()
-
-    /**
-     * Checks that all layers that are visible on the trace, are visible for at least 2 consecutive
-     * entries.
-     */
-    @Presubmit
-    @Test
-    open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        flicker.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry() }
-    }
-
-    /**
-     * Checks that all windows that are visible on the trace, are visible for at least 2 consecutive
-     * entries.
-     */
-    @Presubmit
-    @Test
-    open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        flicker.assertWm { this.visibleWindowsShownMoreThanOneConsecutiveEntry() }
-    }
-}
+    override val flicker: FlickerTest,
+    instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
+    tapl: LauncherInstrumentation = LauncherInstrumentation()
+) : BaseBenchmarkTest(flicker, instrumentation, tapl), ICommonAssertions
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 45024f3..798cc95 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
@@ -20,9 +20,9 @@
 
 import android.tools.common.Rotation
 import android.tools.common.datatypes.Region
-import android.tools.common.datatypes.component.IComponentMatcher
 import android.tools.common.flicker.subject.layers.LayerTraceEntrySubject
 import android.tools.common.flicker.subject.layers.LayersTraceSubject
+import android.tools.common.traces.component.IComponentMatcher
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.helpers.WindowUtils
 
@@ -218,11 +218,11 @@
     assertLayers {
         if (landscapePosLeft) {
             splitAppLayerBoundsSnapToDivider(
-                    component,
-                    landscapePosLeft,
-                    portraitPosTop,
-                    scenario.endRotation
-                )
+                component,
+                landscapePosLeft,
+                portraitPosTop,
+                scenario.endRotation
+            )
         } else {
             splitAppLayerBoundsSnapToDivider(
                     component,
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 983640a..3bc1e2a 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 android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.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/ICommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/ICommonAssertions.kt
new file mode 100644
index 0000000..02d9a056
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/ICommonAssertions.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.wm.shell.flicker
+
+import android.platform.test.annotations.Presubmit
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.device.flicker.legacy.FlickerTest
+import com.android.server.wm.flicker.entireScreenCovered
+import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.statusBarLayerPositionAtStartAndEnd
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.taskBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.taskBarWindowIsAlwaysVisible
+import org.junit.Assume
+import org.junit.Test
+
+interface ICommonAssertions {
+    val flicker: FlickerTest
+
+    /** Checks that all parts of the screen are covered during the transition */
+    @Presubmit @Test fun entireScreenCovered() = flicker.entireScreenCovered()
+
+    /**
+     * Checks that the [ComponentNameMatcher.NAV_BAR] layer is visible during the whole transition
+     */
+    @Presubmit
+    @Test
+    fun navBarLayerIsVisibleAtStartAndEnd() {
+        Assume.assumeFalse(flicker.scenario.isTablet)
+        flicker.navBarLayerIsVisibleAtStartAndEnd()
+    }
+
+    /**
+     * Checks the position of the [ComponentNameMatcher.NAV_BAR] at the start and end of the
+     * transition
+     */
+    @Presubmit
+    @Test
+    fun navBarLayerPositionAtStartAndEnd() {
+        Assume.assumeFalse(flicker.scenario.isTablet)
+        flicker.navBarLayerPositionAtStartAndEnd()
+    }
+
+    /**
+     * Checks that the [ComponentNameMatcher.NAV_BAR] window is visible during the whole transition
+     *
+     * Note: Phones only
+     */
+    @Presubmit
+    @Test
+    fun navBarWindowIsAlwaysVisible() {
+        Assume.assumeFalse(flicker.scenario.isTablet)
+        flicker.navBarWindowIsAlwaysVisible()
+    }
+
+    /**
+     * Checks that the [ComponentNameMatcher.TASK_BAR] layer is visible during the whole transition
+     */
+    @Presubmit
+    @Test
+    fun taskBarLayerIsVisibleAtStartAndEnd() {
+        Assume.assumeTrue(flicker.scenario.isTablet)
+        flicker.taskBarLayerIsVisibleAtStartAndEnd()
+    }
+
+    /**
+     * Checks that the [ComponentNameMatcher.TASK_BAR] window is visible during the whole transition
+     *
+     * Note: Large screen only
+     */
+    @Presubmit
+    @Test
+    fun taskBarWindowIsAlwaysVisible() {
+        Assume.assumeTrue(flicker.scenario.isTablet)
+        flicker.taskBarWindowIsAlwaysVisible()
+    }
+
+    /**
+     * Checks that the [ComponentNameMatcher.STATUS_BAR] layer is visible during the whole
+     * transition
+     */
+    @Presubmit
+    @Test
+    fun statusBarLayerIsVisibleAtStartAndEnd() = flicker.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /**
+     * Checks the position of the [ComponentNameMatcher.STATUS_BAR] at the start and end of the
+     * transition
+     */
+    @Presubmit
+    @Test
+    fun statusBarLayerPositionAtStartAndEnd() = flicker.statusBarLayerPositionAtStartAndEnd()
+
+    /**
+     * Checks that the [ComponentNameMatcher.STATUS_BAR] window is visible during the whole
+     * transition
+     */
+    @Presubmit @Test fun statusBarWindowIsAlwaysVisible() = flicker.statusBarWindowIsAlwaysVisible()
+
+    /**
+     * Checks that all layers that are visible on the trace, are visible for at least 2 consecutive
+     * entries.
+     */
+    @Presubmit
+    @Test
+    fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+        flicker.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry() }
+    }
+
+    /**
+     * Checks that all windows that are visible on the trace, are visible for at least 2 consecutive
+     * entries.
+     */
+    @Presubmit
+    @Test
+    fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+        flicker.assertWm { this.visibleWindowsShownMoreThanOneConsecutiveEntry() }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
index d01a0ee..11c5951 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
@@ -20,11 +20,11 @@
 import android.system.helpers.CommandsHelper
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
-import com.android.wm.shell.flicker.BaseTest
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.LetterboxAppHelper
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import android.tools.device.flicker.legacy.IFlickerTestData
+import com.android.server.wm.flicker.helpers.LetterboxAppHelper
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.wm.shell.flicker.BaseTest
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
 import com.android.wm.shell.flicker.appWindowIsVisibleAtStart
 import org.junit.Assume
@@ -104,8 +104,8 @@
         /**
          * Creates the test configurations.
          *
-         * See [FlickerTestFactory.rotationTests] for configuring screen orientation and
-         * navigation modes.
+         * See [FlickerTestFactory.rotationTests] for configuring screen orientation and navigation
+         * modes.
          */
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
index c57100e..f212a4e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
@@ -17,11 +17,11 @@
 package com.android.wm.shell.flicker.appcompat
 
 import android.platform.test.annotations.Postsubmit
-import androidx.test.filters.RequiresDevice
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import androidx.test.filters.RequiresDevice
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
@@ -35,13 +35,13 @@
  * ```
  *     Rotate non resizable portrait only app to opposite orientation to trigger size compat mode
  * ```
+ *
  * Notes:
  * ```
  *     Some default assertions (e.g., nav bar, status bar and screen covered)
  *     are inherited [BaseTest]
  * ```
  */
-
 @RequiresDevice
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@@ -86,4 +86,4 @@
                 .isInvisible(ComponentNameMatcher.ROTATION)
         }
     }
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
index f111a8d..8e75439 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
@@ -17,11 +17,11 @@
 package com.android.wm.shell.flicker.appcompat
 
 import android.platform.test.annotations.Postsubmit
-import androidx.test.filters.RequiresDevice
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.helpers.WindowUtils
+import androidx.test.filters.RequiresDevice
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
@@ -36,13 +36,13 @@
  *     Rotate app to opposite orientation to trigger size compat mode
  *     Press restart button and wait for letterboxed app to resize
  * ```
+ *
  * Notes:
  * ```
  *     Some default assertions (e.g., nav bar, status bar and screen covered)
  *     are inherited [BaseTest]
  * ```
  */
-
 @RequiresDevice
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@@ -56,9 +56,7 @@
             teardown { letterboxApp.exit(wmHelper) }
         }
 
-    @Postsubmit
-    @Test
-    fun appVisibleAtStartAndEnd() = assertLetterboxAppVisibleAtStartAndEnd()
+    @Postsubmit @Test fun appVisibleAtStartAndEnd() = assertLetterboxAppVisibleAtStartAndEnd()
 
     @Postsubmit
     @Test
@@ -83,4 +81,4 @@
         val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.endRotation)
         flicker.assertLayersEnd { visibleRegion(letterboxApp).coversAtMost(displayBounds) }
     }
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
index 18a3aa7..889e177 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Postsubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
@@ -149,9 +149,7 @@
     @Ignore("Not applicable to this CUJ. Taskbar is not shown on lock screen")
     override fun taskBarWindowIsAlwaysVisible() {}
 
-    /**
-     * Checks that the [ComponentNameMatcher.TASK_BAR] is visible at the end of the transition
-     */
+    /** Checks that the [ComponentNameMatcher.TASK_BAR] is visible at the end of the transition */
     @Postsubmit
     @Test
     fun taskBarLayerIsVisibleAtEnd() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
index 59918fb..e6544c9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
@@ -17,7 +17,7 @@
 package com.android.wm.shell.flicker.pip
 
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
index 36c6f7c..2417c45 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher.Companion.LAUNCHER
+import android.tools.common.traces.component.ComponentNameMatcher.Companion.LAUNCHER
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index db18edb..4b461370 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -21,7 +21,7 @@
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
index 51f0136..bfd5778 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
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 2001f48..5ac9829 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,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
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 6deba1b..bbb1c6c 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
index a626713..6b061bbb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 b30f308..eb1245b 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
@@ -20,7 +20,7 @@
 import android.content.Intent
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
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 0c9c161..b7e73ad 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
@@ -19,13 +19,14 @@
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.EdgeExtensionComponentMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.EdgeExtensionComponentMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
 import com.android.wm.shell.flicker.appWindowIsVisibleAtStart
@@ -34,6 +35,7 @@
 import com.android.wm.shell.flicker.splitAppLayerBoundsKeepVisible
 import com.android.wm.shell.flicker.splitScreenDividerIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerIsVisibleAtStart
+import com.android.wm.shell.flicker.splitscreen.benchmark.CopyContentInSplitBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -49,29 +51,19 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class CopyContentInSplit(flicker: FlickerTest) : SplitScreenBase(flicker) {
-    private val textEditApp = SplitScreenUtils.getIme(instrumentation)
-    private val MagnifierLayer = ComponentNameMatcher("", "magnifier surface bbq wrapper#")
-    private val PopupWindowLayer = ComponentNameMatcher("", "PopupWindow:")
-
+class CopyContentInSplit(override val flicker: FlickerTest) :
+    CopyContentInSplitBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, textEditApp) }
-            transitions {
-                SplitScreenUtils.copyContentInSplit(
-                    instrumentation,
-                    device,
-                    primaryApp,
-                    textEditApp
-                )
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
-    fun cujCompleted() {
+    override fun cujCompleted() {
         flicker.appWindowIsVisibleAtStart(primaryApp)
         flicker.appWindowIsVisibleAtStart(textEditApp)
         flicker.splitScreenDividerIsVisibleAtStart()
@@ -128,8 +120,8 @@
                         ComponentNameMatcher.SNAPSHOT,
                         ComponentNameMatcher.IME_SNAPSHOT,
                         EdgeExtensionComponentMatcher(),
-                        MagnifierLayer,
-                        PopupWindowLayer
+                        magnifierLayer,
+                        popupWindowLayer
                     )
             )
         }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
index 1b55f39..3fd6d17 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
@@ -17,22 +17,21 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
 import android.tools.device.helpers.WindowUtils
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.appWindowBecomesInvisible
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
 import com.android.wm.shell.flicker.layerBecomesInvisible
 import com.android.wm.shell.flicker.layerIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesInvisible
-import com.android.wm.shell.flicker.splitScreenDismissed
 import com.android.wm.shell.flicker.splitScreenDividerBecomesInvisible
+import com.android.wm.shell.flicker.splitscreen.benchmark.DismissSplitScreenByDividerBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -48,37 +47,16 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class DismissSplitScreenByDivider(flicker: FlickerTest) : SplitScreenBase(flicker) {
+class DismissSplitScreenByDivider(override val flicker: FlickerTest) :
+    DismissSplitScreenByDividerBenchmark(flicker), ICommonAssertions {
 
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
-            transitions {
-                if (tapl.isTablet) {
-                    SplitScreenUtils.dragDividerToDismissSplit(
-                        device,
-                        wmHelper,
-                        dragToRight = false,
-                        dragToBottom = true
-                    )
-                } else {
-                    SplitScreenUtils.dragDividerToDismissSplit(
-                        device,
-                        wmHelper,
-                        dragToRight = true,
-                        dragToBottom = true
-                    )
-                }
-                wmHelper.StateSyncBuilder().withFullScreenApp(secondaryApp).waitForAndVerify()
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() = flicker.splitScreenDismissed(primaryApp, secondaryApp, toHome = false)
-
     @Presubmit
     @Test
     fun splitScreenDividerBecomesInvisible() = flicker.splitScreenDividerBecomesInvisible()
@@ -176,12 +154,4 @@
     @Test
     override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
         super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests()
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index 2e81b30..e05b221 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
@@ -17,18 +17,18 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.appWindowBecomesInvisible
 import com.android.wm.shell.flicker.layerBecomesInvisible
 import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesInvisible
-import com.android.wm.shell.flicker.splitScreenDismissed
 import com.android.wm.shell.flicker.splitScreenDividerBecomesInvisible
+import com.android.wm.shell.flicker.splitscreen.benchmark.DismissSplitScreenByGoHomeBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -44,21 +44,14 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class DismissSplitScreenByGoHome(flicker: FlickerTest) : SplitScreenBase(flicker) {
-
+class DismissSplitScreenByGoHome(override val flicker: FlickerTest) :
+    DismissSplitScreenByGoHomeBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
-            transitions {
-                tapl.goHome()
-                wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() = flicker.splitScreenDismissed(primaryApp, secondaryApp, toHome = true)
 
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
index 5180791..0b0a3da 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
@@ -24,6 +24,7 @@
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
 import com.android.wm.shell.flicker.appWindowIsVisibleAtStart
@@ -32,8 +33,7 @@
 import com.android.wm.shell.flicker.splitAppLayerBoundsChanges
 import com.android.wm.shell.flicker.splitScreenDividerIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerIsVisibleAtStart
-import org.junit.Assume
-import org.junit.Before
+import com.android.wm.shell.flicker.splitscreen.benchmark.DragDividerToResizeBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -49,24 +49,19 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class DragDividerToResize(flicker: FlickerTest) : SplitScreenBase(flicker) {
-
+class DragDividerToResize(override val flicker: FlickerTest) :
+    DragDividerToResizeBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
-            transitions { SplitScreenUtils.dragDividerToResizeAndWait(device, wmHelper) }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @Before
-    fun before() {
-        Assume.assumeTrue(tapl.isTablet || !flicker.scenario.isLandscapeOrSeascapeAtStart)
-    }
-
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
-    fun cujCompleted() {
+    override fun cujCompleted() {
         flicker.appWindowIsVisibleAtStart(primaryApp)
         flicker.appWindowIsVisibleAtStart(secondaryApp)
         flicker.splitScreenDividerIsVisibleAtStart()
@@ -74,9 +69,6 @@
         flicker.appWindowIsVisibleAtEnd(primaryApp)
         flicker.appWindowIsVisibleAtEnd(secondaryApp)
         flicker.splitScreenDividerIsVisibleAtEnd()
-
-        // TODO(b/246490534): Add validation for resized app after withAppTransitionIdle is
-        // robust enough to get the correct end state.
     }
 
     @Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
index 69da1e2..e558686 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
@@ -17,7 +17,6 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
@@ -26,6 +25,7 @@
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
 import com.android.wm.shell.flicker.appWindowBecomesVisible
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
@@ -34,9 +34,7 @@
 import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisibleByDrag
 import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
-import com.android.wm.shell.flicker.splitScreenEntered
-import org.junit.Assume
-import org.junit.Before
+import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenByDragFromAllAppsBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -53,40 +51,15 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenByDragFromAllApps(flicker: FlickerTest) : SplitScreenBase(flicker) {
-
-    @Before
-    fun before() {
-        Assume.assumeTrue(tapl.isTablet)
-    }
-
+class EnterSplitScreenByDragFromAllApps(override val flicker: FlickerTest) :
+    EnterSplitScreenByDragFromAllAppsBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup {
-                tapl.goHome()
-                primaryApp.launchViaIntent(wmHelper)
-            }
-            transitions {
-                tapl.launchedAppState.taskbar
-                    .openAllApps()
-                    .getAppIcon(secondaryApp.appName)
-                    .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`)
-                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() =
-        flicker.splitScreenEntered(
-            primaryApp,
-            secondaryApp,
-            fromOtherApp = false,
-            appExistAtStart = false
-        )
-
     @FlakyTest(bugId = 245472831)
     @Test
     fun splitScreenDividerBecomesVisible() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
index 1773846..ab8ecc5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
@@ -17,7 +17,6 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
@@ -26,6 +25,7 @@
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
 import com.android.wm.shell.flicker.layerBecomesVisible
@@ -33,9 +33,7 @@
 import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisibleByDrag
 import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
-import com.android.wm.shell.flicker.splitScreenEntered
-import org.junit.Assume
-import org.junit.Before
+import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenByDragFromNotificationBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -52,39 +50,16 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenByDragFromNotification(flicker: FlickerTest) : SplitScreenBase(flicker) {
-
-    private val sendNotificationApp = SplitScreenUtils.getSendNotification(instrumentation)
-
-    @Before
-    fun before() {
-        Assume.assumeTrue(tapl.isTablet)
-    }
-
+class EnterSplitScreenByDragFromNotification(override val flicker: FlickerTest) :
+    EnterSplitScreenByDragFromNotificationBenchmark(flicker), ICommonAssertions {
     /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup {
-                // Send a notification
-                sendNotificationApp.launchViaIntent(wmHelper)
-                sendNotificationApp.postNotification(wmHelper)
-                tapl.goHome()
-                primaryApp.launchViaIntent(wmHelper)
-            }
-            transitions {
-                SplitScreenUtils.dragFromNotificationToSplit(instrumentation, device, wmHelper)
-                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, sendNotificationApp)
-            }
-            teardown { sendNotificationApp.exit(wmHelper) }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() =
-        flicker.splitScreenEntered(primaryApp, sendNotificationApp, fromOtherApp = false)
-
     @FlakyTest(bugId = 245472831)
     @Test
     fun splitScreenDividerBecomesVisible() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
index c1977e9..516ca97 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
@@ -17,7 +17,6 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -25,15 +24,14 @@
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
 import com.android.wm.shell.flicker.layerBecomesVisible
 import com.android.wm.shell.flicker.layerIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisibleByDrag
 import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
-import com.android.wm.shell.flicker.splitScreenEntered
-import org.junit.Assume
-import org.junit.Before
+import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenByDragFromShortcutBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -49,42 +47,16 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenByDragFromShortcut(flicker: FlickerTest) : SplitScreenBase(flicker) {
-
-    @Before
-    fun before() {
-        Assume.assumeTrue(tapl.isTablet)
-    }
+class EnterSplitScreenByDragFromShortcut(override val flicker: FlickerTest) :
+    EnterSplitScreenByDragFromShortcutBenchmark(flicker), ICommonAssertions {
 
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup {
-                tapl.goHome()
-                SplitScreenUtils.createShortcutOnHotseatIfNotExist(tapl, secondaryApp.appName)
-                primaryApp.launchViaIntent(wmHelper)
-            }
-            transitions {
-                tapl.launchedAppState.taskbar
-                    .getAppIcon(secondaryApp.appName)
-                    .openDeepShortcutMenu()
-                    .getMenuItem("Split Screen Secondary Activity")
-                    .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`)
-                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() =
-        flicker.splitScreenEntered(
-            primaryApp,
-            secondaryApp,
-            fromOtherApp = false,
-            appExistAtStart = false
-        )
-
     @Presubmit
     @Test
     fun splitScreenDividerBecomesVisible() = flicker.splitScreenDividerBecomesVisible()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
index 3bea66e..4af7e24 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
@@ -17,7 +17,6 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
@@ -26,6 +25,7 @@
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
 import com.android.wm.shell.flicker.appWindowBecomesVisible
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
@@ -34,9 +34,7 @@
 import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisibleByDrag
 import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
-import com.android.wm.shell.flicker.splitScreenEntered
-import org.junit.Assume
-import org.junit.Before
+import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenByDragFromTaskbarBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -53,41 +51,16 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenByDragFromTaskbar(flicker: FlickerTest) : SplitScreenBase(flicker) {
-
-    @Before
-    fun before() {
-        Assume.assumeTrue(tapl.isTablet)
-    }
-
+class EnterSplitScreenByDragFromTaskbar(override val flicker: FlickerTest) :
+    EnterSplitScreenByDragFromTaskbarBenchmark(flicker), ICommonAssertions {
     /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup {
-                tapl.goHome()
-                SplitScreenUtils.createShortcutOnHotseatIfNotExist(tapl, secondaryApp.appName)
-                primaryApp.launchViaIntent(wmHelper)
-            }
-            transitions {
-                tapl.launchedAppState.taskbar
-                    .getAppIcon(secondaryApp.appName)
-                    .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`)
-                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() =
-        flicker.splitScreenEntered(
-            primaryApp,
-            secondaryApp,
-            fromOtherApp = false,
-            appExistAtStart = false
-        )
-
     @FlakyTest(bugId = 245472831)
     @Test
     fun splitScreenDividerBecomesVisible() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
index c453877..faad9e8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
@@ -17,20 +17,20 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.appWindowBecomesVisible
 import com.android.wm.shell.flicker.layerBecomesVisible
 import com.android.wm.shell.flicker.layerIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisible
 import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
-import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenFromOverviewBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -46,31 +46,15 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenFromOverview(flicker: FlickerTest) : SplitScreenBase(flicker) {
+class EnterSplitScreenFromOverview(override val flicker: FlickerTest) :
+    EnterSplitScreenFromOverviewBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup {
-                primaryApp.launchViaIntent(wmHelper)
-                secondaryApp.launchViaIntent(wmHelper)
-                tapl.goHome()
-                wmHelper
-                    .StateSyncBuilder()
-                    .withAppTransitionIdle()
-                    .withHomeActivityVisible()
-                    .waitForAndVerify()
-            }
-            transitions {
-                SplitScreenUtils.splitFromOverview(tapl, device)
-                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = true)
-
     @Presubmit
     @Test
     fun splitScreenDividerBecomesVisible() = flicker.splitScreenDividerBecomesVisible()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
index 7abdc06..195b73a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
@@ -20,25 +20,33 @@
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.wm.shell.flicker.BaseTest
+import com.android.wm.shell.flicker.BaseBenchmarkTest
 
-abstract class SplitScreenBase(flicker: FlickerTest) : BaseTest(flicker) {
+abstract class SplitScreenBase(flicker: FlickerTest) : BaseBenchmarkTest(flicker) {
     protected val context: Context = instrumentation.context
     protected val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
     protected val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
 
-    /** {@inheritDoc} */
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            setup {
-                tapl.setEnableRotation(true)
-                setRotation(flicker.scenario.startRotation)
-                tapl.setExpectedRotation(flicker.scenario.startRotation.value)
-                tapl.workspace.switchToOverview().dismissAllTasks()
-            }
-            teardown {
-                primaryApp.exit(wmHelper)
-                secondaryApp.exit(wmHelper)
-            }
+    protected open val defaultSetup: FlickerBuilder.() -> Unit = {
+        setup {
+            tapl.setEnableRotation(true)
+            setRotation(flicker.scenario.startRotation)
+            tapl.setExpectedRotation(flicker.scenario.startRotation.value)
+            tapl.workspace.switchToOverview().dismissAllTasks()
         }
+    }
+
+    protected open val defaultTeardown: FlickerBuilder.() -> Unit = {
+        teardown {
+            primaryApp.exit(wmHelper)
+            secondaryApp.exit(wmHelper)
+        }
+    }
+
+    protected open val withoutTracing: FlickerBuilder.() -> Unit = {
+        withoutLayerTracing()
+        withoutWindowManagerTracing()
+        withoutTransitionTracing()
+        withoutTransactionsTracing()
+    }
 }
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 625987a..1063dfd 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
@@ -19,9 +19,9 @@
 import android.app.Instrumentation
 import android.graphics.Point
 import android.os.SystemClock
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.IComponentMatcher
-import android.tools.common.datatypes.component.IComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.IComponentMatcher
+import android.tools.common.traces.component.IComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import android.tools.device.traces.parsers.toFlickerComponent
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
index fbb7c71..8cf871f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
@@ -20,14 +20,12 @@
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
-import android.tools.common.Rotation
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
-import android.tools.device.helpers.WindowUtils
-import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
 import com.android.wm.shell.flicker.appWindowIsVisibleAtStart
@@ -36,6 +34,7 @@
 import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerIsVisibleAtStart
+import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchAppByDoubleTapDividerBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -51,98 +50,19 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchAppByDoubleTapDivider(flicker: FlickerTest) : SplitScreenBase(flicker) {
-
+class SwitchAppByDoubleTapDivider(override val flicker: FlickerTest) :
+    SwitchAppByDoubleTapDividerBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
-            transitions {
-                SplitScreenUtils.doubleTapDividerToSwitch(device)
-                wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
-
-                waitForLayersToSwitch(wmHelper)
-                waitForWindowsToSwitch(wmHelper)
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    private fun waitForWindowsToSwitch(wmHelper: WindowManagerStateHelper) {
-        wmHelper
-            .StateSyncBuilder()
-            .add("appWindowsSwitched") {
-                val primaryAppWindow =
-                    it.wmState.visibleWindows.firstOrNull { window ->
-                        primaryApp.windowMatchesAnyOf(window)
-                    }
-                        ?: return@add false
-                val secondaryAppWindow =
-                    it.wmState.visibleWindows.firstOrNull { window ->
-                        secondaryApp.windowMatchesAnyOf(window)
-                    }
-                        ?: return@add false
-
-                if (isLandscape(flicker.scenario.endRotation)) {
-                    return@add if (flicker.scenario.isTablet) {
-                        secondaryAppWindow.frame.right <= primaryAppWindow.frame.left
-                    } else {
-                        primaryAppWindow.frame.right <= secondaryAppWindow.frame.left
-                    }
-                } else {
-                    return@add if (flicker.scenario.isTablet) {
-                        primaryAppWindow.frame.bottom <= secondaryAppWindow.frame.top
-                    } else {
-                        primaryAppWindow.frame.bottom <= secondaryAppWindow.frame.top
-                    }
-                }
-            }
-            .waitForAndVerify()
-    }
-
-    private fun waitForLayersToSwitch(wmHelper: WindowManagerStateHelper) {
-        wmHelper
-            .StateSyncBuilder()
-            .add("appLayersSwitched") {
-                val primaryAppLayer =
-                    it.layerState.visibleLayers.firstOrNull { window ->
-                        primaryApp.layerMatchesAnyOf(window)
-                    }
-                        ?: return@add false
-                val secondaryAppLayer =
-                    it.layerState.visibleLayers.firstOrNull { window ->
-                        secondaryApp.layerMatchesAnyOf(window)
-                    }
-                        ?: return@add false
-
-                val primaryVisibleRegion = primaryAppLayer.visibleRegion?.bounds ?: return@add false
-                val secondaryVisibleRegion =
-                    secondaryAppLayer.visibleRegion?.bounds ?: return@add false
-
-                if (isLandscape(flicker.scenario.endRotation)) {
-                    return@add if (flicker.scenario.isTablet) {
-                        secondaryVisibleRegion.right <= primaryVisibleRegion.left
-                    } else {
-                        primaryVisibleRegion.right <= secondaryVisibleRegion.left
-                    }
-                } else {
-                    return@add if (flicker.scenario.isTablet) {
-                        primaryVisibleRegion.bottom <= secondaryVisibleRegion.top
-                    } else {
-                        primaryVisibleRegion.bottom <= secondaryVisibleRegion.top
-                    }
-                }
-            }
-            .waitForAndVerify()
-    }
-
-    private fun isLandscape(rotation: Rotation): Boolean {
-        val displayBounds = WindowUtils.getDisplayBounds(rotation)
-        return displayBounds.width > displayBounds.height
-    }
-
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
-    fun cujCompleted() {
+    override fun cujCompleted() {
         flicker.appWindowIsVisibleAtStart(primaryApp)
         flicker.appWindowIsVisibleAtStart(secondaryApp)
         flicker.splitScreenDividerIsVisibleAtStart()
@@ -150,9 +70,6 @@
         flicker.appWindowIsVisibleAtEnd(primaryApp)
         flicker.appWindowIsVisibleAtEnd(secondaryApp)
         flicker.splitScreenDividerIsVisibleAtEnd()
-
-        // TODO(b/246490534): Add validation for switched app after withAppTransitionIdle is
-        // robust enough to get the correct end state.
     }
 
     @Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
index d675bfb..078d95d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
@@ -17,7 +17,6 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -25,11 +24,12 @@
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.appWindowBecomesVisible
 import com.android.wm.shell.flicker.layerBecomesVisible
 import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
-import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchBackToSplitFromAnotherAppBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -45,29 +45,15 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchBackToSplitFromAnotherApp(flicker: FlickerTest) : SplitScreenBase(flicker) {
-    val thirdApp = SplitScreenUtils.getNonResizeable(instrumentation)
-
+class SwitchBackToSplitFromAnotherApp(override val flicker: FlickerTest) :
+    SwitchBackToSplitFromAnotherAppBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup {
-                SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp)
-
-                thirdApp.launchViaIntent(wmHelper)
-                wmHelper.StateSyncBuilder().withWindowSurfaceAppeared(thirdApp).waitForAndVerify()
-            }
-            transitions {
-                tapl.launchedAppState.quickSwitchToPreviousApp()
-                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = true)
-
     @Presubmit
     @Test
     fun splitScreenDividerBecomesVisible() = flicker.splitScreenDividerBecomesVisible()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
index 9f4cb8c..7c84243 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
@@ -17,7 +17,6 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -25,11 +24,12 @@
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.appWindowBecomesVisible
 import com.android.wm.shell.flicker.layerBecomesVisible
 import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
-import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchBackToSplitFromHomeBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -45,28 +45,15 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchBackToSplitFromHome(flicker: FlickerTest) : SplitScreenBase(flicker) {
-
+class SwitchBackToSplitFromHome(override val flicker: FlickerTest) :
+    SwitchBackToSplitFromHomeBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup {
-                SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp)
-
-                tapl.goHome()
-                wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
-            }
-            transitions {
-                tapl.workspace.quickSwitchToPreviousApp()
-                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = true)
-
     @Presubmit
     @Test
     fun splitScreenDividerBecomesVisible() = flicker.splitScreenDividerBecomesVisible()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
index a33d8ca..7c46d3e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
@@ -17,7 +17,6 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -25,11 +24,12 @@
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.appWindowBecomesVisible
 import com.android.wm.shell.flicker.layerBecomesVisible
 import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
-import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchBackToSplitFromRecentBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -45,28 +45,15 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchBackToSplitFromRecent(flicker: FlickerTest) : SplitScreenBase(flicker) {
-
+class SwitchBackToSplitFromRecent(override val flicker: FlickerTest) :
+    SwitchBackToSplitFromRecentBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup {
-                SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp)
-
-                tapl.goHome()
-                wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
-            }
-            transitions {
-                tapl.workspace.switchToOverview().currentTask.open()
-                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
-    @IwTest(focusArea = "sysui")
-    @Presubmit
-    @Test
-    fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = true)
-
     @Presubmit
     @Test
     fun splitScreenDividerBecomesVisible() = flicker.splitScreenDividerBecomesVisible()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
index 4c96b3a..3b2da8d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
@@ -24,6 +24,7 @@
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
 import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
 import com.android.wm.shell.flicker.appWindowBecomesInvisible
 import com.android.wm.shell.flicker.appWindowBecomesVisible
@@ -36,6 +37,7 @@
 import com.android.wm.shell.flicker.splitAppLayerBoundsSnapToDivider
 import com.android.wm.shell.flicker.splitScreenDividerIsVisibleAtEnd
 import com.android.wm.shell.flicker.splitScreenDividerIsVisibleAtStart
+import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchBetweenSplitPairsBenchmark
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -51,32 +53,19 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchBetweenSplitPairs(flicker: FlickerTest) : SplitScreenBase(flicker) {
-    private val thirdApp = SplitScreenUtils.getIme(instrumentation)
-    private val fourthApp = SplitScreenUtils.getSendNotification(instrumentation)
-
+class SwitchBetweenSplitPairs(override val flicker: FlickerTest) :
+    SwitchBetweenSplitPairsBenchmark(flicker), ICommonAssertions {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            super.transition(this)
-            setup {
-                SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp)
-                SplitScreenUtils.enterSplit(wmHelper, tapl, device, thirdApp, fourthApp)
-                SplitScreenUtils.waitForSplitComplete(wmHelper, thirdApp, fourthApp)
-            }
-            transitions {
-                tapl.launchedAppState.quickSwitchToPreviousApp()
-                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
-            }
-            teardown {
-                thirdApp.exit(wmHelper)
-                fourthApp.exit(wmHelper)
-            }
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
         }
 
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
-    fun cujCompleted() {
+    override fun cujCompleted() {
         flicker.appWindowIsVisibleAtStart(thirdApp)
         flicker.appWindowIsVisibleAtStart(fourthApp)
         flicker.splitScreenDividerIsVisibleAtStart()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
new file mode 100644
index 0000000..a189a3f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
@@ -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 com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class CopyContentInSplitBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val textEditApp = SplitScreenUtils.getIme(instrumentation)
+    protected val magnifierLayer = ComponentNameMatcher("", "magnifier surface bbq wrapper#")
+    protected val popupWindowLayer = ComponentNameMatcher("", "PopupWindow:")
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, textEditApp) }
+            transitions {
+                SplitScreenUtils.copyContentInSplit(
+                    instrumentation,
+                    device,
+                    primaryApp,
+                    textEditApp
+                )
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    open fun cujCompleted() {
+        // The validation of copied text is already done in SplitScreenUtils.copyContentInSplit()
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests()
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
new file mode 100644
index 0000000..55ab7b3
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenDismissed
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class DismissSplitScreenByDividerBenchmark(flicker: FlickerTest) : SplitScreenBase(flicker) {
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
+            transitions {
+                if (tapl.isTablet) {
+                    SplitScreenUtils.dragDividerToDismissSplit(
+                        device,
+                        wmHelper,
+                        dragToRight = false,
+                        dragToBottom = true
+                    )
+                } else {
+                    SplitScreenUtils.dragDividerToDismissSplit(
+                        device,
+                        wmHelper,
+                        dragToRight = true,
+                        dragToBottom = true
+                    )
+                }
+                wmHelper.StateSyncBuilder().withFullScreenApp(secondaryApp).waitForAndVerify()
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() = flicker.splitScreenDismissed(primaryApp, secondaryApp, toHome = false)
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests()
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
new file mode 100644
index 0000000..c4cfd1a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenDismissed
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class DismissSplitScreenByGoHomeBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
+            transitions {
+                tapl.goHome()
+                wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() = flicker.splitScreenDismissed(primaryApp, secondaryApp, toHome = true)
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests()
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
new file mode 100644
index 0000000..146287c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class DragDividerToResizeBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
+            transitions { SplitScreenUtils.dragDividerToResizeAndWait(device, wmHelper) }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @Before
+    fun before() {
+        Assume.assumeTrue(tapl.isTablet || !flicker.scenario.isLandscapeOrSeascapeAtStart)
+    }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    open fun cujCompleted() {
+        // TODO(b/246490534): Add validation for resized app after withAppTransitionIdle is
+        // robust enough to get the correct end state.
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests()
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
new file mode 100644
index 0000000..cc71502
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.common.NavBar
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class EnterSplitScreenByDragFromAllAppsBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                tapl.goHome()
+                primaryApp.launchViaIntent(wmHelper)
+            }
+            transitions {
+                tapl.launchedAppState.taskbar
+                    .openAllApps()
+                    .getAppIcon(secondaryApp.appName)
+                    .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`)
+                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @Before
+    fun before() {
+        Assume.assumeTrue(tapl.isTablet)
+    }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() =
+        flicker.splitScreenEntered(
+            primaryApp,
+            secondaryApp,
+            fromOtherApp = false,
+            appExistAtStart = false
+        )
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+                supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
new file mode 100644
index 0000000..de78f09
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.common.NavBar
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class EnterSplitScreenByDragFromNotificationBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val sendNotificationApp = SplitScreenUtils.getSendNotification(instrumentation)
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                // Send a notification
+                sendNotificationApp.launchViaIntent(wmHelper)
+                sendNotificationApp.postNotification(wmHelper)
+                tapl.goHome()
+                primaryApp.launchViaIntent(wmHelper)
+            }
+            transitions {
+                SplitScreenUtils.dragFromNotificationToSplit(instrumentation, device, wmHelper)
+                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, sendNotificationApp)
+            }
+            teardown { sendNotificationApp.exit(wmHelper) }
+        }
+
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() =
+        flicker.splitScreenEntered(primaryApp, sendNotificationApp, fromOtherApp = false)
+
+    @Before
+    fun before() {
+        Assume.assumeTrue(tapl.isTablet)
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+                supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
new file mode 100644
index 0000000..a29eb40
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.common.NavBar
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class EnterSplitScreenByDragFromShortcutBenchmark(flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    @Before
+    fun before() {
+        Assume.assumeTrue(tapl.isTablet)
+    }
+
+    protected val thisTransition: FlickerBuilder.() -> Unit = {
+        setup {
+            tapl.goHome()
+            SplitScreenUtils.createShortcutOnHotseatIfNotExist(tapl, secondaryApp.appName)
+            primaryApp.launchViaIntent(wmHelper)
+        }
+        transitions {
+            tapl.launchedAppState.taskbar
+                .getAppIcon(secondaryApp.appName)
+                .openDeepShortcutMenu()
+                .getMenuItem("Split Screen Secondary Activity")
+                .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`)
+            SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
+        }
+    }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() =
+        flicker.splitScreenEntered(
+            primaryApp,
+            secondaryApp,
+            fromOtherApp = false,
+            appExistAtStart = false
+        )
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+                supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
new file mode 100644
index 0000000..b2395ca
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.common.NavBar
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class EnterSplitScreenByDragFromTaskbarBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                tapl.goHome()
+                SplitScreenUtils.createShortcutOnHotseatIfNotExist(tapl, secondaryApp.appName)
+                primaryApp.launchViaIntent(wmHelper)
+            }
+            transitions {
+                tapl.launchedAppState.taskbar
+                    .getAppIcon(secondaryApp.appName)
+                    .dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`)
+                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
+            }
+        }
+
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() =
+        flicker.splitScreenEntered(
+            primaryApp,
+            secondaryApp,
+            fromOtherApp = false,
+            appExistAtStart = false
+        )
+
+    @Before
+    fun before() {
+        Assume.assumeTrue(tapl.isTablet)
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
new file mode 100644
index 0000000..e1d85d0
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
@@ -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 com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class EnterSplitScreenFromOverviewBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                primaryApp.launchViaIntent(wmHelper)
+                secondaryApp.launchViaIntent(wmHelper)
+                tapl.goHome()
+                wmHelper
+                    .StateSyncBuilder()
+                    .withAppTransitionIdle()
+                    .withHomeActivityVisible()
+                    .waitForAndVerify()
+            }
+            transitions {
+                SplitScreenUtils.splitFromOverview(tapl, device)
+                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = true)
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests()
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
new file mode 100644
index 0000000..ba8c460
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
@@ -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.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.helpers.WindowUtils
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class SwitchAppByDoubleTapDividerBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
+            transitions {
+                SplitScreenUtils.doubleTapDividerToSwitch(device)
+                wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
+
+                waitForLayersToSwitch(wmHelper)
+                waitForWindowsToSwitch(wmHelper)
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    private fun waitForWindowsToSwitch(wmHelper: WindowManagerStateHelper) {
+        wmHelper
+            .StateSyncBuilder()
+            .add("appWindowsSwitched") {
+                val primaryAppWindow =
+                    it.wmState.visibleWindows.firstOrNull { window ->
+                        primaryApp.windowMatchesAnyOf(window)
+                    }
+                        ?: return@add false
+                val secondaryAppWindow =
+                    it.wmState.visibleWindows.firstOrNull { window ->
+                        secondaryApp.windowMatchesAnyOf(window)
+                    }
+                        ?: return@add false
+
+                if (isLandscape(flicker.scenario.endRotation)) {
+                    return@add if (flicker.scenario.isTablet) {
+                        secondaryAppWindow.frame.right <= primaryAppWindow.frame.left
+                    } else {
+                        primaryAppWindow.frame.right <= secondaryAppWindow.frame.left
+                    }
+                } else {
+                    return@add if (flicker.scenario.isTablet) {
+                        primaryAppWindow.frame.bottom <= secondaryAppWindow.frame.top
+                    } else {
+                        primaryAppWindow.frame.bottom <= secondaryAppWindow.frame.top
+                    }
+                }
+            }
+            .waitForAndVerify()
+    }
+
+    private fun waitForLayersToSwitch(wmHelper: WindowManagerStateHelper) {
+        wmHelper
+            .StateSyncBuilder()
+            .add("appLayersSwitched") {
+                val primaryAppLayer =
+                    it.layerState.visibleLayers.firstOrNull { window ->
+                        primaryApp.layerMatchesAnyOf(window)
+                    }
+                        ?: return@add false
+                val secondaryAppLayer =
+                    it.layerState.visibleLayers.firstOrNull { window ->
+                        secondaryApp.layerMatchesAnyOf(window)
+                    }
+                        ?: return@add false
+
+                val primaryVisibleRegion = primaryAppLayer.visibleRegion?.bounds ?: return@add false
+                val secondaryVisibleRegion =
+                    secondaryAppLayer.visibleRegion?.bounds ?: return@add false
+
+                if (isLandscape(flicker.scenario.endRotation)) {
+                    return@add if (flicker.scenario.isTablet) {
+                        secondaryVisibleRegion.right <= primaryVisibleRegion.left
+                    } else {
+                        primaryVisibleRegion.right <= secondaryVisibleRegion.left
+                    }
+                } else {
+                    return@add if (flicker.scenario.isTablet) {
+                        primaryVisibleRegion.bottom <= secondaryVisibleRegion.top
+                    } else {
+                        primaryVisibleRegion.bottom <= secondaryVisibleRegion.top
+                    }
+                }
+            }
+            .waitForAndVerify()
+    }
+
+    private fun isLandscape(rotation: Rotation): Boolean {
+        val displayBounds = WindowUtils.getDisplayBounds(rotation)
+        return displayBounds.width > displayBounds.height
+    }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    open fun cujCompleted() {
+        // TODO(b/246490534): Add validation for switched app after withAppTransitionIdle is
+        // robust enough to get the correct end state.
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+                supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
new file mode 100644
index 0000000..bbb2edc
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.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.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.common.NavBar
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class SwitchBackToSplitFromAnotherAppBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    private val thirdApp = SplitScreenUtils.getNonResizeable(instrumentation)
+
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp)
+
+                thirdApp.launchViaIntent(wmHelper)
+                wmHelper.StateSyncBuilder().withWindowSurfaceAppeared(thirdApp).waitForAndVerify()
+            }
+            transitions {
+                tapl.launchedAppState.quickSwitchToPreviousApp()
+                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = true)
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+                supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
new file mode 100644
index 0000000..fa38293
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
@@ -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 com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.common.NavBar
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class SwitchBackToSplitFromHomeBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp)
+
+                tapl.goHome()
+                wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+            }
+            transitions {
+                tapl.workspace.quickSwitchToPreviousApp()
+                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = true)
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+                supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
new file mode 100644
index 0000000..1064bd9
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
@@ -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 com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.common.NavBar
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitScreenEntered
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class SwitchBackToSplitFromRecentBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp)
+
+                tapl.goHome()
+                wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
+            }
+            transitions {
+                tapl.workspace.switchToOverview().currentTask.open()
+                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            withoutTracing(this)
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui")
+    @Presubmit
+    @Test
+    fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = true)
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+                supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
new file mode 100644
index 0000000..8f4393f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.Presubmit
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class SwitchBetweenSplitPairsBenchmark(override val flicker: FlickerTest) :
+    SplitScreenBase(flicker) {
+    protected val thirdApp = SplitScreenUtils.getIme(instrumentation)
+    protected val fourthApp = SplitScreenUtils.getSendNotification(instrumentation)
+
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp)
+                SplitScreenUtils.enterSplit(wmHelper, tapl, device, thirdApp, fourthApp)
+                SplitScreenUtils.waitForSplitComplete(wmHelper, thirdApp, fourthApp)
+            }
+            transitions {
+                tapl.launchedAppState.quickSwitchToPreviousApp()
+                SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
+            }
+            teardown {
+                thirdApp.exit(wmHelper)
+                fourthApp.exit(wmHelper)
+            }
+        }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @IwTest(focusArea = "sysui") @Presubmit @Test open fun cujCompleted() {}
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests()
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
index de967bf..afec1ee 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
@@ -33,6 +33,7 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -42,6 +43,7 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.bubbles.BubbleInfo;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -77,7 +79,7 @@
         Intent target = new Intent(mContext, BubblesTestActivity.class);
         Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder(
                 PendingIntent.getActivity(mContext, 0, target, PendingIntent.FLAG_MUTABLE),
-                        Icon.createWithResource(mContext, R.drawable.bubble_ic_create_bubble))
+                Icon.createWithResource(mContext, R.drawable.bubble_ic_create_bubble))
                 .build();
         when(mSbn.getNotification()).thenReturn(mNotif);
         when(mNotif.getBubbleMetadata()).thenReturn(metadata);
@@ -179,6 +181,34 @@
         assertThat(bubble.isConversation()).isFalse();
     }
 
+    @Test
+    public void testBubbleAsBubbleBarBubble_withShortcut() {
+        Bubble bubble = createBubbleWithShortcut();
+        BubbleInfo bubbleInfo = bubble.asBubbleBarBubble();
+
+        assertThat(bubble.getShortcutInfo()).isNotNull();
+        assertThat(bubbleInfo.getShortcutId()).isNotNull();
+        assertThat(bubbleInfo.getShortcutId()).isEqualTo(bubble.getShortcutId());
+        assertThat(bubbleInfo.getKey()).isEqualTo(bubble.getKey());
+        assertThat(bubbleInfo.getUserId()).isEqualTo(bubble.getUser().getIdentifier());
+        assertThat(bubbleInfo.getPackageName()).isEqualTo(bubble.getPackageName());
+    }
+
+    @Test
+    public void testBubbleAsBubbleBarBubble_withoutShortcut() {
+        Intent intent = new Intent(mContext, BubblesTestActivity.class);
+        intent.setPackage(mContext.getPackageName());
+        Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1 /* userId */),
+                null /* icon */, mMainExecutor);
+        BubbleInfo bubbleInfo = bubble.asBubbleBarBubble();
+
+        assertThat(bubble.getShortcutInfo()).isNull();
+        assertThat(bubbleInfo.getShortcutId()).isNull();
+        assertThat(bubbleInfo.getKey()).isEqualTo(bubble.getKey());
+        assertThat(bubbleInfo.getUserId()).isEqualTo(bubble.getUser().getIdentifier());
+        assertThat(bubbleInfo.getPackageName()).isEqualTo(bubble.getPackageName());
+    }
+
     private Bubble createBubbleWithShortcut() {
         ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext)
                 .setId("mockShortcutId")
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TaskStackListenerImplTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TaskStackListenerImplTest.java
index 1347e06..60ee918 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TaskStackListenerImplTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TaskStackListenerImplTest.java
@@ -112,9 +112,9 @@
     @Test
     public void testOnTaskProfileLocked() {
         ActivityManager.RunningTaskInfo info = mock(ActivityManager.RunningTaskInfo.class);
-        mImpl.onTaskProfileLocked(info);
-        verify(mCallback).onTaskProfileLocked(eq(info));
-        verify(mOtherCallback).onTaskProfileLocked(eq(info));
+        mImpl.onTaskProfileLocked(info, 0);
+        verify(mCallback).onTaskProfileLocked(eq(info), eq(0));
+        verify(mOtherCallback).onTaskProfileLocked(eq(info), eq(0));
     }
 
     @Test
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 63de74f..d6387ee 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
@@ -20,6 +20,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_NONE;
@@ -82,6 +83,8 @@
 @RunWith(AndroidTestingRunner.class)
 public class DesktopModeControllerTest extends ShellTestCase {
 
+    private static final int SECOND_DISPLAY = 2;
+
     @Mock
     private ShellController mShellController;
     @Mock
@@ -248,22 +251,22 @@
     public void testShowDesktopApps_allAppsInvisible_bringsToFront() {
         // Set up two active tasks on desktop, task2 is on top of task1.
         RunningTaskInfo freeformTask1 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(freeformTask1.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, freeformTask1.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(freeformTask1.taskId);
         mDesktopModeTaskRepository.updateVisibleFreeformTasks(
-                freeformTask1.taskId, false /* visible */);
+                DEFAULT_DISPLAY, freeformTask1.taskId, false /* visible */);
         RunningTaskInfo freeformTask2 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(freeformTask2.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, freeformTask2.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(freeformTask2.taskId);
         mDesktopModeTaskRepository.updateVisibleFreeformTasks(
-                freeformTask2.taskId, false /* visible */);
+                DEFAULT_DISPLAY, freeformTask2.taskId, false /* visible */);
         when(mShellTaskOrganizer.getRunningTaskInfo(freeformTask1.taskId)).thenReturn(
                 freeformTask1);
         when(mShellTaskOrganizer.getRunningTaskInfo(freeformTask2.taskId)).thenReturn(
                 freeformTask2);
 
         // Run show desktop apps logic
-        mController.showDesktopApps();
+        mController.showDesktopApps(DEFAULT_DISPLAY);
 
         final WindowContainerTransaction wct = getBringAppsToFrontTransaction();
         // Check wct has reorder calls
@@ -283,17 +286,19 @@
     @Test
     public void testShowDesktopApps_appsAlreadyVisible_bringsToFront() {
         final RunningTaskInfo task1 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(task1.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task1.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
-        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, true /* visible */);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task1.taskId,
+                true /* visible */);
         when(mShellTaskOrganizer.getRunningTaskInfo(task1.taskId)).thenReturn(task1);
         final RunningTaskInfo task2 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(task2.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task2.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
-        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, true /* visible */);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task2.taskId,
+                true /* visible */);
         when(mShellTaskOrganizer.getRunningTaskInfo(task2.taskId)).thenReturn(task2);
 
-        mController.showDesktopApps();
+        mController.showDesktopApps(DEFAULT_DISPLAY);
 
         final WindowContainerTransaction wct = getBringAppsToFrontTransaction();
         // Check wct has reorder calls
@@ -312,17 +317,19 @@
     @Test
     public void testShowDesktopApps_someAppsInvisible_reordersAll() {
         final RunningTaskInfo task1 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(task1.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task1.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
-        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, false /* visible */);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task1.taskId,
+                false /* visible */);
         when(mShellTaskOrganizer.getRunningTaskInfo(task1.taskId)).thenReturn(task1);
         final RunningTaskInfo task2 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(task2.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task2.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
-        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, true /* visible */);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task2.taskId,
+                true /* visible */);
         when(mShellTaskOrganizer.getRunningTaskInfo(task2.taskId)).thenReturn(task2);
 
-        mController.showDesktopApps();
+        mController.showDesktopApps(DEFAULT_DISPLAY);
 
         final WindowContainerTransaction wct = getBringAppsToFrontTransaction();
         // Both tasks should be reordered to top, even if one was already visible.
@@ -336,38 +343,87 @@
     }
 
     @Test
+    public void testShowDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplay() {
+        RunningTaskInfo taskDefaultDisplay = createFreeformTask(DEFAULT_DISPLAY);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, taskDefaultDisplay.taskId);
+        mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(taskDefaultDisplay.taskId);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(
+                DEFAULT_DISPLAY, taskDefaultDisplay.taskId, false /* visible */);
+        when(mShellTaskOrganizer.getRunningTaskInfo(taskDefaultDisplay.taskId)).thenReturn(
+                taskDefaultDisplay);
+
+        RunningTaskInfo taskSecondDisplay = createFreeformTask(SECOND_DISPLAY);
+        mDesktopModeTaskRepository.addActiveTask(SECOND_DISPLAY, taskSecondDisplay.taskId);
+        mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(taskSecondDisplay.taskId);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(
+                SECOND_DISPLAY, taskSecondDisplay.taskId, false /* visible */);
+        when(mShellTaskOrganizer.getRunningTaskInfo(taskSecondDisplay.taskId)).thenReturn(
+                taskSecondDisplay);
+
+        mController.showDesktopApps(DEFAULT_DISPLAY);
+
+        WindowContainerTransaction wct = getBringAppsToFrontTransaction();
+        assertThat(wct.getHierarchyOps()).hasSize(1);
+        HierarchyOp op = wct.getHierarchyOps().get(0);
+        assertThat(op.getContainer()).isEqualTo(taskDefaultDisplay.token.asBinder());
+    }
+
+    @Test
     public void testGetVisibleTaskCount_noTasks_returnsZero() {
-        assertThat(mController.getVisibleTaskCount()).isEqualTo(0);
+        assertThat(mController.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0);
     }
 
     @Test
     public void testGetVisibleTaskCount_twoTasks_bothVisible_returnsTwo() {
         RunningTaskInfo task1 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(task1.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task1.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
-        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, true /* visible */);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task1.taskId,
+                true /* visible */);
 
         RunningTaskInfo task2 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(task2.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task2.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
-        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, true /* visible */);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task2.taskId,
+                true /* visible */);
 
-        assertThat(mController.getVisibleTaskCount()).isEqualTo(2);
+        assertThat(mController.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2);
     }
 
     @Test
     public void testGetVisibleTaskCount_twoTasks_oneVisible_returnsOne() {
         RunningTaskInfo task1 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(task1.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task1.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
-        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task1.taskId, true /* visible */);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task1.taskId,
+                true /* visible */);
 
         RunningTaskInfo task2 = createFreeformTask();
-        mDesktopModeTaskRepository.addActiveTask(task2.taskId);
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, task2.taskId);
         mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task2.taskId);
-        mDesktopModeTaskRepository.updateVisibleFreeformTasks(task2.taskId, false /* visible */);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY, task2.taskId,
+                false /* visible */);
 
-        assertThat(mController.getVisibleTaskCount()).isEqualTo(1);
+        assertThat(mController.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1);
+    }
+
+    @Test
+    public void testGetVisibleTaskCount_twoTasksVisibleOnDifferentDisplays_returnsOne() {
+        RunningTaskInfo taskDefaultDisplay = createFreeformTask();
+        mDesktopModeTaskRepository.addActiveTask(DEFAULT_DISPLAY, taskDefaultDisplay.taskId);
+        mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(taskDefaultDisplay.taskId);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(DEFAULT_DISPLAY,
+                taskDefaultDisplay.taskId,
+                true /* visible */);
+
+        RunningTaskInfo taskSecondDisplay = createFreeformTask();
+        mDesktopModeTaskRepository.addActiveTask(SECOND_DISPLAY, taskSecondDisplay.taskId);
+        mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(taskSecondDisplay.taskId);
+        mDesktopModeTaskRepository.updateVisibleFreeformTasks(SECOND_DISPLAY,
+                taskSecondDisplay.taskId,
+                true /* visible */);
+
+        assertThat(mController.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1);
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
index 45cb3a0..3bc2f0e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
@@ -17,10 +17,12 @@
 package com.android.wm.shell.desktopmode
 
 import android.testing.AndroidTestingRunner
+import android.view.Display.DEFAULT_DISPLAY
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.TestShellExecutor
 import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.fail
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -41,8 +43,8 @@
         val listener = TestListener()
         repo.addActiveTaskListener(listener)
 
-        repo.addActiveTask(1)
-        assertThat(listener.activeTaskChangedCalls).isEqualTo(1)
+        repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+        assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(1)
         assertThat(repo.isActiveTask(1)).isTrue()
     }
 
@@ -51,9 +53,9 @@
         val listener = TestListener()
         repo.addActiveTaskListener(listener)
 
-        repo.addActiveTask(1)
-        repo.addActiveTask(1)
-        assertThat(listener.activeTaskChangedCalls).isEqualTo(1)
+        repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+        repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+        assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(1)
     }
 
     @Test
@@ -61,9 +63,22 @@
         val listener = TestListener()
         repo.addActiveTaskListener(listener)
 
-        repo.addActiveTask(1)
-        repo.addActiveTask(2)
-        assertThat(listener.activeTaskChangedCalls).isEqualTo(2)
+        repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+        repo.addActiveTask(DEFAULT_DISPLAY, taskId = 2)
+        assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
+    }
+
+    @Test
+    fun addActiveTask_multipleDisplays_notifiesCorrectListener() {
+        val listener = TestListener()
+        repo.addActiveTaskListener(listener)
+
+        repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+        repo.addActiveTask(DEFAULT_DISPLAY, taskId = 2)
+        repo.addActiveTask(SECOND_DISPLAY, taskId = 3)
+
+        assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
+        assertThat(listener.activeChangesOnSecondaryDisplay).isEqualTo(1)
     }
 
     @Test
@@ -71,10 +86,10 @@
         val listener = TestListener()
         repo.addActiveTaskListener(listener)
 
-        repo.addActiveTask(1)
+        repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
         repo.removeActiveTask(1)
         // Notify once for add and once for remove
-        assertThat(listener.activeTaskChangedCalls).isEqualTo(2)
+        assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(2)
         assertThat(repo.isActiveTask(1)).isFalse()
     }
 
@@ -83,7 +98,17 @@
         val listener = TestListener()
         repo.addActiveTaskListener(listener)
         repo.removeActiveTask(99)
-        assertThat(listener.activeTaskChangedCalls).isEqualTo(0)
+        assertThat(listener.activeChangesOnDefaultDisplay).isEqualTo(0)
+    }
+
+    @Test
+    fun remoteActiveTask_listenerForOtherDisplayNotNotified() {
+        val listener = TestListener()
+        repo.addActiveTaskListener(listener)
+        repo.addActiveTask(DEFAULT_DISPLAY, taskId = 1)
+        repo.removeActiveTask(1)
+        assertThat(listener.activeChangesOnSecondaryDisplay).isEqualTo(0)
+        assertThat(repo.isActiveTask(1)).isFalse()
     }
 
     @Test
@@ -93,14 +118,27 @@
 
     @Test
     fun addListener_notifiesVisibleFreeformTask() {
-        repo.updateVisibleFreeformTasks(1, true)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
         val listener = TestVisibilityListener()
         val executor = TestShellExecutor()
         repo.addVisibleTasksListener(listener, executor)
         executor.flushAll()
 
-        assertThat(listener.hasVisibleFreeformTasks).isTrue()
-        assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(1)
+        assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
+        assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
+    }
+
+    @Test
+    fun addListener_tasksOnDifferentDisplay_doesNotNotify() {
+        repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = true)
+        val listener = TestVisibilityListener()
+        val executor = TestShellExecutor()
+        repo.addVisibleTasksListener(listener, executor)
+        executor.flushAll()
+
+        assertThat(listener.hasVisibleTasksOnDefaultDisplay).isFalse()
+        // One call as adding listener notifies it
+        assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(0)
     }
 
     @Test
@@ -108,13 +146,61 @@
         val listener = TestVisibilityListener()
         val executor = TestShellExecutor()
         repo.addVisibleTasksListener(listener, executor)
-        repo.updateVisibleFreeformTasks(1, true)
-        repo.updateVisibleFreeformTasks(2, true)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
         executor.flushAll()
 
-        assertThat(listener.hasVisibleFreeformTasks).isTrue()
-        // Equal to 2 because adding the listener notifies the current state
-        assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(2)
+        assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
+        assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
+    }
+
+    @Test
+    fun updateVisibleFreeformTasks_addVisibleTaskNotifiesListenerForThatDisplay() {
+        val listener = TestVisibilityListener()
+        val executor = TestShellExecutor()
+        repo.addVisibleTasksListener(listener, executor)
+
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        executor.flushAll()
+
+        assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
+        assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
+        assertThat(listener.hasVisibleTasksOnSecondaryDisplay).isFalse()
+        assertThat(listener.visibleChangesOnSecondaryDisplay).isEqualTo(0)
+
+        repo.updateVisibleFreeformTasks(displayId = 1, taskId = 2, visible = true)
+        executor.flushAll()
+
+        // Listener for secondary display is notified
+        assertThat(listener.hasVisibleTasksOnSecondaryDisplay).isTrue()
+        assertThat(listener.visibleChangesOnSecondaryDisplay).isEqualTo(1)
+        // No changes to listener for default display
+        assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
+    }
+
+    @Test
+    fun updateVisibleFreeformTasks_taskOnDefaultBecomesVisibleOnSecondDisplay_listenersNotified() {
+        val listener = TestVisibilityListener()
+        val executor = TestShellExecutor()
+        repo.addVisibleTasksListener(listener, executor)
+
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        executor.flushAll()
+        assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
+
+        // Mark task 1 visible on secondary display
+        repo.updateVisibleFreeformTasks(displayId = 1, taskId = 1, visible = true)
+        executor.flushAll()
+
+        // Default display should have 2 calls
+        // 1 - visible task added
+        // 2 - visible task removed
+        assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(2)
+        assertThat(listener.hasVisibleTasksOnDefaultDisplay).isFalse()
+
+        // Secondary display should have 1 call for visible task added
+        assertThat(listener.visibleChangesOnSecondaryDisplay).isEqualTo(1)
+        assertThat(listener.hasVisibleTasksOnSecondaryDisplay).isTrue()
     }
 
     @Test
@@ -122,52 +208,83 @@
         val listener = TestVisibilityListener()
         val executor = TestShellExecutor()
         repo.addVisibleTasksListener(listener, executor)
-        repo.updateVisibleFreeformTasks(1, true)
-        repo.updateVisibleFreeformTasks(2, true)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
         executor.flushAll()
 
-        assertThat(listener.hasVisibleFreeformTasks).isTrue()
-        repo.updateVisibleFreeformTasks(1, false)
+        assertThat(listener.hasVisibleTasksOnDefaultDisplay).isTrue()
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
         executor.flushAll()
 
-        // Equal to 2 because adding the listener notifies the current state
-        assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(2)
+        assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(1)
 
-        repo.updateVisibleFreeformTasks(2, false)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = false)
         executor.flushAll()
 
-        assertThat(listener.hasVisibleFreeformTasks).isFalse()
-        assertThat(listener.visibleFreeformTaskChangedCalls).isEqualTo(3)
+        assertThat(listener.hasVisibleTasksOnDefaultDisplay).isFalse()
+        assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(2)
     }
 
     @Test
     fun getVisibleTaskCount() {
         // No tasks, count is 0
-        assertThat(repo.getVisibleTaskCount()).isEqualTo(0)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
 
         // New task increments count to 1
-        repo.updateVisibleFreeformTasks(taskId = 1, visible = true)
-        assertThat(repo.getVisibleTaskCount()).isEqualTo(1)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
 
         // Visibility update to same task does not increase count
-        repo.updateVisibleFreeformTasks(taskId = 1, visible = true)
-        assertThat(repo.getVisibleTaskCount()).isEqualTo(1)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
 
         // Second task visible increments count
-        repo.updateVisibleFreeformTasks(taskId = 2, visible = true)
-        assertThat(repo.getVisibleTaskCount()).isEqualTo(2)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
 
         // Hiding a task decrements count
-        repo.updateVisibleFreeformTasks(taskId = 1, visible = false)
-        assertThat(repo.getVisibleTaskCount()).isEqualTo(1)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
 
         // Hiding all tasks leaves count at 0
-        repo.updateVisibleFreeformTasks(taskId = 2, visible = false)
-        assertThat(repo.getVisibleTaskCount()).isEqualTo(0)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = false)
+        assertThat(repo.getVisibleTaskCount(displayId = 9)).isEqualTo(0)
 
         // Hiding a not existing task, count remains at 0
-        repo.updateVisibleFreeformTasks(taskId = 999, visible = false)
-        assertThat(repo.getVisibleTaskCount()).isEqualTo(0)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 999, visible = false)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+    }
+
+    @Test
+    fun getVisibleTaskCount_multipleDisplays() {
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+        assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
+
+        // New task on default display increments count for that display only
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+        assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(0)
+
+        // New task on secondary display, increments count for that display only
+        repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 2, visible = true)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+        assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
+
+        // Marking task visible on another display, updates counts for both displays
+        repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = true)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+        assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
+
+        // Marking task that is on secondary display, hidden on default display, does not affect
+        // secondary display
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = false)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+        assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(2)
+
+        // Hiding a task on that display, decrements count
+        repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 1, visible = false)
+        assertThat(repo.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
+        assertThat(repo.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
     }
 
     @Test
@@ -197,19 +314,40 @@
     }
 
     class TestListener : DesktopModeTaskRepository.ActiveTasksListener {
-        var activeTaskChangedCalls = 0
-        override fun onActiveTasksChanged() {
-            activeTaskChangedCalls++
+        var activeChangesOnDefaultDisplay = 0
+        var activeChangesOnSecondaryDisplay = 0
+        override fun onActiveTasksChanged(displayId: Int) {
+            when (displayId) {
+                DEFAULT_DISPLAY -> activeChangesOnDefaultDisplay++
+                SECOND_DISPLAY -> activeChangesOnSecondaryDisplay++
+                else -> fail("Active task listener received unexpected display id: $displayId")
+            }
         }
     }
 
     class TestVisibilityListener : DesktopModeTaskRepository.VisibleTasksListener {
-        var hasVisibleFreeformTasks = false
-        var visibleFreeformTaskChangedCalls = 0
+        var hasVisibleTasksOnDefaultDisplay = false
+        var hasVisibleTasksOnSecondaryDisplay = false
 
-        override fun onVisibilityChanged(hasVisibleTasks: Boolean) {
-            hasVisibleFreeformTasks = hasVisibleTasks
-            visibleFreeformTaskChangedCalls++
+        var visibleChangesOnDefaultDisplay = 0
+        var visibleChangesOnSecondaryDisplay = 0
+
+        override fun onVisibilityChanged(displayId: Int, hasVisibleFreeformTasks: Boolean) {
+            when (displayId) {
+                DEFAULT_DISPLAY -> {
+                    hasVisibleTasksOnDefaultDisplay = hasVisibleFreeformTasks
+                    visibleChangesOnDefaultDisplay++
+                }
+                SECOND_DISPLAY -> {
+                    hasVisibleTasksOnSecondaryDisplay = hasVisibleFreeformTasks
+                    visibleChangesOnSecondaryDisplay++
+                }
+                else -> fail("Visible task listener received unexpected display id: $displayId")
+            }
         }
     }
+
+    companion object {
+        const val SECOND_DISPLAY = 1
+    }
 }
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 c9bd695..f506969 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
@@ -25,6 +25,7 @@
 import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
 import android.os.Binder
 import android.testing.AndroidTestingRunner
+import android.view.Display.DEFAULT_DISPLAY
 import android.view.WindowManager
 import android.view.WindowManager.TRANSIT_CHANGE
 import android.view.WindowManager.TRANSIT_NONE
@@ -84,10 +85,10 @@
     @Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler
     @Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler
 
-    lateinit var mockitoSession: StaticMockitoSession
-    lateinit var controller: DesktopTasksController
-    lateinit var shellInit: ShellInit
-    lateinit var desktopModeTaskRepository: DesktopModeTaskRepository
+    private lateinit var mockitoSession: StaticMockitoSession
+    private lateinit var controller: DesktopTasksController
+    private lateinit var shellInit: ShellInit
+    private lateinit var desktopModeTaskRepository: DesktopModeTaskRepository
 
     // Mock running tasks are registered here so we can get the list from mock shell task organizer
     private val runningTasks = mutableListOf<RunningTaskInfo>()
@@ -155,7 +156,7 @@
         markTaskHidden(task1)
         markTaskHidden(task2)
 
-        controller.showDesktopApps()
+        controller.showDesktopApps(DEFAULT_DISPLAY)
 
         val wct = getLatestWct(expectTransition = TRANSIT_NONE)
         assertThat(wct.hierarchyOps).hasSize(3)
@@ -173,7 +174,7 @@
         markTaskVisible(task1)
         markTaskVisible(task2)
 
-        controller.showDesktopApps()
+        controller.showDesktopApps(DEFAULT_DISPLAY)
 
         val wct = getLatestWct(expectTransition = TRANSIT_NONE)
         assertThat(wct.hierarchyOps).hasSize(3)
@@ -191,7 +192,7 @@
         markTaskHidden(task1)
         markTaskVisible(task2)
 
-        controller.showDesktopApps()
+        controller.showDesktopApps(DEFAULT_DISPLAY)
 
         val wct = getLatestWct(expectTransition = TRANSIT_NONE)
         assertThat(wct.hierarchyOps).hasSize(3)
@@ -205,7 +206,7 @@
     fun showDesktopApps_noActiveTasks_reorderHomeToTop() {
         val homeTask = setUpHomeTask()
 
-        controller.showDesktopApps()
+        controller.showDesktopApps(DEFAULT_DISPLAY)
 
         val wct = getLatestWct(expectTransition = TRANSIT_NONE)
         assertThat(wct.hierarchyOps).hasSize(1)
@@ -213,8 +214,26 @@
     }
 
     @Test
+    fun showDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplay() {
+        val homeTaskDefaultDisplay = setUpHomeTask(DEFAULT_DISPLAY)
+        val taskDefaultDisplay = setUpFreeformTask(DEFAULT_DISPLAY)
+        setUpHomeTask(SECOND_DISPLAY)
+        val taskSecondDisplay = setUpFreeformTask(SECOND_DISPLAY)
+        markTaskHidden(taskDefaultDisplay)
+        markTaskHidden(taskSecondDisplay)
+
+        controller.showDesktopApps(DEFAULT_DISPLAY)
+
+        val wct = getLatestWct(expectTransition = TRANSIT_NONE)
+        assertThat(wct.hierarchyOps).hasSize(2)
+        // Expect order to be from bottom: home, task
+        wct.assertReorderAt(index = 0, homeTaskDefaultDisplay)
+        wct.assertReorderAt(index = 1, taskDefaultDisplay)
+    }
+
+    @Test
     fun getVisibleTaskCount_noTasks_returnsZero() {
-        assertThat(controller.getVisibleTaskCount()).isEqualTo(0)
+        assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
     }
 
     @Test
@@ -222,7 +241,7 @@
         setUpHomeTask()
         setUpFreeformTask().also(::markTaskVisible)
         setUpFreeformTask().also(::markTaskVisible)
-        assertThat(controller.getVisibleTaskCount()).isEqualTo(2)
+        assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(2)
     }
 
     @Test
@@ -230,7 +249,15 @@
         setUpHomeTask()
         setUpFreeformTask().also(::markTaskVisible)
         setUpFreeformTask().also(::markTaskHidden)
-        assertThat(controller.getVisibleTaskCount()).isEqualTo(1)
+        assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(1)
+    }
+
+    @Test
+    fun getVisibleTaskCount_twoTasksVisibleOnDifferentDisplays_returnsOne() {
+        setUpHomeTask()
+        setUpFreeformTask(DEFAULT_DISPLAY).also(::markTaskVisible)
+        setUpFreeformTask(SECOND_DISPLAY).also(::markTaskVisible)
+        assertThat(controller.getVisibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
     }
 
     @Test
@@ -258,6 +285,7 @@
         controller.moveToDesktop(fullscreenTask)
 
         with(getLatestWct(expectTransition = TRANSIT_CHANGE)) {
+            // Operations should include home task, freeform task
             assertThat(hierarchyOps).hasSize(3)
             assertReorderSequence(homeTask, freeformTask, fullscreenTask)
             assertThat(changes[fullscreenTask.token.asBinder()]?.windowingMode)
@@ -266,6 +294,28 @@
     }
 
     @Test
+    fun moveToDesktop_onlyFreeformTasksFromCurrentDisplayBroughtToFront() {
+        setUpHomeTask(displayId = DEFAULT_DISPLAY)
+        val freeformTaskDefault = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+        val fullscreenTaskDefault = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
+        markTaskHidden(freeformTaskDefault)
+
+        val homeTaskSecond = setUpHomeTask(displayId = SECOND_DISPLAY)
+        val freeformTaskSecond = setUpFreeformTask(displayId = SECOND_DISPLAY)
+        markTaskHidden(freeformTaskSecond)
+
+        controller.moveToDesktop(fullscreenTaskDefault)
+
+        with(getLatestWct(expectTransition = TRANSIT_CHANGE)) {
+            // Check that hierarchy operations do not include tasks from second display
+            assertThat(hierarchyOps.map { it.container })
+                .doesNotContain(homeTaskSecond.token.asBinder())
+            assertThat(hierarchyOps.map { it.container })
+                .doesNotContain(freeformTaskSecond.token.asBinder())
+        }
+    }
+
+    @Test
     fun moveToFullscreen() {
         val task = setUpFreeformTask()
         controller.moveToFullscreen(task)
@@ -281,6 +331,19 @@
     }
 
     @Test
+    fun moveToFullscreen_secondDisplayTaskHasFreeform_secondDisplayNotAffected() {
+        val taskDefaultDisplay = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+        val taskSecondDisplay = setUpFreeformTask(displayId = SECOND_DISPLAY)
+
+        controller.moveToFullscreen(taskDefaultDisplay)
+
+        with(getLatestWct(expectTransition = TRANSIT_CHANGE)) {
+            assertThat(changes.keys).contains(taskDefaultDisplay.token.asBinder())
+            assertThat(changes.keys).doesNotContain(taskSecondDisplay.token.asBinder())
+        }
+    }
+
+    @Test
     fun getTaskWindowingMode() {
         val fullscreenTask = setUpFullscreenTask()
         val freeformTask = setUpFreeformTask()
@@ -324,6 +387,18 @@
     }
 
     @Test
+    fun handleRequest_fullscreenTask_freeformTaskOnOtherDisplay_returnNull() {
+        assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+        val fullscreenTaskDefaultDisplay = createFullscreenTask(displayId = DEFAULT_DISPLAY)
+        createFreeformTask(displayId = SECOND_DISPLAY)
+
+        val result =
+            controller.handleRequest(Binder(), createTransition(fullscreenTaskDefaultDisplay))
+        assertThat(result).isNull()
+    }
+
+    @Test
     fun handleRequest_freeformTask_freeformVisible_returnNull() {
         assumeTrue(ENABLE_SHELL_TRANSITIONS)
 
@@ -362,6 +437,18 @@
     }
 
     @Test
+    fun handleRequest_freeformTask_freeformOnOtherDisplayOnly_returnSwitchToFullscreenWCT() {
+        assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+        val taskDefaultDisplay = createFreeformTask(displayId = DEFAULT_DISPLAY)
+        createFreeformTask(displayId = SECOND_DISPLAY)
+
+        val result = controller.handleRequest(Binder(), createTransition(taskDefaultDisplay))
+        assertThat(result?.changes?.get(taskDefaultDisplay.token.asBinder())?.windowingMode)
+            .isEqualTo(WINDOWING_MODE_FULLSCREEN)
+    }
+
+    @Test
     fun handleRequest_notOpenOrToFrontTransition_returnNull() {
         assumeTrue(ENABLE_SHELL_TRANSITIONS)
 
@@ -400,35 +487,43 @@
         assertThat(controller.handleRequest(Binder(), createTransition(task))).isNull()
     }
 
-    private fun setUpFreeformTask(): RunningTaskInfo {
-        val task = createFreeformTask()
+    private fun setUpFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
+        val task = createFreeformTask(displayId)
         whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
-        desktopModeTaskRepository.addActiveTask(task.taskId)
+        desktopModeTaskRepository.addActiveTask(displayId, task.taskId)
         desktopModeTaskRepository.addOrMoveFreeformTaskToTop(task.taskId)
         runningTasks.add(task)
         return task
     }
 
-    private fun setUpHomeTask(): RunningTaskInfo {
-        val task = createHomeTask()
+    private fun setUpHomeTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
+        val task = createHomeTask(displayId)
         whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
         runningTasks.add(task)
         return task
     }
 
-    private fun setUpFullscreenTask(): RunningTaskInfo {
-        val task = createFullscreenTask()
+    private fun setUpFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
+        val task = createFullscreenTask(displayId)
         whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
         runningTasks.add(task)
         return task
     }
 
     private fun markTaskVisible(task: RunningTaskInfo) {
-        desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = true)
+        desktopModeTaskRepository.updateVisibleFreeformTasks(
+            task.displayId,
+            task.taskId,
+            visible = true
+        )
     }
 
     private fun markTaskHidden(task: RunningTaskInfo) {
-        desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = false)
+        desktopModeTaskRepository.updateVisibleFreeformTasks(
+            task.displayId,
+            task.taskId,
+            visible = false
+        )
     }
 
     private fun getLatestWct(
@@ -457,6 +552,10 @@
     ): TransitionRequestInfo {
         return TransitionRequestInfo(type, task, null /* remoteTransition */)
     }
+
+    companion object {
+        const val SECOND_DISPLAY = 2
+    }
 }
 
 private fun WindowContainerTransaction.assertReorderAt(index: Int, task: RunningTaskInfo) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
index dc91d75..cf1ff32 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
@@ -21,14 +21,17 @@
 import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
 import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.view.Display.DEFAULT_DISPLAY
 import com.android.wm.shell.TestRunningTaskInfoBuilder
 
 class DesktopTestHelpers {
     companion object {
         /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */
         @JvmStatic
-        fun createFreeformTask(): RunningTaskInfo {
+        @JvmOverloads
+        fun createFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
             return TestRunningTaskInfoBuilder()
+                    .setDisplayId(displayId)
                     .setToken(MockToken().token())
                     .setActivityType(ACTIVITY_TYPE_STANDARD)
                     .setWindowingMode(WINDOWING_MODE_FREEFORM)
@@ -38,8 +41,10 @@
 
         /** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
         @JvmStatic
-        fun createFullscreenTask(): RunningTaskInfo {
+        @JvmOverloads
+        fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
             return TestRunningTaskInfoBuilder()
+                    .setDisplayId(displayId)
                     .setToken(MockToken().token())
                     .setActivityType(ACTIVITY_TYPE_STANDARD)
                     .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
@@ -49,8 +54,10 @@
 
         /** Create a new home task */
         @JvmStatic
-        fun createHomeTask(): RunningTaskInfo {
+        @JvmOverloads
+        fun createHomeTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
             return TestRunningTaskInfoBuilder()
+                    .setDisplayId(displayId)
                     .setToken(MockToken().token())
                     .setActivityType(ACTIVITY_TYPE_HOME)
                     .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
index 2c5a5cd..4fad054 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
@@ -71,12 +71,6 @@
     @Mock
     Resources mResources;
     @Mock
-    SurfaceControl.Transaction mStartT;
-    @Mock
-    SurfaceControl.Transaction mFinishT;
-    @Mock
-    SurfaceControl.Transaction mAnimationT;
-    @Mock
     Transitions.TransitionFinishCallback mTransitionFinishCallback;
     @Mock
     ShellExecutor mExecutor;
@@ -88,7 +82,7 @@
         MockitoAnnotations.initMocks(this);
 
         doReturn(mExecutor).when(mTransitions).getMainExecutor();
-        doReturn(mAnimationT).when(mTransactionFactory).get();
+        doReturn(new SurfaceControl.Transaction()).when(mTransactionFactory).get();
         doReturn(mResources).when(mContext).getResources();
         doReturn(mDisplayMetrics).when(mResources).getDisplayMetrics();
         when(mResources.getDisplayMetrics())
@@ -115,7 +109,9 @@
         runOnUiThread(() -> {
             try {
                 assertTrue(mExitDesktopTaskTransitionHandler
-                        .startAnimation(mToken, info, mStartT, mFinishT,
+                        .startAnimation(mToken, info,
+                                new SurfaceControl.Transaction(),
+                                new SurfaceControl.Transaction(),
                                 mTransitionFinishCallback));
             } catch (Exception e) {
                 exceptions.add(e);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 6995d10..04f2c99 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -268,7 +268,7 @@
     }
 
     @Test
-    public void saveReentryState_userHasResized_savesSize() {
+    public void saveReentryState_nonEmptyUserResizeBounds_savesSize() {
         final Rect bounds = new Rect(0, 0, 10, 10);
         final Rect resizedBounds = new Rect(0, 0, 30, 30);
         when(mMockPipBoundsAlgorithm.getSnapFraction(bounds)).thenReturn(1.0f);
@@ -281,6 +281,19 @@
     }
 
     @Test
+    public void saveReentryState_emptyUserResizeBounds_savesSize() {
+        final Rect bounds = new Rect(0, 0, 10, 10);
+        final Rect resizedBounds = new Rect(0, 0, 0, 0);
+        when(mMockPipBoundsAlgorithm.getSnapFraction(bounds)).thenReturn(1.0f);
+        when(mMockPipTouchHandler.getUserResizeBounds()).thenReturn(resizedBounds);
+        when(mMockPipBoundsState.hasUserResizedPip()).thenReturn(true);
+
+        mPipController.saveReentryState(bounds);
+
+        verify(mMockPipBoundsState).saveReentryState(new Size(10, 10), 1.0f);
+    }
+
+    @Test
     public void onDisplayConfigurationChanged_inPip_movePip() {
         final int displayId = 1;
         final Rect bounds = new Rect(0, 0, 10, 10);
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 a9f311f..92cbf7f 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
@@ -180,8 +180,9 @@
         TestRemoteTransition testRemote = new TestRemoteTransition();
 
         IBinder transition = mSplitScreenTransitions.startEnterTransition(
-                TRANSIT_SPLIT_SCREEN_PAIR_OPEN, new WindowContainerTransaction(),
-                new RemoteTransition(testRemote, "Test"), mStageCoordinator, null, null);
+                TRANSIT_OPEN, new WindowContainerTransaction(),
+                new RemoteTransition(testRemote, "Test"), mStageCoordinator, null, null,
+                TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
         mMainStage.onTaskAppeared(mMainChild, createMockSurface());
         mSideStage.onTaskAppeared(mSideChild, createMockSurface());
         boolean accepted = mStageCoordinator.startAnimation(transition, info,
@@ -397,7 +398,7 @@
     }
 
     private TransitionInfo createEnterPairInfo() {
-        return new TransitionInfoBuilder(TRANSIT_SPLIT_SCREEN_PAIR_OPEN, 0)
+        return new TransitionInfoBuilder(TRANSIT_OPEN, 0)
                 .addChange(TRANSIT_OPEN, mMainChild)
                 .addChange(TRANSIT_OPEN, mSideChild)
                 .build();
@@ -406,9 +407,9 @@
     private void enterSplit() {
         TransitionInfo enterInfo = createEnterPairInfo();
         IBinder enterTransit = mSplitScreenTransitions.startEnterTransition(
-                TRANSIT_SPLIT_SCREEN_PAIR_OPEN, new WindowContainerTransaction(),
+                TRANSIT_OPEN, new WindowContainerTransaction(),
                 new RemoteTransition(new TestRemoteTransition(), "Test"),
-                mStageCoordinator, null, null);
+                mStageCoordinator, null, null, TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
         mMainStage.onTaskAppeared(mMainChild, createMockSurface());
         mSideStage.onTaskAppeared(mSideChild, createMockSurface());
         mStageCoordinator.startAnimation(enterTransit, enterInfo,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index e6219d1..d27064d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -152,10 +152,15 @@
         when(mStageCoordinator.isSplitActive()).thenReturn(true);
 
         final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        final WindowContainerTransaction wct = spy(new WindowContainerTransaction());
 
         mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
-        verify(mSideStage).addTask(eq(task), eq(wct));
+        verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
+                eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
+        verify(mMainStage).reparentTopTask(eq(wct));
+        verify(mMainStage).evictAllChildren(eq(wct));
+        verify(mSideStage).evictAllChildren(eq(wct));
+        verify(mSplitLayout).resetDividerPosition();
         assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
         assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
     }
@@ -171,14 +176,11 @@
         final WindowContainerTransaction wct = new WindowContainerTransaction();
 
         mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
-        verify(mMainStage).addTask(eq(task), eq(wct));
+        verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
+                eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
+        verify(mMainStage).evictAllChildren(eq(wct));
         assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
         assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getSideStagePosition());
-
-        mStageCoordinator.moveToStage(task, SPLIT_POSITION_TOP_OR_LEFT, wct);
-        verify(mSideStage).addTask(eq(task), eq(wct));
-        assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getSideStagePosition());
-        assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
index 784ad9b..1a1bebd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
@@ -126,6 +126,12 @@
         verify(mCallbacks).onStatusChanged(eq(mRootTask.isVisible), eq(true));
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testUnknownTaskVanished() {
+        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
+        mStageTaskListener.onTaskVanished(task);
+    }
+
     @Test
     public void testTaskVanished() {
         // With shell transitions, the transition manages status changes, so skip this test.
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index bf62acf..8115a5d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -265,17 +265,17 @@
         mStartingSurfaceDrawer.mWindowRecords.addRecord(taskId,
                 new StartingSurfaceDrawer.StartingWindowRecord() {
                     @Override
-                    public void removeIfPossible(StartingWindowRemovalInfo info,
+                    public boolean removeIfPossible(StartingWindowRemovalInfo info,
                             boolean immediately) {
-
+                        return true;
                     }
                 });
         mStartingSurfaceDrawer.mWindowlessRecords.addRecord(taskId,
                 new StartingSurfaceDrawer.StartingWindowRecord() {
                     @Override
-                    public void removeIfPossible(StartingWindowRemovalInfo info,
+                    public boolean removeIfPossible(StartingWindowRemovalInfo info,
                             boolean immediately) {
-
+                        return true;
                     }
                 });
         mStartingSurfaceDrawer.clearAllWindows();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
new file mode 100644
index 0000000..348b365
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor
+
+import android.app.ActivityManager
+import android.graphics.PointF
+import android.graphics.Rect
+import android.os.IBinder
+import android.testing.AndroidTestingRunner
+import android.view.Display
+import android.window.WindowContainerToken
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
+import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.Mockito.any
+import org.mockito.MockitoAnnotations
+
+/**
+ * Tests for [DragPositioningCallbackUtility].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:DragPositioningCallbackUtilityTest
+ */
+@RunWith(AndroidTestingRunner::class)
+class DragPositioningCallbackUtilityTest {
+    @Mock
+    private lateinit var mockWindowDecoration: WindowDecoration<*>
+    @Mock
+    private lateinit var taskToken: WindowContainerToken
+    @Mock
+    private lateinit var taskBinder: IBinder
+    @Mock
+    private lateinit var mockDisplayController: DisplayController
+    @Mock
+    private lateinit var mockDisplayLayout: DisplayLayout
+    @Mock
+    private lateinit var mockDisplay: Display
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        whenever(taskToken.asBinder()).thenReturn(taskBinder)
+        whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
+        whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI)
+        whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { i ->
+            (i.arguments.first() as Rect).set(STABLE_BOUNDS)
+        }
+
+        mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply {
+            taskId = TASK_ID
+            token = taskToken
+            minWidth = MIN_WIDTH
+            minHeight = MIN_HEIGHT
+            defaultMinSize = DEFAULT_MIN
+            displayId = DISPLAY_ID
+            configuration.windowConfiguration.bounds = STARTING_BOUNDS
+        }
+        mockWindowDecoration.mDisplay = mockDisplay
+        whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID }
+    }
+
+    @Test
+    fun testChangeBoundsDoesNotChangeHeightWhenLessThanMin() {
+        val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
+        val repositionTaskBounds = Rect()
+
+        // Resize to width of 95px and height of 5px with min width of 10px
+        val newX = STARTING_BOUNDS.right.toFloat() - 5
+        val newY = STARTING_BOUNDS.top.toFloat() + 95
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+            false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta,
+            mockDisplayController, mockWindowDecoration)
+
+        assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 5)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom)
+    }
+
+    @Test
+    fun testChangeBoundsDoesNotChangeWidthWhenLessThanMin() {
+        val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
+        val repositionTaskBounds = Rect()
+
+        // Resize to height of 95px and width of 5px with min width of 10px
+        val newX = STARTING_BOUNDS.right.toFloat() - 95
+        val newY = STARTING_BOUNDS.top.toFloat() + 5
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+            false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta,
+            mockDisplayController, mockWindowDecoration)
+
+        assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 5)
+        assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom)
+    }
+
+    @Test
+    fun testChangeBoundsDoesNotChangeHeightWhenNegative() {
+        val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
+        val repositionTaskBounds = Rect()
+
+        // Resize to width of 95px and width of -5px with minimum of 10px
+        val newX = STARTING_BOUNDS.right.toFloat() - 5
+        val newY = STARTING_BOUNDS.top.toFloat() + 105
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+            false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta,
+            mockDisplayController, mockWindowDecoration)
+
+        assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 5)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom)
+    }
+
+    @Test
+    fun testChangeBoundsRunsWhenResizeBoundsValid() {
+        val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
+        val repositionTaskBounds = Rect()
+
+        // Shrink to height 20px and width 20px with both min height/width equal to 10px
+        val newX = STARTING_BOUNDS.right.toFloat() - 80
+        val newY = STARTING_BOUNDS.top.toFloat() + 80
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+                false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta,
+                mockDisplayController, mockWindowDecoration)
+        assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 80)
+        assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 80)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom)
+    }
+
+    @Test
+    fun testChangeBoundsDoesNotRunWithNegativeHeightAndWidth() {
+        val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
+        val repositionTaskBounds = Rect()
+        // Shrink to height -5px and width -5px with both min height/width equal to 10px
+        val newX = STARTING_BOUNDS.right.toFloat() - 105
+        val newY = STARTING_BOUNDS.top.toFloat() + 105
+
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+            false /* hasMoved */, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta,
+            mockDisplayController, mockWindowDecoration)
+        assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom)
+    }
+
+    @Test
+    fun testChangeBounds_toDisallowedBounds_freezesAtLimit() {
+        var hasMoved = false
+        val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(),
+            STARTING_BOUNDS.bottom.toFloat())
+        val repositionTaskBounds = Rect()
+        // Initial resize to width and height 110px.
+        var newX = STARTING_BOUNDS.right.toFloat() + 10
+        var newY = STARTING_BOUNDS.bottom.toFloat() + 10
+        var delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+        assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+            hasMoved, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta,
+            mockDisplayController, mockWindowDecoration))
+        hasMoved = true
+        // Resize width to 120px, height to disallowed area which should not result in a change.
+        newX += 10
+        newY = DISALLOWED_RESIZE_AREA.top.toFloat()
+        delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+        assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+            hasMoved, repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta,
+            mockDisplayController, mockWindowDecoration))
+        assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+        assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
+        assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right + 20)
+        assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom + 10)
+    }
+
+    companion object {
+        private const val TASK_ID = 5
+        private const val MIN_WIDTH = 10
+        private const val MIN_HEIGHT = 10
+        private const val DENSITY_DPI = 20
+        private const val DEFAULT_MIN = 40
+        private const val DISPLAY_ID = 1
+        private const val NAVBAR_HEIGHT = 50
+        private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
+        private val STARTING_BOUNDS = Rect(0, 0, 100, 100)
+        private val DISALLOWED_RESIZE_AREA = Rect(
+            DISPLAY_BOUNDS.left,
+            DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
+            DISPLAY_BOUNDS.right,
+            DISPLAY_BOUNDS.bottom)
+        private val STABLE_BOUNDS = Rect(
+            DISPLAY_BOUNDS.left,
+            DISPLAY_BOUNDS.top,
+            DISPLAY_BOUNDS.right,
+            DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT
+        )
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
new file mode 100644
index 0000000..5bea8f2
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
@@ -0,0 +1,266 @@
+package com.android.wm.shell.windowdecor
+
+import android.app.ActivityManager
+import android.app.WindowConfiguration
+import android.graphics.Rect
+import android.os.IBinder
+import android.testing.AndroidTestingRunner
+import android.view.Display
+import android.window.WindowContainerToken
+import android.window.WindowContainerTransaction
+import android.window.WindowContainerTransaction.Change.CHANGE_DRAG_RESIZING
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.Mockito.any
+import org.mockito.Mockito.argThat
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+/**
+ * Tests for [FluidResizeTaskPositioner].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:FluidResizeTaskPositionerTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class FluidResizeTaskPositionerTest : ShellTestCase() {
+
+    @Mock
+    private lateinit var mockShellTaskOrganizer: ShellTaskOrganizer
+    @Mock
+    private lateinit var mockWindowDecoration: WindowDecoration<*>
+    @Mock
+    private lateinit var mockDragStartListener: DragPositioningCallbackUtility.DragStartListener
+
+    @Mock
+    private lateinit var taskToken: WindowContainerToken
+    @Mock
+    private lateinit var taskBinder: IBinder
+
+    @Mock
+    private lateinit var mockDisplayController: DisplayController
+    @Mock
+    private lateinit var mockDisplayLayout: DisplayLayout
+    @Mock
+    private lateinit var mockDisplay: Display
+
+    private lateinit var taskPositioner: FluidResizeTaskPositioner
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        taskPositioner =
+            FluidResizeTaskPositioner(
+                mockShellTaskOrganizer,
+                mockWindowDecoration,
+                mockDisplayController,
+                mockDragStartListener
+            )
+
+        whenever(taskToken.asBinder()).thenReturn(taskBinder)
+        whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
+        whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI)
+        whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { i ->
+            (i.arguments.first() as Rect).set(STABLE_BOUNDS)
+        }
+
+        mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply {
+            taskId = TASK_ID
+            token = taskToken
+            minWidth = MIN_WIDTH
+            minHeight = MIN_HEIGHT
+            defaultMinSize = DEFAULT_MIN
+            displayId = DISPLAY_ID
+            configuration.windowConfiguration.bounds = STARTING_BOUNDS
+        }
+        mockWindowDecoration.mDisplay = mockDisplay
+        whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID }
+    }
+
+    @Test
+    fun testDragResize_notMove_skipsTransactionOnEnd() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_TOP or CTRL_TYPE_RIGHT,
+                STARTING_BOUNDS.left.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        taskPositioner.onDragPositioningEnd(
+                STARTING_BOUNDS.left.toFloat() + 10,
+                STARTING_BOUNDS.top.toFloat() + 10
+        )
+
+        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_noEffectiveMove_skipsTransactionOnMoveAndEnd() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_TOP or CTRL_TYPE_RIGHT,
+                STARTING_BOUNDS.left.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        taskPositioner.onDragPositioningMove(
+                STARTING_BOUNDS.left.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        taskPositioner.onDragPositioningEnd(
+                STARTING_BOUNDS.left.toFloat() + 10,
+                STARTING_BOUNDS.top.toFloat() + 10
+        )
+
+        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_hasEffectiveMove_issuesTransactionOnMoveAndEnd() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_TOP or CTRL_TYPE_RIGHT,
+                STARTING_BOUNDS.left.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        taskPositioner.onDragPositioningMove(
+                STARTING_BOUNDS.left.toFloat() + 10,
+                STARTING_BOUNDS.top.toFloat()
+        )
+        val rectAfterMove = Rect(STARTING_BOUNDS)
+        rectAfterMove.right += 10
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
+                        change.configuration.windowConfiguration.bounds == rectAfterMove
+            }
+        })
+
+        taskPositioner.onDragPositioningEnd(
+                STARTING_BOUNDS.left.toFloat() + 10,
+                STARTING_BOUNDS.top.toFloat() + 10
+        )
+        val rectAfterEnd = Rect(rectAfterMove)
+        rectAfterEnd.top += 10
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
+                        change.configuration.windowConfiguration.bounds == rectAfterEnd
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_move_skipsDragResizingFlag() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_UNDEFINED, // Move
+                STARTING_BOUNDS.left.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Move the task 10px to the right.
+        val newX = STARTING_BOUNDS.left.toFloat() + 10
+        val newY = STARTING_BOUNDS.top.toFloat()
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.changeMask and CHANGE_DRAG_RESIZING) != 0) &&
+                        change.dragResizing
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_resize_setsDragResizingFlag() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_RIGHT, // Resize right
+                STARTING_BOUNDS.left.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Resize the task by 10px to the right.
+        val newX = STARTING_BOUNDS.right.toFloat() + 10
+        val newY = STARTING_BOUNDS.top.toFloat()
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.changeMask and CHANGE_DRAG_RESIZING) != 0) &&
+                        change.dragResizing
+            }
+        })
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.changeMask and CHANGE_DRAG_RESIZING) != 0) &&
+                        !change.dragResizing
+            }
+        })
+    }
+
+    private fun WindowContainerTransaction.Change.ofBounds(bounds: Rect): Boolean {
+        return ((windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) &&
+                bounds == configuration.windowConfiguration.bounds
+    }
+
+    companion object {
+        private const val TASK_ID = 5
+        private const val MIN_WIDTH = 10
+        private const val MIN_HEIGHT = 10
+        private const val DENSITY_DPI = 20
+        private const val DEFAULT_MIN = 40
+        private const val DISPLAY_ID = 1
+        private const val NAVBAR_HEIGHT = 50
+        private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
+        private val STARTING_BOUNDS = Rect(0, 0, 100, 100)
+        private val DISALLOWED_RESIZE_AREA = Rect(
+                DISPLAY_BOUNDS.left,
+                DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
+                DISPLAY_BOUNDS.right,
+                DISPLAY_BOUNDS.bottom)
+        private val STABLE_BOUNDS = Rect(
+                DISPLAY_BOUNDS.left,
+                DISPLAY_BOUNDS.top,
+                DISPLAY_BOUNDS.right,
+                DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT
+        )
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt
deleted file mode 100644
index 94c064b..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt
+++ /dev/null
@@ -1,553 +0,0 @@
-package com.android.wm.shell.windowdecor
-
-import android.app.ActivityManager
-import android.app.WindowConfiguration
-import android.graphics.Rect
-import android.os.IBinder
-import android.testing.AndroidTestingRunner
-import android.view.Display
-import android.window.WindowContainerToken
-import android.window.WindowContainerTransaction
-import android.window.WindowContainerTransaction.Change.CHANGE_DRAG_RESIZING
-import androidx.test.filters.SmallTest
-import com.android.wm.shell.common.DisplayController
-import com.android.wm.shell.common.DisplayLayout
-import com.android.wm.shell.ShellTaskOrganizer
-import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.windowdecor.TaskPositioner.CTRL_TYPE_BOTTOM
-import com.android.wm.shell.windowdecor.TaskPositioner.CTRL_TYPE_RIGHT
-import com.android.wm.shell.windowdecor.TaskPositioner.CTRL_TYPE_TOP
-import com.android.wm.shell.windowdecor.TaskPositioner.CTRL_TYPE_UNDEFINED
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.`when`
-import org.mockito.Mockito.any
-import org.mockito.Mockito.argThat
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-
-/**
- * Tests for [TaskPositioner].
- *
- * Build/Install/Run:
- * atest WMShellUnitTests:TaskPositionerTest
- */
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class TaskPositionerTest : ShellTestCase() {
-
-    @Mock
-    private lateinit var mockShellTaskOrganizer: ShellTaskOrganizer
-    @Mock
-    private lateinit var mockWindowDecoration: WindowDecoration<*>
-    @Mock
-    private lateinit var mockDragStartListener: TaskPositioner.DragStartListener
-
-    @Mock
-    private lateinit var taskToken: WindowContainerToken
-    @Mock
-    private lateinit var taskBinder: IBinder
-
-    @Mock
-    private lateinit var mockDisplayController: DisplayController
-    @Mock
-    private lateinit var mockDisplayLayout: DisplayLayout
-    @Mock
-    private lateinit var mockDisplay: Display
-
-    private lateinit var taskPositioner: TaskPositioner
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        taskPositioner = TaskPositioner(
-                mockShellTaskOrganizer,
-                mockWindowDecoration,
-                mockDisplayController,
-                mockDragStartListener
-        )
-
-        `when`(taskToken.asBinder()).thenReturn(taskBinder)
-        `when`(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
-        `when`(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI)
-        `when`(mockDisplayLayout.getStableBounds(any())).thenAnswer { i ->
-            (i.arguments.first() as Rect).set(STABLE_BOUNDS)
-        }
-
-        mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply {
-            taskId = TASK_ID
-            token = taskToken
-            minWidth = MIN_WIDTH
-            minHeight = MIN_HEIGHT
-            defaultMinSize = DEFAULT_MIN
-            displayId = DISPLAY_ID
-            configuration.windowConfiguration.bounds = STARTING_BOUNDS
-        }
-        mockWindowDecoration.mDisplay = mockDisplay
-        `when`(mockDisplay.displayId).thenAnswer { DISPLAY_ID }
-    }
-
-    @Test
-    fun testDragResize_notMove_skipsTransactionOnEnd() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_TOP or CTRL_TYPE_RIGHT,
-                STARTING_BOUNDS.left.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        taskPositioner.onDragPositioningEnd(
-                STARTING_BOUNDS.left.toFloat() + 10,
-                STARTING_BOUNDS.top.toFloat() + 10
-        )
-
-        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_noEffectiveMove_skipsTransactionOnMoveAndEnd() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_TOP or CTRL_TYPE_RIGHT,
-                STARTING_BOUNDS.left.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        taskPositioner.onDragPositioningMove(
-                STARTING_BOUNDS.left.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        taskPositioner.onDragPositioningEnd(
-                STARTING_BOUNDS.left.toFloat() + 10,
-                STARTING_BOUNDS.top.toFloat() + 10
-        )
-
-        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_hasEffectiveMove_issuesTransactionOnMoveAndEnd() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_TOP or CTRL_TYPE_RIGHT,
-                STARTING_BOUNDS.left.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        taskPositioner.onDragPositioningMove(
-                STARTING_BOUNDS.left.toFloat() + 10,
-                STARTING_BOUNDS.top.toFloat()
-        )
-        val rectAfterMove = Rect(STARTING_BOUNDS)
-        rectAfterMove.right += 10
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
-                        change.configuration.windowConfiguration.bounds == rectAfterMove
-            }
-        })
-
-        taskPositioner.onDragPositioningEnd(
-                STARTING_BOUNDS.left.toFloat() + 10,
-                STARTING_BOUNDS.top.toFloat() + 10
-        )
-        val rectAfterEnd = Rect(rectAfterMove)
-        rectAfterEnd.top += 10
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
-                        change.configuration.windowConfiguration.bounds == rectAfterEnd
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_move_skipsDragResizingFlag() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_UNDEFINED, // Move
-                STARTING_BOUNDS.left.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Move the task 10px to the right.
-        val newX = STARTING_BOUNDS.left.toFloat() + 10
-        val newY = STARTING_BOUNDS.top.toFloat()
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.changeMask and CHANGE_DRAG_RESIZING) != 0) &&
-                        change.dragResizing
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_resize_setsDragResizingFlag() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT, // Resize right
-                STARTING_BOUNDS.left.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Resize the task by 10px to the right.
-        val newX = STARTING_BOUNDS.right.toFloat() + 10
-        val newY = STARTING_BOUNDS.top.toFloat()
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.changeMask and CHANGE_DRAG_RESIZING) != 0) &&
-                        change.dragResizing
-            }
-        })
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.changeMask and CHANGE_DRAG_RESIZING) != 0) &&
-                        !change.dragResizing
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_resize_setBoundsDoesNotChangeHeightWhenLessThanMin() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
-                STARTING_BOUNDS.right.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Resize to width of 95px and height of 5px with min width of 10px
-        val newX = STARTING_BOUNDS.right.toFloat() - 5
-        val newY = STARTING_BOUNDS.top.toFloat() + 95
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS)
-                                != 0) && change.configuration.windowConfiguration.bounds.top ==
-                        STARTING_BOUNDS.top &&
-                        change.configuration.windowConfiguration.bounds.bottom ==
-                        STARTING_BOUNDS.bottom
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_resize_setBoundsDoesNotChangeWidthWhenLessThanMin() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
-                STARTING_BOUNDS.right.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Resize to height of 95px and width of 5px with min width of 10px
-        val newX = STARTING_BOUNDS.right.toFloat() - 95
-        val newY = STARTING_BOUNDS.top.toFloat() + 5
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS)
-                                != 0) && change.configuration.windowConfiguration.bounds.right ==
-                        STARTING_BOUNDS.right &&
-                        change.configuration.windowConfiguration.bounds.left ==
-                        STARTING_BOUNDS.left
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_resize_setBoundsDoesNotChangeHeightWhenNegative() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
-                STARTING_BOUNDS.right.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Resize to height of -5px and width of 95px
-        val newX = STARTING_BOUNDS.right.toFloat() - 5
-        val newY = STARTING_BOUNDS.top.toFloat() + 105
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS)
-                                != 0) && change.configuration.windowConfiguration.bounds.top ==
-                        STARTING_BOUNDS.top &&
-                        change.configuration.windowConfiguration.bounds.bottom ==
-                        STARTING_BOUNDS.bottom
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_resize_setBoundsDoesNotChangeWidthWhenNegative() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
-                STARTING_BOUNDS.right.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Resize to width of -5px and height of 95px
-        val newX = STARTING_BOUNDS.right.toFloat() - 105
-        val newY = STARTING_BOUNDS.top.toFloat() + 5
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS)
-                                != 0) && change.configuration.windowConfiguration.bounds.right ==
-                        STARTING_BOUNDS.right &&
-                        change.configuration.windowConfiguration.bounds.left ==
-                        STARTING_BOUNDS.left
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_resize_setBoundsRunsWhenResizeBoundsValid() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
-                STARTING_BOUNDS.right.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Shrink to height 20px and width 20px with both min height/width equal to 10px
-        val newX = STARTING_BOUNDS.right.toFloat() - 80
-        val newY = STARTING_BOUNDS.top.toFloat() + 80
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_resize_setBoundsDoesNotRunWithNegativeHeightAndWidth() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
-                STARTING_BOUNDS.right.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Shrink to height 5px and width 5px with both min height/width equal to 10px
-        val newX = STARTING_BOUNDS.right.toFloat() - 95
-        val newY = STARTING_BOUNDS.top.toFloat() + 95
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_resize_useDefaultMinWhenMinWidthInvalid() {
-        mockWindowDecoration.mTaskInfo.minWidth = -1
-
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
-                STARTING_BOUNDS.right.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Shrink to width and height of 3px with invalid minWidth = -1 and defaultMinSize = 5px
-        val newX = STARTING_BOUNDS.right.toFloat() - 97
-        val newY = STARTING_BOUNDS.top.toFloat() + 97
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
-            }
-        })
-    }
-
-    @Test
-    fun testDragResize_resize_useMinWidthWhenValid() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
-                STARTING_BOUNDS.right.toFloat(),
-                STARTING_BOUNDS.top.toFloat()
-        )
-
-        // Shrink to width and height of 7px with valid minWidth = 10px and defaultMinSize = 5px
-        val newX = STARTING_BOUNDS.right.toFloat() - 93
-        val newY = STARTING_BOUNDS.top.toFloat() + 93
-        taskPositioner.onDragPositioningMove(
-                newX,
-                newY
-        )
-
-        taskPositioner.onDragPositioningEnd(newX, newY)
-
-        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder &&
-                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
-            }
-        })
-    }
-
-    fun testDragResize_toDisallowedBounds_freezesAtLimit() {
-        taskPositioner.onDragPositioningStart(
-                CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, // Resize right-bottom corner
-                STARTING_BOUNDS.right.toFloat(),
-                STARTING_BOUNDS.bottom.toFloat()
-        )
-
-        // Resize the task by 10px to the right and bottom, a valid destination
-        val newBounds = Rect(
-                STARTING_BOUNDS.left,
-                STARTING_BOUNDS.top,
-                STARTING_BOUNDS.right + 10,
-                STARTING_BOUNDS.bottom + 10)
-        taskPositioner.onDragPositioningMove(
-                newBounds.right.toFloat(),
-                newBounds.bottom.toFloat()
-        )
-
-        // Resize the task by another 10px to the right (allowed) and to just in the disallowed
-        // area of the Y coordinate.
-        val newBounds2 = Rect(
-                newBounds.left,
-                newBounds.top,
-                newBounds.right + 10,
-                DISALLOWED_RESIZE_AREA.top
-        )
-        taskPositioner.onDragPositioningMove(
-                newBounds2.right.toFloat(),
-                newBounds2.bottom.toFloat()
-        )
-
-        taskPositioner.onDragPositioningEnd(newBounds2.right.toFloat(), newBounds2.bottom.toFloat())
-
-        // The first resize falls in the allowed area, verify there's a change for it.
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder && change.ofBounds(newBounds)
-            }
-        })
-        // The second resize falls in the disallowed area, verify there's no change for it.
-        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder && change.ofBounds(newBounds2)
-            }
-        })
-        // Instead, there should be a change for its allowed portion (the X movement) with the Y
-        // staying frozen in the last valid resize position.
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
-            return@argThat wct.changes.any { (token, change) ->
-                token == taskBinder && change.ofBounds(
-                        Rect(
-                                newBounds2.left,
-                                newBounds2.top,
-                                newBounds2.right,
-                                newBounds.bottom // Stayed at the first resize destination.
-                        )
-                )
-            }
-        })
-    }
-
-    private fun WindowContainerTransaction.Change.ofBounds(bounds: Rect): Boolean {
-        return ((windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0) &&
-                bounds == configuration.windowConfiguration.bounds
-    }
-
-    companion object {
-        private const val TASK_ID = 5
-        private const val MIN_WIDTH = 10
-        private const val MIN_HEIGHT = 10
-        private const val DENSITY_DPI = 20
-        private const val DEFAULT_MIN = 40
-        private const val DISPLAY_ID = 1
-        private const val NAVBAR_HEIGHT = 50
-        private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
-        private val STARTING_BOUNDS = Rect(0, 0, 100, 100)
-        private val DISALLOWED_RESIZE_AREA = Rect(
-                DISPLAY_BOUNDS.left,
-                DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
-                DISPLAY_BOUNDS.right,
-                DISPLAY_BOUNDS.bottom)
-        private val STABLE_BOUNDS = Rect(
-                DISPLAY_BOUNDS.left,
-                DISPLAY_BOUNDS.top,
-                DISPLAY_BOUNDS.right,
-                DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT
-        )
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
new file mode 100644
index 0000000..498082b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor
+
+import android.app.ActivityManager
+import android.app.WindowConfiguration
+import android.graphics.Rect
+import android.os.IBinder
+import android.testing.AndroidTestingRunner
+import android.view.Display
+import android.window.WindowContainerToken
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
+import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.Mockito.any
+import org.mockito.Mockito.argThat
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+/**
+ * Tests for [VeiledResizeTaskPositioner].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:VeiledResizeTaskPositionerTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class VeiledResizeTaskPositionerTest : ShellTestCase() {
+
+    @Mock
+    private lateinit var mockShellTaskOrganizer: ShellTaskOrganizer
+    @Mock
+    private lateinit var mockDesktopWindowDecoration: DesktopModeWindowDecoration
+    @Mock
+    private lateinit var mockDragStartListener: DragPositioningCallbackUtility.DragStartListener
+
+    @Mock
+    private lateinit var taskToken: WindowContainerToken
+    @Mock
+    private lateinit var taskBinder: IBinder
+
+    @Mock
+    private lateinit var mockDisplayController: DisplayController
+    @Mock
+    private lateinit var mockDisplayLayout: DisplayLayout
+    @Mock
+    private lateinit var mockDisplay: Display
+
+    private lateinit var taskPositioner: VeiledResizeTaskPositioner
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        taskPositioner =
+            VeiledResizeTaskPositioner(
+                mockShellTaskOrganizer,
+                mockDesktopWindowDecoration,
+                mockDisplayController,
+                mockDragStartListener
+            )
+
+        whenever(taskToken.asBinder()).thenReturn(taskBinder)
+        whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
+        whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI)
+        whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { i ->
+            (i.arguments.first() as Rect).set(STABLE_BOUNDS)
+        }
+
+        mockDesktopWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply {
+            taskId = TASK_ID
+            token = taskToken
+            minWidth = MIN_WIDTH
+            minHeight = MIN_HEIGHT
+            defaultMinSize = DEFAULT_MIN
+            displayId = DISPLAY_ID
+            configuration.windowConfiguration.bounds = STARTING_BOUNDS
+        }
+        mockDesktopWindowDecoration.mDisplay = mockDisplay
+        whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID }
+    }
+
+    @Test
+    fun testDragResize_noMove_showsResizeVeil() {
+        taskPositioner.onDragPositioningStart(
+            CTRL_TYPE_TOP or CTRL_TYPE_RIGHT,
+            STARTING_BOUNDS.left.toFloat(),
+            STARTING_BOUNDS.top.toFloat()
+        )
+        verify(mockDesktopWindowDecoration).showResizeVeil()
+
+        taskPositioner.onDragPositioningEnd(
+            STARTING_BOUNDS.left.toFloat(),
+            STARTING_BOUNDS.top.toFloat()
+        )
+        verify(mockDesktopWindowDecoration).hideResizeVeil()
+    }
+
+    @Test
+    fun testDragResize_movesTask_doesNotShowResizeVeil() {
+        taskPositioner.onDragPositioningStart(
+            CTRL_TYPE_UNDEFINED,
+            STARTING_BOUNDS.left.toFloat() + 50,
+            STARTING_BOUNDS.top.toFloat()
+        )
+
+        taskPositioner.onDragPositioningMove(
+            STARTING_BOUNDS.left.toFloat() + 60,
+            STARTING_BOUNDS.top.toFloat() + 10
+        )
+        val rectAfterMove = Rect(STARTING_BOUNDS)
+        rectAfterMove.left += 10
+        rectAfterMove.right += 10
+        rectAfterMove.top += 10
+        rectAfterMove.bottom += 10
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
+                        change.configuration.windowConfiguration.bounds == rectAfterMove
+            }
+        })
+
+        taskPositioner.onDragPositioningEnd(
+            STARTING_BOUNDS.left.toFloat() + 70,
+            STARTING_BOUNDS.top.toFloat() + 20
+        )
+        val rectAfterEnd = Rect(rectAfterMove)
+        rectAfterEnd.left += 10
+        rectAfterEnd.top += 10
+        rectAfterEnd.right += 10
+        rectAfterEnd.bottom += 10
+
+        verify(mockDesktopWindowDecoration, never()).createResizeVeil()
+        verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
+                        change.configuration.windowConfiguration.bounds == rectAfterEnd
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_resize_boundsUpdateOnEnd() {
+        taskPositioner.onDragPositioningStart(
+            CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+            STARTING_BOUNDS.right.toFloat(),
+            STARTING_BOUNDS.top.toFloat()
+        )
+        verify(mockDesktopWindowDecoration).showResizeVeil()
+
+        taskPositioner.onDragPositioningMove(
+            STARTING_BOUNDS.right.toFloat() + 10,
+            STARTING_BOUNDS.top.toFloat() + 10
+        )
+
+        val rectAfterMove = Rect(STARTING_BOUNDS)
+        rectAfterMove.right += 10
+        rectAfterMove.top += 10
+        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
+                        change.configuration.windowConfiguration.bounds == rectAfterMove
+            }
+        })
+
+        taskPositioner.onDragPositioningEnd(
+            STARTING_BOUNDS.right.toFloat() + 20,
+            STARTING_BOUNDS.top.toFloat() + 20
+        )
+        val rectAfterEnd = Rect(rectAfterMove)
+        rectAfterEnd.right += 10
+        rectAfterEnd.top += 10
+        verify(mockDesktopWindowDecoration, times(2)).updateResizeVeil(any())
+        verify(mockDesktopWindowDecoration).hideResizeVeil()
+
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
+                        change.configuration.windowConfiguration.bounds == rectAfterEnd
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_noEffectiveMove_skipsTransactionOnEnd() {
+        taskPositioner.onDragPositioningStart(
+            CTRL_TYPE_TOP or CTRL_TYPE_RIGHT,
+            STARTING_BOUNDS.left.toFloat(),
+            STARTING_BOUNDS.top.toFloat()
+        )
+        verify(mockDesktopWindowDecoration).showResizeVeil()
+
+        taskPositioner.onDragPositioningMove(
+            STARTING_BOUNDS.left.toFloat(),
+            STARTING_BOUNDS.top.toFloat()
+        )
+
+        taskPositioner.onDragPositioningEnd(
+            STARTING_BOUNDS.left.toFloat() + 10,
+            STARTING_BOUNDS.top.toFloat() + 10
+        )
+        verify(mockDesktopWindowDecoration).hideResizeVeil()
+
+        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
+            }
+        })
+    }
+
+    companion object {
+        private const val TASK_ID = 5
+        private const val MIN_WIDTH = 10
+        private const val MIN_HEIGHT = 10
+        private const val DENSITY_DPI = 20
+        private const val DEFAULT_MIN = 40
+        private const val DISPLAY_ID = 1
+        private const val NAVBAR_HEIGHT = 50
+        private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
+        private val STARTING_BOUNDS = Rect(0, 0, 100, 100)
+        private val STABLE_BOUNDS = Rect(
+            DISPLAY_BOUNDS.left,
+            DISPLAY_BOUNDS.top,
+            DISPLAY_BOUNDS.right,
+            DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT
+        )
+    }
+}
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 fc4bfd97..5a2326b 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
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.windowdecor;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
 import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlBuilder;
 import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlTransaction;
 
@@ -86,6 +88,7 @@
 public class WindowDecorationTests extends ShellTestCase {
     private static final Rect TASK_BOUNDS = new Rect(100, 300, 400, 400);
     private static final Point TASK_POSITION_IN_PARENT = new Point(40, 60);
+    private static final int CORNER_RADIUS = 20;
 
     private final WindowDecoration.RelayoutResult<TestView> mRelayoutResult =
             new WindowDecoration.RelayoutResult<>();
@@ -130,6 +133,7 @@
         mCaptionMenuShadowRadiusId = R.dimen.test_caption_menu_shadow_radius;
         mCaptionMenuCornerRadiusId = R.dimen.test_caption_menu_corner_radius;
         mRelayoutParams.mShadowRadiusId = R.dimen.test_window_decor_shadow_radius;
+        mRelayoutParams.mCornerRadius = CORNER_RADIUS;
 
         doReturn(mMockSurfaceControlViewHost).when(mMockSurfaceControlViewHostFactory)
                 .create(any(), any(), any());
@@ -209,6 +213,7 @@
                 .setBounds(TASK_BOUNDS)
                 .setPositionInParent(TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y)
                 .setVisible(true)
+                .setWindowingMode(WINDOWING_MODE_FREEFORM)
                 .build();
         taskInfo.isFocused = true;
         // Density is 2. Shadow radius is 10px. Caption height is 64px.
@@ -249,6 +254,8 @@
                 .setPosition(taskSurface, TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y);
         verify(mMockSurfaceControlFinishT)
                 .setWindowCrop(taskSurface, 300, 100);
+        verify(mMockSurfaceControlStartT).setCornerRadius(taskSurface, CORNER_RADIUS);
+        verify(mMockSurfaceControlFinishT).setCornerRadius(taskSurface, CORNER_RADIUS);
         verify(mMockSurfaceControlStartT)
                 .show(taskSurface);
         verify(mMockSurfaceControlStartT)
diff --git a/libs/hwui/effects/GainmapRenderer.cpp b/libs/hwui/effects/GainmapRenderer.cpp
index bfe4eaf..613f52b 100644
--- a/libs/hwui/effects/GainmapRenderer.cpp
+++ b/libs/hwui/effects/GainmapRenderer.cpp
@@ -38,7 +38,7 @@
 
 using namespace renderthread;
 
-static float getTargetHdrSdrRatio(const SkColorSpace* destColorspace) {
+float getTargetHdrSdrRatio(const SkColorSpace* destColorspace) {
     // We should always have a known destination colorspace. If we don't we must be in some
     // legacy mode where we're lost and also definitely not going to HDR
     if (destColorspace == nullptr) {
diff --git a/libs/hwui/effects/GainmapRenderer.h b/libs/hwui/effects/GainmapRenderer.h
index 4ed2445..0ab03f0 100644
--- a/libs/hwui/effects/GainmapRenderer.h
+++ b/libs/hwui/effects/GainmapRenderer.h
@@ -25,6 +25,8 @@
 
 namespace android::uirenderer {
 
+float getTargetHdrSdrRatio(const SkColorSpace* destColorspace);
+
 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,
diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp
index c57e6f0..38d17de 100644
--- a/libs/hwui/jni/BitmapFactory.cpp
+++ b/libs/hwui/jni/BitmapFactory.cpp
@@ -401,6 +401,14 @@
         decodeColorType = kN32_SkColorType;
     }
 
+    // b/276879147, fallback to RGBA_8888 when decoding HEIF and P010 is not supported.
+    if (decodeColorType == kRGBA_1010102_SkColorType &&
+        codec->getEncodedFormat() == SkEncodedImageFormat::kHEIF &&
+        env->CallStaticBooleanMethod(gImageDecoder_class,
+                                     gImageDecoder_isP010SupportedForHEVCMethodID) == JNI_FALSE) {
+        decodeColorType = kN32_SkColorType;
+    }
+
     sk_sp<SkColorSpace> decodeColorSpace = codec->computeOutputColorSpace(
             decodeColorType, prefColorSpace);
 
diff --git a/libs/hwui/jni/BitmapFactory.h b/libs/hwui/jni/BitmapFactory.h
index 45bffc4..a079cb4 100644
--- a/libs/hwui/jni/BitmapFactory.h
+++ b/libs/hwui/jni/BitmapFactory.h
@@ -1,8 +1,9 @@
 #ifndef _ANDROID_GRAPHICS_BITMAP_FACTORY_H_
 #define _ANDROID_GRAPHICS_BITMAP_FACTORY_H_
 
+#include <SkEncodedImageFormat.h>
+
 #include "GraphicsJNI.h"
-#include "SkEncodedImageFormat.h"
 
 extern jclass gOptions_class;
 extern jfieldID gOptions_justBoundsFieldID;
@@ -26,6 +27,9 @@
 extern jclass gBitmapConfig_class;
 extern jmethodID gBitmapConfig_nativeToConfigMethodID;
 
+extern jclass gImageDecoder_class;
+extern jmethodID gImageDecoder_isP010SupportedForHEVCMethodID;
+
 jstring getMimeTypeAsJavaString(JNIEnv*, SkEncodedImageFormat);
 
 #endif  // _ANDROID_GRAPHICS_BITMAP_FACTORY_H_
diff --git a/libs/hwui/jni/ImageDecoder.cpp b/libs/hwui/jni/ImageDecoder.cpp
index db1c188..6744c6c 100644
--- a/libs/hwui/jni/ImageDecoder.cpp
+++ b/libs/hwui/jni/ImageDecoder.cpp
@@ -25,6 +25,7 @@
 #include <SkCodecAnimation.h>
 #include <SkColorSpace.h>
 #include <SkColorType.h>
+#include <SkEncodedImageFormat.h>
 #include <SkImageInfo.h>
 #include <SkRect.h>
 #include <SkSize.h>
@@ -48,7 +49,8 @@
 
 using namespace android;
 
-static jclass    gImageDecoder_class;
+jclass gImageDecoder_class;
+jmethodID gImageDecoder_isP010SupportedForHEVCMethodID;
 static jclass    gSize_class;
 static jclass    gDecodeException_class;
 static jclass    gCanvas_class;
@@ -298,6 +300,14 @@
         colorType = kN32_SkColorType;
     }
 
+    // b/276879147, fallback to RGBA_8888 when decoding HEIF and P010 is not supported.
+    if (colorType == kRGBA_1010102_SkColorType &&
+        decoder->mCodec->getEncodedFormat() == SkEncodedImageFormat::kHEIF &&
+        env->CallStaticBooleanMethod(gImageDecoder_class,
+                                     gImageDecoder_isP010SupportedForHEVCMethodID) == JNI_FALSE) {
+        colorType = kN32_SkColorType;
+    }
+
     if (!decoder->setOutColorType(colorType)) {
         doThrowISE(env, "Failed to set out color type!");
         return nullptr;
@@ -540,6 +550,8 @@
     gImageDecoder_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/ImageDecoder"));
     gImageDecoder_constructorMethodID = GetMethodIDOrDie(env, gImageDecoder_class, "<init>", "(JIIZZ)V");
     gImageDecoder_postProcessMethodID = GetMethodIDOrDie(env, gImageDecoder_class, "postProcessAndRelease", "(Landroid/graphics/Canvas;)I");
+    gImageDecoder_isP010SupportedForHEVCMethodID =
+            GetStaticMethodIDOrDie(env, gImageDecoder_class, "isP010SupportedForHEVC", "()Z");
 
     gSize_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/util/Size"));
     gSize_constructorMethodID = GetMethodIDOrDie(env, gSize_class, "<init>", "(II)V");
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index a4960ea..c58ba68 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -26,6 +26,7 @@
 #include "SkM44.h"
 #include "include/gpu/GpuTypes.h" // from Skia
 #include "utils/GLUtils.h"
+#include <effects/GainmapRenderer.h>
 
 namespace android {
 namespace uirenderer {
@@ -129,6 +130,7 @@
     info.height = fboSize.height();
     mat4.getColMajor(&info.transform[0]);
     info.color_space_ptr = canvas->imageInfo().colorSpace();
+    info.currentHdrSdrRatio = getTargetHdrSdrRatio(info.color_space_ptr);
 
     // ensure that the framebuffer that the webview will render into is bound before we clear
     // the stencil and/or draw the functor.
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index e6ef95b..e299d12 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -30,6 +30,7 @@
 #include "renderthread/VulkanManager.h"
 #include "thread/ThreadBase.h"
 #include "utils/TimeUtils.h"
+#include "effects/GainmapRenderer.h"
 
 namespace android {
 namespace uirenderer {
@@ -73,6 +74,7 @@
             .clip_right = mClip.fRight,
             .clip_bottom = mClip.fBottom,
             .is_layer = !vulkan_info.fFromSwapchainOrAndroidWindow,
+            .currentHdrSdrRatio = getTargetHdrSdrRatio(mImageInfo.colorSpace()),
     };
     mat4.getColMajor(&params.transform[0]);
     params.secondary_command_buffer = vulkan_info.fSecondaryCommandBuffer;
diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
index e168a7b..adf3c06 100644
--- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
@@ -32,6 +32,7 @@
 #include "renderthread/EglManager.h"
 #include "thread/ThreadBase.h"
 #include "utils/TimeUtils.h"
+#include "effects/GainmapRenderer.h"
 
 #include <SkBlendMode.h>
 
@@ -139,6 +140,7 @@
         info.height = mFBInfo.height();
         mat4.getColMajor(&info.transform[0]);
         info.color_space_ptr = canvas->imageInfo().colorSpace();
+        info.currentHdrSdrRatio = getTargetHdrSdrRatio(info.color_space_ptr);
 
         glViewport(0, 0, info.width, info.height);
 
diff --git a/libs/hwui/private/hwui/DrawGlInfo.h b/libs/hwui/private/hwui/DrawGlInfo.h
index 501b8df..7888c87 100644
--- a/libs/hwui/private/hwui/DrawGlInfo.h
+++ b/libs/hwui/private/hwui/DrawGlInfo.h
@@ -86,6 +86,11 @@
         // commands are issued.
         kStatusDrew = 0x4
     };
+
+    // The current HDR/SDR ratio that we are rendering to. The transform to SDR will already
+    // be baked into the color_space_ptr, so this is just to indicate the amount of extended
+    // range is available if desired
+    float currentHdrSdrRatio;
 };  // struct DrawGlInfo
 
 }  // namespace uirenderer
diff --git a/libs/hwui/private/hwui/DrawVkInfo.h b/libs/hwui/private/hwui/DrawVkInfo.h
index 5c59657..8f7063d 100644
--- a/libs/hwui/private/hwui/DrawVkInfo.h
+++ b/libs/hwui/private/hwui/DrawVkInfo.h
@@ -71,6 +71,11 @@
 
   // Input: Whether destination surface is offscreen surface.
   bool is_layer;
+
+  // The current HDR/SDR ratio that we are rendering to. The transform to SDR will already
+  // be baked into the color_space_ptr, so this is just to indicate the amount of extended
+  // range is available if desired
+  float currentHdrSdrRatio;
 };
 
 }  // namespace uirenderer
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 193544e..88b9643 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -934,13 +934,25 @@
                     }
                 }
                 levelCaps = createFromProfileLevel(mMime, profile, maxLevel);
-                // remove profile from this format otherwise levelCaps.isFormatSupported will
-                // get into this same conditon and loop forever.
-                Map<String, Object> mapWithoutProfile = new HashMap<>(map);
-                mapWithoutProfile.remove(MediaFormat.KEY_PROFILE);
-                MediaFormat formatWithoutProfile = new MediaFormat(mapWithoutProfile);
-                if (levelCaps != null && !levelCaps.isFormatSupported(formatWithoutProfile)) {
-                    return false;
+                // We must remove the profile from this format otherwise levelCaps.isFormatSupported
+                // will get into this same condition and loop forever. Furthermore, since levelCaps
+                // does not contain features and bitrate specific keys, keep only keys relevant for
+                // a level check.
+                Map<String, Object> levelCriticalFormatMap = new HashMap<>(map);
+                final Set<String> criticalKeys =
+                    isVideo() ? VideoCapabilities.VIDEO_LEVEL_CRITICAL_FORMAT_KEYS :
+                    isAudio() ? AudioCapabilities.AUDIO_LEVEL_CRITICAL_FORMAT_KEYS :
+                    null;
+
+                // critical keys will always contain KEY_MIME, but should also contain others to be
+                // meaningful
+                if (criticalKeys != null && criticalKeys.size() > 1 && levelCaps != null) {
+                    levelCriticalFormatMap.keySet().retainAll(criticalKeys);
+
+                    MediaFormat levelCriticalFormat = new MediaFormat(levelCriticalFormatMap);
+                    if (!levelCaps.isFormatSupported(levelCriticalFormat)) {
+                        return false;
+                    }
                 }
             }
             if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) {
@@ -1633,6 +1645,16 @@
             }
         }
 
+        /* package private */
+        // must not contain KEY_PROFILE
+        static final Set<String> AUDIO_LEVEL_CRITICAL_FORMAT_KEYS = Set.of(
+                // We don't set level-specific limits for audio codecs today. Key candidates would
+                // be sample rate, bit rate or channel count.
+                // MediaFormat.KEY_SAMPLE_RATE,
+                // MediaFormat.KEY_CHANNEL_COUNT,
+                // MediaFormat.KEY_BIT_RATE,
+                MediaFormat.KEY_MIME);
+
         /** @hide */
         public boolean supportsFormat(MediaFormat format) {
             Map<String, Object> map = format.getMap();
@@ -2357,6 +2379,15 @@
             return ok;
         }
 
+        /* package private */
+        // must not contain KEY_PROFILE
+        static final Set<String> VIDEO_LEVEL_CRITICAL_FORMAT_KEYS = Set.of(
+                MediaFormat.KEY_WIDTH,
+                MediaFormat.KEY_HEIGHT,
+                MediaFormat.KEY_FRAME_RATE,
+                MediaFormat.KEY_BIT_RATE,
+                MediaFormat.KEY_MIME);
+
         /**
          * @hide
          * @throws java.lang.ClassCastException */
diff --git a/media/java/android/media/projection/IMediaProjectionManager.aidl b/media/java/android/media/projection/IMediaProjectionManager.aidl
index 835e4c3..a3cd623 100644
--- a/media/java/android/media/projection/IMediaProjectionManager.aidl
+++ b/media/java/android/media/projection/IMediaProjectionManager.aidl
@@ -20,11 +20,23 @@
 import android.media.projection.IMediaProjectionCallback;
 import android.media.projection.IMediaProjectionWatcherCallback;
 import android.media.projection.MediaProjectionInfo;
+import android.media.projection.ReviewGrantedConsentResult;
 import android.os.IBinder;
 import android.view.ContentRecordingSession;
 
 /** {@hide} */
 interface IMediaProjectionManager {
+    /**
+     * Intent extra indicating if user must review access to the consent token already granted.
+     */
+    const String EXTRA_USER_REVIEW_GRANTED_CONSENT = "extra_media_projection_user_consent_required";
+
+    /**
+     * Intent extra indicating the package attempting to re-use granted consent.
+     */
+    const String EXTRA_PACKAGE_REUSING_GRANTED_CONSENT =
+            "extra_media_projection_package_reusing_consent";
+
     @UnsupportedAppUsage
     boolean hasProjectionPermission(int uid, String packageName);
 
@@ -37,6 +49,21 @@
             boolean permanentGrant);
 
     /**
+     * Returns the current {@link IMediaProjection} instance associated with the given
+     * package, or {@code null} if it is not possible to re-use the current projection.
+     *
+     * <p>Should only be invoked when the user has reviewed consent for a re-used projection token.
+     * Requires that there is a prior session waiting for the user to review consent, and the given
+     * package details match those on the current projection.
+     *
+     * @see {@link #isCurrentProjection}
+     */
+    @EnforcePermission("android.Manifest.permission.MANAGE_MEDIA_PROJECTION")
+    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+            + ".permission.MANAGE_MEDIA_PROJECTION)")
+    IMediaProjection getProjection(int uid, String packageName);
+
+    /**
      * Returns {@code true} if the given {@link IMediaProjection} corresponds to the current
      * projection, or {@code false} otherwise.
      */
@@ -58,7 +85,7 @@
      */
     @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
             + ".permission.MANAGE_MEDIA_PROJECTION)")
-    void requestConsentForInvalidProjection(IMediaProjection projection);
+    void requestConsentForInvalidProjection(in IMediaProjection projection);
 
     @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
             + ".permission.MANAGE_MEDIA_PROJECTION)")
@@ -94,9 +121,32 @@
      *
      * @param incomingSession the nullable incoming content recording session
      * @param projection      the non-null projection the session describes
+     * @throws SecurityException If the provided projection is not current.
      */
   @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
             + ".permission.MANAGE_MEDIA_PROJECTION)")
     boolean setContentRecordingSession(in ContentRecordingSession incomingSession,
             in IMediaProjection projection);
+
+    /**
+     * Sets the result of the user reviewing the recording permission, when the host app is re-using
+     * the consent token.
+     *
+     * <p>Ignores the provided result if the given projection is not the current projection.
+     *
+     * <p>Based on the given result:
+     * <ul>
+     *   <li>If UNKNOWN or RECORD_CANCEL, then tear down the recording.</li>
+     *   <li>If RECORD_CONTENT_DISPLAY, then record the default display.</li>
+     *   <li>If RECORD_CONTENT_TASK, record the task indicated by
+     *     {@link IMediaProjection#getLaunchCookie}.</li>
+     * </ul>
+     * @param projection The projection associated with the consent result. Must be the current
+     * projection instance, unless the given result is RECORD_CANCEL.
+     */
+    @EnforcePermission("android.Manifest.permission.MANAGE_MEDIA_PROJECTION")
+    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+            + ".permission.MANAGE_MEDIA_PROJECTION)")
+    void setUserReviewGrantedConsentResult(ReviewGrantedConsentResult consentResult,
+            in @nullable IMediaProjection projection);
 }
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java b/media/java/android/media/projection/ReviewGrantedConsentResult.aidl
similarity index 61%
copy from services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java
copy to media/java/android/media/projection/ReviewGrantedConsentResult.aidl
index 7c339d2..4f25be7 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java
+++ b/media/java/android/media/projection/ReviewGrantedConsentResult.aidl
@@ -14,14 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.server.companion.datatransfer.contextsync;
+package android.media.projection;
 
-/** Callback for call metadata syncing. */
-public abstract class CallMetadataSyncCallback {
+/**
+ * Indicates result of user interacting with consent dialog, when their review is required due to
+ * app re-using the token.
 
-    abstract void processCallControlAction(int crossDeviceCallId, int callControlAction);
-
-    abstract void requestCrossDeviceSync(int userId);
-
-    abstract void updateStatus(int userId, boolean shouldSyncCallMetadata);
+ * @hide
+ */
+@Backing(type="int")
+enum ReviewGrantedConsentResult {
+    UNKNOWN = -1,
+    RECORD_CANCEL = 0,
+    RECORD_CONTENT_DISPLAY = 1,
+    RECORD_CONTENT_TASK = 2,
 }
diff --git a/media/java/android/media/soundtrigger/SoundTriggerInstrumentation.java b/media/java/android/media/soundtrigger/SoundTriggerInstrumentation.java
index 80bc5c0..3dfc587 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerInstrumentation.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerInstrumentation.java
@@ -231,9 +231,17 @@
          */
         public void setModelCallback(@NonNull @CallbackExecutor Executor executor, @NonNull
                 ModelCallback callback) {
+            Objects.requireNonNull(callback);
+            Objects.requireNonNull(executor);
             synchronized (SoundTriggerInstrumentation.this.mLock) {
-                mModelCallback = Objects.requireNonNull(callback);
-                mModelExecutor = Objects.requireNonNull(executor);
+                if (mModelCallback == null) {
+                    for (var droppedConsumer : mDroppedConsumerList) {
+                        executor.execute(() -> droppedConsumer.accept(callback));
+                    }
+                    mDroppedConsumerList.clear();
+                }
+                mModelCallback = callback;
+                mModelExecutor = executor;
             }
         }
 
@@ -267,9 +275,11 @@
 
         private void wrap(Consumer<ModelCallback> consumer) {
             synchronized (SoundTriggerInstrumentation.this.mLock) {
-                if (mModelCallback != null && mModelExecutor != null) {
+                if (mModelCallback != null) {
                     final ModelCallback callback = mModelCallback;
                     mModelExecutor.execute(() -> consumer.accept(callback));
+                } else {
+                    mDroppedConsumerList.add(consumer);
                 }
             }
         }
@@ -282,6 +292,8 @@
         private ModelCallback mModelCallback = null;
         @GuardedBy("SoundTriggerInstrumentation.this.mLock")
         private Executor mModelExecutor = null;
+        @GuardedBy("SoundTriggerInstrumentation.this.mLock")
+        private final List<Consumer<ModelCallback>> mDroppedConsumerList = new ArrayList<>();
     }
 
     /**
@@ -374,9 +386,18 @@
          */
         public void setRecognitionCallback(@NonNull @CallbackExecutor Executor executor,
                 @NonNull RecognitionCallback callback) {
+            Objects.requireNonNull(callback);
+            Objects.requireNonNull(executor);
             synchronized (SoundTriggerInstrumentation.this.mLock) {
+                if (mRecognitionCallback == null) {
+                    for (var droppedConsumer : mDroppedConsumerList) {
+                        executor.execute(() -> droppedConsumer.accept(callback));
+                    }
+                    mDroppedConsumerList.clear();
+                }
                 mRecognitionCallback = callback;
                 mRecognitionExecutor = executor;
+
             }
         }
 
@@ -401,9 +422,11 @@
 
         private void wrap(Consumer<RecognitionCallback> consumer) {
             synchronized (SoundTriggerInstrumentation.this.mLock) {
-                if (mRecognitionCallback != null && mRecognitionExecutor != null) {
+                if (mRecognitionCallback != null) {
                     final RecognitionCallback callback = mRecognitionCallback;
                     mRecognitionExecutor.execute(() -> consumer.accept(callback));
+                } else {
+                    mDroppedConsumerList.add(consumer);
                 }
             }
         }
@@ -416,6 +439,8 @@
         private Executor mRecognitionExecutor = null;
         @GuardedBy("SoundTriggerInstrumentation.this.mLock")
         private RecognitionCallback mRecognitionCallback = null;
+        @GuardedBy("SoundTriggerInstrumentation.this.mLock")
+        private final List<Consumer<RecognitionCallback>> mDroppedConsumerList = new ArrayList<>();
     }
 
     // Implementation of injection interface passed to the HAL.
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
index b6d70af..78352871 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerManager.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java
@@ -54,7 +54,6 @@
 
 import com.android.internal.app.ISoundTriggerService;
 import com.android.internal.app.ISoundTriggerSession;
-import com.android.internal.util.Preconditions;
 
 import java.util.HashMap;
 import java.util.List;
@@ -67,6 +66,8 @@
  * models. Usage of this class is restricted to system or signature applications only. This allows
  * OEMs to write apps that can manage non-voice based sound trigger models.
  *
+ * If no ST module is available, {@link getModuleProperties()} will return {@code null}, and all
+ * other methods will throw {@link IllegalStateException}.
  * @hide
  */
 @SystemApi
@@ -82,7 +83,7 @@
 
     // Stores a mapping from the sound model UUID to the SoundTriggerInstance created by
     // the createSoundTriggerDetector() call.
-    private final HashMap<UUID, SoundTriggerDetector> mReceiverInstanceMap;
+    private final HashMap<UUID, SoundTriggerDetector> mReceiverInstanceMap = new HashMap<>();
 
     /**
      * @hide
@@ -121,7 +122,6 @@
         }
         mContext = context;
         mSoundTriggerService = soundTriggerService;
-        mReceiverInstanceMap = new HashMap<UUID, SoundTriggerDetector>();
     }
 
     /**
@@ -160,7 +160,7 @@
                 .findFirst()
                 .orElse(null);
         if (moduleProps == null) {
-            throw new IllegalStateException("Fake ST HAL should always be available");
+            throw new AssertionError("Fake ST HAL should always be available");
         }
         return moduleProps;
     }
@@ -183,7 +183,6 @@
         }
         mContext = Objects.requireNonNull(context);
         mSoundTriggerService = Objects.requireNonNull(soundTriggerService);
-        mReceiverInstanceMap = new HashMap<UUID, SoundTriggerDetector>();
     }
 
     /**
@@ -241,7 +240,8 @@
         }
         try {
             GenericSoundModel model =
-                    mSoundTriggerSession.getSoundModel(new ParcelUuid(soundModelId));
+                    mSoundTriggerSession.getSoundModel(
+                            new ParcelUuid(Objects.requireNonNull(soundModelId)));
             if (model == null) {
                 return null;
             }
@@ -265,7 +265,8 @@
         }
 
         try {
-            mSoundTriggerSession.deleteSoundModel(new ParcelUuid(soundModelId));
+            mSoundTriggerSession.deleteSoundModel(
+                    new ParcelUuid(Objects.requireNonNull(soundModelId)));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -291,8 +292,8 @@
     @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
     public SoundTriggerDetector createSoundTriggerDetector(UUID soundModelId,
             @NonNull SoundTriggerDetector.Callback callback, @Nullable Handler handler) {
-        if (soundModelId == null || mSoundTriggerSession == null) {
-            return null;
+        if (mSoundTriggerSession == null) {
+            throw new IllegalStateException("No underlying SoundTriggerModule available");
         }
 
         SoundTriggerDetector oldInstance = mReceiverInstanceMap.get(soundModelId);
@@ -301,7 +302,8 @@
         }
         try {
             SoundTriggerDetector newInstance = new SoundTriggerDetector(mSoundTriggerSession,
-                    mSoundTriggerSession.getSoundModel(new ParcelUuid(soundModelId)),
+                    mSoundTriggerSession.getSoundModel(
+                        new ParcelUuid(Objects.requireNonNull(soundModelId))),
                     callback, handler);
             mReceiverInstanceMap.put(soundModelId, newInstance);
             return newInstance;
@@ -469,8 +471,8 @@
     @UnsupportedAppUsage
     @TestApi
     public int loadSoundModel(@NonNull SoundModel soundModel) {
-        if (soundModel == null || mSoundTriggerSession == null) {
-            return STATUS_ERROR;
+        if (mSoundTriggerSession == null) {
+            throw new IllegalStateException("No underlying SoundTriggerModule available");
         }
 
         try {
@@ -513,11 +515,11 @@
     @UnsupportedAppUsage
     public int startRecognition(@NonNull UUID soundModelId, @Nullable Bundle params,
         @NonNull ComponentName detectionService, @NonNull RecognitionConfig config) {
-        Preconditions.checkNotNull(soundModelId);
-        Preconditions.checkNotNull(detectionService);
-        Preconditions.checkNotNull(config);
+        Objects.requireNonNull(soundModelId);
+        Objects.requireNonNull(detectionService);
+        Objects.requireNonNull(config);
         if (mSoundTriggerSession == null) {
-            return STATUS_ERROR;
+            throw new IllegalStateException("No underlying SoundTriggerModule available");
         }
         try {
             return mSoundTriggerSession.startRecognitionForService(new ParcelUuid(soundModelId),
@@ -534,11 +536,12 @@
     @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public int stopRecognition(UUID soundModelId) {
-        if (soundModelId == null || mSoundTriggerSession == null) {
-            return STATUS_ERROR;
+        if (mSoundTriggerSession == null) {
+            throw new IllegalStateException("No underlying SoundTriggerModule available");
         }
         try {
-            return mSoundTriggerSession.stopRecognitionForService(new ParcelUuid(soundModelId));
+            return mSoundTriggerSession.stopRecognitionForService(
+                    new ParcelUuid(Objects.requireNonNull(soundModelId)));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -551,12 +554,12 @@
     @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public int unloadSoundModel(UUID soundModelId) {
-        if (soundModelId == null || mSoundTriggerSession == null) {
-            return STATUS_ERROR;
+        if (mSoundTriggerSession == null) {
+            throw new IllegalStateException("No underlying SoundTriggerModule available");
         }
         try {
             return mSoundTriggerSession.unloadSoundModel(
-                    new ParcelUuid(soundModelId));
+                    new ParcelUuid(Objects.requireNonNull(soundModelId)));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -604,7 +607,10 @@
     @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
     @UnsupportedAppUsage
     public int getModelState(UUID soundModelId) {
-        if (soundModelId == null || mSoundTriggerSession == null) {
+        if (mSoundTriggerSession == null) {
+            throw new IllegalStateException("No underlying SoundTriggerModule available");
+        }
+        if (soundModelId == null) {
             return STATUS_ERROR;
         }
         try {
@@ -652,11 +658,12 @@
     public int setParameter(@Nullable UUID soundModelId,
             @ModelParams int modelParam, int value) {
         if (mSoundTriggerSession == null) {
-            return SoundTrigger.STATUS_INVALID_OPERATION;
+            throw new IllegalStateException("No underlying SoundTriggerModule available");
         }
 
         try {
-            return mSoundTriggerSession.setParameter(new ParcelUuid(soundModelId), modelParam,
+            return mSoundTriggerSession.setParameter(
+                    new ParcelUuid(Objects.requireNonNull(soundModelId)), modelParam,
                     value);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -679,11 +686,11 @@
     public int getParameter(@NonNull UUID soundModelId,
             @ModelParams int modelParam) {
         if (mSoundTriggerSession == null) {
-            throw new IllegalArgumentException("Sound model is not loaded: "
-                            + soundModelId.toString());
+            throw new IllegalStateException("No underlying SoundTriggerModule available");
         }
         try {
-            return mSoundTriggerSession.getParameter(new ParcelUuid(soundModelId), modelParam);
+            return mSoundTriggerSession.getParameter(
+                    new ParcelUuid(Objects.requireNonNull(soundModelId)), modelParam);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -703,10 +710,11 @@
     public ModelParamRange queryParameter(@Nullable UUID soundModelId,
             @ModelParams int modelParam) {
         if (mSoundTriggerSession == null) {
-            return null;
+            throw new IllegalStateException("No underlying SoundTriggerModule available");
         }
         try {
-            return mSoundTriggerSession.queryParameter(new ParcelUuid(soundModelId), modelParam);
+            return mSoundTriggerSession.queryParameter(
+                    new ParcelUuid(Objects.requireNonNull(soundModelId)), modelParam);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/media/java/android/media/soundtrigger/TEST_MAPPING b/media/java/android/media/soundtrigger/TEST_MAPPING
new file mode 100644
index 0000000..3d73795
--- /dev/null
+++ b/media/java/android/media/soundtrigger/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsSoundTriggerTestCases"
+    }
+  ]
+}
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 80a3e70..d749b91 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -223,7 +223,8 @@
                 break;
             }
             case DO_TIME_SHIFT_SET_MODE: {
-                mTvInputSessionImpl.timeShiftSetMode((Integer) msg.obj);
+                mTvInputSessionImpl.timeShiftSetMode(msg.arg1);
+                break;
             }
             case DO_TIME_SHIFT_ENABLE_POSITION_TRACKING: {
                 mTvInputSessionImpl.timeShiftEnablePositionTracking((Boolean) msg.obj);
diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java
index 9a995a0..a396b7e 100644
--- a/media/java/android/media/tv/TvRecordingClient.java
+++ b/media/java/android/media/tv/TvRecordingClient.java
@@ -396,6 +396,12 @@
         }
     }
 
+    // For testing purposes only.
+    /** @hide */
+    public TvInputManager.SessionCallback getSessionCallback() {
+        return mSessionCallback;
+    }
+
     /**
      * Callback used to receive various status updates on the
      * {@link android.media.tv.TvInputService.RecordingSession}
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 9552200..44aff64 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -385,6 +385,10 @@
 
     process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
 
+    if (env->ExceptionCheck()) {
+        return UNKNOWN_ERROR;
+    }
+
     // update the piid
     Parcel *request = parcelForJavaObject(env, piidParcel);
     auto reply = std::make_unique<Parcel>();
@@ -407,6 +411,10 @@
 
     process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
 
+    if (env->ExceptionCheck()) {
+        return UNKNOWN_ERROR;
+    }
+
     // update the piid
     Parcel *request = parcelForJavaObject(env, piidParcel);
     auto reply = std::make_unique<Parcel>();
diff --git a/packages/BackupRestoreConfirmation/res/values-zh-rHK/strings.xml b/packages/BackupRestoreConfirmation/res/values-zh-rHK/strings.xml
index d3bcd6e..f25c9af 100644
--- a/packages/BackupRestoreConfirmation/res/values-zh-rHK/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zh-rHK/strings.xml
@@ -18,17 +18,17 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"完整備份"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"完整還原"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"系統收到將所有資料完整備份到連線桌上電腦的要求,請問您允許進行備份嗎?\n\n如果您本人並未提出備份要求,請勿允許繼續進行這項作業。"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"系統收到將所有資料完整備份到連線桌上電腦的要求,請問你允許進行備份嗎?\n\n如果你本人並未提出備份要求,請勿允許繼續進行這項作業。"</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"備份我的資料"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"不要備份"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"系統收到從連線的桌上電腦完整還原所有資料的要求,請問您允許進行還原嗎?\n\n如果您本人並未提出還原要求,請勿允許繼續進行這項作業。這項作業將取代裝置上現有的全部資料!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"系統收到從連線的桌上電腦完整還原所有資料的要求,請問你允許進行還原嗎?\n\n如果你本人並未提出還原要求,請勿允許繼續進行這項作業。這項作業將取代裝置上現有的全部資料!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"還原我的資料"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"不要還原"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"在下面輸入您目前的備份密碼:"</string>
-    <string name="device_encryption_restore_text" msgid="1570864916855208992">"請在下面輸入您的裝置加密密碼。"</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"請在下面輸入您的裝置加密密碼,這也會用來將封存備份加密。"</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"請輸入為完整備份資料加密的專用密碼。如果留空,系統將使用您目前的備份密碼:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"如果您想將完整的備份資料加密,請在下面輸入一組密碼:"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"在下面輸入你目前的備份密碼:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"請在下面輸入你的裝置加密密碼。"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"請在下面輸入你的裝置加密密碼,這也會用來將封存備份加密。"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"請輸入為完整備份資料加密的專用密碼。如果留空,系統將使用你目前的備份密碼:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"如果你想將完整的備份資料加密,請在下面輸入一組密碼:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"如果還原的資料經過加密處理,請在下面輸入密碼:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"正在開始備份..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"備份完畢"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
index 0578256..f2f91fd 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
@@ -4,14 +4,14 @@
     <string name="app_name" msgid="2809080280462257271">"流動網絡供應商通訊"</string>
     <string name="android_system_label" msgid="2797790869522345065">"流動網絡供應商"</string>
     <string name="portal_notification_id" msgid="5155057562457079297">"流動數據量已用盡"</string>
-    <string name="no_data_notification_id" msgid="668400731803969521">"您的流動數據已停用"</string>
+    <string name="no_data_notification_id" msgid="668400731803969521">"你的流動數據已停用"</string>
     <string name="portal_notification_detail" msgid="2295729385924660881">"輕按即可瀏覽 %s 網站"</string>
-    <string name="no_data_notification_detail" msgid="3112125343857014825">"請與您的服務供應商 (%s) 聯絡"</string>
+    <string name="no_data_notification_detail" msgid="3112125343857014825">"請與你的服務供應商 (%s) 聯絡"</string>
     <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"沒有流動數據連線"</string>
     <string name="no_mobile_data_connection" msgid="544980465184147010">"透過「%s」新增數據或漫遊計劃"</string>
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"流動數據狀態"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"登入流動網絡"</string>
-    <string name="ssl_error_warning" msgid="3127935140338254180">"您正在嘗試加入的網絡有安全性問題。"</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"你正在嘗試加入的網絡有安全性問題。"</string>
     <string name="ssl_error_example" msgid="6188711843183058764">"例如,登入頁面可能並不屬於所顯示的機構。"</string>
     <string name="ssl_error_continue" msgid="1138548463994095584">"仍要透過瀏覽器繼續操作"</string>
     <string name="performance_boost_notification_channel" msgid="3475440855635538592">"效能提升服務"</string>
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
index 6bfcd82..8c35da1 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
@@ -58,6 +58,7 @@
             android:textSize="14sp"
             android:layout_marginTop="2dp"
             style="@style/TextAppearance"
+            android:focusable="true"
             android:textColor="?android:attr/textColorSecondary"/>
 
     </LinearLayout>
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 7a5b564..fc0807b 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Gee programme op &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dieselfde toestemmings as op &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Dit kan &lt;strong&gt;Mikrofoon-&lt;/strong&gt;, &lt;strong&gt;Kamera-&lt;/strong&gt;, &lt;strong&gt;Liggingtoegang-&lt;/strong&gt; en ander sensitiewe toestemmings op &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; insluit. &lt;br/&gt;&lt;br/&gt;Jy kan hierdie toestemmings enige tyd in jou Instellings op &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; verander."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Program-ikoon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Meer Inligting-knoppie"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Foon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakte"</string>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index 09a4de1..90bc531 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string>
     <string name="consent_no" msgid="2640796915611404382">"አትፍቀድ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ተመለስ"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"በ&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ላይ ላሉ መተግበሪያዎች በ&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ላይ ካሉት ጋር ተመሳሳይ ፈቃዶች ይሰጣቸው?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"ይህ &lt;strong&gt;ማይክሮፎን&lt;/strong&gt;፣ &lt;strong&gt;ካሜራ&lt;/strong&gt; እና &lt;strong&gt;የአካባቢ መዳረሻ&lt;/strong&gt; እና ሌሎች አደገኛ ፈቃዶችን &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; ላይ ሊያካትት ይችላል። &lt;br/&gt;&lt;br/&gt;እነዚህን ቅንብሮች በማንኛውም ጊዜ ቅንብሮችዎ ውስጥ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; ላይ መቀየር ይችላሉ።"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"የመተግበሪያ አዶ"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"የተጨማሪ መረጃ አዝራር"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ስልክ"</string>
     <string name="permission_sms" msgid="6337141296535774786">"ኤስኤምኤስ"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"ዕውቂያዎች"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index 5a854e2..5a33b96 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"السماح"</string>
     <string name="consent_no" msgid="2640796915611404382">"عدم السماح"</string>
     <string name="consent_back" msgid="2560683030046918882">"رجوع"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‏هل تريد منح التطبيقات على &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; نفس الأذونات على &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;؟"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"‏قد يتضمّن هذا الوصول إلى &lt;strong&gt;الميكروفون&lt;/strong&gt; و&lt;strong&gt;الكاميرا&lt;/strong&gt; و&lt;strong&gt;الموقع الجغرافي&lt;/strong&gt; وأذونات الوصول إلى المعلومات الحساسة الأخرى في &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;يمكنك تغيير هذه الأذونات في أي وقت في إعداداتك على &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"رمز التطبيق"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"زر مزيد من المعلومات"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"الهاتف"</string>
     <string name="permission_sms" msgid="6337141296535774786">"الرسائل القصيرة"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"جهات الاتصال"</string>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index 4c08891..991a8a3 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিয়ক"</string>
     <string name="consent_no" msgid="2640796915611404382">"অনুমতি নিদিব"</string>
     <string name="consent_back" msgid="2560683030046918882">"উভতি যাওক"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"এপ্‌সমূহক &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ত দিয়াৰ দৰে &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;তো একে অনুমতি প্ৰদান কৰিবনে?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"এইটোত &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;ৰ &lt;strong&gt;মাইক্ৰ’ফ’ন&lt;/strong&gt;, &lt;strong&gt;কেমেৰা&lt;/strong&gt;, আৰু &lt;strong&gt;অৱস্থানৰ এক্সেছ&lt;/strong&gt;, আৰু অন্য সংবেদনশীল অনুমতিসমূহ অন্তৰ্ভুক্ত হ’ব পাৰে। &lt;br/&gt;&lt;br/&gt;আপুনি যিকোনো সময়তে &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;ত থকা আপোনাৰ ছেটিঙত এই অনুমতিসমূহ সলনি কৰিব পাৰে।"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"এপৰ চিহ্ন"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"অধিক তথ্যৰ বুটাম"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ফ’ন"</string>
     <string name="permission_sms" msgid="6337141296535774786">"এছএমএছ"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"সম্পৰ্ক"</string>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index 56fad60..6ab0d16 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazındakı tətbiqlərə &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazındakılarla eyni icazələr verilsin?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Buraya &lt;strong&gt;Mikrofon&lt;/strong&gt;, &lt;strong&gt;Kamera&lt;/strong&gt; və &lt;strong&gt;Məkana giriş&lt;/strong&gt;, eləcə də &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; cihazında digər həssas icazələr daxil ola bilər. Bu icazələri istənilən vaxt &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; cihazında ayarlarınızda dəyişə bilərsiniz.&lt;/p&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Tətbiq İkonası"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Ətraflı Məlumat Düyməsi"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakt"</string>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 457abf9..5e45714 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Aplikcijama na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dajete sve dozvole kao na uređaju &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"To može da obuhvata pristup &lt;strong&gt;mikrofonu&lt;/strong&gt;, &lt;strong&gt;kameri&lt;/strong&gt;, i &lt;strong&gt;lokaciji&lt;/strong&gt;, i druge osetljive dozvole na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Možete da promenite te dozvole u bilo kom trenutku u Podešavanjima na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Dugme za više informacija"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 335ec44..3af0171 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дазваляць"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Даць праграмам на прыладзе &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; такія самыя дазволы, што і на прыладзе &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Праграмы змогуць атрымліваць доступ да &lt;strong&gt;мікрафона&lt;/strong&gt;, &lt;strong&gt;камеры&lt;/strong&gt; і &lt;strong&gt;даных пра месцазнаходжанне&lt;/strong&gt;, а таксама да іншай канфідэнцыяльнай інфармацыі на прыладзе &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Вы можаце ў любы час змяніць гэтыя дазволы ў Наладах на прыладзе &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Значок праграмы"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Кнопка \"Даведацца больш\""</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Тэлефон"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Кантакты"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index ae26942..48c9aef 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string>
     <string name="consent_no" msgid="2640796915611404382">"Забраняване"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Искате ли да дадете на приложенията на &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; същите разрешения както на &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Това може да включва достъп до &lt;strong&gt;микрофона&lt;/strong&gt;, &lt;strong&gt;камерата&lt;/strong&gt; и &lt;strong&gt;местоположението&lt;/strong&gt;, както и други разрешения за достъп до поверителна информация на &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Имате възможност да промените тези разрешения по всяко време от настройките на &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Икона на приложението"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Бутон за още информация"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Телефон"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Контакти"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 259a860..10eda0e 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string>
     <string name="consent_no" msgid="2640796915611404382">"অনুমতি দেবেন না"</string>
     <string name="consent_back" msgid="2560683030046918882">"ফিরুন"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-এ যে অনুমতি দেওয়া আছে &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-এও সেই একই অনুমতি দিতে চান?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"এর মধ্যে &lt;strong&gt;মাইক্রোফোন&lt;/strong&gt;, &lt;strong&gt;ক্যামেরা&lt;/strong&gt;, ও &lt;strong&gt;লোকেশন সংক্রান্ত অ্যাক্সেস &lt;/strong&gt;, এবং &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;.-এর অন্যান্য সংবেদনশীল অনুমতি অন্তর্ভুক্ত থাকতে পারে &lt;br/&gt;&lt;br/&gt;আপনি যেকোনও সময়&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;.-এর সেটিংস থেকে এইসব অনুমতি পরিবর্তন করতে পারবেন"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"অ্যাপের আইকন"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"আরও তথ্য সংক্রান্ত বোতাম"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ফোন"</string>
     <string name="permission_sms" msgid="6337141296535774786">"এসএমএস"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"পরিচিতি"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 1b6970d..0901d2a 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dati aplikacijama na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ista odobrenja kao na uređaju &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Ovo može uključivati odobrenja za pristup &lt;strong&gt;mikrofonu&lt;/strong&gt;, &lt;strong&gt;kameri&lt;/strong&gt; i &lt;strong&gt;lokaciji&lt;/strong&gt; te druga osjetljiva odobrenja na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Ova odobrenja možete bilo kada promijeniti u Postavkama na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Dugme Više informacija"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 6b9238f..85787ee 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vols concedir a les aplicacions del dispositiu &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; els mateixos permisos que tenen a &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Això pot incloure l\'accés al &lt;strong&gt;micròfon&lt;/strong&gt;, a la &lt;strong&gt;càmera&lt;/strong&gt; i a la &lt;strong&gt;ubicació&lt;/strong&gt;, així com altres permisos sensibles a &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Pots canviar aquestes permisos en qualsevol moment a Configuració, a &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Icona de l\'aplicació"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Botó Més informació"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telèfon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contactes"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index beb6060..c38ffaf 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Udělit aplikacím v zařízení &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; stejné oprávnění, jako mají v zařízení &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"To může zahrnovat oprávnění &lt;strong&gt;Mikrofon&lt;/strong&gt;, &lt;strong&gt;Fotoparát&lt;/strong&gt; a &lt;strong&gt;Přístup k poloze&lt;/strong&gt; a další citlivá oprávnění na zařízení &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Tato oprávnění můžete kdykoli změnit v Nastavení na zařízení &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikace"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Tlačítko Další informace"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakty"</string>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 40c93bd..36da3e3 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vil du give apps på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; de samme tilladelser som på &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Dette kan omfatte &lt;strong&gt;mikrofon-&lt;/strong&gt;, &lt;strong&gt;kamera-&lt;/strong&gt; og &lt;strong&gt;lokationsadgang&lt;/strong&gt; samt andre tilladelser til at tilgå følsomme oplysninger på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Du kan til enhver tid ændre disse tilladelser under Indstillinger på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Appikon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Knappen Flere oplysninger"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"Sms"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakter"</string>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 99cf792..0b13546 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -20,8 +20,7 @@
     <string name="confirmation_title" msgid="4593465730772390351">"Zulassen, dass &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; auf das Gerät &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; zugreifen darf?"</string>
     <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>
-    <!-- no translation found for summary_watch (898569637110705523) -->
-    <skip />
+    <string name="summary_watch" msgid="898569637110705523">"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 dann Daten wie den Namen eines Anrufers synchronisieren, mit deinen Benachrichtigungen interagieren und auf die Berechtigungen „Telefon“, „SMS“, „Kontakte“, „Kalender“, „Anruflisten“ und „Geräte in der Nähe“ zugreifen."</string>
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Diese App darf dann Daten wie den Namen eines Anrufers synchronisieren und auf folgende Berechtigungen auf deinem <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> zugreifen"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Zulassen, dass &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; das Gerät &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; verwalten darf"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"Glass-Geräte"</string>
@@ -39,17 +38,23 @@
     <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Darf das Gerät &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; diese Aktion ausführen?"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein Gerät (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) um die Berechtigung, Apps und andere Systemfunktionen auf Geräte in der Nähe zu streamen"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
-    <!-- no translation found for summary_generic_single_device (4181180669689590417) -->
-    <skip />
-    <!-- no translation found for summary_generic (1761976003668044801) -->
-    <skip />
+    <string name="summary_generic_single_device" msgid="4181180669689590417">"Diese App kann dann Daten wie den Namen eines Anrufers zwischen deinem Smartphone und deinem Gerät (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) synchronisieren"</string>
+    <string name="summary_generic" msgid="1761976003668044801">"Diese App kann dann Daten wie den Namen eines Anrufers zwischen deinem Smartphone und dem ausgewählten Gerät synchronisieren"</string>
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Apps auf &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; die gleichen Berechtigungen geben wie auf &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Dazu können &lt;strong&gt;Mikrofon&lt;/strong&gt;, &lt;strong&gt;Kamera&lt;/strong&gt; und &lt;strong&gt;Standortzugriff&lt;/strong&gt; sowie weitere vertrauliche Berechtigungen auf &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; gehören. &lt;br/&gt;&lt;br/&gt;Du kannst diese Berechtigungen jederzeit in den Einstellungen von &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; ändern."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"App-Symbol"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Weitere-Infos-Schaltfläche"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakte"</string>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 137ea73..63a7248 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string>
     <string name="consent_no" msgid="2640796915611404382">"Να μην επιτρέπεται"</string>
     <string name="consent_back" msgid="2560683030046918882">"Πίσω"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Παραχώρηση των ίδιων αδειών στις εφαρμογές στη συσκευή &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; όπως στη συσκευή &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;;"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Μπορεί να περιλαμβάνει την πρόσβαση στο &lt;strong&gt;Μικρόφωνο&lt;/strong&gt;, την &lt;strong&gt;Κάμερα&lt;/strong&gt;, και την &lt;strong&gt;Τοποθεσία&lt;/strong&gt;, καθώς και άλλες άδειες πρόσβασης σε ευαίσθητες πληροφορίες στη συσκευή &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Μπορείτε να αλλάξετε αυτές τις άδειες ανά πάσα στιγμή από τις Ρυθμίσεις της συσκευής &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Εικονίδιο εφαρμογής"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Κουμπί περισσότερων πληροφορ."</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Τηλέφωνο"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Επαφές"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index 3a3ef18..00a3ccb 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Give apps on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the same permissions as on &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"This may include &lt;strong&gt;Microphone&lt;/strong&gt;, &lt;strong&gt;Camera&lt;/strong&gt;, and &lt;strong&gt;Location access&lt;/strong&gt;, and other sensitive permissions on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;You can change these permissions any time in your Settings on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"App icon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"More information button"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Phone"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index 4afe1a8..0caa453 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -43,10 +43,14 @@
     <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>
+    <string name="permission_expanded" msgid="5234121789170200621">"Expanded"</string>
+    <string name="permission_expand" msgid="1464954219517793480">"Expand"</string>
+    <string name="permission_collapsed" msgid="3193316780088731226">"Collapsed"</string>
+    <string name="permission_collapse" msgid="6555844383912351944">"Collapse"</string>
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Give apps on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the same permissions as on &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"This may include &lt;strong&gt;Microphone&lt;/strong&gt;, &lt;strong&gt;Camera&lt;/strong&gt;, and &lt;strong&gt;Location access&lt;/strong&gt;, and other sensitive permissions on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;You can change these permissions any time in your Settings on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"App Icon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"More Information Button"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Phone"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index 3a3ef18..00a3ccb 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Give apps on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the same permissions as on &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"This may include &lt;strong&gt;Microphone&lt;/strong&gt;, &lt;strong&gt;Camera&lt;/strong&gt;, and &lt;strong&gt;Location access&lt;/strong&gt;, and other sensitive permissions on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;You can change these permissions any time in your Settings on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"App icon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"More information button"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Phone"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index 3a3ef18..00a3ccb 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Give apps on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the same permissions as on &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"This may include &lt;strong&gt;Microphone&lt;/strong&gt;, &lt;strong&gt;Camera&lt;/strong&gt;, and &lt;strong&gt;Location access&lt;/strong&gt;, and other sensitive permissions on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;You can change these permissions any time in your Settings on &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"App icon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"More information button"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Phone"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index e5d11dc..591f2d1 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -43,10 +43,14 @@
     <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>
+    <string name="permission_expanded" msgid="5234121789170200621">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎Expanded‎‏‎‎‏‎"</string>
+    <string name="permission_expand" msgid="1464954219517793480">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‎‎‎‎Expand‎‏‎‎‏‎"</string>
+    <string name="permission_collapsed" msgid="3193316780088731226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‎‎Collapsed‎‏‎‎‏‎"</string>
+    <string name="permission_collapse" msgid="6555844383912351944">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎Collapse‎‏‎‎‏‎"</string>
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‏‏‏‏‎‎Give apps on &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; the same permissions as on &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;?‎‏‎‎‏‎"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‏‎This may include &lt;strong&gt;Microphone&lt;/strong&gt;, &lt;strong&gt;Camera&lt;/strong&gt;, and &lt;strong&gt;Location access&lt;/strong&gt;, and other sensitive permissions on &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;You can change these permissions any time in your Settings on &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;.‎‏‎‎‏‎"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎App Icon‎‏‎‎‏‎"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎More Information Button‎‏‎‎‏‎"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎Phone‎‏‎‎‏‎"</string>
     <string name="permission_sms" msgid="6337141296535774786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎SMS‎‏‎‎‏‎"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‎Contacts‎‏‎‎‏‎"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index f4d8d08..c4f4ce3 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"¿Dar a las apps de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; los mismos permisos que tienen en &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Esto puede incluir &lt;strong&gt;Micrófono&lt;/strong&gt;, &lt;strong&gt;Cámara&lt;/strong&gt;, y &lt;strong&gt;Acceso a la ubicación&lt;/strong&gt;, así como otros permisos sensibles en &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Puedes cambiar estos permisos en cualquier momento desde la Configuración de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ícono de la app"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Botón Más información"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Teléfono"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contactos"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index 11e64f3..7ddd7a3e 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"¿Dar a las aplicaciones de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; los mismos permisos que &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Esta acción puede dar acceso al &lt;strong&gt;micrófono&lt;/strong&gt;, la &lt;strong&gt;cámara&lt;/strong&gt; y la &lt;strong&gt;ubicación&lt;/strong&gt;, así como a otros permisos sensibles en &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Puedes cambiar estos permisos cuando quieras en los ajustes de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Icono de la aplicación"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Botón Más información"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Teléfono"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contactos"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 696b83f..126082d 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Kas anda rakendustele seadmes &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; samad load, mis seadmes &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"See võib hõlmata &lt;strong&gt;mikrofoni&lt;/strong&gt;, &lt;strong&gt;kaamerat&lt;/strong&gt; ja &lt;strong&gt;juurdepääsu asukohale&lt;/strong&gt; ning muid tundlikke lube seadmes &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Võite neid lube seadme &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; seadetes igal ajal muuta."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Rakenduse ikoon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Nupp Lisateave"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontaktid"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 6ce4654..3539890 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; gailuan dituzten baimen berberak eman nahi dizkiezu &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; gailuko aplikazioei?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Baliteke &lt;strong&gt;mikrofonoa&lt;/strong&gt;, &lt;strong&gt;kamera&lt;/strong&gt; eta &lt;strong&gt;kokapena&lt;/strong&gt; erabiltzeko baimenak barne hartzea, baita kontuzko informazioa erabiltzeko &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; gailuko beste baimen batzuk ere. &lt;br/&gt;&lt;br/&gt;Baimen horiek aldatzeko, joan &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; gailuaren ezarpenetara."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Aplikazioaren ikonoa"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Informazio gehiagorako botoia"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefonoa"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMSak"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontaktuak"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 6a19bd6..6e9d8b4 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"اجازه دادن"</string>
     <string name="consent_no" msgid="2640796915611404382">"اجازه ندادن"</string>
     <string name="consent_back" msgid="2560683030046918882">"برگشتن"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‏به برنامه‌های موجود در &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; همان اجازه‌های &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; داده شود؟"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"‏این مورد ممکن است شامل دسترسی به &lt;strong&gt;میکروفون&lt;/strong&gt;، &lt;strong&gt;دوربین&lt;/strong&gt;، و &lt;strong&gt;مکان&lt;/strong&gt;، و دیگر اجازه‌های حساس در &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; شود. &lt;br/&gt;&lt;br/&gt;هر زمان خواستید می‌توانید این اجازه‌ها را در «تنظیمات» &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; تغییر دهید."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"نماد برنامه"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"دکمه اطلاعات بیشتر"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"تلفن"</string>
     <string name="permission_sms" msgid="6337141296535774786">"پیامک"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"مخاطبین"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index b8186bb..700f879 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Anna laitteen &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; sovelluksille samat luvat kuin laitteella &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Tähän voi kuulua pääsy &lt;strong&gt;mikrofoniin&lt;/strong&gt;, &lt;strong&gt;kameraan&lt;/strong&gt;, ja &lt;strong&gt;sijaintiin &lt;/strong&gt;, ja muihin arkaluontoisiin lupiin laitteella&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Voit muuttaa lupia milloin tahansa laitteen &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; asetuksissa."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Sovelluskuvake"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Lisätietopainike"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Puhelin"</string>
     <string name="permission_sms" msgid="6337141296535774786">"Tekstiviesti"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Yhteystiedot"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index d0cee6f..8440c4d 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Accorder aux applications sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; les autorisations déjà accordées sur &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Cela peut inclure l\'accès &lt;strong&gt;au microphone&lt;/strong&gt;, &lt;strong&gt;à l\'appareil photo&lt;/strong&gt;, et &lt;strong&gt;à la position&lt;/strong&gt;, ainsi que d\'autres autorisations sensibles sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Vous pouvez modifier ces autorisations à tout moment dans vos paramètres sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Icône de l\'application"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Bouton En savoir plus"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Téléphone"</string>
     <string name="permission_sms" msgid="6337141296535774786">"Messages texte"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index b51188e..85f02480 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Accorder les mêmes autorisations aux applis sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; que sur &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Ceci peut inclure l\'accès au &lt;strong&gt;micro&lt;/strong&gt;, à l\'&lt;strong&gt;appareil photo&lt;/strong&gt; et à la &lt;strong&gt;position&lt;/strong&gt;, ainsi que d\'autres autorisations sensibles sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Vous pouvez modifier ces autorisations à tout moment dans vos paramètres sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Icône d\'application"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Bouton Plus d\'informations"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Téléphone"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
@@ -69,6 +77,6 @@
     <string name="permission_app_streaming_summary" msgid="606923325679670624">"Diffuser en streaming les applis de votre téléphone"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Diffusez des applis et d\'autres fonctionnalités système en streaming depuis votre téléphone"</string>
-    <string name="device_type" product="default" msgid="8268703872070046263">"Téléphone"</string>
-    <string name="device_type" product="tablet" msgid="5038791954983067774">"Tablette"</string>
+    <string name="device_type" product="default" msgid="8268703872070046263">"téléphone"</string>
+    <string name="device_type" product="tablet" msgid="5038791954983067774">"tablette"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index f5017d1..0edd8bd 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Queres darlles ás aplicacións de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; os mesmos permisos que teñen as de &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Con esta acción podes conceder acceso a &lt;strong&gt;Micrófono&lt;/strong&gt;, &lt;strong&gt;Cámara&lt;/strong&gt;, e &lt;strong&gt;Acceso á localización&lt;/strong&gt;, así como outros permisos de acceso á información confidencial de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Podes cambiar estes permisos en calquera momento na configuración de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Icona de aplicación"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Botón de máis información"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Teléfono"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contactos"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index e717c51..4b23226 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"મંજૂરી આપો"</string>
     <string name="consent_no" msgid="2640796915611404382">"મંજૂરી આપશો નહીં"</string>
     <string name="consent_back" msgid="2560683030046918882">"પાછળ"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; પરની ઍપને &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; પર છે તે જ પરવાનગીઓ આપીએ?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"આમાં &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; પરના &lt;strong&gt;માઇક્રોફોન&lt;/strong&gt;, &lt;strong&gt;કૅમેરા&lt;/strong&gt; અને &lt;strong&gt;લોકેશનના ઍક્સેસ&lt;/strong&gt; તથા અન્ય સંવેદનશીલ માહિતીની પરવાનગીઓ શામેલ હોઈ શકે છે. &lt;br/&gt;&lt;br/&gt;તમે કોઈપણ સમયે &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g> પર તમારા સેટિંગમાં આ પરવાનગીઓમાં ફેરફાર કરી શકો છો&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ઍપનું આઇકન"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"વધુ માહિતી માટેનું બટન"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ફોન"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"સંપર્કો"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index 4f1f711..97bad5a 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमति न दें"</string>
     <string name="consent_back" msgid="2560683030046918882">"वापस जाएं"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"क्या &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; पर ऐप्लिकेशन को वही अनुमतियां देनी हैं जो &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; पर दी हैं?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"इसमें &lt;strong&gt;माइक्रोफ़ोन&lt;/strong&gt;, &lt;strong&gt;कैमरा&lt;/strong&gt;, &lt;strong&gt;जगह की जानकारी&lt;/strong&gt;, के ऐक्सेस के साथ-साथ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; पर संवेदनशील जानकारी ऐक्सेस करने की अन्य अनुमतियां भी शामिल हो सकती हैं. &lt;br/&gt;&lt;br/&gt;इन अनुमतियों को &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; में जाकर कभी-भी बदला जा सकता है."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ऐप्लिकेशन आइकॉन"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"ज़्यादा जानकारी वाला बटन"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"फ़ोन"</string>
     <string name="permission_sms" msgid="6337141296535774786">"मैसेज (एसएमएस)"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"संपर्क"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index 84e8b63..22332ef 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dati jednaka dopuštenja aplikacijama na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; kao i na uređaju &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"To može uključivati &lt;strong&gt;pristup mikrofonu&lt;/strong&gt;, &lt;strong&gt;kameri&lt;/strong&gt; i &lt;strong&gt;lokaciji&lt;/strong&gt; te druga dopuštenja za osjetljive podatke na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Ta dopuštenja uvijek možete promijeniti u postavkama na uređaju &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Gumb Više informacija"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index 6057171..652f7f6 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Ugyanolyan engedélyeket ad a(z) &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; eszközön található alkalmazásoknak, mint a(z) &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; eszköz esetén?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Ide tartozhat a &lt;strong&gt;mikrofonhoz&lt;/strong&gt;, a &lt;strong&gt;kamerához&lt;/strong&gt; és a &lt;strong&gt;helyadatokhoz&lt;/strong&gt; való hozzáférés, valamint a(z) &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; eszközön érvényes egyéb bizalmas engedélyek is. &lt;br/&gt;&lt;br/&gt;Ezeket az engedélyeket bármikor módosíthatja a(z) &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; eszköz beállításai között."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Alkalmazás ikonja"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"További információ gomb"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Címtár"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 7975361..54edc7f 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string>
     <string name="consent_no" msgid="2640796915611404382">"Չթույլատրել"</string>
     <string name="consent_back" msgid="2560683030046918882">"Հետ"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-ում հավելվածներին տա՞լ նույն թույլտվությունները, ինչ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-ում"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Սա կարող է ներառել &lt;strong&gt;խոսափողի&lt;/strong&gt;, &lt;strong&amp;gtտեսախցիկի&lt;/strong&gt;, &lt;strong&gt;տեղադրության&lt;/strong&gt; և այլ կոնֆիդենցիալ տվյալների օգտագործման թույլտվությունները &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; սարքում։ &lt;br/&gt;&lt;br/&gt;Այդ թույլտվությունները ցանկացած ժամանակ կարող եք փոխել &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; սարքի ձեր կարգավորումներում։"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Հավելվածի պատկերակ"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"«Այլ տեղեկություններ» կոճակ"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Հեռախոս"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Կոնտակտներ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 2876967..84181ad 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Berikan aplikasi di &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; izin yang sama seperti di &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Ini bisa termasuk &lt;strong&gt;Mikrofon&lt;/strong&gt;, &lt;strong&gt;Kamera&lt;/strong&gt;, dan &lt;strong&gt;Akses lokasi&lt;/strong&gt;, serta izin sensitif lainnya di &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Anda dapat mengubah izin ini kapan saja di Setelan &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikon Aplikasi"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Tombol Informasi Lainnya"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telepon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontak"</string>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index bca9921..a50aee3 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Veita forritum í &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; sömu heimildir og í &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Þetta getur átt við um &lt;strong&gt;hljóðnema&lt;/strong&gt;, &lt;strong&gt;myndavél&lt;/strong&gt;, &lt;strong&gt;aðgang að staðsetningu&lt;/strong&gt; og aðrar heimildir fyrir viðkvæmu efni í &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Þú getur breytt þessum heimildum hvenær sem er í stillingunum í &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Tákn forrits"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Hnappur fyrir upplýsingar"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Sími"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Tengiliðir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 5f5497ab5..9800eed 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vuoi dare alle app su &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; le stesse autorizzazioni che hai dato su &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Potrebbero essere incluse le autorizzazioni &lt;strong&gt;Microfono&lt;/strong&gt;, &lt;strong&gt;Fotocamera&lt;/strong&gt; e &lt;strong&gt;Accesso alla posizione&lt;/strong&gt;, oltre ad altre autorizzazioni sensibili su &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Puoi cambiare queste autorizzazioni in qualsiasi momento nelle Impostazioni su &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Icona dell\'app"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Pulsante Altre informazioni"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefono"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contatti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 7dde216..78fe5d9 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
     <string name="consent_no" msgid="2640796915611404382">"אין אישור"</string>
     <string name="consent_back" msgid="2560683030046918882">"חזרה"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‏האם לתת לאפליקציות ב-‎&lt;strong&gt;‎‏<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>‏‎&lt;/strong&gt;‎‏ את אותן הרשאות כמו ב-‏‎&lt;strong&gt;‎‏<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>‏‎&lt;/strong&gt;‎‏?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"‏ההרשאות עשויות לכלול גישה ל&lt;strong&gt;מיקרופון&lt;/strong&gt;, ל&lt;strong&gt;מצלמה&lt;/strong&gt;, ול&lt;strong&gt;מיקום&lt;/strong&gt;, וכן גישה למידע רגיש אחר ב-&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;אפשר לשנות את ההרשאות האלה בכל שלב בהגדרות של &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"סמל האפליקציה"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"לחצן מידע נוסף"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"טלפון"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"אנשי קשר"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index 8301654..febd00a 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"許可"</string>
     <string name="consent_no" msgid="2640796915611404382">"許可しない"</string>
     <string name="consent_back" msgid="2560683030046918882">"戻る"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; のアプリに &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; の場合と同じ権限を付与しますか?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"これには、&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; の&lt;strong&gt;マイク&lt;/strong&gt;、&lt;strong&gt;カメラ&lt;/strong&gt;、&lt;strong&gt;位置情報へのアクセス&lt;/strong&gt;や、その他の機密情報に関わる権限が含まれる可能性があります。&lt;br/&gt;&lt;br/&gt;これらの権限は &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; の [設定] でいつでも変更できます。"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"アプリのアイコン"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"詳細情報ボタン"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"電話"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"連絡先"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 88c03c6..2d1c440 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string>
     <string name="consent_no" msgid="2640796915611404382">"არ დაიშვას"</string>
     <string name="consent_back" msgid="2560683030046918882">"უკან"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"გსურთ აპებს &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-ზე იგივე ნებართვები მიანიჭოთ, როგორიც აქვს &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-ზე?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"ეს შესაძლოა მოიცავდეს შემდეგს: &lt;strong&gt;მიკროფონი&lt;/strong&gt;, &lt;strong&gt;კამერა&lt;/strong&gt; და &lt;strong&gt;მდებარეობაზე წვდომა&lt;/strong&gt; და &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;-ის სხვა ნებართვა სენსიტიურ ინფორმაციაზე. &lt;br/&gt;&lt;br/&gt;ამ ნებართვების შეცვლა ნებისმიერ დროს შეგიძლიათ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;-ის პარამეტრებიდან."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"აპის ხატულა"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"დამატებითი ინფორმაციის ღილაკი"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Phone"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"კონტაქტები"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index fe3afa1..a4ee4f1 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string>
     <string name="consent_no" msgid="2640796915611404382">"Рұқсат бермеу"</string>
     <string name="consent_back" msgid="2560683030046918882">"Артқа"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; құрылғысындағы қолданбаларға &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; құрылғысындағыдай рұқсаттар берілсін бе?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Оған &lt;strong&gt;микрофонды&lt;/strong&gt;, &lt;strong&gt;камераны&lt;/strong&gt; және &lt;strong&gt;локацияны пайдалану рұқсаттары&lt;/strong&gt;, сондай-ақ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; құрылғысындағы басқа да құпия ақпарат рұқсаттары кіруі мүмкін. &lt;br/&gt;&lt;br/&gt;Бұл рұқсаттарды кез келген уақытта &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; құрылғысындағы параметрлерден өзгертуіңізге болады."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Қолданба белгішесі"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"\"Қосымша ақпарат\" түймесі"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Телефон"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Контактілер"</string>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 62ad055..3b9e8b5 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string>
     <string name="consent_no" msgid="2640796915611404382">"មិនអនុញ្ញាត"</string>
     <string name="consent_back" msgid="2560683030046918882">"ថយក្រោយ"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ផ្ដល់​ការអនុញ្ញាតឱ្យ​កម្មវិធីនៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ដូចនៅលើ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ឬ?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"សកម្មភាពនេះ​អាចរួមបញ្ចូល&lt;strong&gt;មីក្រូហ្វូន&lt;/strong&gt; &lt;strong&gt;កាមេរ៉ា&lt;/strong&gt; និង&lt;strong&gt;សិទ្ធិចូលប្រើទីតាំង&lt;/strong&gt; និងការអនុញ្ញាត​ដែលមានលក្ខណៈរសើបផ្សេងទៀតនៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;។ &lt;br/&gt;&lt;br/&gt;អ្នកអាចប្ដូរ​ការអនុញ្ញាតទាំងនេះ​បានគ្រប់ពេល​នៅក្នុងការកំណត់​របស់អ្នកនៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;។"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"រូប​កម្មវិធី"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"ប៊ូតុងព័ត៌មានបន្ថែម"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ទូរសព្ទ"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 940c8f9..8375875 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ಅನುಮತಿಸಬೇಡಿ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ಹಿಂದೆ"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;/strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ನಲ್ಲಿನ ಅನುಮತಿಗಳನ್ನೇ &lt;/strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ನಲ್ಲಿನ ಆ್ಯಪ್‌ಗಳಿಗೆ ನೀಡಬೇಕೆ?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"ಇದು &lt;strong&gt;ಮೈಕ್ರೋಫೋನ್&lt;/strong&gt;, &lt;strong&gt;ಕ್ಯಾಮರಾ&lt;/strong&gt;, and &lt;strong&gt;ಸ್ಥಳದ ಆ್ಯಕ್ಸೆಸ್&lt;/strong&gt;, ಮತ್ತು &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; ನಲ್ಲಿ ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಗಾಗಿ ಇತರ ಅನುಮತಿಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು. &lt;br/&gt;&lt;br/&gt;ನೀವು &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; ನಲ್ಲಿನ ನಿಮ್ಮ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಈ ಅನುಮತಿಗಳನ್ನು ಯಾವಾಗ ಬೇಕಾದರೂ ಬದಲಾಯಿಸಬಹುದು."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ಆ್ಯಪ್ ಐಕಾನ್"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"ಹೆಚ್ಚಿನ ಮಾಹಿತಿಯ ಬಟನ್"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ಫೋನ್"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"ಸಂಪರ್ಕಗಳು"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 5c225c2..6c35beb 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"허용"</string>
     <string name="consent_no" msgid="2640796915611404382">"허용 안함"</string>
     <string name="consent_back" msgid="2560683030046918882">"뒤로"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;에 설치된 앱에 &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;에 설치된 앱과 동일한 권한을 부여하시겠습니까?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"여기에는 &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;의 &lt;strong&gt;마이크&lt;/strong&gt;, &lt;strong&gt;카메라&lt;/strong&gt;, &lt;strong&gt;위치 정보 액세스&lt;/strong&gt; 및 기타 민감한 권한이 포함될 수 있습니다. &lt;br/&gt;&lt;br/&gt;언제든지 &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;의 설정에서 이러한 권한을 변경할 수 있습니다."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"앱 아이콘"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"추가 정보 버튼"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"전화"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"연락처"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index ed750a8..ddf50f3 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Ооба"</string>
     <string name="consent_no" msgid="2640796915611404382">"Уруксат берилбесин"</string>
     <string name="consent_back" msgid="2560683030046918882">"Артка"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; түзмөгүнө да &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; түзмөгүнө берилген уруксаттар берилсинби?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Буга &lt;strong&gt;Микрофонду&lt;/strong&gt;, &lt;strong&gt;Камераны&lt;/strong&gt; пайдалануу жана &lt;strong&gt;Жайгашкан жерди аныктоо&lt;/strong&gt;, ошондой эле &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; түзмөгүндөгү башка купуя маалыматты көрүүгө уруксаттар кириши мүмкүн. &lt;br/&gt;&lt;br/&gt;Каалаган убакта &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; түзмөгүндөгү параметрлерге өтүп, бул уруксаттарды өзгөртө аласыз."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Колдонмонун сүрөтчөсү"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Дагы маалымат баскычы"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Телефон"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Байланыштар"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 9058820..742bfaf 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ບໍ່ອະນຸຍາດ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ກັບຄືນ"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ໃຫ້ການອະນຸຍາດແອັບຢູ່ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ເປັນການອະນຸຍາດດຽວກັນກັບຢູ່ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ບໍ?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"ສິ່ງນີ້ອາດຮວມມີສິດເຂົ້າເຖິງ &lt;strong&gt;ໄມໂຄຣໂຟນ&lt;/strong&gt;, &lt;strong&gt;ກ້ອງຖ່າຍຮູບ&lt;/strong&gt; ແລະ &lt;strong&gt;ສະຖານທີ່&lt;/strong&gt; ພ້ອມທັງການອະນຸຍາດທີ່ລະອຽດອ່ອນອື່ນໆຢູ່ໃນ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;ທ່ານສາມາດປ່ຽນແປງສິດການອະນຸຍາດເຫຼົ່ານີ້ໄດ້ທຸກເວລາໃນການຕັ້ງຄ່າຂອງທ່ານຢູ່ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ໄອຄອນແອັບ"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"ປຸ່ມຂໍ້ມູນເພີ່ມເຕີມ"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ໂທລະສັບ"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"ລາຍຊື່ຜູ້ຕິດຕໍ່"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index 7af2476..3a38726 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Neleisti"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atgal"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Suteikti &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; esančioms programoms tuos pačius leidimus kaip &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; esančioms programoms?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Tai gali apimti &lt;strong&gt;mikrofono&lt;/strong&gt;, &lt;strong&gt;fotoaparato&lt;/strong&gt;, ir &lt;strong&gt;prieigos prie vietovės&lt;/strong&gt;, leidimus bei kitus leidimus pasiekti neskelbtiną informaciją įrenginyje &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Šiuos leidimus galite bet kada pakeisti įrenginio &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; nustatymų skiltyje."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Programos piktograma"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Mygtukas „Daugiau informacijos“"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefonas"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontaktai"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index b74834b..1311975 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vai lietotnēm ierīcē &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; piešķirt tādas pašas atļaujas kā ierīcē &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Tās var būt &lt;strong&gt;mikrofona&lt;/strong&gt;, &lt;strong&gt;kameras&lt;/strong&gt;, &lt;strong&gt;atrašanās vietas piekļuves&lt;/strong&gt; atļaujas, kā arī citas sensitīvas atļaujas ierīcē &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Atļaujas varat jebkurā brīdī mainīt ierīces &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; iestatījumos."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Lietotnes ikona"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Plašākas informācijas poga"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Tālrunis"</string>
     <string name="permission_sms" msgid="6337141296535774786">"Īsziņas"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontaktpersonas"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index f420766..a203abc 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволувај"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Дасе дадат исти дозволи на апликациите на &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; како на &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Ова може да вклучува дозволи за пристап до &lt;strong&gt;микрофонот&lt;/strong&gt;, &lt;strong&gt;камерата&lt;/strong&gt; и &lt;strong&gt;локацијата&lt;/strong&gt;, како и други чувствителни дозволи на &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Дозволиве може да ги промените во секое време во „Поставки“ на &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Икона на апликацијата"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Копче за повеќе информации"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Телефон"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Контакти"</string>
@@ -69,6 +77,6 @@
     <string name="permission_app_streaming_summary" msgid="606923325679670624">"Стримувајте ги апликациите на телефонот"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
     <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Апликации за стриминг и други системски карактеристики од вашиот телефон"</string>
-    <string name="device_type" product="default" msgid="8268703872070046263">"телефон"</string>
-    <string name="device_type" product="tablet" msgid="5038791954983067774">"таблет"</string>
+    <string name="device_type" product="default" msgid="8268703872070046263">"Телефон"</string>
+    <string name="device_type" product="tablet" msgid="5038791954983067774">"Таблет"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index 0a9adb6..d6566c7 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string>
     <string name="consent_no" msgid="2640796915611404382">"അനുവദിക്കരുത്"</string>
     <string name="consent_back" msgid="2560683030046918882">"മടങ്ങുക"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; എന്നതിലെ അതേ അനുമതികൾ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; എന്നതിലെ ആപ്പുകൾക്ക് നൽകണോ?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. എന്നതിലെ &lt;strong&gt;മൈക്രോഫോൺ&lt;/strong&gt;, &lt;strong&gt;ക്യാമറ&lt;/strong&gt;, and &lt;strong&gt;ലൊക്കേഷൻ ആക്‌സസ്&lt;/strong&gt;, സെൻസിറ്റീവ് വിവരങ്ങൾക്കുള്ള മറ്റ് അനുമതികൾ എന്നിവയും ഇതിൽ ഉൾപ്പെട്ടേക്കാം. &lt;br/&gt;&lt;br/&gt;നിങ്ങൾക്ക് &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; എന്നതിലെ ക്രമീകരണത്തിൽ ഏതുസമയത്തും ഈ അനുമതികൾ മാറ്റാം."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ആപ്പ് ഐക്കൺ"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"കൂടുതൽ വിവരങ്ങൾ ബട്ടൺ"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ഫോൺ"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index 7eb2e8d..32e27e9 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Зөвшөөрөх"</string>
     <string name="consent_no" msgid="2640796915611404382">"Бүү зөвшөөр"</string>
     <string name="consent_back" msgid="2560683030046918882">"Буцах"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; дээрх аппуудад &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; дээрхтэй адил зөвшөөрөл өгөх үү?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Үүнд &lt;strong&gt;Микрофон&lt;/strong&gt;, &lt;strong&gt;Камер&lt;/strong&gt;,, &lt;strong&gt;Байршлын хандалт&lt;/strong&gt; болон &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; дээрх бусад эмзэг зөвшөөрөл багтаж болно. &lt;br/&gt;&lt;br/&gt;Та эдгээр зөвшөөрлийг &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; дээрх Тохиргоондоо хүссэн үедээ өөрчлөх боломжтой."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Aппын дүрс тэмдэг"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Дэлгэрэнгүй мэдээллийн товчлуур"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Утас"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Харилцагчид"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index b999641..8b0e079 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमती देऊ नका"</string>
     <string name="consent_back" msgid="2560683030046918882">"मागे जा"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; वरील अ‍ॅप्सना &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; प्रमाणेच परवानग्या द्यायच्या आहेत का?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"यामध्ये पुढील गोष्टी समाविष्ट असू शकतात &lt;strong&gt;मायक्रोफोन&lt;/strong&gt;, &lt;strong&gt;कॅमेरा&lt;/strong&gt;, and &lt;strong&gt;स्थान अ‍ॅक्सेस&lt;/strong&gt;, आणि &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; वरील इतर संवेदनशील परवानग्या. &lt;br/&gt;&lt;br/&gt;तुम्ही &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; वर तुमच्या सेटिंग्ज मध्ये कोणत्याही वेळेला या परवानग्या बदलू शकता."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"अ‍ॅप आयकन"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"अधिक माहिती बटण"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"फोन"</string>
     <string name="permission_sms" msgid="6337141296535774786">"एसएमएस"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 626b3cf..c5cd0d7 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Beri apl pada &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; kebenaran yang sama seperti pada &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Ini mungkin termasuk &lt;strong&gt;Mikrofon&lt;/strong&gt;, &lt;strong&gt;Kamera&lt;/strong&gt; dan &lt;strong&gt;Akses lokasi&lt;/strong&gt; serta kebenaran sensitif lain pada &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Anda boleh menukar kebenaran ini pada bila-bila masa dalam Tetapan anda pada &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikon Apl"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Butang Maklumat Lagi"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kenalan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index bf9b422..228e70a 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string>
     <string name="consent_no" msgid="2640796915611404382">"ခွင့်မပြုပါ"</string>
     <string name="consent_back" msgid="2560683030046918882">"နောက်သို့"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"အက်ပ်များကို &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; တွင်ပေးထားသည့် ခွင့်ပြုချက်များအတိုင်း &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; တွင် ပေးမလား။"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; တွင် &lt;strong&gt;မိုက်ခရိုဖုန်း&lt;/strong&gt;၊ &lt;strong&gt;ကင်မရာ&lt;/strong&gt;၊ &lt;strong&gt;တည်နေရာသုံးခွင့်&lt;/strong&gt; နှင့် အခြားသတိထားရမည့် ခွင့်ပြုချက်များ ပါဝင်နိုင်သည်။ &lt;br/&gt;&lt;br/&gt;ဤခွင့်ပြုချက်များကို &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; ရှိ ဆက်တင်များတွင် အချိန်မရွေး ပြောင်းနိုင်သည်။"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"အက်ပ်သင်္ကေတ"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"နောက်ထပ်အချက်အလက်များ ခလုတ်"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ဖုန်း"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS စာတိုစနစ်"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"အဆက်အသွယ်များ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 3863d1d..75e78fa 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vil du gi apper på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; de samme tillatelsene som på &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Dette kan inkludere &lt;strong&gt;mikrofon&lt;/strong&gt;-, &lt;strong&gt;kamera&lt;/strong&gt;- og &lt;strong&gt;posisjonstilgang&lt;/strong&gt; samt andre sensitive tillatelser på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Du kan når som helst endre disse tillatelsene i innstillingene på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Appikon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Mer informasjon-knapp"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakter"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index 60888e5..abcf09f 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमति नदिनुहोस्"</string>
     <string name="consent_back" msgid="2560683030046918882">"पछाडि"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; मा भएका एपहरूलाई पनि &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; मा दिइएकै अनुमति दिने हो?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"यसअन्तर्गत &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; का &lt;strong&gt;माइक्रोफोन&lt;/strong&gt;, &lt;strong&gt;क्यामेरा&lt;/strong&gt; र &lt;strong&gt;लोकेसन प्रयोग गर्ने अनुमति&lt;/strong&gt; तथा अन्य संवेदनशील अनुमतिहरू समावेश हुन्छन्। &lt;br/&gt;&lt;br/&gt;तपाईं जुनसुकै बेला &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; का सेटिङमा गई यी अनुमति परिवर्तन गर्न सक्नुहुन्छ।"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"एपको आइकन"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"थप जानकारी देखाउने बटन"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"फोन"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacts"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 2b78bb1..1c26783 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Apps op de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dezelfde rechten geven als op de &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Dit kan &lt;strong&gt;Microfoon&lt;/strong&gt;, &lt;strong&gt;Camera&lt;/strong&gt; en &lt;strong&gt;Locatietoegang&lt;/strong&gt; en andere gevoelige rechten op de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; omvatten. &lt;br/&gt;&lt;br/&gt;Je kunt deze rechten altijd wijzigen in je Instellingen op de &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"App-icoon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Knop Meer informatie"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefoon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"Sms"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contacten"</string>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 9b5116dc..a9acef2 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ପଛକୁ ଫେରନ୍ତୁ"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ପରି &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;ରେ ଥିବା ଆପ୍ସକୁ ସମାନ ଅନୁମତିଗୁଡ଼ିକ ଦେବେ?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"ଏହା &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;ରେ &lt;strong&gt;ମାଇକ୍ରୋଫୋନ&lt;/strong&gt;, &lt;strong&gt;କେମେରା&lt;/strong&gt;, ଏବଂ &lt;strong&gt;ଲୋକେସନ ଆକ୍ସେସ&lt;/strong&gt; ଏବଂ ଅନ୍ୟ ସମ୍ବେଦନଶୀଳ ଅନୁମତିଗୁଡ଼ିକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରିପାରେ। &lt;br/&gt;&lt;br/&gt;ଆପଣ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;ରେ ଯେ କୌଣସି ସମୟରେ ଆପଣଙ୍କ ସେଟିଂସରେ ଏହି ଅନୁମତିଗୁଡ଼ିକୁ ପରିବର୍ତ୍ତନ କରିପାରିବେ।"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ଆପ ଆଇକନ"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"ଅଧିକ ସୂଚନା ବଟନ"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ଫୋନ"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"କଣ୍ଟାକ୍ଟଗୁଡ଼ିକ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index c6bbf37..2874699 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"ਆਗਿਆ ਦਿਓ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ਆਗਿਆ ਨਾ ਦਿਓ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ਪਿੱਛੇ"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ਕੀ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; \'ਤੇ ਮੌਜੂਦ ਐਪਾਂ ਨੂੰ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; \'ਤੇ ਮੌਜੂਦ ਐਪਾਂ ਵਾਂਗ ਇਜਾਜ਼ਤਾਂ ਦੇਣੀਆਂ ਹਨ?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"ਇਸ ਵਿੱਚ &lt;strong&gt;ਮਾਈਕ੍ਰੋਫ਼ੋਨ&lt;/strong&gt;, &lt;strong&gt;ਕੈਮਰਾ&lt;/strong&gt;, ਅਤੇ &lt;strong&gt;ਟਿਕਾਣਾ ਪਹੁੰਚ&lt;/strong&gt;, ਅਤੇ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; \'ਤੇ ਮੌਜੂਦ ਹੋਰ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਸੰਬੰਧੀ ਇਜਾਜ਼ਤਾਂ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀਆਂ ਹਨ। &lt;br/&gt;&lt;br/&gt;ਤੁਸੀਂ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; \'ਤੇ ਮੌਜੂਦ ਆਪਣੀਆਂ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਕਿਸੇ ਵੀ ਵੇਲੇ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਬਦਲ ਸਕਦੇ ਹੋ।"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ਐਪ ਪ੍ਰਤੀਕ"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"ਹੋਰ ਜਾਣਕਾਰੀ ਬਟਨ"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ਫ਼ੋਨ"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"ਸੰਪਰਕ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index 87db327..7cb4138 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Czy aplikacjom na urządzeniu &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; przyznać te same uprawnienia co na urządzeniu &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Wśród nich mogą być dane dostępu do &lt;strong&gt;Mikrofonu&lt;/strong&gt;, &lt;strong&gt;Aparatu&lt;/strong&gt;, i &lt;strong&gt;Lokalizacji&lt;/strong&gt;, i inne uprawnienia newralgiczne na urządzeniu &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Możesz w dowolnym momencie zmienić uprawnienia na urządzeniu &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacji"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Przycisk – więcej informacji"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS-y"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakty"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index c630fce..0bd4989 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dar aos apps no dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; as mesmas permissões do dispositivo &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Isso pode incluir acesso ao &lt;strong&gt;Microfone&lt;/strong&gt;, à &lt;strong&gt;Câmera&lt;/strong&gt; e à &lt;strong&gt;Localização&lt;/strong&gt;, além de outras permissões sensíveis no dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Você pode mudar essas permissões a qualquer momento nas Configurações do dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ícone do app"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Botão \"Mais informações\""</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Smartphone"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contatos"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 59d4423..38f142a 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dar às apps no dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; as mesmas autorizações de &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Isto pode incluir o acesso ao &lt;strong&gt;microfone&lt;/strong&gt;, &lt;strong&gt;câmara&lt;/strong&gt;, e &lt;strong&gt;localização&lt;/strong&gt;, bem como outras autorizações confidenciais no dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Pode alterar estas autorizações em qualquer altura nas Definições do dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ícone da app"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Botão Mais informações"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telemóvel"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contactos"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index c630fce..0bd4989 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Dar aos apps no dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; as mesmas permissões do dispositivo &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Isso pode incluir acesso ao &lt;strong&gt;Microfone&lt;/strong&gt;, à &lt;strong&gt;Câmera&lt;/strong&gt; e à &lt;strong&gt;Localização&lt;/strong&gt;, além de outras permissões sensíveis no dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Você pode mudar essas permissões a qualquer momento nas Configurações do dispositivo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ícone do app"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Botão \"Mais informações\""</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Smartphone"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Contatos"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 785ad86..c72feea 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Acorzi aplicațiilor de pe &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; aceleași permisiuni ca pe &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Aici pot fi incluse accesul la &lt;strong&gt;microfon&lt;/strong&gt;, la &lt;strong&gt;camera foto&lt;/strong&gt;, la &lt;strong&gt;locație&lt;/strong&gt; și alte permisiuni de accesare a informațiilor sensibile de pe &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Poți modifica oricând aceste permisiuni din Setările de pe &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Pictograma aplicației"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Butonul Mai multe informații"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Agendă"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 6b03b43..6c2beba 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string>
     <string name="consent_no" msgid="2640796915611404382">"Запретить"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Предоставить приложениям на устройстве &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; те же разрешения, что на устройстве &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"У приложений может появиться доступ к &lt;strong&gt;микрофону&lt;/strong&gt;, &lt;strong&gt;камере&lt;/strong&gt;, &lt;strong&gt;местоположению&lt;/strong&gt; и другой конфиденциальной информации на устройстве &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Вы можете в любое время изменить разрешения в настройках на устройстве &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Значок приложения"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Кнопка информации"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Телефон"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Контакты"</string>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index c6821c3..b6c3bd2 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string>
     <string name="consent_no" msgid="2640796915611404382">"ඉඩ නොදෙන්න"</string>
     <string name="consent_back" msgid="2560683030046918882">"ආපසු"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; the හි යෙදුම්වලට &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; හි අවසරම දෙන්නද?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"මෙයට &lt;strong&gt;මයික්‍රොෆෝනය&lt;/strong&gt;, &lt;strong&gt;කැමරාව&lt;/strong&gt;, සහ &lt;strong&gt;ස්ථාන ප්‍රවේශය&lt;/strong&gt;, සහ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; මත අනෙකුත් සංවේදී අවසර ඇතුළත් විය හැක. &lt;br/&gt;&lt;br/&gt;ඔබට &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; හි ඔබේ සැකසීම් තුළ ඕනෑම වේලාවක මෙම අවසර වෙනස් කළ හැක."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"යෙදුම් නිරූපකය"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"වැඩිදුර තොරතුරු බොත්තම"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"දුරකථනය"</string>
     <string name="permission_sms" msgid="6337141296535774786">"කෙටිපණිවුඩය"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"සම්බන්‍ධතා"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 24a0f19..af01838 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nepovoliť"</string>
     <string name="consent_back" msgid="2560683030046918882">"Späť"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Chcete udeliť aplikáciám v zariadení &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; rovnaké povolenia ako v zariadení &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Môžu zahŕňať prístup k &lt;strong&gt;mikrofónu&lt;/strong&gt;, &lt;strong&gt;kamere&lt;/strong&gt; a &lt;strong&gt;polohe&lt;/strong&gt;, a ďalšie citlivé povolenia v zariadení &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Tieto povolenia môžete kedykoľvek zmeniť v nastaveniach zariadenia &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikácie"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Tlačidlo Ďalšie informácie"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefón"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakty"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 6058ae1..20e9822 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Ali želite aplikacijam v napravi &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; odobriti enaka dovoljenja kot v napravi &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"To lahko vključuje &lt;strong&gt;dostop do mikrofona&lt;/strong&gt;, &lt;strong&gt;fotoaparata&lt;/strong&gt; in &lt;strong&gt;lokacije&lt;/strong&gt; ter druga občutljiva dovoljenja v napravi &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Ta dovoljenja lahko kadar koli spremenite v nastavitvah v napravi &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona aplikacije"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Gumb za več informacij"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Stiki"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index aeab5bf..1153394 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"T\'i jepen aplikacioneve në &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; të njëjtat leje si në &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Kjo mund të përfshijë qasjen te &lt;strong&gt;Mikrofoni&lt;/strong&gt;, &lt;strong&gt;Kamera&lt;/strong&gt;, dhe &lt;strong&gt;Vendndodhja&lt;/strong&gt;, dhe leje të tjera për informacione delikate në &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Ti mund t\'i ndryshosh këto leje në çdo kohë te \"Cilësimet\" në &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ikona e aplikacionit"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Butoni \"Më shumë informacione\""</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefoni"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontaktet"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index cdcddf1..b7699f4 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволи"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Апликцијама на уређају &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; дајете све дозволе као на уређају &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"То може да обухвата приступ &lt;strong&gt;микрофону&lt;/strong&gt;, &lt;strong&gt;камери&lt;/strong&gt;, и &lt;strong&gt;локацији&lt;/strong&gt;, и друге осетљиве дозволе на уређају &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Можете да промените те дозволе у било ком тренутку у Подешавањима на уређају &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Икона апликације"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Дугме за више информација"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Телефон"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Контакти"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index f43f973..36451e3 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Vill du ge apparna på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; samma behörigheter som de har på &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Detta kan inkludera &lt;strong&gt;Mikrofon-&lt;/strong&gt;, &lt;strong&gt;Kamera-&lt;/strong&gt;, och &lt;strong&gt;Platsåtkomst&lt;/strong&gt;, samt andra känsliga behörigheter på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Du kan ändra dessa behörigheter när som helst i inställningarna på &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Appikon"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Knappen Mer information"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"Sms"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontakter"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index e784373..452fc36 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string>
     <string name="consent_no" msgid="2640796915611404382">"Usiruhusu"</string>
     <string name="consent_back" msgid="2560683030046918882">"Nyuma"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Ungependa kuzipa programu katika &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ruhusa ile ile kama kwenye &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Hii ni pamoja na &lt;strong&gt;Maikrofoni&lt;/strong&gt;, &lt;strong&gt;Kamera&lt;/strong&gt;, na &lt;strong&gt;Uwezo wa kufikia mahali&lt;/strong&gt;, na ruhusa nyingine nyeti kwenye &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Unaweza kubadilisha ruhusa hizi wakati wowote katika Mipangilio yako kwenye &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Aikoni ya Programu"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Kitufe cha Maelezo Zaidi"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Simu"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Anwani"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index e5fe2b2..ab8a433 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string>
     <string name="consent_no" msgid="2640796915611404382">"அனுமதிக்க வேண்டாம்"</string>
     <string name="consent_back" msgid="2560683030046918882">"பின்செல்"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; சாதனத்தில் இருக்கும் அதே அனுமதிகளை &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; சாதனத்தில் உள்ள ஆப்ஸுக்கும் வழங்கவா?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"&lt;strong&gt;மைக்ரோஃபோன்&lt;/strong&gt;, &lt;strong&gt;கேமரா&lt;/strong&gt;, &lt;strong&gt;இருப்பிட அணுகல்&lt;/strong&gt;, ஆகியவற்றுக்கான அனுமதிகளும் &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; சாதனத்தில் உள்ள பிற பாதுகாக்கவேண்டிய தகவல்களுக்கான அனுமதிகளும் இதில் அடங்கக்கூடும். &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; &lt;br/&gt;&lt;br/&gt;சாதனத்தில் உள்ள அமைப்புகளில் இந்த அனுமதிகளை எப்போது வேண்டுமானாலும் மாற்றிக்கொள்ளலாம்."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ஆப்ஸ் ஐகான்"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"கூடுதல் தகவல்கள் பட்டன்"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"மொபைல்"</string>
     <string name="permission_sms" msgid="6337141296535774786">"மெசேஜ்"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"தொடர்புகள்"</string>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index ee20fbc..4111ee7 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"అనుమతించండి"</string>
     <string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string>
     <string name="consent_back" msgid="2560683030046918882">"వెనుకకు"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;లోని యాప్‌లకు &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;లో ఉన్న అనుమతులను ఇవ్వాలా?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"వీటిలో భాగంగా &lt;strong&gt;మైక్రోఫోన్&lt;/strong&gt;, &lt;strong&gt;కెమెరా&lt;/strong&gt;, ఇంకా &lt;strong&gt;లొకేషన్ యాక్సెస్&lt;/strong&gt;, అలాగే &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;పై ఇతర గోప్యమైన సమాచార యాక్సెస్ అనుమతులు ఉండవచ్చు. &lt;br/&gt;&lt;br/&gt;ఈ అనుమతులను మీరు &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;లోని మీ సెట్టింగ్‌లలో ఎప్పుడైనా మార్చవచ్చు."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"యాప్ చిహ్నం"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"మరింత సమాచారం బటన్"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"ఫోన్"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"కాంటాక్ట్‌లు"</string>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index fc55930..fe28c1c 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"อนุญาต"</string>
     <string name="consent_no" msgid="2640796915611404382">"ไม่อนุญาต"</string>
     <string name="consent_back" msgid="2560683030046918882">"กลับ"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ให้แอปใน &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; มีสิทธิ์เหมือนกับใน &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ไหม"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"โดยอาจรวมถึงสิทธิ์เข้าถึง &lt;strong&gt;ไมโครโฟน&lt;/strong&gt; &lt;strong&gt;กล้อง&lt;/strong&gt; และ&lt;strong&gt;ตำแหน่ง&lt;/strong&gt; ตลอดจนสิทธิ์ที่มีความละเอียดอ่อนอื่นๆ ใน &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; &lt;br/&gt;&lt;br/&gt;คุณเปลี่ยนแปลงสิทธิ์เหล่านี้ได้ทุกเมื่อในการตั้งค่าบน &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ไอคอนแอป"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"ปุ่มข้อมูลเพิ่มเติม"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"โทรศัพท์"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"รายชื่อติดต่อ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 6e4ce39..7ce70f8 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Bigyan ang mga app sa &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ng mga pahintulot na mayroon din sa &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Posibleng kasama rito ang &lt;strong&gt;access sa Mikropono&lt;/strong&gt;, &lt;strong&gt;Camera&lt;/strong&gt;, at &lt;strong&gt;Lokasyon&lt;/strong&gt;, at iba pang pahintulot sa sensitibong impormasyon sa &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Puwede mong baguhin ang mga pahintulot na ito anumang oras sa iyong Mga Setting sa &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Icon ng App"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Button ng Dagdag Impormasyon"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telepono"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Mga Contact"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index f9466db..47b936f 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -33,7 +33,7 @@
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
     <string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
     <string name="summary_computer" msgid="3798467601598297062"></string>
-    <string name="helper_title_computer" msgid="4671071173916176037">"Google Play hizmetleri"</string>
+    <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Hizmetleri"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
     <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazının bu işlem yapmasına izin verilsin mi?"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması <xliff:g id="DEVICE_NAME">%2$s</xliff:g> cihazınız adına uygulamaları ve diğer sistem özelliklerini yakındaki cihazlara aktarmak için izin istiyor"</string>
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazındaki uygulamalara, &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazındakiyle aynı izinler verilsin mi?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Bu; &lt;strong&gt;Mikrofon&lt;/strong&gt;, &lt;strong&gt;Kamera&lt;/strong&gt; ve &lt;strong&gt;Konum erişimi&lt;/strong&gt; izinlerinin yanı sıra &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; cihazındaki diğer hassas bilgilere erişim izinlerini içerebilir. &lt;br/&gt;&lt;br/&gt;&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; cihazının Ayarlar bölümünden istediğiniz zaman bu izinleri değiştirebilirsiniz."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Uygulama Simgesi"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Daha Fazla Bilgi Düğmesi"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kişiler"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 5b192a8..541d8cd 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволяти"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Надати додаткам на пристрої &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; такі самі дозволи, що й на пристрої &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Це можуть бути дозволи &lt;strong&gt;Мікрофон&lt;/strong&gt;, &lt;strong&gt;Камера&lt;/strong&gt;, &lt;strong&gt;Геодані&lt;/strong&gt;, а також інші дозволи на доступ до чутливих даних на пристрої &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Ви можете будь-коли змінити ці дозволи в налаштуваннях на пристрої &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Значок додатка"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Кнопка \"Докладніше\""</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Телефон"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Контакти"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index beeaef3..ff07ae4 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"اجازت دیں"</string>
     <string name="consent_no" msgid="2640796915611404382">"اجازت نہ دیں"</string>
     <string name="consent_back" msgid="2560683030046918882">"پیچھے"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‏ایپس کو &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; پر وہی اجازتیں دیں جو &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; پر دی گئی ہیں؟"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"‏اس میں ‎&lt;strong&gt;‎مائیکروفون‎&lt;/strong&gt; ،&lt;strong&gt;‎کیمرا‎&lt;/strong&gt;‎ اور ‎&lt;strong&gt;‎مقام تک رسائی‎&lt;/strong&gt;‎ اور ‎&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;‎ پر دیگر حساس اجازتیں شامل ہو سکتی ہیں۔ ‎&lt;br/&gt;&lt;br/&gt;‎آپ ‎&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;‎ پر کسی بھی وقت اپنی ترتیبات میں ان اجازتوں کو تبدیل کر سکتے ہیں۔"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"ایپ کا آئیکن"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"مزید معلومات کا بٹن"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"فون"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"رابطے"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 567539a..1a2ba15 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovalariga &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; qurilmasidagi kabi bir xil ruxsatlar berilsinmi?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Ilovada &lt;strong&gt;,ikrofon&lt;/strong&gt;, &lt;strong&gt;kamera&lt;/strong&gt;, &lt;strong&gt;joylashuv axboroti&lt;/strong&gt;, va &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g> qurilmasidagi boshqa shaxsiy maʼlumotlarga kirish imkoni paydo boʻladi&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Bu ruxsatlarni istalgan vaqt &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g> sozlamalari orqali oʻzgartirish mumkin&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Ilova belgisi"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Batafsil axborot tugmasi"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Telefon"</string>
     <string name="permission_sms" msgid="6337141296535774786">"SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Kontaktlar"</string>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index d4eefeb..8e3f577 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -43,10 +43,18 @@
     <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>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Cấp cho các ứng dụng trên &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; các quyền giống như trên &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Những quyền này có thể bao gồm quyền truy cập vào &lt;strong&gt;Micrô&lt;/strong&gt;, &lt;strong&gt;Máy ảnh&lt;/strong&gt;, và &lt;strong&gt;Thông tin vị trí&lt;/strong&gt;, cũng như các quyền truy cập thông tin nhạy cảm khác trên &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Bạn có thể thay đổi những quyền này bất cứ lúc nào trong phần Cài đặt trên &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Biểu tượng ứng dụng"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Nút thông tin khác"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Điện thoại"</string>
     <string name="permission_sms" msgid="6337141296535774786">"Tin nhắn SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Danh bạ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index ea07086..d3ba55e 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"允许"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允许"</string>
     <string name="consent_back" msgid="2560683030046918882">"返回"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"要让&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;上的应用享有在&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;上的同等权限吗?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"这可能包括&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;的&lt;strong&gt;麦克风&lt;/strong&gt;、&lt;strong&gt;摄像头&lt;/strong&gt;和&lt;strong&gt;位置信息访问权限&lt;/strong&gt;以及其他敏感权限。&lt;br/&gt;&lt;br/&gt;您随时可以在&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;的“设置”中更改这些权限。"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"应用图标"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"更多信息按钮"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"手机"</string>
     <string name="permission_sms" msgid="6337141296535774786">"短信"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"通讯录"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 3c2dcea..7a413fb 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -24,14 +24,14 @@
     <string name="summary_watch_single_device" msgid="3173948915947011333">"此應用程式將可同步資訊 (例如來電者的名稱),並可在<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>上取得以下權限"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"要允許「<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>
     <string name="profile_name_glasses" msgid="8488394059007275998">"眼鏡"</string>
-    <string name="summary_glasses_multi_device" msgid="615259525961937348">"必須使用此應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可透過通知與您互動,並存取電話、短訊、通訊錄、麥克風和附近的裝置權限。"</string>
+    <string name="summary_glasses_multi_device" msgid="615259525961937348">"必須使用此應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可透過通知與你互動,並存取電話、短訊、通訊錄、麥克風和附近的裝置權限。"</string>
     <string name="summary_glasses_single_device" msgid="3000909894067413398">"此應用程式將可在<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>上取得以下權限"</string>
-    <string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取您手機中的這項資料"</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="2396773196949578425">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 要求權限,以便在裝置間串流應用程式的內容"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
-    <string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取您手機中的這項資料"</string>
+    <string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取你手機中的這項資料"</string>
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 要求權限,以便存取手機上的相片、媒體和通知"</string>
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允許"</string>
     <string name="consent_back" msgid="2560683030046918882">"返回"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; 上的應用程式可獲在 &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; 上的相同權限嗎?"</string>
-    <string name="permission_sync_summary" msgid="765497944331294275">"這可能包括 &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; 的&lt;strong&gt;麥克風&lt;/strong&gt;、&lt;strong&gt;相機&lt;/strong&gt;和&lt;strong&gt;位置資訊存取權&lt;/strong&gt;以及其他敏感資料權限。&lt;br/&gt;&lt;br/&gt;您隨時可透過 &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; 的「設定」變更這些權限。"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"應用程式圖示"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"「更多資料」按鈕"</string>
+    <string name="permission_sync_summary" msgid="765497944331294275">"這可能包括 &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; 的&lt;strong&gt;麥克風&lt;/strong&gt;、&lt;strong&gt;相機&lt;/strong&gt;和&lt;strong&gt;位置資訊存取權&lt;/strong&gt;以及其他敏感資料權限。&lt;br/&gt;&lt;br/&gt;你隨時可透過 &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; 的「設定」變更這些權限。"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"手機"</string>
     <string name="permission_sms" msgid="6337141296535774786">"短訊"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"通訊錄"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index f22fcba..d31c74b 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允許"</string>
     <string name="consent_back" msgid="2560683030046918882">"返回"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"要讓「<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;的應用程式沿用在「<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;上的權限嗎?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"這可能包括 &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt; 的&lt;strong&gt;麥克風&lt;/strong&gt;、&lt;strong&gt;相機&lt;/strong&gt;和&lt;strong&gt;位置資訊存取權&lt;/strong&gt;以及機密權限。&lt;br/&gt;&lt;br/&gt;你隨時可透過 &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt; 的「設定」變更這些權限。"</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"應用程式圖示"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"更多資訊按鈕"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"電話"</string>
     <string name="permission_sms" msgid="6337141296535774786">"簡訊"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"聯絡人"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index 1de5713..8384e8d 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -43,10 +43,18 @@
     <string name="consent_yes" msgid="8344487259618762872">"Vumela"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ungavumeli"</string>
     <string name="consent_back" msgid="2560683030046918882">"Emuva"</string>
+    <!-- no translation found for permission_expanded (5234121789170200621) -->
+    <skip />
+    <!-- no translation found for permission_expand (1464954219517793480) -->
+    <skip />
+    <!-- no translation found for permission_collapsed (3193316780088731226) -->
+    <skip />
+    <!-- no translation found for permission_collapse (6555844383912351944) -->
+    <skip />
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Nikeza ama-app &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; izimvume ezifanayot &lt;strong&gt;njengaku-<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Lokhu kungahilela &lt;strong&gt;Imakrofoni&lt;/strong&gt;, &lt;strong&gt;Ikhamera&lt;/strong&gt;, kanye &lt;strong&gt;Nokufinyelelwa kwendawo&lt;/strong&gt;, nezinye izimvume ezizwelayo &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Ungakwazi ukushintsha lezi zimvume noma nini Kumasethingi akho ku-&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
-    <string name="vendor_icon_description" msgid="4445875290032225965">"Isithonjana Se-app"</string>
-    <string name="vendor_header_button_description" msgid="6566660389500630608">"Inkinobho Yolwazi Olwengeziwe"</string>
+    <!-- no translation found for vendor_header_button_description (7994879208461111473) -->
+    <skip />
     <string name="permission_phone" msgid="2661081078692784919">"Ifoni"</string>
     <string name="permission_sms" msgid="6337141296535774786">"I-SMS"</string>
     <string name="permission_contacts" msgid="3858319347208004438">"Oxhumana nabo"</string>
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 74072e9..2502bbf 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -113,17 +113,11 @@
     <!-- Back button for the helper consent dialog [CHAR LIMIT=30] -->
     <string name="consent_back">Back</string>
 
-    <!-- Action when permission list view is expanded CHAR LIMIT=30] -->
-    <string name="permission_expanded">Expanded</string>
+    <!-- Expand permission in the list CHAR LIMIT=30] -->
+    <string name="permission_expand">Expand <xliff:g id="permission_type" example="Notification">%1$s</xliff:g></string>
 
-    <!-- Expand action permission list CHAR LIMIT=30] -->
-    <string name="permission_expand">Expand</string>
-
-    <!-- Action when permission list view is collapsed CHAR LIMIT=30] -->
-    <string name="permission_collapsed">Collapsed</string>
-
-    <!-- Collapse action permission list CHAR LIMIT=30] -->
-    <string name="permission_collapse">Collapse</string>
+    <!-- Collapse permission int the list CHAR LIMIT=30] -->
+    <string name="permission_collapse">Collapse <xliff:g id="permission_type" example="Notification">%1$s</xliff:g></string>
 
     <!-- ================== System data transfer ==================== -->
     <!-- Title of the permission sync confirmation dialog. [CHAR LIMIT=NONE] -->
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
index b86ef64..f594bf2 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
@@ -124,7 +124,7 @@
         }
 
         setAccessibility(view, viewType,
-                AccessibilityNodeInfo.ACTION_CLICK, R.string.permission_expand);
+                AccessibilityNodeInfo.ACTION_CLICK, R.string.permission_expand, 0);
 
         // Add expand buttons if the permissions are more than PERMISSION_SIZE in this list also
         // make the summary invisible by default.
@@ -137,18 +137,16 @@
                     viewHolder.mExpandButton.setImageResource(R.drawable.btn_expand_less);
                     viewHolder.mPermissionSummary.setVisibility(View.VISIBLE);
                     viewHolder.mExpandButton.setTag(R.drawable.btn_expand_less);
-                    view.setContentDescription(mContext.getString(R.string.permission_expanded));
                     setAccessibility(view, viewType,
-                            AccessibilityNodeInfo.ACTION_CLICK, R.string.permission_collapse);
-                    viewHolder.mPermissionSummary.setFocusable(true);
+                            AccessibilityNodeInfo.ACTION_CLICK,
+                            R.string.permission_collapse, R.string.permission_expand);
                 } else {
                     viewHolder.mExpandButton.setImageResource(R.drawable.btn_expand_more);
                     viewHolder.mPermissionSummary.setVisibility(View.GONE);
                     viewHolder.mExpandButton.setTag(R.drawable.btn_expand_more);
-                    view.setContentDescription(mContext.getString(R.string.permission_collapsed));
                     setAccessibility(view, viewType,
-                            AccessibilityNodeInfo.ACTION_CLICK, R.string.permission_expanded);
-                    viewHolder.mPermissionSummary.setFocusable(false);
+                            AccessibilityNodeInfo.ACTION_CLICK,
+                            R.string.permission_expand, R.string.permission_collapse);
                 }
             });
         } else {
@@ -200,14 +198,20 @@
         }
     }
 
-    private void setAccessibility(View view, int viewType, int action, int resourceId) {
-        final String actionString = mContext.getString(resourceId);
+    private void setAccessibility(View view, int viewType, int action, int statusResourceId,
+            int actionResourceId) {
         final String permission = mContext.getString(sTitleMap.get(viewType));
+
+        if (actionResourceId != 0) {
+            view.announceForAccessibility(
+                    getHtmlFromResources(mContext, actionResourceId, permission));
+        }
+
         view.setAccessibilityDelegate(new View.AccessibilityDelegate() {
             public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
                 super.onInitializeAccessibilityNodeInfo(host, info);
                 info.addAction(new AccessibilityNodeInfo.AccessibilityAction(action,
-                        actionString + permission));
+                        getHtmlFromResources(mContext, statusResourceId, permission)));
             }
         });
     }
diff --git a/packages/CredentialManager/AndroidManifest.xml b/packages/CredentialManager/AndroidManifest.xml
index 8724d69..4161601 100644
--- a/packages/CredentialManager/AndroidManifest.xml
+++ b/packages/CredentialManager/AndroidManifest.xml
@@ -42,15 +42,6 @@
         android:excludeFromRecents="true"
         android:theme="@style/Theme.CredentialSelector">
     </activity>
-
-    <receiver
-        android:name=".CredentialProviderReceiver"
-        android:exported="true"
-        android:permission="android.permission.LAUNCH_CREDENTIAL_SELECTOR">
-        <intent-filter>
-            <action android:name="android.credentials.ui.action.CREDMAN_ENABLED_PROVIDERS_UPDATED"/>
-        </intent-filter>
-    </receiver>
   </application>
 
 </manifest>
diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml
index b093ced..18d5164 100644
--- a/packages/CredentialManager/res/values-am/strings.xml
+++ b/packages/CredentialManager/res/values-am/strings.xml
@@ -10,7 +10,7 @@
     <string name="content_description_hide_password" msgid="6841375971631767996">"የይለፍ ቃል ደብቅ"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"በይለፍ ቃል ይበልጥ ደህንነቱ የተጠበቀ"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"በይለፍ ቁልፎች ውስብስብ የይለፍ ቁልፎችን መፍጠር ወይም ማስታወስ አያስፈልግዎትም"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"የይለፍ ቁልፎች የእርስዎን የጣት አሻራ፣ መልክ ወይም የማያ ገጽ መቆለፊያ በመጠቀም የሚፈጥሯቸው የተመሰጠሩ ዲጂታል ቆልፎች ናቸው"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"የይለፍ ቁልፎች የእርስዎን የጣት አሻራ፣ መልክ ወይም የማያ ገፅ መቆለፊያ በመጠቀም የሚፈጥሯቸው የተመሰጠሩ ዲጂታል ቆልፎች ናቸው"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"በሌሎች መሣሪያዎች ላይ መግባት እንዲችሉ በሚስጥር ቁልፍ አስተዳዳሪ ላይ ይቀመጣሉ"</string>
     <string name="more_about_passkeys_title" msgid="7797903098728837795">"ስለየይለፍ ቁልፎች ተጨማሪ"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"የይለፍ ቃል የሌለው ቴክኖሎጂ"</string>
diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml
index 0f40d49..bb629f3 100644
--- a/packages/CredentialManager/res/values-mk/strings.xml
+++ b/packages/CredentialManager/res/values-mk/strings.xml
@@ -7,7 +7,7 @@
     <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="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>
diff --git a/packages/CredentialManager/res/values-zh-rHK/strings.xml b/packages/CredentialManager/res/values-zh-rHK/strings.xml
index 44484a5..524a00d 100644
--- a/packages/CredentialManager/res/values-zh-rHK/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rHK/strings.xml
@@ -9,16 +9,16 @@
     <string name="content_description_show_password" msgid="3283502010388521607">"顯示密碼"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"隱藏密碼"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"使用密鑰確保帳戶安全"</string>
-    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"有了密鑰,您便無需建立或記住複雜的密碼"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"密鑰是您使用指紋、面孔或螢幕鎖定時建立的加密數碼鑰匙"</string>
-    <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"密鑰已儲存至密碼管理工具,方便您在其他裝置上登入"</string>
+    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"有了密鑰,你便無需建立或記住複雜的密碼"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"密鑰是你使用指紋、面孔或螢幕鎖定時建立的加密數碼鑰匙"</string>
+    <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"密鑰已儲存至密碼管理工具,方便你在其他裝置上登入"</string>
     <string name="more_about_passkeys_title" msgid="7797903098728837795">"進一步瞭解密鑰"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"無密碼技術"</string>
     <string name="passwordless_technology_detail" msgid="6853928846532955882">"只要有密鑰,就無需使用密碼登入。使用指紋、面孔識別、PIN 或滑動畫出圖案,便可驗證身分並建立密鑰。"</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"公開金鑰加密技術"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"密鑰根據 FIDO 聯盟 (包括 Google、Apple、Microsoft 等) 及 W3C 標準,使用加密配對金鑰技術。私密 - 公開金鑰組專為應用程式或網站建立,與建立密碼時使用的使用者名稱和作為密碼的字元字串不同。私密金鑰會安全地儲存在裝置或密碼管理工具上,用來確認您的身分。公開金鑰會與應用程式或網站伺服器共用。只要有對應的金鑰,就能立即註冊和登入。"</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"密鑰根據 FIDO 聯盟 (包括 Google、Apple、Microsoft 等) 及 W3C 標準,使用加密配對金鑰技術。私密 - 公開金鑰組專為應用程式或網站建立,與建立密碼時使用的使用者名稱和作為密碼的字元字串不同。私密金鑰會安全地儲存在裝置或密碼管理工具上,用來確認你的身分。公開金鑰會與應用程式或網站伺服器共用。只要有對應的金鑰,就能立即註冊和登入。"</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"提升帳戶安全性"</string>
-    <string name="improved_account_security_detail" msgid="9123750251551844860">"系統會為應用程式或網站建立專用的對應金鑰,因此您不會錯誤登入欺詐的應用程式或網站。此外,伺服器上只會保留公開金鑰,因此可大幅降低駭客入侵的風險。"</string>
+    <string name="improved_account_security_detail" msgid="9123750251551844860">"系統會為應用程式或網站建立專用的對應金鑰,因此你不會錯誤登入欺詐的應用程式或網站。此外,伺服器上只會保留公開金鑰,因此可大幅降低駭客入侵的風險。"</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"流暢轉換"</string>
     <string name="seamless_transition_detail" msgid="4475509237171739843">"我們將會改用無密碼技術,而密碼仍可與密鑰並行使用。"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"選擇儲存<xliff:g id="CREATETYPES">%1$s</xliff:g>的位置"</string>
@@ -35,7 +35,7 @@
     <string name="save_credential_to_title" msgid="3172811692275634301">"將<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>儲存至"</string>
     <string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"要在其他裝置上建立密鑰嗎?"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"要將「<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>」用於所有的登入資料嗎?"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"此密碼管理工具將儲存「<xliff:g id="USERNAME">%1$s</xliff:g>」的密碼和密鑰,協助您輕鬆登入"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"此密碼管理工具將儲存「<xliff:g id="USERNAME">%1$s</xliff:g>」的密碼和密鑰,協助你輕鬆登入"</string>
     <string name="set_as_default" msgid="4415328591568654603">"設定為預設"</string>
     <string name="use_once" msgid="9027366575315399714">"單次使用"</string>
     <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> 個密碼 • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> 個密鑰"</string>
diff --git a/packages/CredentialManager/res/values/colors.xml b/packages/CredentialManager/res/values/colors.xml
deleted file mode 100644
index 09837df62..0000000
--- a/packages/CredentialManager/res/values/colors.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-  <color name="purple_200">#FFBB86FC</color>
-  <color name="purple_500">#FF6200EE</color>
-  <color name="purple_700">#FF3700B3</color>
-  <color name="teal_200">#FF03DAC5</color>
-  <color name="teal_700">#FF018786</color>
-  <color name="black">#FF000000</color>
-  <color name="white">#FFFFFFFF</color>
-</resources>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index 3e65251..3402857 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <!-- The name of this application. Credential Manager is a service that centralizes and provides
   access to a user's credentials used to sign in to various apps. [CHAR LIMIT=80] -->
@@ -71,6 +86,8 @@
   <string name="use_provider_for_all_description">This password manager for <xliff:g id="username" example="becket@gmail.com">%1$s</xliff:g> will store your passwords and passkeys to help you easily sign in</string>
   <!-- This is a label for a button that sets this password manager as the default. [CHAR LIMIT=20] -->
   <string name="set_as_default">Set as default</string>
+  <!-- This is a button text to navigate the user to their system settings. [CHAR LIMIT=30] -->
+  <string name="settings">Settings</string>
   <!-- This is a label for a button that makes this password manager be used just in this specific case. [CHAR LIMIT=20] -->
   <string name="use_once">Use once</string>
   <!-- Appears as an option row subtitle to show how many passwords and passkeys are saved in this option when there are passwords and passkeys. [CHAR LIMIT=80] -->
@@ -99,13 +116,13 @@
   <!-- Strings for the get flow. -->
   <!-- This appears as the title of the modal bottom sheet asking for user confirmation to use the single previously saved passkey to sign in to the app. [CHAR LIMIT=200] -->
   <string name="get_dialog_title_use_passkey_for">Use your saved passkey for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
-  <!-- This appears as the title of the dialog asking for user confirmation to use the single previously saved credential to sign in to the app. [CHAR LIMIT=200] -->
-  <string name="get_dialog_title_use_sign_in_for">Use your saved sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
-  <!-- This appears as the title of the dialog asking for user to make a choice from various previously saved credentials to sign in to the app. [CHAR LIMIT=200] -->
-  <string name="get_dialog_title_choose_sign_in_for">Choose a saved sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g></string>
-  <!-- This appears as the title of the dialog asking for user to make a choice from various previously saved credentials to sign in to the app. [CHAR LIMIT=200] -->
+  <!-- This appears as the title of the dialog asking for user confirmation to use the single user credential (previously saved or to be created) to sign in to the app. [CHAR LIMIT=200] -->
+  <string name="get_dialog_title_use_sign_in_for">Use your sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
+  <!-- This appears as the title of the dialog asking for user to make a choice from various available user credentials (previously saved or to be created) to sign in to the app. [CHAR LIMIT=200] -->
+  <string name="get_dialog_title_choose_sign_in_for">Choose a sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g></string>
+  <!-- This appears as the title of the dialog asking for user to make a choice from options of available user information (e.g. driver's license, vaccination status) to pass to the app. [CHAR LIMIT=200] -->
   <string name="get_dialog_title_choose_option_for">Choose an option for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
-  <!-- This appears as the title of the dialog asking user to use a previously saved credentials to sign in to the app. [CHAR LIMIT=200] -->
+  <!-- This appears as the title of the dialog asking user to send a piece of user information (e.g. driver's license, vaccination status) to the app. [CHAR LIMIT=200] -->
   <string name="get_dialog_title_use_info_on">Use this info on <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
   <!-- This is a label for a button that links the user to different sign-in methods . [CHAR LIMIT=80] -->
   <string name="get_dialog_use_saved_passkey_for">Sign in another way</string>
diff --git a/packages/CredentialManager/res/values/themes.xml b/packages/CredentialManager/res/values/themes.xml
index 428c85a..22329e9f 100644
--- a/packages/CredentialManager/res/values/themes.xml
+++ b/packages/CredentialManager/res/values/themes.xml
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
 <resources>
   <style name="Theme.CredentialSelector" parent="@*android:style/ThemeOverlay.DeviceDefault.Accent.DayNight">
     <item name="android:windowContentOverlay">@null</item>
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index a9bee03..693e767 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -107,7 +107,6 @@
 
         initialUiState = when (requestInfo?.type) {
             RequestInfo.TYPE_CREATE -> {
-                val defaultProviderIdSetByUser = userConfigRepo.getDefaultProviderId()
                 val isPasskeyFirstUse = userConfigRepo.getIsPasskeyFirstUse()
                 val providerEnableListUiState = getCreateProviderEnableListInitialUiState()
                 val providerDisableListUiState = getCreateProviderDisableListInitialUiState()
@@ -119,7 +118,8 @@
                         disabledProviders = providerDisableListUiState,
                         defaultProviderIdPreferredByApp =
                         requestDisplayInfoUiState.appPreferredDefaultProviderId,
-                        defaultProviderIdSetByUser = defaultProviderIdSetByUser,
+                        defaultProviderIdsSetByUser =
+                        requestDisplayInfoUiState.userSetDefaultProviderIds,
                         requestDisplayInfo = requestDisplayInfoUiState,
                         isOnPasskeyIntroStateAlready = false,
                         isPasskeyFirstUse = isPasskeyFirstUse,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialProviderReceiver.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialProviderReceiver.kt
deleted file mode 100644
index ee8cffe..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialProviderReceiver.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.credentialmanager
-
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.util.Log
-import com.android.credentialmanager.common.Constants
-
-
-class CredentialProviderReceiver : BroadcastReceiver() {
-
-    override fun onReceive(context: Context?, intent: Intent?) {
-        Log.d(Constants.LOG_TAG, "Received intent in CredentialProviderReceiver")
-
-        val sharedPreferences = context?.getSharedPreferences(context?.packageName,
-                Context.MODE_PRIVATE)
-        sharedPreferences?.edit()?.remove(UserConfigRepo.DEFAULT_PROVIDER)?.commit()
-    }
-}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index 8b9c8b9..6549b2d 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -16,6 +16,7 @@
 
 package com.android.credentialmanager
 
+import android.app.Activity
 import android.content.Intent
 import android.credentials.ui.BaseDialogResult
 import android.credentials.ui.RequestInfo
@@ -47,6 +48,8 @@
 class CredentialSelectorActivity : ComponentActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        overrideActivityTransition(Activity.OVERRIDE_TRANSITION_OPEN,
+            0, 0)
         Log.d(Constants.LOG_TAG, "Creating new CredentialSelectorActivity")
         try {
             val (isCancellationRequest, shouldShowCancellationUi, _) =
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index 8b74d76..de67989 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -255,7 +255,8 @@
             disabledProviders = prevUiState.disabledProviders,
             defaultProviderIdPreferredByApp =
             prevUiState.requestDisplayInfo.appPreferredDefaultProviderId,
-            defaultProviderIdSetByUser = userConfigRepo.getDefaultProviderId(),
+            defaultProviderIdsSetByUser =
+            prevUiState.requestDisplayInfo.userSetDefaultProviderIds,
             requestDisplayInfo = prevUiState.requestDisplayInfo,
             isOnPasskeyIntroStateAlready = true,
             isPasskeyFirstUse = userConfigRepo.getIsPasskeyFirstUse()
@@ -269,28 +270,10 @@
         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,
             )
         )
     }
@@ -315,7 +298,10 @@
         uiState = uiState.copy(
             createCredentialUiState = uiState.createCredentialUiState?.copy(
                 currentScreenState =
-                if (activeEntry.activeProvider.id == userConfigRepo.getDefaultProviderId() ||
+                if (uiState.createCredentialUiState?.requestDisplayInfo?.userSetDefaultProviderIds
+                        ?.contains(activeEntry.activeProvider.id) ?: true ||
+                    !(uiState.createCredentialUiState?.foundCandidateFromUserDefaultProvider
+                    ?: false) ||
                     !TextUtils.isEmpty(uiState.createCredentialUiState?.requestDisplayInfo
                         ?.appPreferredDefaultProviderId))
                     CreateScreenState.CREATION_OPTION_SELECTION
@@ -325,18 +311,7 @@
         )
     }
 
-    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() {
+    fun createFlowOnLaunchSettings() {
         credManRepo.onSettingLaunchCancel()
         uiState = uiState.copy(dialogState = DialogState.CANCELED_FOR_SETTINGS)
     }
@@ -349,16 +324,6 @@
         )
     }
 
-    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(
@@ -367,17 +332,6 @@
         )
     }
 
-    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
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index 57035d4..00c2f1a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -61,6 +61,7 @@
 import androidx.credentials.provider.PublicKeyCredentialEntry
 import androidx.credentials.provider.RemoteEntry
 import org.json.JSONObject
+import java.time.Instant
 
 // TODO: remove all !! checks
 fun getAppLabel(
@@ -420,7 +421,7 @@
                     id = it.providerFlattenedComponentName,
                     displayName = providerLabel,
                     icon = providerIcon,
-                    createOptions = toCreationOptionInfoList(
+                    sortedCreateOptions = toSortedCreationOptionInfoList(
                         it.providerFlattenedComponentName, it.saveEntries, context
                     ),
                     remoteEntry = toRemoteInfo(it.providerFlattenedComponentName, it.remoteEntry),
@@ -483,6 +484,7 @@
                     context.getDrawable(R.drawable.ic_password_24) ?: return null,
                     preferImmediatelyAvailableCredentials = false,
                     appPreferredDefaultProviderId = appPreferredDefaultProviderId,
+                    userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(),
                 )
                 is CreatePublicKeyCredentialRequest -> {
                     newRequestDisplayInfoFromPasskeyJson(
@@ -492,6 +494,7 @@
                         preferImmediatelyAvailableCredentials =
                         createCredentialRequestJetpack.preferImmediatelyAvailableCredentials,
                         appPreferredDefaultProviderId = appPreferredDefaultProviderId,
+                        userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(),
                     )
                 }
                 is CreateCustomCredentialRequest -> {
@@ -508,6 +511,7 @@
                             ?: context.getDrawable(R.drawable.ic_other_sign_in_24) ?: return null,
                         preferImmediatelyAvailableCredentials = false,
                         appPreferredDefaultProviderId = appPreferredDefaultProviderId,
+                        userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(),
                     )
                 }
                 else -> null
@@ -518,13 +522,13 @@
             enabledProviders: List<EnabledProviderInfo>,
             disabledProviders: List<DisabledProviderInfo>?,
             defaultProviderIdPreferredByApp: String?,
-            defaultProviderIdSetByUser: String?,
+            defaultProviderIdsSetByUser: Set<String>,
             requestDisplayInfo: RequestDisplayInfo,
             isOnPasskeyIntroStateAlready: Boolean,
             isPasskeyFirstUse: Boolean,
         ): CreateCredentialUiState? {
-            var lastSeenProviderWithNonEmptyCreateOptions: EnabledProviderInfo? = null
             var remoteEntry: RemoteInfo? = null
+            var remoteEntryProvider: EnabledProviderInfo? = null
             var defaultProviderPreferredByApp: EnabledProviderInfo? = null
             var defaultProviderSetByUser: EnabledProviderInfo? = null
             var createOptionsPairs:
@@ -535,14 +539,24 @@
                         defaultProviderPreferredByApp = enabledProvider
                     }
                 }
-                if (defaultProviderIdSetByUser != null) {
-                    if (enabledProvider.id == defaultProviderIdSetByUser) {
+                if (enabledProvider.sortedCreateOptions.isNotEmpty() &&
+                    defaultProviderIdsSetByUser.contains(enabledProvider.id)) {
+                    if (defaultProviderSetByUser == null) {
                         defaultProviderSetByUser = enabledProvider
+                    } else {
+                        val newLastUsedTime = enabledProvider.sortedCreateOptions.firstOrNull()
+                          ?.lastUsedTime
+                        val curLastUsedTime = defaultProviderSetByUser?.sortedCreateOptions
+                        ?.firstOrNull()?.lastUsedTime ?: Instant.MIN
+                        if (newLastUsedTime != null) {
+                            if (curLastUsedTime == null || newLastUsedTime > curLastUsedTime) {
+                                defaultProviderSetByUser = enabledProvider
+                            }
+                        }
                     }
                 }
-                if (enabledProvider.createOptions.isNotEmpty()) {
-                    lastSeenProviderWithNonEmptyCreateOptions = enabledProvider
-                    enabledProvider.createOptions.forEach {
+                if (enabledProvider.sortedCreateOptions.isNotEmpty()) {
+                    enabledProvider.sortedCreateOptions.forEach {
                         createOptionsPairs.add(Pair(it, enabledProvider))
                     }
                 }
@@ -554,6 +568,7 @@
                         return null
                     }
                     remoteEntry = currRemoteEntry
+                    remoteEntryProvider = enabledProvider
                 }
             }
             val defaultProvider = defaultProviderPreferredByApp ?: defaultProviderSetByUser
@@ -561,27 +576,26 @@
                 createOptionSize = createOptionsPairs.size,
                 isOnPasskeyIntroStateAlready = isOnPasskeyIntroStateAlready,
                 requestDisplayInfo = requestDisplayInfo,
-                defaultProvider = defaultProvider,
                 remoteEntry = remoteEntry,
                 isPasskeyFirstUse = isPasskeyFirstUse
             ) ?: return null
+            val sortedCreateOptionsPairs = createOptionsPairs.sortedWith(
+                compareByDescending { it.first.lastUsedTime }
+            )
             return CreateCredentialUiState(
                 enabledProviders = enabledProviders,
                 disabledProviders = disabledProviders,
                 currentScreenState = initialScreenState,
                 requestDisplayInfo = requestDisplayInfo,
-                sortedCreateOptionsPairs = createOptionsPairs.sortedWith(
-                    compareByDescending { it.first.lastUsedTime }
-                ),
-                hasDefaultProvider = defaultProvider != null,
+                sortedCreateOptionsPairs = sortedCreateOptionsPairs,
                 activeEntry = toActiveEntry(
-                    /*defaultProvider=*/defaultProvider,
-                    /*createOptionSize=*/createOptionsPairs.size,
-                    /*lastSeenProviderWithNonEmptyCreateOptions=*/
-                    lastSeenProviderWithNonEmptyCreateOptions,
-                    /*remoteEntry=*/remoteEntry
+                    defaultProvider = defaultProvider,
+                    sortedCreateOptionsPairs = sortedCreateOptionsPairs,
+                    remoteEntry = remoteEntry,
+                    remoteEntryProvider = remoteEntryProvider,
                 ),
                 remoteEntry = remoteEntry,
+                foundCandidateFromUserDefaultProvider = defaultProviderSetByUser != null,
             )
         }
 
@@ -589,59 +603,43 @@
             createOptionSize: Int,
             isOnPasskeyIntroStateAlready: Boolean,
             requestDisplayInfo: RequestDisplayInfo,
-            defaultProvider: EnabledProviderInfo?,
             remoteEntry: RemoteInfo?,
             isPasskeyFirstUse: Boolean,
         ): CreateScreenState? {
-            return if (isPasskeyFirstUse && requestDisplayInfo.type ==
-                CredentialType.PASSKEY && !isOnPasskeyIntroStateAlready) {
+            return if (isPasskeyFirstUse && requestDisplayInfo.type == CredentialType.PASSKEY &&
+                !isOnPasskeyIntroStateAlready) {
                 CreateScreenState.PASSKEY_INTRO
-            } else if ((defaultProvider == null || defaultProvider.createOptions.isEmpty()) &&
-                createOptionSize > 1) {
-                CreateScreenState.PROVIDER_SELECTION
-            } else if (((defaultProvider == null || defaultProvider.createOptions.isEmpty()) &&
-                    createOptionSize == 1) || (defaultProvider != null &&
-                    defaultProvider.createOptions.isNotEmpty())) {
-                CreateScreenState.CREATION_OPTION_SELECTION
             } else if (createOptionSize == 0 && remoteEntry != null) {
                 CreateScreenState.EXTERNAL_ONLY_SELECTION
             } else {
-                Log.d(
-                    Constants.LOG_TAG,
-                    "Unexpected failure: the screen state failed to instantiate" +
-                        " because the provider list is empty."
-                )
-                null
+                CreateScreenState.CREATION_OPTION_SELECTION
             }
         }
 
         private fun toActiveEntry(
             defaultProvider: EnabledProviderInfo?,
-            createOptionSize: Int,
-            lastSeenProviderWithNonEmptyCreateOptions: EnabledProviderInfo?,
+            sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
             remoteEntry: RemoteInfo?,
+            remoteEntryProvider: EnabledProviderInfo?,
         ): ActiveEntry? {
             return if (
-                defaultProvider != null && defaultProvider.createOptions.isEmpty() &&
-                remoteEntry != null
+                sortedCreateOptionsPairs.isEmpty() && remoteEntry != null &&
+                remoteEntryProvider != null
             ) {
-                ActiveEntry(defaultProvider, remoteEntry)
-            } else if (
-                defaultProvider != null && defaultProvider.createOptions.isNotEmpty()
-            ) {
-                ActiveEntry(defaultProvider, defaultProvider.createOptions.first())
-            } else if (createOptionSize == 1) {
-                ActiveEntry(
-                    lastSeenProviderWithNonEmptyCreateOptions!!,
-                    lastSeenProviderWithNonEmptyCreateOptions.createOptions.first()
-                )
+                ActiveEntry(remoteEntryProvider, remoteEntry)
+            } else if (defaultProvider != null &&
+                defaultProvider.sortedCreateOptions.isNotEmpty()) {
+                ActiveEntry(defaultProvider, defaultProvider.sortedCreateOptions.first())
+            } else if (sortedCreateOptionsPairs.isNotEmpty()) {
+                val (topEntry, topEntryProvider) = sortedCreateOptionsPairs.first()
+                ActiveEntry(topEntryProvider, topEntry)
             } else null
         }
 
         /**
          * Note: caller required handle empty list due to parsing error.
          */
-        private fun toCreationOptionInfoList(
+        private fun toSortedCreationOptionInfoList(
             providerId: String,
             creationEntries: List<Entry>,
             context: Context,
@@ -664,7 +662,9 @@
                     footerDescription = createEntry.description?.toString()
                 ))
             }
-            return result
+            return result.sortedWith(
+                compareByDescending { it.lastUsedTime }
+            )
         }
 
         private fun toRemoteInfo(
@@ -690,6 +690,7 @@
             context: Context,
             preferImmediatelyAvailableCredentials: Boolean,
             appPreferredDefaultProviderId: String?,
+            userSetDefaultProviderIds: Set<String>,
         ): RequestDisplayInfo? {
             val json = JSONObject(requestJson)
             var passkeyUsername = ""
@@ -711,6 +712,7 @@
                 context.getDrawable(R.drawable.ic_passkey_24) ?: return null,
                 preferImmediatelyAvailableCredentials,
                 appPreferredDefaultProviderId,
+                userSetDefaultProviderIds,
             )
         }
     }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/UserConfigRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/UserConfigRepo.kt
index a17f2c8..bfcca49 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/UserConfigRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/UserConfigRepo.kt
@@ -23,15 +23,6 @@
     val sharedPreferences: SharedPreferences = context.getSharedPreferences(
         context.packageName, Context.MODE_PRIVATE)
 
-    fun setDefaultProvider(
-        providerId: String
-    ) {
-        sharedPreferences.edit().apply {
-            putString(DEFAULT_PROVIDER, providerId)
-            apply()
-        }
-    }
-
     fun setIsPasskeyFirstUse(
         isFirstUse: Boolean
     ) {
@@ -41,16 +32,11 @@
         }
     }
 
-    fun getDefaultProviderId(): String? {
-        return sharedPreferences.getString(DEFAULT_PROVIDER, null)
-    }
-
     fun getIsPasskeyFirstUse(): Boolean {
         return sharedPreferences.getBoolean(IS_PASSKEY_FIRST_USE, true)
     }
 
     companion object {
-        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"
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 10a75d4..250e3b1 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/material/ModalBottomSheet.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/material/ModalBottomSheet.kt
@@ -454,7 +454,7 @@
     if (color.isSpecified) {
         val alpha by animateFloatAsState(
             targetValue = if (visible) 1f else 0f,
-            animationSpec = TweenSpec()
+            animationSpec = TweenSpec(durationMillis = SwipeableDefaults.DefaultDurationMillis)
         )
         LocalConfiguration.current
         val resources = LocalContext.current.resources
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/material/Swipeable.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/material/Swipeable.kt
index 3e2de83..e9aaeee 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/material/Swipeable.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/material/Swipeable.kt
@@ -19,6 +19,7 @@
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.SpringSpec
+import androidx.compose.animation.core.Spring
 import androidx.compose.foundation.gestures.DraggableState
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.draggable
@@ -791,7 +792,12 @@
     /**
      * The default animation used by [SwipeableState].
      */
-    val AnimationSpec = SpringSpec<Float>()
+    val AnimationSpec = SpringSpec<Float>(stiffness = Spring.StiffnessMediumLow)
+
+    /**
+     * The default animation duration used by Scrim in enter/exit transitions.
+     */
+    val DefaultDurationMillis: Int = 400
 
     /**
      * The default velocity threshold (1.8 dp per millisecond) used by [swipeable].
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
index 53731f0..3399681 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
@@ -20,6 +20,11 @@
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import com.android.compose.rememberSystemUiController
@@ -28,6 +33,8 @@
 import com.android.credentialmanager.common.material.rememberModalBottomSheetState
 import com.android.credentialmanager.ui.theme.EntryShape
 import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
+import kotlinx.coroutines.launch
+
 
 /** Draws a modal bottom sheet with the same styles and effects shared by various flows. */
 @Composable
@@ -35,8 +42,10 @@
     sheetContent: @Composable ColumnScope.() -> Unit,
     onDismiss: () -> Unit
 ) {
+    var isInitialRender by remember { mutableStateOf(true) }
+    val scope = rememberCoroutineScope()
     val state = rememberModalBottomSheetState(
-        initialValue = ModalBottomSheetValue.Expanded,
+        initialValue = ModalBottomSheetValue.Hidden,
         skipHalfExpanded = true
     )
     val sysUiController = rememberSystemUiController()
@@ -54,7 +63,12 @@
     ) {}
     LaunchedEffect(state.currentValue) {
         if (state.currentValue == ModalBottomSheetValue.Hidden) {
-            onDismiss()
+            if (isInitialRender) {
+                isInitialRender = false
+                scope.launch { state.show() }
+            } else {
+                onDismiss()
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index 9d871ed..dfa517b 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -88,27 +88,11 @@
                                 onLearnMore = viewModel::createFlowOnLearnMore,
                                 onLog = { viewModel.logUiEvent(it) },
                         )
-                        CreateScreenState.PROVIDER_SELECTION -> ProviderSelectionCard(
-                                requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
-                                disabledProviderList = createCredentialUiState
-                                        .disabledProviders,
-                                sortedCreateOptionsPairs =
-                                createCredentialUiState.sortedCreateOptionsPairs,
-                                hasRemoteEntry = createCredentialUiState.remoteEntry != null,
-                                onOptionSelected =
-                                viewModel::createFlowOnEntrySelectedFromFirstUseScreen,
-                                onDisabledProvidersSelected =
-                                viewModel::createFlowOnDisabledProvidersSelected,
-                                onMoreOptionsSelected =
-                                viewModel::createFlowOnMoreOptionsSelectedOnProviderSelection,
-                                onLog = { viewModel.logUiEvent(it) },
-                        )
                         CreateScreenState.CREATION_OPTION_SELECTION -> CreationSelectionCard(
                                 requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
                                 enabledProviderList = createCredentialUiState.enabledProviders,
                                 providerInfo = createCredentialUiState
                                         .activeEntry?.activeProvider!!,
-                                hasDefaultProvider = createCredentialUiState.hasDefaultProvider,
                                 createOptionInfo =
                                 createCredentialUiState.activeEntry.activeEntryInfo
                                         as CreateOptionInfo,
@@ -121,21 +105,15 @@
                         CreateScreenState.MORE_OPTIONS_SELECTION -> MoreOptionsSelectionCard(
                                 requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
                                 enabledProviderList = createCredentialUiState.enabledProviders,
-                                disabledProviderList = createCredentialUiState
-                                        .disabledProviders,
+                                disabledProviderList = createCredentialUiState.disabledProviders,
                                 sortedCreateOptionsPairs =
                                 createCredentialUiState.sortedCreateOptionsPairs,
-                                hasDefaultProvider = createCredentialUiState.hasDefaultProvider,
-                                isFromProviderSelection =
-                                createCredentialUiState.isFromProviderSelection!!,
-                                onBackProviderSelectionButtonSelected =
-                                viewModel::createFlowOnBackProviderSelectionButtonSelected,
                                 onBackCreationSelectionButtonSelected =
                                 viewModel::createFlowOnBackCreationSelectionButtonSelected,
                                 onOptionSelected =
                                 viewModel::createFlowOnEntrySelectedFromMoreOptionScreen,
                                 onDisabledProvidersSelected =
-                                viewModel::createFlowOnDisabledProvidersSelected,
+                                viewModel::createFlowOnLaunchSettings,
                                 onRemoteEntrySelected = viewModel::createFlowOnEntrySelected,
                                 onLog = { viewModel.logUiEvent(it) },
                         )
@@ -144,11 +122,11 @@
                                 viewModel.onIllegalUiState("Expect active entry to be non-null" +
                                         " upon default provider dialog.")
                             } else {
-                                DefaultProviderConfirmationCard(
+                                NonDefaultUsageConfirmationCard(
                                         selectedEntry = createCredentialUiState.activeEntry,
                                         onIllegalScreenState = viewModel::onIllegalUiState,
-                                        onChangeDefaultSelected =
-                                        viewModel::createFlowOnChangeDefaultSelected,
+                                        onLaunchSettings =
+                                        viewModel::createFlowOnLaunchSettings,
                                         onUseOnceSelected = viewModel::createFlowOnUseOnceSelected,
                                         onLog = { viewModel.logUiEvent(it) },
                                 )
@@ -263,94 +241,11 @@
 }
 
 @Composable
-fun ProviderSelectionCard(
-    requestDisplayInfo: RequestDisplayInfo,
-    disabledProviderList: List<DisabledProviderInfo>?,
-    sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
-    hasRemoteEntry: Boolean,
-    onOptionSelected: (ActiveEntry) -> Unit,
-    onDisabledProvidersSelected: () -> Unit,
-    onMoreOptionsSelected: () -> Unit,
-    onLog: @Composable (UiEventEnum) -> Unit,
-) {
-    SheetContainerCard {
-        item { HeadlineIcon(bitmap = requestDisplayInfo.typeIcon.toBitmap().asImageBitmap()) }
-        item { Divider(thickness = 16.dp, color = Color.Transparent) }
-        item {
-            HeadlineText(
-                text = stringResource(
-                    R.string.choose_provider_title,
-                    when (requestDisplayInfo.type) {
-                        CredentialType.PASSKEY ->
-                            stringResource(R.string.passkeys)
-                        CredentialType.PASSWORD ->
-                            stringResource(R.string.passwords)
-                        CredentialType.UNKNOWN -> stringResource(R.string.sign_in_info)
-                    }
-                )
-            )
-        }
-        item { Divider(thickness = 24.dp, color = Color.Transparent) }
-
-        item {
-            Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
-                BodyMediumText(text = stringResource(R.string.choose_provider_body))
-            }
-        }
-        item { Divider(thickness = 16.dp, color = Color.Transparent) }
-        item {
-            CredentialContainerCard {
-                Column(
-                    verticalArrangement = Arrangement.spacedBy(2.dp)
-                ) {
-                    sortedCreateOptionsPairs.forEach { entry ->
-                        MoreOptionsInfoRow(
-                            requestDisplayInfo = requestDisplayInfo,
-                            providerInfo = entry.second,
-                            createOptionInfo = entry.first,
-                            onOptionSelected = {
-                                onOptionSelected(
-                                    ActiveEntry(
-                                        entry.second,
-                                        entry.first
-                                    )
-                                )
-                            }
-                        )
-                    }
-                    MoreOptionsDisabledProvidersRow(
-                        disabledProviders = disabledProviderList,
-                        onDisabledProvidersSelected = onDisabledProvidersSelected,
-                    )
-                }
-            }
-        }
-        if (hasRemoteEntry) {
-            item { Divider(thickness = 24.dp, color = Color.Transparent) }
-            item {
-                CtaButtonRow(
-                    leftButton = {
-                        ActionButton(
-                            stringResource(R.string.string_more_options),
-                            onMoreOptionsSelected
-                        )
-                    }
-                )
-            }
-        }
-    }
-    onLog(CreateCredentialEvent.CREDMAN_CREATE_CRED_PROVIDER_SELECTION)
-}
-
-@Composable
 fun MoreOptionsSelectionCard(
         requestDisplayInfo: RequestDisplayInfo,
         enabledProviderList: List<EnabledProviderInfo>,
         disabledProviderList: List<DisabledProviderInfo>?,
         sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
-        hasDefaultProvider: Boolean,
-        isFromProviderSelection: Boolean,
-        onBackProviderSelectionButtonSelected: () -> Unit,
         onBackCreationSelectionButtonSelected: () -> Unit,
         onOptionSelected: (ActiveEntry) -> Unit,
         onDisabledProvidersSelected: () -> Unit,
@@ -369,9 +264,7 @@
                     CredentialType.UNKNOWN -> stringResource(R.string.sign_in_info)
                 }
             ),
-            onNavigationIconClicked =
-            if (isFromProviderSelection) onBackProviderSelectionButtonSelected
-            else onBackCreationSelectionButtonSelected,
+            onNavigationIconClicked = onBackCreationSelectionButtonSelected,
             bottomPadding = 16.dp,
         )
     }) {
@@ -379,30 +272,26 @@
         item {
             CredentialContainerCard {
                 Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
-                    // Only in the flows with default provider(not first time use) we can show the
-                    // createOptions here, or they will be shown on ProviderSelectionCard
-                    if (hasDefaultProvider) {
-                        sortedCreateOptionsPairs.forEach { entry ->
-                            MoreOptionsInfoRow(
-                                requestDisplayInfo = requestDisplayInfo,
-                                providerInfo = entry.second,
-                                createOptionInfo = entry.first,
-                                onOptionSelected = {
-                                    onOptionSelected(
-                                        ActiveEntry(
-                                            entry.second,
-                                            entry.first
-                                        )
+                    sortedCreateOptionsPairs.forEach { entry ->
+                        MoreOptionsInfoRow(
+                            requestDisplayInfo = requestDisplayInfo,
+                            providerInfo = entry.second,
+                            createOptionInfo = entry.first,
+                            onOptionSelected = {
+                                onOptionSelected(
+                                    ActiveEntry(
+                                        entry.second,
+                                        entry.first
                                     )
-                                }
-                            )
-                        }
-                        MoreOptionsDisabledProvidersRow(
-                            disabledProviders = disabledProviderList,
-                            onDisabledProvidersSelected =
-                            onDisabledProvidersSelected,
+                                )
+                            }
                         )
                     }
+                    MoreOptionsDisabledProvidersRow(
+                        disabledProviders = disabledProviderList,
+                        onDisabledProvidersSelected =
+                        onDisabledProvidersSelected,
+                    )
                     enabledProviderList.forEach {
                         if (it.remoteEntry != null) {
                             RemoteEntryRow(
@@ -420,10 +309,10 @@
 }
 
 @Composable
-fun DefaultProviderConfirmationCard(
+fun NonDefaultUsageConfirmationCard(
         selectedEntry: ActiveEntry,
         onIllegalScreenState: (String) -> Unit,
-        onChangeDefaultSelected: () -> Unit,
+        onLaunchSettings: () -> Unit,
         onUseOnceSelected: () -> Unit,
         onLog: @Composable (UiEventEnum) -> Unit,
 ) {
@@ -454,14 +343,14 @@
             CtaButtonRow(
                 leftButton = {
                     ActionButton(
-                        stringResource(R.string.use_once),
-                        onClick = onUseOnceSelected
+                        stringResource(R.string.settings),
+                        onClick = onLaunchSettings,
                     )
                 },
                 rightButton = {
                     ConfirmButton(
-                        stringResource(R.string.set_as_default),
-                        onClick = onChangeDefaultSelected
+                        stringResource(R.string.use_once),
+                        onClick = onUseOnceSelected,
                     )
                 },
             )
@@ -479,7 +368,6 @@
         onOptionSelected: (BaseEntry) -> Unit,
         onConfirm: () -> Unit,
         onMoreOptionsSelected: () -> Unit,
-        hasDefaultProvider: Boolean,
         onLog: @Composable (UiEventEnum) -> Unit,
 ) {
     SheetContainerCard {
@@ -527,16 +415,9 @@
             if (enabledProvider.remoteEntry != null) {
                 remoteEntry = enabledProvider.remoteEntry
             }
-            createOptionsSize += enabledProvider.createOptions.size
+            createOptionsSize += enabledProvider.sortedCreateOptions.size
         }
-        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
-        }
+        val shouldShowMoreOptionsButton = createOptionsSize > 1 || remoteEntry != null
         item {
             CtaButtonRow(
                 leftButton = if (shouldShowMoreOptionsButton) {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
index 225dbf2..fe1ce1b 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
@@ -29,12 +29,9 @@
   val currentScreenState: CreateScreenState,
   val requestDisplayInfo: RequestDisplayInfo,
   val sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
-  // Should not change with the real time update of default provider, only determine whether
-  // we're showing provider selection page at the beginning
-  val hasDefaultProvider: Boolean,
   val activeEntry: ActiveEntry? = null,
   val remoteEntry: RemoteInfo? = null,
-  val isFromProviderSelection: Boolean? = null,
+  val foundCandidateFromUserDefaultProvider: Boolean,
 )
 
 internal fun hasContentToDisplay(state: CreateCredentialUiState): Boolean {
@@ -50,11 +47,12 @@
 )
 
 class EnabledProviderInfo(
-  icon: Drawable,
-  id: String,
-  displayName: String,
-  var createOptions: List<CreateOptionInfo>,
-  var remoteEntry: RemoteInfo?,
+    icon: Drawable,
+    id: String,
+    displayName: String,
+    // Sorted by last used time
+    var sortedCreateOptions: List<CreateOptionInfo>,
+    var remoteEntry: RemoteInfo?,
 ) : ProviderInfo(icon, id, displayName)
 
 class DisabledProviderInfo(
@@ -108,6 +106,7 @@
   val typeIcon: Drawable,
   val preferImmediatelyAvailableCredentials: Boolean,
   val appPreferredDefaultProviderId: String?,
+  val userSetDefaultProviderIds: Set<String>,
 )
 
 /**
@@ -123,7 +122,6 @@
 enum class CreateScreenState {
   PASSKEY_INTRO,
   MORE_ABOUT_PASSKEYS_INTRO,
-  PROVIDER_SELECTION,
   CREATION_OPTION_SELECTION,
   MORE_OPTIONS_SELECTION,
   DEFAULT_PROVIDER_CONFIRMATION,
diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp
index fd982f5..6ecd328 100644
--- a/packages/PackageInstaller/Android.bp
+++ b/packages/PackageInstaller/Android.bp
@@ -39,8 +39,7 @@
 
     certificate: "platform",
     privileged: true,
-    platform_apis: false,
-    sdk_version: "system_current",
+    platform_apis: true,
     rename_resources_package: false,
     static_libs: [
         "xz-java",
@@ -57,8 +56,7 @@
 
     certificate: "platform",
     privileged: true,
-    platform_apis: false,
-    sdk_version: "system_current",
+    platform_apis: true,
     rename_resources_package: false,
     overrides: ["PackageInstaller"],
 
@@ -77,8 +75,7 @@
 
     certificate: "platform",
     privileged: true,
-    platform_apis: false,
-    sdk_version: "system_current",
+    platform_apis: true,
     rename_resources_package: false,
     overrides: ["PackageInstaller"],
 
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index 9ee6fbd..6ccebfd 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -9,6 +9,7 @@
     <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
     <uses-permission android:name="android.permission.DELETE_PACKAGES" />
     <uses-permission android:name="android.permission.READ_INSTALL_SESSIONS" />
+    <uses-permission android:name="android.permission.READ_INSTALLED_SESSION_PATHS" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" />
     <uses-permission android:name="android.permission.USE_RESERVED_DISK" />
diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml
index efb73b4..9005718 100644
--- a/packages/PackageInstaller/res/values-es/strings.xml
+++ b/packages/PackageInstaller/res/values-es/strings.xml
@@ -26,7 +26,7 @@
     <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_reminder" msgid="3750986542284587290">"¿Actualizar esta aplicación con <xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>?\n\nEsta aplicación suele recibir actualizaciones de <xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>. Si actualizas a través de otra fuente, puede que recibas futuras actualizaciones de cualquier fuente de tu teléfono. La funcionalidad de la aplicación puede cambiar."</string>
+    <string name="install_confirm_question_update_owner_reminder" msgid="3750986542284587290">"¿Actualizar esta aplicación a través de <xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>?\n\nEsta aplicación normalmente recibe actualizaciones a través de <xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>. Si la actualizas usando otra fuente, puede que recibas futuras actualizaciones a través de cualquier fuente en tu teléfono. La funcionalidad de la aplicación puede cambiar."</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>
diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
index 6412eff..b36770d 100644
--- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
@@ -34,11 +34,11 @@
     <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"此應用程式與電視不兼容。"</string>
     <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"應用程式與手機不兼容,無法安裝應用程式。"</string>
     <string name="install_failed_invalid_apk" msgid="8581007676422623930">"套件似乎無效,無法安裝應用程式。"</string>
-    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"無法在您的平板電腦上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
-    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"無法在您的電視上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
-    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"無法在您的手機上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"無法在你的平板電腦上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"無法在你的電視上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"無法在你的手機上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
     <string name="launch" msgid="3952550563999890101">"開啟"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"您的管理員不允許安裝來自不明來源的應用程式"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"你的管理員不允許安裝來自不明來源的應用程式"</string>
     <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"此使用者無法安裝來源不明的應用程式"</string>
     <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"此使用者無法安裝應用程式"</string>
     <string name="ok" msgid="7871959885003339302">"確定"</string>
@@ -55,9 +55,9 @@
     <string name="uninstall_application_title" msgid="4045420072401428123">"解除安裝應用程式"</string>
     <string name="uninstall_update_title" msgid="824411791011583031">"解除安裝更新"</string>
     <string name="uninstall_activity_text" msgid="1928194674397770771">"「<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>」屬於以下應用程式:"</string>
-    <string name="uninstall_application_text" msgid="3816830743706143980">"您要解除安裝此應用程式嗎?"</string>
-    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"您要為"<b>"所有"</b>"使用者解除安裝這個應用程式嗎?應用程式及其資料會從裝置上的"<b>"所有"</b>"使用者設定檔中移除。"</string>
-    <string name="uninstall_application_text_user" msgid="498072714173920526">"您要為使用者<xliff:g id="USERNAME">%1$s</xliff:g>解除安裝此應用程式嗎?"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"你要解除安裝此應用程式嗎?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"你要為"<b>"所有"</b>"使用者解除安裝這個應用程式嗎?應用程式及其資料會從裝置上的"<b>"所有"</b>"使用者設定檔中移除。"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"你要為使用者<xliff:g id="USERNAME">%1$s</xliff:g>解除安裝此應用程式嗎?"</string>
     <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"要從工作設定檔解除安裝此應用程式嗎?"</string>
     <string name="uninstall_update_text" msgid="863648314632448705">"要將此應用程式回復至原廠版本嗎?系統會移除所有資料。"</string>
     <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"要將此應用程式回復至原廠版本嗎?系統會移除所有資料。此裝置的所有使用者 (包括使用工作設定檔的使用者) 亦會受影響。"</string>
@@ -77,8 +77,8 @@
     <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"無法解除安裝可用的裝置管理員應用程式"</string>
     <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"無法為<xliff:g id="USERNAME">%1$s</xliff:g>解除安裝可用的裝置管理員應用程式"</string>
     <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"部分使用者或設定檔需要使用此應用程式,因此無法完全解除安裝"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"這是您設定檔所需的應用程式,因此無法解除安裝。"</string>
-    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"這是您的裝置管理員要求安裝的應用程式,因此無法解除安裝。"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"這是你設定檔所需的應用程式,因此無法解除安裝。"</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"這是你的裝置管理員要求安裝的應用程式,因此無法解除安裝。"</string>
     <string name="manage_device_administrators" msgid="3092696419363842816">"管理裝置管理員應用程式"</string>
     <string name="manage_users" msgid="1243995386982560813">"管理使用者"</string>
     <string name="uninstall_failed_msg" msgid="2176744834786696012">"無法解除安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
@@ -87,13 +87,13 @@
     <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear 不支援安裝/解除安裝操作。"</string>
     <string name="message_staging" msgid="8032722385658438567">"正在準備安裝應用程式…"</string>
     <string name="app_name_unknown" msgid="6881210203354323926">"不明"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"為安全起見,您的平板電腦目前不得安裝此來源的不明應用程式。您可以在「設定」中變更這項設定。"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"為安全起見,您的電視目前不得安裝此來源的不明應用程式。您可以在「設定」中變更這項設定。"</string>
-    <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"為安全起見,您的手錶目前不得安裝此來源的不明應用程式。您可以在「設定」中變更這項設定。"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"為安全起見,您的手機目前不得安裝此來源的不明應用程式。您可以在「設定」中變更這項設定。"</string>
-    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"來源不明的應用程式可能會侵害您的手機和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致手機損壞或資料遺失的責任。"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"來源不明的應用程式可能會侵害您的平板電腦和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致平板電腦損壞或資料遺失的責任。"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"來源不明的應用程式可能會侵害您的電視和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致電視損壞或資料遺失的責任。"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"為安全起見,你的平板電腦目前不得安裝此來源的不明應用程式。你可以在「設定」中變更這項設定。"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"為安全起見,你的電視目前不得安裝此來源的不明應用程式。你可以在「設定」中變更這項設定。"</string>
+    <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"為安全起見,你的手錶目前不得安裝此來源的不明應用程式。你可以在「設定」中變更這項設定。"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"為安全起見,你的手機目前不得安裝此來源的不明應用程式。你可以在「設定」中變更這項設定。"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"來源不明的應用程式可能會侵害你的手機和個人資料。安裝此應用程式,即表示你同意承擔因使用這個應用程式而導致手機損壞或資料遺失的責任。"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"來源不明的應用程式可能會侵害你的平板電腦和個人資料。安裝此應用程式,即表示你同意承擔因使用這個應用程式而導致平板電腦損壞或資料遺失的責任。"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"來源不明的應用程式可能會侵害你的電視和個人資料。安裝此應用程式,即表示你同意承擔因使用這個應用程式而導致電視損壞或資料遺失的責任。"</string>
     <string name="cloned_app_label" msgid="7503612829833756160">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」複製本"</string>
     <string name="anonymous_source_continue" msgid="4375745439457209366">"繼續"</string>
     <string name="external_sources_settings" msgid="4046964413071713807">"設定"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index c81e75b..3ba2acb 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -375,16 +375,15 @@
             final int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID,
                     -1 /* defaultValue */);
             final SessionInfo info = mInstaller.getSessionInfo(sessionId);
-            final String resolvedBaseCodePath = intent.getStringExtra(
-                    PackageInstaller.EXTRA_RESOLVED_BASE_PATH);
-            if (info == null || !info.isSealed() || resolvedBaseCodePath == null) {
+            String resolvedPath = info.getResolvedBaseApkPath();
+            if (info == null || !info.isSealed() || resolvedPath == null) {
                 Log.w(TAG, "Session " + mSessionId + " in funky state; ignoring");
                 finish();
                 return;
             }
 
             mSessionId = sessionId;
-            packageSource = Uri.fromFile(new File(resolvedBaseCodePath));
+            packageSource = Uri.fromFile(new File(resolvedPath));
             mOriginatingURI = null;
             mReferrerURI = null;
             mPendingUserActionReason = info.getPendingUserActionReason();
diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml
index c1cec38..d5dc97a 100644
--- a/packages/PrintSpooler/res/values-am/strings.xml
+++ b/packages/PrintSpooler/res/values-am/strings.xml
@@ -39,7 +39,7 @@
     <string name="all_printers" msgid="5018829726861876202">"ሁሉም አታሚዎች…"</string>
     <string name="print_dialog" msgid="32628687461331979">"የህትመት መገናኛ"</string>
     <string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
-    <string name="page_description_template" msgid="6831239682256197161">"ገጽ <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> ከ<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
+    <string name="page_description_template" msgid="6831239682256197161">"ገፅ <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> ከ<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
     <string name="summary_template" msgid="8899734908625669193">"ማጠቃለያ፣ ቅጂዎች <xliff:g id="COPIES">%1$s</xliff:g>፣ የወረቀት መጠን <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
     <string name="expand_handle" msgid="7282974448109280522">"እጀታን ወደ ውጭ ላክ"</string>
     <string name="collapse_handle" msgid="6886637989442507451">"እጀታን ሰብስብ"</string>
diff --git a/packages/PrintSpooler/res/values-zh-rHK/strings.xml b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
index 9a98cee..aa0af31 100644
--- a/packages/PrintSpooler/res/values-zh-rHK/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
@@ -88,7 +88,7 @@
     <string name="no_connection_to_printer" msgid="2159246915977282728">"尚未與打印機連線"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用 <xliff:g id="SERVICE">%1$s</xliff:g> 嗎?"</string>
-    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文件可能會通過一部或多部伺服器才傳送至打印機。"</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"你的文件可能會通過一部或多部伺服器才傳送至打印機。"</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"黑白"</item>
     <item msgid="2762241247228983754">"彩色"</item>
diff --git a/packages/SettingsLib/AppPreference/res/values-de/strings.xml b/packages/SettingsLib/AppPreference/res/values-de/strings.xml
new file mode 100644
index 0000000..d48a9fa
--- /dev/null
+++ b/packages/SettingsLib/AppPreference/res/values-de/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="install_type_instant" msgid="7217305006127216917">"Instant App"</string>
+</resources>
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index 01f92c4..19b7e85 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -17,6 +17,7 @@
 package com.android.settingslib.collapsingtoolbar;
 
 import android.app.ActionBar;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -59,7 +60,8 @@
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        if (mCustomizeLayoutResId > 0 && !BuildCompatUtils.isAtLeastS()) {
+        // for backward compatibility on R devices or wearable devices due to small device size.
+        if (mCustomizeLayoutResId > 0 && (!BuildCompatUtils.isAtLeastS() || isWatch())) {
             super.setContentView(mCustomizeLayoutResId);
             return;
         }
@@ -157,6 +159,14 @@
         return getToolbarDelegate().getAppBarLayout();
     }
 
+    private boolean isWatch() {
+        PackageManager packageManager = getPackageManager();
+        if (packageManager == null) {
+            return false;
+        }
+        return packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH);
+    }
+
     private CollapsingToolbarDelegate getToolbarDelegate() {
         if (mToolbardelegate == null) {
             mToolbardelegate = new CollapsingToolbarDelegate(new DelegateCallback());
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
index 76e1df1..ea4ac2c 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
@@ -62,7 +62,6 @@
     private SparseIntArray mPostureRotationLockSettings;
     private SparseIntArray mPostureDefaultRotationLockSettings;
     private SparseIntArray mPostureRotationLockFallbackSettings;
-    private String mLastSettingValue;
     private List<SettableDeviceState> mSettableDeviceStates;
 
     @VisibleForTesting
@@ -209,10 +208,7 @@
     }
 
     private void initializeInMemoryMap() {
-        String serializedSetting =
-                mSecureSettings.getStringForUser(
-                        Settings.Secure.DEVICE_STATE_ROTATION_LOCK,
-                        UserHandle.USER_CURRENT);
+        String serializedSetting = getPersistedSettingValue();
         if (TextUtils.isEmpty(serializedSetting)) {
             // No settings saved, we should load the defaults and persist them.
             fallbackOnDefaults();
@@ -290,19 +286,25 @@
     }
 
     private void persistSettingIfChanged(String newSettingValue) {
+        String lastSettingValue = getPersistedSettingValue();
         Log.v(TAG, "persistSettingIfChanged: "
-                + "last=" + mLastSettingValue + ", "
+                + "last=" + lastSettingValue + ", "
                 + "new=" + newSettingValue);
-        if (TextUtils.equals(mLastSettingValue, newSettingValue)) {
+        if (TextUtils.equals(lastSettingValue, newSettingValue)) {
             return;
         }
-        mLastSettingValue = newSettingValue;
         mSecureSettings.putStringForUser(
                 Settings.Secure.DEVICE_STATE_ROTATION_LOCK,
                 /* value= */ newSettingValue,
                 UserHandle.USER_CURRENT);
     }
 
+    private String getPersistedSettingValue() {
+        return mSecureSettings.getStringForUser(
+                Settings.Secure.DEVICE_STATE_ROTATION_LOCK,
+                UserHandle.USER_CURRENT);
+    }
+
     private void loadDefaults() {
         mSettableDeviceStates = new ArrayList<>(mPostureRotationLockDefaults.length);
         mPostureDefaultRotationLockSettings = new SparseIntArray(
@@ -351,7 +353,6 @@
         pw.println("mDeviceStateRotationLockSettings: " + mPostureRotationLockSettings);
         pw.println("mPostureRotationLockFallbackSettings: " + mPostureRotationLockFallbackSettings);
         pw.println("mSettableDeviceStates: " + mSettableDeviceStates);
-        pw.println("mLastSettingValue: " + mLastSettingValue);
         pw.decreaseIndent();
     }
 
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt
index 9c70be9..6a13eb8 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt
@@ -19,6 +19,7 @@
 import android.content.Context
 import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_FOLDED
 import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_HALF_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY
 import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNFOLDED
 import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNKNOWN
 import android.provider.Settings.Secure.DeviceStateRotationLockKey
@@ -33,6 +34,8 @@
         context.resources.getIntArray(R.array.config_halfFoldedDeviceStates)
     private val unfoldedDeviceStates =
         context.resources.getIntArray(R.array.config_openDeviceStates)
+    private val rearDisplayDeviceStates =
+        context.resources.getIntArray(R.array.config_rearDisplayDeviceStates)
 
     @DeviceStateRotationLockKey
     fun deviceStateToPosture(deviceState: Int): Int {
@@ -40,6 +43,7 @@
             in foldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_FOLDED
             in halfFoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_HALF_FOLDED
             in unfoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_UNFOLDED
+            in rearDisplayDeviceStates -> DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY
             else -> DEVICE_STATE_ROTATION_KEY_UNKNOWN
         }
     }
@@ -49,6 +53,7 @@
             DEVICE_STATE_ROTATION_KEY_FOLDED -> foldedDeviceStates.firstOrNull()
             DEVICE_STATE_ROTATION_KEY_HALF_FOLDED -> halfFoldedDeviceStates.firstOrNull()
             DEVICE_STATE_ROTATION_KEY_UNFOLDED -> unfoldedDeviceStates.firstOrNull()
+            DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY -> rearDisplayDeviceStates.firstOrNull()
             else -> null
         }
     }
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_ic_info.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_ic_info.xml
deleted file mode 100644
index c8037c8..0000000
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_ic_info.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<!-- copy from frameworks/base/core/res/res/drawable/ic_info.xml-->
-<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="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
-</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
index ca84db8..b1c26e8 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
@@ -46,16 +46,6 @@
             android:textAppearance="?android:attr/textAppearanceListItem"
             style="@style/MainSwitchText.Settingslib" />
 
-        <ImageView
-            android:id="@+id/restricted_icon"
-            android:layout_width="@dimen/settingslib_restricted_icon_size"
-            android:layout_height="@dimen/settingslib_restricted_icon_size"
-            android:tint="?android:attr/colorAccent"
-            android:layout_gravity="center_vertical"
-            android:layout_marginEnd="@dimen/settingslib_restricted_icon_margin_end"
-            android:src="@drawable/settingslib_ic_info"
-            android:visibility="gone" />
-
         <Switch
             android:id="@android:id/switch_widget"
             android:layout_width="wrap_content"
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v33/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v33/settingslib_main_switch_bar.xml
index 2aa26e3..ab0cf31 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v33/settingslib_main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v33/settingslib_main_switch_bar.xml
@@ -49,16 +49,6 @@
             android:lineBreakWordStyle="phrase"
             style="@style/MainSwitchText.Settingslib" />
 
-        <ImageView
-            android:id="@+id/restricted_icon"
-            android:layout_width="@dimen/settingslib_restricted_icon_size"
-            android:layout_height="@dimen/settingslib_restricted_icon_size"
-            android:tint="?android:attr/colorAccent"
-            android:layout_gravity="center_vertical"
-            android:layout_marginEnd="@dimen/settingslib_restricted_icon_margin_end"
-            android:src="@drawable/settingslib_ic_info"
-            android:visibility="gone" />
-
         <Switch
             android:id="@android:id/switch_widget"
             android:layout_width="wrap_content"
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml
index b39d09f..bf34db9 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_bar.xml
@@ -38,17 +38,6 @@
         android:layout_marginStart="@dimen/settingslib_switchbar_subsettings_margin_start"
         android:textAlignment="viewStart"/>
 
-    <ImageView
-        android:id="@+id/restricted_icon"
-        android:layout_width="@dimen/settingslib_restricted_icon_size"
-        android:layout_height="@dimen/settingslib_restricted_icon_size"
-        android:tint="?android:attr/colorAccent"
-        android:theme="@android:style/Theme.Material"
-        android:layout_gravity="center_vertical"
-        android:layout_marginEnd="@dimen/settingslib_restricted_icon_margin_end"
-        android:src="@drawable/settingslib_ic_info"
-        android:visibility="gone"/>
-
     <Switch
         android:id="@android:id/switch_widget"
         android:layout_width="wrap_content"
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml b/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml
index a50fc7c..ad888e5 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml
@@ -17,9 +17,8 @@
 
 <resources>
 
-    <style name="MainSwitchText.Settingslib" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+    <style name="MainSwitchText.Settingslib" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title.Inverse">
         <item name="android:textSize">20sp</item>
         <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
-        <item name="android:textColor">@android:color/black</item>
     </style>
 </resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
index 88b2c87..0d9ffff 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
@@ -17,16 +17,9 @@
 
 <resources>
 
-    <!-- Restricted icon size in switch bar -->
-    <dimen name="settingslib_restricted_icon_size">@android:dimen/config_restrictedIconSize</dimen>
-
-    <!-- Restricted icon in switch bar -->
-    <dimen name="settingslib_restricted_icon_margin_end">16dp</dimen>
-
     <!-- Size of title margin -->
     <dimen name="settingslib_switch_title_margin">24dp</dimen>
 
-    <!-- SwitchBar sub settings margin start / end -->
+    <!-- SwitchBar sub settings margin start -->
     <dimen name="settingslib_switchbar_subsettings_margin_start">56dp</dimen>
-    <dimen name="settingslib_switchbar_subsettings_margin_end">16dp</dimen>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-de/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-de/strings.xml
new file mode 100644
index 0000000..d61ff96
--- /dev/null
+++ b/packages/SettingsLib/ProfileSelector/res/values-de/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2022 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="settingslib_category_personal" msgid="1142302328104700620">"Privat"</string>
+    <string name="settingslib_category_work" msgid="4867750733682444676">"Dienstlich"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ky/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ky/strings.xml
index e61ffdb..88008d6 100644
--- a/packages/SettingsLib/SearchWidget/res/values-ky/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-ky/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="search_menu" msgid="1914043873178389845">"Жөндөөлөрдү издөө"</string>
+    <string name="search_menu" msgid="1914043873178389845">"Параметрлерди издөө"</string>
 </resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-vi/strings.xml b/packages/SettingsLib/SearchWidget/res/values-vi/strings.xml
index 90daf11..ec6682e 100644
--- a/packages/SettingsLib/SearchWidget/res/values-vi/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-vi/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="search_menu" msgid="1914043873178389845">"Tìm trong thông tin cài đặt"</string>
+    <string name="search_menu" msgid="1914043873178389845">"Tìm chế độ cài đặt"</string>
 </resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-zu/strings.xml b/packages/SettingsLib/SearchWidget/res/values-zu/strings.xml
index 900f4ba..3d36fa6 100644
--- a/packages/SettingsLib/SearchWidget/res/values-zu/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-zu/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="search_menu" msgid="1914043873178389845">"Sesha izilungiselelo"</string>
+    <string name="search_menu" msgid="1914043873178389845">"Amasethingi okusesha"</string>
 </resources>
diff --git a/packages/SettingsLib/Spa/build.gradle b/packages/SettingsLib/Spa/build.gradle
index 4fd2b5d..e68ef85 100644
--- a/packages/SettingsLib/Spa/build.gradle
+++ b/packages/SettingsLib/Spa/build.gradle
@@ -14,17 +14,27 @@
  * limitations under the License.
  */
 
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
 buildscript {
     ext {
         BUILD_TOOLS_VERSION = "30.0.3"
         MIN_SDK = 21
         TARGET_SDK = 33
         jetpack_compose_version = '1.4.0-beta01'
-        jetpack_compose_compiler_version = '1.4.0'
+        jetpack_compose_compiler_version = '1.4.4'
     }
 }
 plugins {
-    id 'com.android.application' version '8.0.0-beta05' apply false
-    id 'com.android.library' version '8.0.0-beta05' apply false
-    id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
+    id 'com.android.application' version '8.0.0' apply false
+    id 'com.android.library' version '8.0.0' apply false
+    id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
+}
+subprojects {
+    tasks.withType(KotlinCompile).configureEach {
+        kotlinOptions {
+            jvmTarget = "17"
+            freeCompilerArgs = ["-Xjvm-default=all"]
+        }
+    }
 }
diff --git a/packages/SettingsLib/Spa/gallery/build.gradle b/packages/SettingsLib/Spa/gallery/build.gradle
index 416a403..212aa7b 100644
--- a/packages/SettingsLib/Spa/gallery/build.gradle
+++ b/packages/SettingsLib/Spa/gallery/build.gradle
@@ -42,12 +42,8 @@
         }
     }
     compileOptions {
-        sourceCompatibility JavaVersion.VERSION_11
-        targetCompatibility JavaVersion.VERSION_11
-    }
-    kotlinOptions {
-        jvmTarget = '11'
-        freeCompilerArgs = ["-Xjvm-default=all"]
+        sourceCompatibility JavaVersion.VERSION_17
+        targetCompatibility JavaVersion.VERSION_17
     }
     buildFeatures {
         compose true
diff --git a/packages/SettingsLib/Spa/spa/build.gradle b/packages/SettingsLib/Spa/spa/build.gradle
index 9962c93..fb945a3 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle
+++ b/packages/SettingsLib/Spa/spa/build.gradle
@@ -51,10 +51,6 @@
         sourceCompatibility JavaVersion.VERSION_17
         targetCompatibility JavaVersion.VERSION_17
     }
-    kotlinOptions {
-        jvmTarget = '17'
-        freeCompilerArgs = ["-Xjvm-default=all"]
-    }
     buildFeatures {
         compose true
     }
@@ -79,7 +75,7 @@
     api "androidx.compose.ui:ui-tooling-preview:$jetpack_compose_version"
     api "androidx.lifecycle:lifecycle-livedata-ktx"
     api "androidx.lifecycle:lifecycle-runtime-compose"
-    api "androidx.navigation:navigation-compose:2.6.0-alpha07"
+    api "androidx.navigation:navigation-compose:2.6.0-alpha08"
     api "com.github.PhilJay:MPAndroidChart:v3.1.0-alpha"
     api "com.google.android.material:material:1.7.0-alpha03"
     debugApi "androidx.compose.ui:ui-tooling:$jetpack_compose_version"
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
index f0df9a6..8cbf7cc 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
@@ -19,7 +19,6 @@
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.material.icons.Icons
@@ -40,7 +39,6 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.DpOffset
 import androidx.compose.ui.unit.dp
 import com.android.settingslib.spa.framework.theme.SettingsDimension
 import com.android.settingslib.spa.framework.theme.SettingsTheme
@@ -60,13 +58,17 @@
 
     Box(
         modifier = Modifier
-            .padding(SettingsDimension.itemPadding)
+            .padding(
+                start = SettingsDimension.itemPaddingStart,
+                top = SettingsDimension.itemPaddingAround,
+                end = SettingsDimension.itemPaddingEnd,
+                bottom = SettingsDimension.itemPaddingAround,
+            )
             .selectableGroup(),
     ) {
         val contentPadding = PaddingValues(horizontal = SettingsDimension.itemPaddingEnd)
         Button(
             onClick = { expanded = true },
-            modifier = Modifier.height(36.dp),
             colors = ButtonDefaults.buttonColors(
                 containerColor = SettingsTheme.colorScheme.spinnerHeaderContainer,
                 contentColor = SettingsTheme.colorScheme.onSpinnerHeaderContainer,
@@ -86,7 +88,6 @@
             expanded = expanded,
             onDismissRequest = { expanded = false },
             modifier = Modifier.background(SettingsTheme.colorScheme.spinnerItemContainer),
-            offset = DpOffset(x = 0.dp, y = 4.dp),
         ) {
             for (option in options) {
                 DropdownMenuItem(
@@ -116,7 +117,9 @@
 ) {
     Text(
         text = option?.text ?: "",
-        modifier = modifier.padding(end = SettingsDimension.itemPaddingEnd),
+        modifier = modifier
+            .padding(end = SettingsDimension.itemPaddingEnd)
+            .padding(vertical = SettingsDimension.itemPaddingAround),
         color = color,
         style = MaterialTheme.typography.labelLarge,
     )
diff --git a/packages/SettingsLib/Spa/testutils/build.gradle b/packages/SettingsLib/Spa/testutils/build.gradle
index e7f7db2..23a9add 100644
--- a/packages/SettingsLib/Spa/testutils/build.gradle
+++ b/packages/SettingsLib/Spa/testutils/build.gradle
@@ -41,10 +41,6 @@
         sourceCompatibility JavaVersion.VERSION_17
         targetCompatibility JavaVersion.VERSION_17
     }
-    kotlinOptions {
-        jvmTarget = '17'
-        freeCompilerArgs = ["-Xjvm-default=all"]
-    }
     buildFeatures {
         compose true
     }
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-mk/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-mk/strings.xml
index 56ed2d9..fc5b94b 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-mk/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-mk/strings.xml
@@ -19,7 +19,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="no_applications" msgid="5800789569715871963">"Нема апликации."</string>
     <string name="menu_show_system" msgid="906304605807554788">"Прикажи го системот"</string>
-    <string name="menu_hide_system" msgid="374571689914923020">"Сокриј го системот"</string>
+    <string name="menu_hide_system" msgid="374571689914923020">"Скриј го системот"</string>
     <string name="app_permission_summary_allowed" msgid="6115213465364138103">"Со дозволен пристап"</string>
     <string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Без дозволен пристап"</string>
     <string name="version_text" msgid="4001669804596458577">"верзија <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 707768e..2e20eae 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Meer tyd."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Minder tyd."</string>
     <string name="cancel" msgid="5665114069455378395">"Kanselleer"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Volgende"</string>
+    <string name="back" msgid="5554327870352703710">"Terug"</string>
+    <string name="save" msgid="3745809743277153149">"Stoor"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Klaar"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Wekkers en onthounotas"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Voeg nuwe gebruiker by?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Jy kan hierdie toestel met ander mense deel deur bykomende gebruikers te skep. Elke gebruiker het sy eie spasie wat hulle kan pasmaak met programme, muurpapier en so meer. Gebruikers kan ook toestelinstellings wat almal raak, soos Wi-Fi, aanpas.\n\nWanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul eie spasie opstel.\n\nEnige gebruiker kan programme vir alle ander gebruikers opdateer. Toeganklikheidinstellings en -dienste sal dalk nie na die nuwe gebruiker oorgedra word nie."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Wanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul spasie opstel.\n\nEnige gebruiker kan programme vir al die ander gebruikers opdateer."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Maak hierdie gebruiker ’n admin?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Admins het spesiale voorregte wat ander gebruikers nie het nie. ’n Admin kan alle gebruikers bestuur, hierdie toestel opdateer of terugstel, instellings wysig, alle geïnstalleerde apps sien, en adminvoorregte vir ander mense gee of herroep."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Maak admin"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Moet die gebruiker nou opgestel word?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Maak seker die persoon is beskikbaar om die toestel te vat en hul spasie op te stel"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Stel profiel nou op?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Dit sal ’n nuwe gastesessie begin en alle programme en data van die huidige sessie uitvee"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Verlaat gasmodus?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Dit sal programme en data in die huidige gastesessie uitvee"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ja, maak hulle ’n admin"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nee, moet hulle nie ’n admin maak nie"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Gaan uit"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Stoor gasaktiwiteit?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Jy kan aktiwiteit in die huidige sessie stoor of alle programme en data uitvee"</string>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index e8e404f..6fb1274 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -243,7 +243,7 @@
     <item msgid="8612549335720461635">"4ኬ (የተጠበቀ)"</item>
     <item msgid="7322156123728520872">"4ኬ (ከፍ ተድርጎ የተመጣጠነ)"</item>
     <item msgid="7735692090314849188">"4ኬ (ከፍ ተድርጎ የተመጣጠነ፣ የተጠበቀ)"</item>
-    <item msgid="7346816300608639624">"720ፒ፣ 1080ፒ (ሁለትዮሽ ማያ ገጽ)"</item>
+    <item msgid="7346816300608639624">"720ፒ፣ 1080ፒ (ሁለትዮሽ ማያ ገፅ)"</item>
   </string-array>
   <string-array name="enable_opengl_traces_entries">
     <item msgid="4433736508877934305">"ምንም"</item>
@@ -258,7 +258,7 @@
   </string-array>
   <string-array name="track_frame_time_entries">
     <item msgid="634406443901014984">"ጠፍቷል"</item>
-    <item msgid="1288760936356000927">"ማያ ገጽ ላይ እንደ አሞሌዎች"</item>
+    <item msgid="1288760936356000927">"ማያ ገፅ ላይ እንደ አሞሌዎች"</item>
     <item msgid="5023908510820531131">"በ<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g> ውስጥ"</item>
   </string-array>
   <string-array name="debug_hw_overdraw_entries">
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 986208f..de7144c 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -362,7 +362,7 @@
     <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"የሃርድዌር ንብርብሮች ሲዘምኑ አረንጓዴ አብራ"</string>
     <string name="debug_hw_overdraw" msgid="8944851091008756796">"የጂፒዩ አልፎ መሳል አርም"</string>
     <string name="disable_overlays" msgid="4206590799671557143">"የHW ተደራቢዎችን አሰናክል"</string>
-    <string name="disable_overlays_summary" msgid="1954852414363338166">"ለማያ ገጽ ማቀናበሪያ ሁልጊዜ GPU ተጠቀም"</string>
+    <string name="disable_overlays_summary" msgid="1954852414363338166">"ለማያ ገፅ ማቀናበሪያ ሁልጊዜ GPU ተጠቀም"</string>
     <string name="simulate_color_space" msgid="1206503300335835151">"የቀለም ህዋ አስመስል"</string>
     <string name="enable_opengl_traces_title" msgid="4638773318659125196">"የ OpenGL ክትትሎችን ያንቁ"</string>
     <string name="usb_audio_disable_routing" msgid="3367656923544254975">"የUSB ተሰሚ ማዛወር ያሰናክሉ"</string>
@@ -370,7 +370,7 @@
     <string name="debug_layout" msgid="1659216803043339741">"የአቀማመጥ ገደቦችን አሳይ"</string>
     <string name="debug_layout_summary" msgid="8825829038287321978">"የቅንጥብ ገደቦች፣ ጠርዞች፣ ወዘተ አሳይ"</string>
     <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"የቀኝ-ወደ-ግራ አቀማመጥ አቅጣጫ አስገድድ"</string>
-    <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ለሁሉም አካባቢዎች የማያ ገጽ አቀማመጥ ከቀኝ-ወደ-ግራ እንዲሆን አስገድድ"</string>
+    <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ለሁሉም አካባቢዎች የማያ ገፅ አቀማመጥ ከቀኝ-ወደ-ግራ እንዲሆን አስገድድ"</string>
     <string name="transparent_navigation_bar" msgid="1933192171384678484">"የግልፅነት የአሰሳ አሞሌ"</string>
     <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"የአሰሳ አሞሌ የዳራ ቀለምን በነባሪ ግልጽ አድርግ"</string>
     <string name="window_blurs" msgid="6831008984828425106">"የመስኮት ደረጃ ብዥታዎችን ፍቀድ"</string>
@@ -393,7 +393,7 @@
     <string name="show_all_anrs" msgid="9160563836616468726">"የጀርባ ኤኤንአሮችን አሳይ"</string>
     <string name="show_all_anrs_summary" msgid="8562788834431971392">"ለጀርባ መተግበሪያዎች የመተግበሪያ ምላሽ አይሰጥም መገናኛን አሳይ"</string>
     <string name="show_notification_channel_warnings" msgid="3448282400127597331">"የማሳወቂያ ሰርጥ ማስጠንቀቂያዎችን አሳይ"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"አንድ መተግበሪያ የሚሰራ ሰርጥ ሳይኖረው ማሳወቂያ ሲለጥፍ በማያ ገጽ-ላይ ማስጠንቀቂያን ያሳያል"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"አንድ መተግበሪያ የሚሰራ ሰርጥ ሳይኖረው ማሳወቂያ ሲለጥፍ በማያ ገፅ-ላይ ማስጠንቀቂያን ያሳያል"</string>
     <string name="force_allow_on_external" msgid="9187902444231637880">"በውጫዊ ላይ ሃይል ይፈቀዳል"</string>
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"የዝርዝር ሰነዶች እሴቶች ግምት ውስጥ ሳያስገባ ማንኛውም መተግበሪያ ወደ ውጫዊ ማከማቻው ለመጻፍ ብቁ ያደርጋል"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"እንቅስቃሴዎች ዳግመኛ እንዲመጣጠኑ አስገድድ"</string>
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"ተጨማሪ ጊዜ።"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"ያነሰ ጊዜ።"</string>
     <string name="cancel" msgid="5665114069455378395">"ይቅር"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"ቀጣይ"</string>
+    <string name="back" msgid="5554327870352703710">"ተመለስ"</string>
+    <string name="save" msgid="3745809743277153149">"አስቀምጥ"</string>
     <string name="okay" msgid="949938843324579502">"እሺ"</string>
     <string name="done" msgid="381184316122520313">"ተከናውኗል"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ማንቂያዎች እና አስታዋሾች"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"አዲስ ተጠቃሚ ይታከል?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"ተጨማሪ ተጠቃሚዎችን በመፍጠር ይህን መሣሪያ ለሌሎች ሰዎች ማጋራት ይችላሉ። እያንዳንዱ ተጠቃሚ በራሱ መተግበሪያዎች፣ ልጣፍ እና በመሳሰሉ ነገሮች ሊያበጀው የሚችል የራሱ ቦታ አለው። ተጠቃሚዎችም እንዲሁ እንደ Wi‑Fi ያሉ በሁሉም ሰው ላይ ተጽዕኖ ሊኖራቸው የሚችሉ የመሣሪያ ቅንብሮችን ማስተካከል ይችላሉ። \n\nእርስዎ አንድ አዲስ ተጠቃሚ ሲያክሉ ያ ሰው የራሱ ቦታ ማዘጋጀት አለበት።\n\nማንኛውም ተጠቃሚ መተግበሪያዎችን ለሌሎች ተጠቃሚዎች ሁሉ ሊያዘምኑ ይችላሉ።"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"እርስዎ አንድ አዲስ ተጠቃሚ ሲያክሉ ያ ሰው የራሱ ቦታ ማዘጋጀት አለበት።\n\nማንኛውም ተጠቃሚ መተግበሪያዎችን ለሌሎች ተጠቃሚዎች ሁሉ ሊያዘምን ይችላል።"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"ይህ ተጠቃሚ አስተዳዳሪ ይደረጉ?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"አስተዳዳሪዎች ሌሎች ተጠቃሚዎች የሌሏቸው ልዩ መብቶች አሏቸው። አንድ አስተዳዳሪ ሁሉንም ተጠቃሚዎች ማስተዳደር፣ ይህን መሣሪያ ማዘመን ወይም ዳግም ማስጀመር፣ ቅንብሮች መቀየር፣ ሁሉንም የተጫኑ መተግበሪያዎች ማየት እና ለሌሎች የአስተዳዳሪ መብቶችን መፍቀድ ወይም መከልከል ይችላሉ።"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"አስተዳዳሪ አድርግ"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"ተጠቃሚ አሁን ይዋቀር?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ግለሰቡ መሣሪያውን ወስደው ቦታቸውን ለማዋቀር እንደሚገኙ ያረጋግጡ"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"መገለጫ አሁን ይዋቀር?"</string>
@@ -595,7 +589,7 @@
     <string name="user_new_profile_name" msgid="2405500423304678841">"አዲስ መገለጫ"</string>
     <string name="user_info_settings_title" msgid="6351390762733279907">"የተጠቃሚ መረጃ"</string>
     <string name="profile_info_settings_title" msgid="105699672534365099">"የመገለጫ መረጃ"</string>
-    <string name="user_need_lock_message" msgid="4311424336209509301">"የተገደበ መገለጫ መፍጠር ከመቻልዎ በፊት መተግበሪያዎችዎን እና የግል ውሂብዎን ለመጠበቅ ቁልፍ ማያ ገጽ ማዋቀር አለብዎት።"</string>
+    <string name="user_need_lock_message" msgid="4311424336209509301">"የተገደበ መገለጫ መፍጠር ከመቻልዎ በፊት መተግበሪያዎችዎን እና የግል ውሂብዎን ለመጠበቅ ቁልፍ ማያ ገፅ ማዋቀር አለብዎት።"</string>
     <string name="user_set_lock_button" msgid="1427128184982594856">"ቁልፍ አዘጋጅ"</string>
     <string name="user_switch_to_user" msgid="6975428297154968543">"ወደ <xliff:g id="USER_NAME">%s</xliff:g> ቀይር"</string>
     <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"አዲስ ተጠቃሚ በመፍጠር ላይ…"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ይህ አዲስ የእንግዳ ክፍለ-ጊዜ ይጀምራል እና ሁሉንም መተግበሪያዎች እና ውሂብ አሁን ካለው ክፍለ-ጊዜ ይሰርዛል"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ከእንግዳ ሁኔታ ይውጣ?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ይህ አሁን ካለው የእንግዳ ክፍለ-ጊዜ መተግበሪያዎችን እና ውሂብን ይሰርዛል"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"አዎ፣ እነሱን አስተዳዳሪ ያድርጓቸው"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"አይ፣ እነሱን አስተዳዳሪ አያድርጓቸው"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ውጣ"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"የእንግዳ እንቅስቃሴ ይቀመጥ?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"እንቅስቃሴን አሁን ካለው ክፍለ-ጊዜ ማስቀመጥ ወይም ሁሉንም መተግበሪያዎች እና ውሂብ መሰረዝ ይችላሉ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index ae4b89d..fe08faf 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"وقت أكثر."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"وقت أقل."</string>
     <string name="cancel" msgid="5665114069455378395">"إلغاء"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"التالي"</string>
+    <string name="back" msgid="5554327870352703710">"رجوع"</string>
+    <string name="save" msgid="3745809743277153149">"حفظ"</string>
     <string name="okay" msgid="949938843324579502">"حسنًا"</string>
     <string name="done" msgid="381184316122520313">"تم"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"المنبّهات والتذكيرات"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"هل تريد إضافة مستخدم جديد؟"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"‏يمكنك مشاركة هذا الجهاز مع أشخاص آخرين من خلال إنشاء حسابات لمستخدمين إضافيين. وسيحصل كل مستخدم على مساحته الخاصة التي يمكنه تخصيصها بتطبيقاته وخلفياته التي يريدها وغير ذلك. ويمكن أيضًا للمستخدمين ضبط إعدادات الجهاز مثل Wi-Fi والتي تؤثر في جميع المستخدمين.\n\nعند إضافة مستخدم جديد، عليه إعداد مساحته.\n\nيمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين. وقد لا يتم نقل إعدادات وخدمات \"سهولة الاستخدام\" إلى المستخدم الجديد."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"عند إضافة مستخدم جديد، عليه إعداد مساحته.\n\nويمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"هل تريد منح هذا المستخدم امتيازات المشرف؟"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"تتوفّر للمشرفين امتيازات خاصة لا يتم منحها للمستخدمين الآخرين. يمكن للمشرف إدارة حسابات جميع المستخدمين، وتحديث الجهاز أو إعادة ضبطه، وتعديل الإعدادات، والاطّلاع على جميع التطبيقات المثبّتة، ومنح امتيازات المشرف للمستخدمين الآخرين أو إبطالها."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"منح المستخدم امتيازات المشرف"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"هل تريد إعداد المستخدم الآن؟"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"يُرجى التأكّد من أن الشخص يمكنه استخدام الجهاز الآن وإعداد مساحته."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"هل ترغب في إعداد ملف شخصي الآن؟"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ستؤدي إعادة الضبط إلى بدء جلسة ضيف جديدة وحذف جميع التطبيقات والبيانات من الجلسة الحالية."</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"هل تريد الخروج من وضع الضيف؟"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"سيؤدي الخروج من وضع الضيف إلى حذف التطبيقات والبيانات من جلسة الضيف الحالية."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"نعم، أريد منح هذا المستخدم امتيازات المشرف."</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"لا أريد منح هذا المستخدم امتيازات المشرف."</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"خروج"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"هل تريد حفظ النشاط في وضع الضيف؟"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"يمكنك حفظ نشاط من الجلسة الحالية أو حذف كلّ التطبيقات والبيانات."</string>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index 539b8a6..2eaf5fa 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -275,7 +275,7 @@
     <item msgid="6506681373060736204">"সৰ্বাধিক ৪টা প্ৰক্ৰিয়া"</item>
   </string-array>
   <string-array name="usb_configuration_titles">
-    <item msgid="3358668781763928157">"চ্চাৰ্জ কৰি থকা হৈছে"</item>
+    <item msgid="3358668781763928157">"চাৰ্জ কৰি থকা হৈছে"</item>
     <item msgid="7804797564616858506">"এমটিপি (মিডিয়া ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
     <item msgid="910925519184248772">"পিটিপি (পিকচাৰ ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
     <item msgid="3825132913289380004">"RNDIS (USB ইথাৰনেট)"</item>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 93813e2..48bc957 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -256,7 +256,7 @@
     <string name="bugreport_in_power" msgid="8664089072534638709">"বাগ ৰিপৰ্টৰ শ্ৱৰ্টকাট"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"পাৱাৰ মেনুত বাগ প্ৰতিবেদন গ্ৰহণ কৰিবলৈ এটা বুটাম দেখুৱাওক"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"জাগ্ৰত কৰি ৰাখক"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"চ্চাৰ্জ হৈ থকাৰ সময়ত স্ক্ৰীন কেতিয়াও সুপ্ত অৱস্থালৈ নাযায়"</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"চাৰ্জ হৈ থকাৰ সময়ত স্ক্ৰীন কেতিয়াও সুপ্ত অৱস্থালৈ নাযায়"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"ব্লুটুথ HCI স্নুপ ল’গ সক্ষম কৰক"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"ব্লুটুথ পেকেট সংগ্ৰহ কৰক। (এই ছেটিংটো সলনি কৰাৰ পাছত ব্লুটুথ ট’গল কৰক)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"ঔইএম আনলক"</string>
@@ -477,7 +477,7 @@
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"লাহে লাহে চাৰ্জ হৈছে"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"বেতাঁৰৰ মাধ্যমেৰে চাৰ্জ হৈ আছে"</string>
     <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"চাৰ্জ কৰি থকা হৈছে"</string>
-    <string name="battery_info_status_discharging" msgid="6962689305413556485">"চ্চাৰ্জ কৰা নাই"</string>
+    <string name="battery_info_status_discharging" msgid="6962689305413556485">"চাৰ্জ কৰা নাই"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"সংযোগ হৈ আছে, চাৰ্জ হৈ থকা নাই"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"চাৰ্জ হ’ল"</string>
     <string name="battery_info_status_full_charged" msgid="3536054261505567948">"সম্পূৰ্ণ চাৰ্জ হৈছে"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 9d441c9..41039b2 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Daha çox vaxt."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Daha az vaxt."</string>
     <string name="cancel" msgid="5665114069455378395">"Ləğv edin"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Növbəti"</string>
+    <string name="back" msgid="5554327870352703710">"Geri"</string>
+    <string name="save" msgid="3745809743277153149">"Yadda saxlayın"</string>
     <string name="okay" msgid="949938843324579502">"Ok"</string>
     <string name="done" msgid="381184316122520313">"Hazırdır"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Siqnallar və xatırladıcılar"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Yeni istifadəçi əlavə edilsin?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Əlavə istifadəçilər yaratmaqla bu cihazı digərləri ilə paylaşa bilərsiniz. Hər bir istifadəçinin tətbiq, divar kağızı və daha çoxu ilə fərdiləşdirə biləcəyi fərdi məkanları olacaq. İstifadəçilər hər kəsə təsir edən Wi‑Fi kimi cihaz ayarlarını da tənzimləyə biləcək.\n\nYeni istifadəçi əlavə etdiyiniz zaman həmin istifadəçi öz məkanını ayarlamalıdır.\n\nİstənilən istifadəçi tətbiqləri digər bütün istifadəçilər üçün güncəlləyə bilər. Əlçatımlılıq ayarları və xidmətlər yeni istifadəçiyə transfer edilməyə bilər."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Yeni istifadəçi əlavə etdiyiniz zaman həmin şəxs öz yerini quraşdırmalıdır.\n\nİstənilən istifadəçi bütün digər istifadəçilərdən olan tətbiqləri güncəlləşdirə bilər."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Bu istifadəçi admin edilsin?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Adminlərin xüsusi imtiyazları var. Admin bütün istifadəçiləri idarə edə, bu cihazı güncəlləyə və ya sıfırlaya, ayarları dəyişə, quraşdırılmış bütün tətbiqlərə baxa, başqaları üçün admin imtiyazları verə və ya ləğv edə bilər."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Admin edin"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"İstifadəçi indi ayarlansın?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Şəxsin cihazı götürə bilməsinə və yerini quraşdıra bilməsinə əmin olun"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Profil indi quraşdırılsın?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Bu, yeni qonaq sessiyası başladacaq və cari sessiyadan bütün tətbiqləri və datanı siləcək"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Qonaq rejimindən çıxılsın?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bununla cari qonaq sessiyasındakı bütün tətbiqlər və data silinəcək"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Bəli, admin edin"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Xeyr, admin etməyin"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Çıxın"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Qonaq fəaliyyəti saxlansın?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Cari sessiyadakı fəaliyyəti saxlaya və ya bütün tətbiq və datanı silə bilərsiniz"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 62025e4..14a9e70 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Više vremena."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Manje vremena."</string>
     <string name="cancel" msgid="5665114069455378395">"Otkaži"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Dalje"</string>
+    <string name="back" msgid="5554327870352703710">"Nazad"</string>
+    <string name="save" msgid="3745809743277153149">"Sačuvaj"</string>
     <string name="okay" msgid="949938843324579502">"Potvrdi"</string>
     <string name="done" msgid="381184316122520313">"Gotovo"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmi i podsetnici"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Dodajete novog korisnika?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Ovaj uređaj možete da delite sa drugim ljudima ako napravite još korisnika. Svaki korisnik ima sopstveni prostor, koji može da prilagođava pomoću aplikacija, pozadine i slično. Korisnici mogu da prilagođavaju i podešavanja uređaja koja utiču na svakoga, poput Wi‑Fi-ja.\n\nKada dodate novog korisnika, ta osoba treba da podesi sopstveni prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike. Podešavanja i usluge pristupačnosti ne mogu da se prenose na novog korisnika."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Kada dodate novog korisnika, ta osoba treba da podesi sopstveni prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Želite da postavite ovog korisnika za administratora?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratori imaju posebne privilegije koje ostali korisnici nemaju. Administrator može da upravlja svim korisnicima, ažurira ili resetuje ovaj uređaj, prilagođava podešavanja, pregleda sve instalirane aplikacije i dodeljuje ili opoziva privilegije administratora za druge."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Postavi za administratora"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Podešavate korisnika?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Ta osoba treba da uzme uređaj i podesi svoj prostor"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Želite li da odmah podesite profil?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Time ćete pokrenuti novu sesiju gosta i izbrisati sve aplikacije i podatke iz aktuelne sesije"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Izlazite iz režima gosta?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Time ćete izbrisati sve aplikacije i podatke iz aktuelne sesije gosta"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Da, postavi ga za administratora"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Ne, ne postavljaj ga za administratora"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Izađi"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Sačuvaćete aktivnosti gosta?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Sačuvajte aktivnosti iz aktuelne sesije ili izbrišite sve aplikacije i podatke"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 4a81fab..02b428d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Больш часу."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Менш часу."</string>
     <string name="cancel" msgid="5665114069455378395">"Скасаваць"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Далей"</string>
+    <string name="back" msgid="5554327870352703710">"Назад"</string>
+    <string name="save" msgid="3745809743277153149">"Захаваць"</string>
     <string name="okay" msgid="949938843324579502">"ОК"</string>
     <string name="done" msgid="381184316122520313">"Гатова"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Будзільнікі і напаміны"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Дадаць новага карыстальніка?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Вы можаце адкрыць доступ да гэтай прылады іншым людзям шляхам стварэння дадатковых карыстальнікаў. Кожны карыстальнік мае свой уласны раздзел, на якім ён можа наладзіць свае праграмы, шпалеры і іншае. Карыстальнікі таксама могуць наладжваць параметры прылады, напрыклад Wi-Fi, якія ўплываюць на ўсіх.\n\nКалі вы дадаяце новага карыстальніка, ён павінен наладзіць свой раздзел.\n\nЛюбы карыстальнік можа абнаўляць праграмы для ўсіх астатніх карыстальнікаў. Спецыяльныя магчымасці наладжваюцца асабіста кожным карыстальнікам."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Пасля стварэння профіля яго трэба наладзіць.\n\nЛюбы карыстальнік прылады можа абнаўляць праграмы ўсіх іншых карыстальнікаў."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Зрабіць гэтага карыстальніка адміністратарам?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Адміністратары маюць спецыяльныя правы, якіх няма ў звычайных карыстальнікаў. Адмінстратар можа кіраваць усімі карыстальнікамі, абнаўляць або скідваць ПЗ прылады, змяняць налады, праглядаць усталяваныя праграмы, даваць іншым карыстальнікам або адклікаць правы адміністратара."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Зрабіць адміністратарам"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Наладзіць профіль?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Пераканайцеся, што чалавек мае магчымасць узяць прыладу і наладзіць свой раздзел"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Наладзiць профiль?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Будзе запушчаны новы гасцявы сеанс. Усе праграмы і даныя бягучага сеанса будуць выдалены"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Выйсці з гасцявога рэжыму?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Будуць выдалены праграмы і даныя бягучага гасцявога сеанса"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Так, зрабіць адміністратарам"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Не рабіць адміністратарам"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Выйсці"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Захаваць дзеянні госця?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Можна захаваць даныя пра дзеянні ў бягучым сеансе ці выдаліць праграмы і даныя"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index b6b76c5..8a08f51 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Повече време."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"По-малко време."</string>
     <string name="cancel" msgid="5665114069455378395">"Отказ"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Напред"</string>
+    <string name="back" msgid="5554327870352703710">"Назад"</string>
+    <string name="save" msgid="3745809743277153149">"Запазване"</string>
     <string name="okay" msgid="949938843324579502">"ОK"</string>
     <string name="done" msgid="381184316122520313">"Готово"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Будилници и напомняния"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Добавяне на нов потребител?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Можете да споделите това устройство с други хора, като създадете допълнителни потребители. Всеки от тях има собствено работно пространство, което може да персонализира с приложения, тапет и др. Потребителите могат също да коригират настройки на устройството, които засягат всички – например за Wi‑Fi.\n\nКогато добавите нов потребител, той трябва да настрои работното си пространство.\n\nВсеки потребител може да актуализира приложенията за всички останали потребители. Настройките и услугите за достъпност може да не се прехвърлят за новия потребител."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Когато добавите нов потребител, той трябва да настрои работното си пространство.\n\nВсеки потребител може да актуализира приложенията за всички останали потребители."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Искате ли да зададете този потребител като администратор?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Администраторите имат специални права, с които другите потребители не разполагат. Администраторите могат да управляват всички потребители, да актуализират или нулират това устройство, да променят настройките, да преглеждат всички инсталирани приложения, да предоставят или отменят администраторски права на други хора."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Задаване като администратор"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Настройване на потребителя?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Уверете се, че човекът има възможност да вземе устройството и да настрои работното си пространство."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Ще настроите ли потребителския профил сега?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Така ще стартирате нова сесия като гост и ще изтриете всички приложения и данни от текущата сесия"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Изход от режима на гост?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Така ще изтриете приложенията и данните от текущата сесия като гост"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Да, задаване като администратор"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Не, без задаване като администратор"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Изход"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Запазване на активността като гост?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Можете да запазите активността от сесията или да изтриете всички прил. и данни"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index a4ff171..5d7d5b5 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"আরও বেশি।"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"আরও কম।"</string>
     <string name="cancel" msgid="5665114069455378395">"বাতিল"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"পরবর্তী"</string>
+    <string name="back" msgid="5554327870352703710">"ফিরে যান"</string>
+    <string name="save" msgid="3745809743277153149">"সেভ করুন"</string>
     <string name="okay" msgid="949938843324579502">"ঠিক আছে"</string>
     <string name="done" msgid="381184316122520313">"হয়ে গেছে"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"অ্যালার্ম এবং রিমাইন্ডার"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"নতুন ব্যবহারকারী জুড়বেন?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"আপনি একাধিক ব্যবহারকারীর আইডি তৈরি করে অন্যদের সাথে এই ডিভাইসটি শেয়ার করতে পারেন। ডিভাইসের স্টোরেজে প্রত্যেক ব্যবহারকারী তার নিজস্ব জায়গা পাবেন যা তিনি অ্যাপ, ওয়ালপেপার এবং আরও অনেক কিছু দিয়ে কাস্টমাইজ করতে পারেন। ওয়াই-ফাই এর মতো ডিভাইস সেটিংস, যেগুলি সকলের ক্ষেত্রে প্রযোজ্য হয়, সেগুলি ব্যবহারকারীরা পরিবর্তন করতে পারবেন।\n\nনতুন ব্যবহারকারীর আইডি যোগ করলে সেই ব্যক্তিকে স্টোরেজে তার নিজের জায়গা সেট-আপ করতে হবে।\n\nঅন্যান্য ব্যবহারকারীদের হয়ে যে কোনও ব্যবহারকারী অ্যাপ আপডেট করতে পারবেন। তবে ব্যবহারযোগ্যতার সেটিংস এবং পরিষেবা নতুন ব্যবহারকারীর ক্ষেত্রে প্রযোজ্য নাও হতে পারে।"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট-আপ করে নিতে হবে৷\n\nযেকোনও ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন৷"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"এই ব্যবহারকারীকে অ্যাডমিন করবেন?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"অ্যাডমিনদের কাছে বিশেষ সুবিধা থাকে যা অন্যান্য ব্যবহারকারীর কাছে থাকে না। কোনও অ্যাডমিন সব ব্যবহারকারীদের ম্যানেজ, এই ডিভাইস আপডেট বা রিসেট, সেটিংস পরিবর্তন করতে, ইনস্টল করা সব অ্যাপ দেখতে এবং অন্যান্যদের জন্য অ্যাডমিনের বিশেষ সুবিধার অনুমোদন করতে বা তুলে নিতে পারবেন।"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"নতুন অ্যাডমিন বেছে নিন"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"এখন ব্যবহারকারী সেট-আপ করবেন?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"নিশ্চিত করুন, যে ব্যক্তিটি ডিভাইসটি নেওয়ার জন্য এবং তার জায়গা সেট-আপ করার জন্য উপলব্ধ আছেন"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"এখনই প্রোফাইল সেট-আপ করবেন?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"এটি নতুন অতিথি সেশন চালু করবে এবং বর্তমান সেশন থেকে সব অ্যাপ ও ডেটা মুছে দেবে"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"\'অতিথি মোড\' ছেড়ে বেরিয়ে আসবেন?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"এটি বর্তমান অতিথি সেশন থেকে অ্যাপ ও ডেটা মুছে দেবে"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"হ্যাঁ, তাদের অ্যাডমিন করুন"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"না, তাদের অ্যাডমিন করবেন না"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"বেরিয়ে আসুন"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"অতিথি মোডের অ্যাক্টিভিটি সেভ করবেন?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"আপনি বর্তমান সেশন থেকে অ্যাক্টিভিটি সেভ করতে বা সব অ্যাপ ও ডেটা মুছতে পারবেন"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index f8f742b..962e215 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Més temps"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Menys temps"</string>
     <string name="cancel" msgid="5665114069455378395">"Cancel·la"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Següent"</string>
+    <string name="back" msgid="5554327870352703710">"Enrere"</string>
+    <string name="save" msgid="3745809743277153149">"Desa"</string>
     <string name="okay" msgid="949938843324579502">"D\'acord"</string>
     <string name="done" msgid="381184316122520313">"Fet"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes i recordatoris"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Vols afegir un usuari nou?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Pots compartir aquest dispositiu amb altres persones creant usuaris addicionals. Cada usuari té el seu propi espai, que pot personalitzar amb aplicacions i fons de pantalla, entre d\'altres. Els usuaris també poden ajustar opcions de configuració del dispositiu, com ara la Wi-Fi, que afecten els altres usuaris.\n\nQuan afegeixis un usuari nou, haurà de configurar el seu espai.\n\nTots els usuaris poden actualitzar les aplicacions de la resta. És possible que la configuració i els serveis d\'accessibilitat no es transfereixin a l\'usuari nou."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Quan s\'afegeix un usuari nou, aquesta persona ha de configurar el seu espai.\n\nQualsevol usuari pot actualitzar les aplicacions dels altres usuaris."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Vols convertir aquest usuari en administrador?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Els administradors tenen privilegis especials que altres usuaris no tenen. Un administrador pot gestionar tots els usuaris, actualitzar o restablir aquest dispositiu, modificar la configuració, veure totes les aplicacions instal·lades i concedir o revocar privilegis d\'administrador a altres usuaris."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Converteix en administrador"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Vols configurar l\'usuari ara?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Assegura\'t que la persona estigui disponible per accedir al dispositiu i configurar el seu espai."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Vols configurar el perfil ara?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Aquesta acció iniciarà una nova sessió de convidat i suprimirà totes les aplicacions i dades de la sessió actual"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sortir del mode de convidat?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Aquesta acció suprimirà les aplicacions i dades de la sessió de convidat actual"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Sí, converteix en administrador"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"No, no converteixis en administrador"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Surt"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Desar l\'activitat de convidat?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Pots desar l\'activitat de la sessió actual o suprimir totes les apps i dades"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 9813ffc..18c77cf 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Delší doba"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Kratší doba"</string>
     <string name="cancel" msgid="5665114069455378395">"Zrušit"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Další"</string>
+    <string name="back" msgid="5554327870352703710">"Zpět"</string>
+    <string name="save" msgid="3745809743277153149">"Uložit"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Hotovo"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Budíky a připomenutí"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Přidat nového uživatele?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Vytvořením dalších uživatelů můžete toto zařízení sdílet s jinými lidmi. Každý uživatel má svůj prostor, který si může přizpůsobit instalací aplikací, přidáním tapety apod. Uživatelé také mohou upravit nastavení zařízení (např. Wi-Fi), která ovlivní všechny uživatele.\n\nKaždý nově přidaný uživatel si musí nastavit vlastní prostor.\n\nKaždý uživatel může aktualizovat aplikace všech ostatních uživatelů."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Když přidáte nového uživatele, musí si nastavit vlastní prostor.\n\nJakýkoli uživatel může aktualizovat aplikace všech ostatních uživatelů."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Nastavit uživatele jako administrátora?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administrátoři mají zvláštní oprávnění, která ostatní uživatelé nemají. Administrátor může spravovat všechny uživatele, aktualizovat nebo resetovat toto zařízení, zobrazit všechny nainstalované aplikace a udělit nebo zrušit ostatním administrátorská práva."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Nastavit jako administrátora"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Nastavit uživatele?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Ujistěte se, že je uživatel k dispozici a může si v zařízení nastavit svůj prostor"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Nastavit profil?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tímto zahájíte novou relaci hosta a smažete všechny aplikace a data z aktuální relace"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Ukončit režim hosta?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tímto smažete aplikace a data z aktuální relace hosta"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ano, nastavit jako administrátora"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Ne, nenastavovat jako administrátora"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Ukončit"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Uložit aktivitu hosta?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Aktivitu z aktuální relace můžete uložit, nebo všechny aplikace a data smazat"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 33131c8..1673ad6 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mere tid."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Mindre tid."</string>
     <string name="cancel" msgid="5665114069455378395">"Annuller"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Næste"</string>
+    <string name="back" msgid="5554327870352703710">"Tilbage"</string>
+    <string name="save" msgid="3745809743277153149">"Gem"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Udfør"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmer og påmindelser"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Vil du tilføje en ny bruger?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dele denne enhed med andre ved at oprette ekstra brugere. Hver bruger har sit personlige område, som kan tilpasses med apps, baggrund osv. Brugerne kan også justere enhedsindstillinger, som for eksempel Wi-Fi, som påvirker alle.\n\nNår du tilføjer en ny bruger, skal vedkommende konfigurere sit område.\n\nAlle brugere kan opdatere apps for alle andre brugere. Indstillinger og tjenester for hjælpefunktioner overføres muligvis ikke til den nye bruger."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Når du tilføjer en ny bruger, skal personen konfigurere sit rum.\n\nAlle brugere kan opdatere apps for alle de andre brugere."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Vil du tildele denne bruger administratorrettigheder?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratorer har særlige rettigheder, som andre brugere ikke har. En administrator kan administrere alle brugere, opdatere eller gendanne denne enhed, skifte indstillinger, se alle installerede apps og tildele eller tilbagekalde andres administratorrettigheder."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Tildel administratorrettigheder"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Vil du konfigurere brugeren nu?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Sørg for, at brugeren har mulighed for at tage enheden og konfigurere sit eget rum"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Vil du oprette en profil nu?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Denne handling starter en ny gæstesession og sletter alle apps og data fra den aktuelle session"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vil du afslutte gæstetilstanden?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Denne handling sletter apps og data fra den aktuelle gæstesession."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ja, tildel vedkommende administratorrettigheder"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nej, tildel ikke vedkommende administratorrettigheder"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Luk"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vil du gemme gæsteaktiviteten?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Du kan gemme aktivitet fra den aktuelle session eller slette alle apps og data"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index c32baec..1227576 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mehr Zeit."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Weniger Zeit."</string>
     <string name="cancel" msgid="5665114069455378395">"Abbrechen"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Weiter"</string>
+    <string name="back" msgid="5554327870352703710">"Zurück"</string>
+    <string name="save" msgid="3745809743277153149">"Speichern"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Fertig"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Wecker und Erinnerungen"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Neuen Nutzer hinzufügen?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kannst dieses Gerät zusammen mit anderen nutzen, indem du weitere Nutzer erstellst. Jeder erhält einen eigenen Bereich, in dem er Apps, den Hintergrund usw. personalisieren kann. Außerdem lassen sich Geräteeinstellungen wie WLAN ändern, die sich auf alle Nutzer auswirken.\n\nWenn du einen neuen Nutzer hinzufügst, muss dieser seinen Bereich einrichten.\n\nJeder Nutzer kann Apps für alle anderen Nutzer aktualisieren. Bedienungshilfen-Einstellungen und -Dienste werden möglicherweise nicht auf den neuen Nutzer übertragen."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Wenn du einen neuen Nutzer hinzufügst, muss dieser seinen Bereich einrichten.\n\nJeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Diesen Nutzer als Administrator festlegen?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Im Gegensatz zu anderen Nutzern haben Administratoren besondere Berechtigungen. Ein Administrator kann alle Nutzer verwalten, dieses Gerät aktualisieren oder zurücksetzen, Einstellungen ändern, alle installierten Apps sehen und für andere Administratorberechtigungen gewähren oder aufheben."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Als Administrator festlegen"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Nutzer jetzt einrichten?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Die Person muss Zugang zum Gerät haben und bereit sein, ihren Bereich einzurichten."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Profil jetzt einrichten?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Hierdurch wird eine neue Gastsitzung gestartet und alle Apps und Daten der aktuellen Sitzung werden gelöscht"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Gastmodus beenden?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Hierdurch werden Apps und Daten der aktuellen Gastsitzung gelöscht"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ja, als Administrator festlegen"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nein, nicht als Administrator festlegen"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Beenden"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Gastaktivität speichern?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Speichere Aktivitäten der aktuellen Sitzung oder lösche alle Apps und Daten"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 0364665..429b07ec 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Περισσότερη ώρα."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Λιγότερη ώρα."</string>
     <string name="cancel" msgid="5665114069455378395">"Ακύρωση"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Επόμενο"</string>
+    <string name="back" msgid="5554327870352703710">"Πίσω"</string>
+    <string name="save" msgid="3745809743277153149">"Αποθήκευση"</string>
     <string name="okay" msgid="949938843324579502">"ΟΚ"</string>
     <string name="done" msgid="381184316122520313">"Τέλος"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ξυπνητήρια και ειδοποιήσεις"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Προσθήκη νέου χρήστη;"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Μπορείτε να μοιραστείτε αυτήν τη συσκευή με άλλα άτομα, δημιουργώντας επιπλέον χρήστες. Κάθε χρήστης θα έχει το δικό του χώρο, τον οποίο μπορεί να προσαρμόσει με τις δικές του εφαρμογές, ταπετσαρία κ.λπ. Οι χρήστες μπορούν επίσης να προσαρμόσουν ρυθμίσεις της συσκευής, όπως το Wi‑Fi, που επηρεάζουν τους πάντες.\n\nΚατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες. Οι ρυθμίσεις και οι υπηρεσίες προσβασιμότητας ενδέχεται να μην μεταφερθούν στον νέο χρήστη."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει το χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Να εκχωρηθούν δικαιώματα διαχειριστή σε αυτόν τον χρήστη;"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Οι διαχειριστές έχουν ειδικά προνόμια που δεν έχουν οι υπόλοιποι χρήστες Ένας διαχειριστής μπορεί να διαχειριστεί όλους τους χρήστες, να ενημερώσει ή να επαναφέρει αυτήν τη συσκευή, να τροποποιήσει τις ρυθμίσεις, να δει όλες τις εγκατεστημένες εφαρμογές και να εκχωρήσει ή να ανακαλέσει προνόμια διαχειριστή άλλων χρηστών."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Εκχώρηση δικαιωμάτων διαχειριστή"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Να γίνει ρύθμιση χρήστη τώρα;"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Βεβαιωθείτε ότι ο χρήστης μπορεί να πάρει τη συσκευή και ρυθμίστε το χώρο του"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Να γίνει ρύθμιση προφίλ τώρα;"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Με αυτόν τον τρόπο θα ξεκινήσει μια νέα περίοδος σύνδεσης επισκέπτη και θα διαγραφούν όλες οι εφαρμογές και τα δεδομένα από την τρέχουσα περίοδο σύνδεσης"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Έξοδος από λειτ. επισκέπτη;"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Θα διαγραφούν εφαρμογές και δεδομένα από την τρέχουσα περίοδο σύνδεσης επισκέπτη"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ναι, να γίνει εκχώρηση δικαιωμάτων διαχειριστή"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Όχι, να μην γίνει εκχώρηση δικαιωμάτων διαχειριστή"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Έξοδος"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Αποθήκευση δραστ. επισκέπτη;"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Αποθήκευση δραστ. τρέχουσας περιόδου σύνδεσης ή διαγραφή εφαρμογών και δεδομένων"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 38a7c32..49ab2df 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Más tiempo"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Menos tiempo"</string>
     <string name="cancel" msgid="5665114069455378395">"Cancelar"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Siguiente"</string>
+    <string name="back" msgid="5554327870352703710">"Atrás"</string>
+    <string name="save" msgid="3745809743277153149">"Guardar"</string>
     <string name="okay" msgid="949938843324579502">"Aceptar"</string>
     <string name="done" msgid="381184316122520313">"Listo"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmas y recordatorios"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"¿Agregar usuario nuevo?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Para compartir este dispositivo, crea más usuarios. Cada uno tendrá su propio espacio y podrá personalizarlo con apps, un fondo de pantalla y mucho más. Los usuarios también podrán ajustar algunas opciones del dispositivo, como la conexión Wi‑Fi, que afectan a todos los usuarios.\n\nCuando agregues un nuevo usuario, esa persona deberá configurar su espacio.\n\nCualquier usuario podrá actualizar las apps de otras personas. Es posible que no se transfieran los servicios ni las opciones de accesibilidad al nuevo usuario."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Cuando agregas un nuevo usuario, esa persona debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"¿Quieres convertir a este usuario en administrador?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Los administradores tienen privilegios especiales que no tienen otros usuarios. Un administrador puede administrar a todos los usuarios, actualizar o restablecer el dispositivo, modificar parámetros de configuración, ver todas las apps instaladas y otorgar o revocar privilegios de administrador de otros usuarios."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Convertir en administrador"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"¿Configurar el usuario ahora?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Asegúrate de que la persona pueda acceder al dispositivo y configurar su espacio."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"¿Quieres configurar tu perfil ahora?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Esta acción comenzará una nueva sesión de invitado y borrará todas las apps y los datos de la sesión actual"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"¿Salir del modo de invitado?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Esta acción borrará todas las apps y los datos de la sesión de invitado actual"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Sí, convertir en administrador"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"No, no convertir en administrador"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Salir"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"¿Guardar actividad de invitado?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puedes guardar la actividad de la sesión actual o borrar las apps y los datos"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 995a426..a4f5d55 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Más tiempo."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Menos tiempo."</string>
     <string name="cancel" msgid="5665114069455378395">"Cancelar"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Siguiente"</string>
+    <string name="back" msgid="5554327870352703710">"Atrás"</string>
+    <string name="save" msgid="3745809743277153149">"Guardar"</string>
     <string name="okay" msgid="949938843324579502">"Aceptar"</string>
     <string name="done" msgid="381184316122520313">"Hecho"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmas y recordatorios"</string>
@@ -546,7 +543,7 @@
     <string name="zen_mode_forever" msgid="3339224497605461291">"Hasta que lo desactives"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"justo ahora"</string>
     <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_device_name" product="tablet" msgid="3714653244000242800">"Esta tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"No se puede reproducir contenido en este dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualiza la cuenta para cambiar"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"¿Añadir nuevo usuario?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Puedes compartir este dispositivo si creas más usuarios. Cada uno tendrá su propio espacio y podrá personalizarlo con aplicaciones, un fondo de pantalla y mucho más. Los usuarios también pueden ajustar opciones del dispositivo, como la conexión Wi‑Fi, que afectan a todos los usuarios.\n\nCuando añadas un usuario, tendrá que configurar su espacio.\n\nCualquier usuario puede actualizar aplicaciones de todos los usuarios. Es posible que no se transfieran los servicios y opciones de accesibilidad al nuevo usuario."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Al añadir un nuevo usuario, dicha persona debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"¿Convertir a este usuario en administrador?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Los administradores tienen privilegios especiales que otros usuarios no tienen. Los administradores pueden gestionar todos los usuarios, actualizar o restablecer este dispositivo, modificar los ajustes, ver todas las aplicaciones instaladas y conceder o revocar privilegios de administrador a otros usuarios."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Convertir en administrador"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"¿Configurar usuario ahora?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Asegúrate de que la persona está disponible en este momento para usar el dispositivo y configurar su espacio."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"¿Quieres configurar un perfil ahora?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Se iniciará una nueva sesión de invitado y se borrarán todas las aplicaciones y datos de esta sesión"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"¿Salir del modo Invitado?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Se eliminarán todas las aplicaciones y datos de la sesión de invitado actual"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Sí, convertir en administrador"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"No convertir en administrador"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Salir"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"¿Guardar actividad de invitado?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puedes guardar la actividad de esta sesión o eliminar todas las aplicaciones y datos"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index c882eb9..05f9560 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Denbora gehiago."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Denbora gutxiago."</string>
     <string name="cancel" msgid="5665114069455378395">"Utzi"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Hurrengoa"</string>
+    <string name="back" msgid="5554327870352703710">"Atzera"</string>
+    <string name="save" msgid="3745809743277153149">"Gorde"</string>
     <string name="okay" msgid="949938843324579502">"Ados"</string>
     <string name="done" msgid="381184316122520313">"Eginda"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmak eta abisuak"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Beste erabiltzaile bat gehitu nahi duzu?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Gailu hau beste pertsona batzuekin partekatzeko, sortu erabiltzaile gehiago. Erabiltzaile bakoitzak bere eremua izango du eta, bertan, aplikazioak, horma-papera eta antzekoak pertsonalizatu ahal izango ditu. Horrez gain, agian erabiltzaile guztiei eragingo dieten ezarpen batzuk ere doi daitezke; adibidez, wifi-konexioarena.\n\nErabiltzaile bat gehitzen duzunean, pertsona horrek berak konfiguratu beharko du bere eremua.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak. Baliteke erabilerraztasun-ezarpenak eta -zerbitzuak ez transferitzea erabiltzaile berriei."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Erabiltzaile bat gehitzen duzunean, erabiltzaile horrek bere eremua konfiguratu beharko du.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Administratzaile egin nahi duzu erabiltzaile hau?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Beste erabiltzaileek baino baimen gehiago dauzkate administratzaileek. Administratzaileek erabiltzaile guztiak kudea ditzakete, gailu hau eguneratu edo berrezarri, ezarpenak aldatu, instalatutako aplikazio guztiak ikusi, eta besteei administratzaile-baimenak eman eta kendu."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Egin administratzaile"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Erabiltzailea konfiguratu?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Ziurtatu pertsona horrek gailua hartu eta bere eremua konfigura dezakeela"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Profila konfiguratu?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Gonbidatuentzako saio berri bat abiaraziko da, eta saio honetako aplikazio eta datu guztiak ezabatuko"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Gonbidatu modutik irten nahi duzu?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Gonbidatuentzako saio honetako aplikazioak eta datuak ezabatuko dira"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Bai, egin administratzaile"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Ez, ez egin administratzaile"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Irten"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Gonbidatuaren jarduerak gorde nahi dituzu?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Saio honetako jarduerak gorde ditzakezu, edo aplikazio eta datu guztiak ezabatu"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 5643322..7c500ec 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"زمان بیشتر."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"زمان کمتر."</string>
     <string name="cancel" msgid="5665114069455378395">"لغو"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"بعدی"</string>
+    <string name="back" msgid="5554327870352703710">"برگشتن"</string>
+    <string name="save" msgid="3745809743277153149">"ذخیره"</string>
     <string name="okay" msgid="949938843324579502">"تأیید"</string>
     <string name="done" msgid="381184316122520313">"تمام"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"زنگ‌های هشدار و یادآوری‌ها"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"کاربر جدیدی اضافه می‌کنید؟"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"‏با ایجاد کاربران بیشتر، می‌توانید این دستگاه را با دیگران به‌اشتراک بگذارید. هر کاربر فضای مخصوص به خودش را دارد که می‌تواند آن را با برنامه‌ها، کاغذدیواری و موارد دیگر سفارشی کند. همچنین کاربران می‌توانند تنظیماتی در دستگاه ایجاد کنند، مانند تنظیمات Wi-Fi، که بر تنظیمات بقیه اثر دارد.\n\nوقتی کاربر جدیدی اضافه می‌کنید، آن شخص باید فضای خودش را تنظیم کند.\n\nهر کاربر می‌تواند برنامه‌ها را برای سایر کاربران به‌روزرسانی کند. دسترس‌پذیری، تنظیمات، و سرویس‌ها قابل‌انتقال به کاربر جدید نیستند."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"وقتی کاربر جدیدی اضافه می‌کنید آن فرد باید فضای خودش را تنظیم کند.\n\nهر کاربری می‌تواند برنامه‌ها را برای همه کاربران دیگر به‌روزرسانی کند."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"این کاربر سرپرست شود؟"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"سرپرستان امتیازهای ویژه‌ای دارند که کاربران دیگر ندارند. سرپرست می‌تواند همه کاربران را مدیریت کند، این دستگاه را به‌روز یا بازنشانی کند، تنظیمات را تغییر دهد، همه برنامه‌های نصب‌شده را ببیند، و امتیازهای سرپرست را به دیگران اعطا کند یا از آن‌ها بگیرد."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"انتخاب به‌عنوان سرپرست"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"هم اکنون کاربر تنظیم شود؟"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"مطمئن شوید شخص در دسترس است تا دستگاه را بگیرد و فضایش را تنظیم کند"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"اکنون نمایه را تنظیم می‌کنید؟"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"با این کار، جلسه مهمان جدیدی شروع خواهد شد و همه برنامه‌ها و داده‌ها از جلسه کنونی حذف خواهند شد"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"از حالت مهمان خارج می‌شوید؟"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"با این کار، برنامه‌ها و داده‌ها از جلسه مهمان کنونی حذف خواهند شد."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"بله، سرپرست شود"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"نه، سرپرست نشود"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"خروج"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"فعالیت مهمان ذخیره شود؟"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"می‌توانید فعالیت جلسه کنونی را ذخیره کنید یا همه برنامه و داده‌ها را حذف کنید"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 6377d2a..fe84597 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Enemmän aikaa"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Vähemmän aikaa"</string>
     <string name="cancel" msgid="5665114069455378395">"Peru"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Seuraava"</string>
+    <string name="back" msgid="5554327870352703710">"Takaisin"</string>
+    <string name="save" msgid="3745809743277153149">"Tallenna"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Valmis"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Herätykset ja muistutukset"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Lisätäänkö uusi käyttäjä?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Voit jakaa tämän laitteen muiden kanssa luomalla lisää käyttäjiä. Kullakin käyttäjällä on oma tilansa, jota he voivat muokata esimerkiksi omilla sovelluksilla ja taustakuvilla. Käyttäjät voivat myös muokata laiteasetuksia, kuten Wi‑Fi-asetuksia, jotka vaikuttavat laitteen kaikkiin käyttäjiin.\n\nKun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia. Esteettömyysominaisuuksia tai ‑palveluita ei välttämättä siirretä uudelle käyttäjälle."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Kun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Tehdäänkö tästä käyttäjästä järjestelmänvalvoja?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Järjestelmänvalvojilla on enemmän oikeuksia kuin muilla. Järjestelmänvalvoja voi hallinnoida kaikkia käyttäjiä, päivittää tai nollata tämän laitteen, muokata asetuksia, nähdä asennetut sovellukset ja antaa tai peruuttaa järjestelmänvalvojan oikeudet muilta."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Muuta järjestelmänvalvojaksi"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Lisätäänkö käyttäjä nyt?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Varmista, että käyttäjä voi ottaa laitteen nyt ja määrittää oman tilansa."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Määritetäänkö profiilin asetukset nyt?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tämä aloittaa uuden vierailija-käyttökerran ja kaikki nykyisen istunnon sovellukset ja data poistetaan"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Poistutaanko vierastilasta?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tämä poistaa nykyisen vierailija-käyttökerran sovellukset ja datan"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Kyllä, tee hänestä järjestelmänvalvoja"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Ei, älä tee hänestä järjestelmänvalvojaa"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sulje"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Tallennetaanko vierastoiminta?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Voit tallentaa tämän istunnon toimintaa tai poistaa kaikki sovellukset ja datan"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 33c4b98..32cc94d 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Plus longtemps."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Moins longtemps."</string>
     <string name="cancel" msgid="5665114069455378395">"Annuler"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Suivant"</string>
+    <string name="back" msgid="5554327870352703710">"Retour"</string>
+    <string name="save" msgid="3745809743277153149">"Enregistrer"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"OK"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes et rappels"</string>
@@ -543,7 +540,7 @@
     <string name="alarm_template_far" msgid="6382760514842998629">"le <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durée"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Toujours demander"</string>
-    <string name="zen_mode_forever" msgid="3339224497605461291">"Jusqu\'à la désactivation"</string>
+    <string name="zen_mode_forever" msgid="3339224497605461291">"Jusqu\'à ce que vous le désactiviez"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"À l\'instant"</string>
     <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>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Ajouter un utilisateur ?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Vous pouvez partager cet appareil avec d\'autres personnes en ajoutant des utilisateurs. Chaque utilisateur dispose de son propre espace où il peut personnaliser ses applications et son fond d\'écran, entre autres. Chaque utilisateur peut également modifier les paramètres de l\'appareil qui s\'appliquent à tous, tels que le Wi-Fi.\n\nLorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nN\'importe quel utilisateur peut mettre à jour les applications pour tous les autres. Toutefois, il est possible que les services et les paramètres d\'accessibilité ne soient pas transférés vers le nouvel utilisateur."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nN\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Définir cet utilisateur comme administrateur ?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Les administrateurs ont des droits spéciaux que les autres utilisateurs n\'ont pas. Un administrateur peut gérer tous les utilisateurs, mettre à jour ou réinitialiser cet appareil, modifier les paramètres, voir toutes les applis installées et accorder ou révoquer des droits d\'administrateur pour d\'autres."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Définir comme administrateur"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Configurer l\'utilisateur ?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Assurez-vous que la personne est prête à utiliser l\'appareil et à configurer son espace."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Configurer le profil maintenant ?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Cette action lancera une nouvelle session Invité et supprimera toutes les applis et données de la session actuelle"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Quitter le mode Invité ?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Cette action supprimera les applis et données de la session Invité actuelle."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Oui, le définir comme administrateur"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Non, ne pas le définir comme administrateur"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Quitter"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Enregistrer l\'activité ?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Enregistrez l\'activité de la session actuelle ou supprimez les applis et données"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 9dffccb..ec0fba9 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Máis tempo."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Menos tempo."</string>
     <string name="cancel" msgid="5665114069455378395">"Cancelar"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Seguinte"</string>
+    <string name="back" msgid="5554327870352703710">"Atrás"</string>
+    <string name="save" msgid="3745809743277153149">"Gardar"</string>
     <string name="okay" msgid="949938843324579502">"Aceptar"</string>
     <string name="done" msgid="381184316122520313">"Feito"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmas e recordatorios"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Engadir un usuario novo?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Podes compartir este dispositivo con outras persoas a través da creación de usuarios adicionais. Cada usuario ten o seu propio espazo que pode personalizar coas súas propias aplicacións, fondos de pantalla etc. Os usuarios tamén poden modificar as opcións de configuración do dispositivo, como a rede wifi, que afectan a todo o mundo.\n\nCando engadas un usuario novo, este deberá configurar o seu espazo.\n\nCalquera usuario pode actualizar as aplicacións para todos os demais usuarios. Non se poden transferir ao novo usuario os servizos nin a configuración de accesibilidade."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Cando engadas un usuario novo, este deberá configurar o seu espazo.\n\nCalquera usuario pode actualizar as aplicacións para todos os demais usuarios."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Queres converter este usuario en administrador?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Os administradores teñen privilexios especiais cos que non contan outros usuarios. Un administrador pode xestionar todos os usuarios, actualizar ou restablecer este dispositivo, modificar a configuración, ver todas as aplicacións instaladas, e concederlles ou quitarlles os privilexios de administrador a outras persoas."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Converter en administrador"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Configurar o usuario agora?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Asegúrate de que a persoa está dispoñible para acceder ao dispositivo e configurar o seu espazo"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Configurar o perfil agora?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Iniciarase unha nova sesión de convidado e eliminaranse todas as aplicacións e datos desta sesión"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Saír do modo de convidado?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Eliminaranse as aplicacións e os datos da sesión de convidado actual"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Si, convertelo en administrador"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Non, non convertelo en administrador"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Saír"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Gardar actividade do convidado?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Podes gardar a actividade da sesión ou eliminar todas as aplicacións e datos"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 157b4f7..13579e9 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"વધુ સમય."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"ઓછો સમય."</string>
     <string name="cancel" msgid="5665114069455378395">"રદ કરો"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"આગળ"</string>
+    <string name="back" msgid="5554327870352703710">"પાછળ"</string>
+    <string name="save" msgid="3745809743277153149">"સાચવો"</string>
     <string name="okay" msgid="949938843324579502">"ઓકે"</string>
     <string name="done" msgid="381184316122520313">"થઈ ગયું"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"અલાર્મ અને રિમાઇન્ડર"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"નવા વપરાશકર્તાને ઉમેરીએ?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"તમે વધારાના વપરાશકર્તાઓ બનાવીને અન્ય લોકો સાથે આ ડિવાઇસને શેર કરી શકો છો. દરેક વપરાશકર્તા પાસે તેમની પોતાની સ્પેસ છે, જેને તેઓ ઍપ, વૉલપેપર, વગેરે સાથે કસ્ટમાઇઝ કરી શકે છે. વપરાશકર્તાઓ પ્રત્યેક વ્યક્તિને અસર કરતી હોય તેવી ડિવાઇસ સેટિંગ જેમ કે વાઇ-ફાઇને પણ સમાયોજિત કરી શકે છે.\n\nજ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમની સ્પેસ સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા અન્ય બધા વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે. નવા વપરાશકર્તાને ઍક્સેસિબિલિટી સેટિંગ અને સેવાઓ ટ્રાન્સફર ન પણ થાય."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ અપ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"આ વપરાશકર્તાને ઍડમિન બનાવવા છે?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"ઍડમિન પાસે વિશિષ્ટ વિશેષાધિકારો હોય છે જે અન્ય વપરાશકર્તાઓ પાસે હોતા નથી. ઍડમિન બધા વપરાશકર્તાઓને મેનેજ કરી શકે, આ ડિવાઇસને અપડેટ અથવા રીસેટ કરી શકે, સેટિંગમાં ફેરફાર કરી શકે, ઇન્સ્ટૉલ કરેલી બધી ઍપ જોઈ શકે અને અન્ય લોકોને ઍડમિનના અધિકારો આપી શકે અથવા તેમને રદબાતલ કરી શકે."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"ઍડમિન બનાવો"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"અત્યારે જ વપરાશકર્તાને સેટ અપ કરીએ?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ખાતરી કરો કે વ્યક્તિ ડિવાઇસ લેવા અને તેમના સ્થાનનું સેટ અપ કરવા માટે ઉપલબ્ધ છે"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"હવે પ્રોફાઇલ સેટ કરીએ?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"આમ કરવાથી કોઈ નવું અતિથિ સત્ર ચાલુ થશે તેમજ હાલના સત્રમાંની તમામ ઍપ અને ડેટા ડિલીટ થશે"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"શું અતિથિ મોડમાંથી બહાર નીકળીએ?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"આમ કરવાથી હાલના અતિથિ સત્રની તમામ ઍપ અને ડેટા ડિલીટ કરવામાં આવશે"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"હા, તેમને ઍડમિન બનાવો"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"ના, તેમને ઍડમિન બનાવશો નહીં"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"બહાર નીકળો"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"શું અતિથિ પ્રવૃત્તિ સાચવીએ?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"તમે હાલના સત્રની પ્રવૃત્તિ સાચવી શકો છો અથવા તમામ ઍપ અને ડેટા ડિલીટ કરી શકો છો"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 41528f3..289dbe0 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -486,7 +486,7 @@
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dopušteno"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nije dopušteno"</string>
-    <string name="install_other_apps" msgid="3232595082023199454">"Instalacija nepoznatih apl."</string>
+    <string name="install_other_apps" msgid="3232595082023199454">"Instalacija nepoznatih aplikacija"</string>
     <string name="home" msgid="973834627243661438">"Početni zaslon postavki"</string>
   <string-array name="battery_labels">
     <item msgid="7878690469765357158">"0%"</item>
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Više vremena."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Manje vremena."</string>
     <string name="cancel" msgid="5665114069455378395">"Odustani"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Dalje"</string>
+    <string name="back" msgid="5554327870352703710">"Natrag"</string>
+    <string name="save" msgid="3745809743277153149">"Spremi"</string>
     <string name="okay" msgid="949938843324579502">"U redu"</string>
     <string name="done" msgid="381184316122520313">"Gotovo"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmi i podsjetnici"</string>
@@ -543,7 +540,7 @@
     <string name="alarm_template_far" msgid="6382760514842998629">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pitaj svaki put"</string>
-    <string name="zen_mode_forever" msgid="3339224497605461291">"Dok ne isključite"</string>
+    <string name="zen_mode_forever" msgid="3339224497605461291">"Do isključivanja"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Upravo sad"</string>
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ovaj telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ovaj tablet"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Dodati novog korisnika?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Da biste ovaj uređaj dijelili s drugima, možete napraviti dodatne korisnike. Svaki korisnik ima svoj prostor koji može prilagoditi pomoću vlastitih aplikacija, pozadine i tako dalje. Korisnici mogu prilagoditi i postavke uređaja koje utječu na sve ostale korisnike, na primjer Wi‑Fi.\n\nKada dodate novog korisnika, ta osoba mora postaviti svoj prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike. Postavke i usluge pristupačnosti možda se neće prenijeti na novog korisnika."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Želite li ovom korisniku dodijeliti status administratora?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratori imaju posebne ovlasti koje drugi korisnici nemaju. Administrator može upravljati svim korisnicima, ažurirati ili vratiti ovaj uređaj na zadano, izmijeniti postavke, vidjeti sve instalirane aplikacije i dodijeliti ili oduzeti drugima administratorske ovlasti."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Dodijeli status administratora"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Želite li postaviti korisnika?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Uređaj morate dati toj osobi da sama postavi svoj prostor"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Želite li sada postaviti profil?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Time će se pokrenuti nova gostujuća sesija i izbrisati sve aplikacije i podaci iz trenutačne sesije."</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Napustiti način rada za goste?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Time će se izbrisati aplikacije i podaci iz trenutačne gostujuće sesije."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Da, dodijeli status administratora"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Ne, nemoj dodijeliti status administratora"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Izlaz"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Spremiti aktivnosti gosta?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Možete spremiti aktivnosti iz ove sesije ili izbrisati sve aplikacije i podatke"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 36e4f39..463e59a 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Több idő."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Kevesebb idő."</string>
     <string name="cancel" msgid="5665114069455378395">"Mégse"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Tovább"</string>
+    <string name="back" msgid="5554327870352703710">"Vissza"</string>
+    <string name="save" msgid="3745809743277153149">"Mentés"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Kész"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ébresztések és emlékeztetők"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Hozzáad új felhasználót?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"További felhasználók létrehozásával megoszthatja ezt az eszközt másokkal. Minden felhasználó saját felülettel rendelkezik, amelyet személyre szabhat saját alkalmazásaival, háttérképével stb. A felhasználók módosíthatják az eszköz beállításait is, például a Wi‑Fi használatát, amely mindenkit érint.\n\nHa új felhasználót ad hozzá, az illetőnek be kell állítania saját felületét.\n\nBármely felhasználó frissítheti az alkalmazásokat valamennyi felhasználó számára. Előfordulhat, hogy a kisegítő lehetőségekkel kapcsolatos beállításokat és szolgáltatásokat nem viszi át a rendszer az új felhasználóhoz."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Ha új felhasználót ad hozzá, az illetőnek be kell állítania saját tárterületét.\n\nBármely felhasználó frissítheti az alkalmazásokat valamennyi felhasználó számára."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Beállítja ezt a felhasználót adminisztrátornak?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Az adminisztrátorok olyan speciális jogosultságokkal rendelkeznek, amelyekkel a többi felhasználó nem. Az adminisztrátorok kezelhetik az összes felhasználót, frissíthetik vagy visszaállíthatják az eszközt, módosíthatják a beállításokat, megnézhetik az összes telepített alkalmazást, valamint megadhatnak és visszavonhatnak adminisztrátori jogosultságokat más felhasználóknál."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Adminisztrátori jogosultság megadása"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Beállít most egy felhasználót?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Győződjön meg arról, hogy a személy hozzá tud férni az eszközhöz, hogy beállíthassa a területét"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Létrehoz most egy profilt?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"A művelettel új vendégmunkamenetet indít, valamint az összes alkalmazást és adatot törli az aktuális munkamenetből"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Kilép a vendég módból?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"A művelettel törlődnek az aktuális vendégmunkamenet alkalmazásai és adatai"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Igen, legyen adminisztrátor"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nem, ne legyen adminisztrátor"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Kilépés"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Menti a vendégtevékenységeket?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Tevékenységeket menthet az aktuális munkamenetből, vagy minden appot és adatot törölhet"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 23a8044..62d5abb 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Ավելացնել ժամանակը:"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Պակասեցնել ժամանակը:"</string>
     <string name="cancel" msgid="5665114069455378395">"Չեղարկել"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Առաջ"</string>
+    <string name="back" msgid="5554327870352703710">"Հետ"</string>
+    <string name="save" msgid="3745809743277153149">"Պահել"</string>
     <string name="okay" msgid="949938843324579502">"Եղավ"</string>
     <string name="done" msgid="381184316122520313">"Պատրաստ է"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Զարթուցիչներ և հիշեցումներ"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Ավելացնե՞լ նոր օգտատեր"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Այս սարքից կարող եք օգտվել մի քանի հոգով: Դրա համար անհրաժեշտ է ստեղծել լրացուցիչ պրոֆիլներ: Յուրաքանչյուր օգտատեր կարող է կարգավորել իր պրոֆիլը ըստ իր հայեցողության և ճաշակի (օր.՝ ընտրել իր ուզած պաստառը, տեղադրել անհրաժեշտ հավելվածները և այլն): Բացի այդ, օգտատերերը կարող են կարգավորել սարքի որոշ պարամետրեր (օր.՝ Wi-Fi-ը), որոնք կգործեն նաև մյուս պրոֆիլների համար:\n\nԵրբ նոր պրոֆիլ ավելացնեք, տվյալ օգտատերը պետք է կարգավորի այն:\n\nՅուրաքանչյուր օգտատեր կարող է թարմացնել մյուս օգտատերերի հավելվածները: Հատուկ գործառույթների և ծառայությունների կարգավորումները կարող են չփոխանցվել նոր օգտատերերին:"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Երբ նոր օգտատեր եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը:\n\nՑանկացած օգտատեր կարող է թարմացնել հավելվածները բոլոր օգտատերերի համար:"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Տրամադրե՞լ այս օգտատիրոջն ադմինիստրատորի իրավունքներ"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Ադմինիստրատորներն ունեն հատուկ արտոնություններ, որոնք մյուս օգտատերերը չունեն։ Նրանք կարող են կառավարել բոլոր օգտատերերին, թարմացնել կամ վերակայել այս սարքը, փոփոխել կարգավորումները, տեսնել բոլոր տեղադրված հավելվածները և տրամադրել/հետ կանչել այլ օգտատերերի ադմինիստրատորի արտոնությունները։"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Տրամադրել ադմինիստրատորի իրավունքներ"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Կարգավորե՞լ պրոֆիլը"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Համոզվեք, որ անձը կարող է վերցնել սարքը և կարգավորել իր տարածքը"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Կարգավորե՞լ պրոֆիլը հիմա:"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Կսկսվի հյուրի նոր աշխատաշրջան, իսկ նախորդ աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Դուրս գա՞լ հյուրի ռեժիմից"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Հյուրի ընթացիկ աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Այո, տրամադրել ադմինիստրատորի իրավունքներ"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Ոչ, չտրամադրել ադմինիստրատորի իրավունքներ"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Դուրս գալ"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Պահե՞լ հյուրի ռեժիմի պատմությունը"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Պահեք ընթացիկ աշխատաշրջանի պատմությունը կամ ջնջեք հավելվածներն ու տվյալները"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 0037b2d..0e6c74b 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Lebih lama."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Lebih cepat."</string>
     <string name="cancel" msgid="5665114069455378395">"Batal"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Berikutnya"</string>
+    <string name="back" msgid="5554327870352703710">"Kembali"</string>
+    <string name="save" msgid="3745809743277153149">"Simpan"</string>
     <string name="okay" msgid="949938843324579502">"Oke"</string>
     <string name="done" msgid="381184316122520313">"Selesai"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarm dan pengingat"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Tambahkan pengguna baru?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Anda dapat menggunakan perangkat ini bersama orang lain dengan membuat pengguna tambahan. Setiap pengguna memiliki ruang sendiri, yang dapat disesuaikan dengan aplikasi, wallpaper, dan lainnya. Pengguna juga dapat menyesuaikan setelan perangkat seperti Wi-Fi yang dapat memengaruhi semua pengguna lain.\n\nSaat Anda menambahkan pengguna baru, pengguna tersebut perlu menyiapkan ruangnya.\n\nPengguna mana pun dapat mengupdate aplikasi untuk semua pengguna lainnya. Layanan dan setelan aksesibilitas mungkin tidak ditransfer ke pengguna baru."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruang mereka sendiri.\n\nPengguna mana pun dapat memperbarui aplikasi untuk semua pengguna lain."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Jadikan pengguna ini sebagai admin?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Admin memiliki hak istimewa khusus yang tidak dimiliki pengguna lain. Admin dapat mengelola semua pengguna, mengupdate atau mereset perangkat ini, mengubah setelan, melihat semua aplikasi terinstal, dan memberi atau mencabut hak istimewa admin untuk pengguna lain."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Jadikan admin"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Siapkan pengguna sekarang?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Pastikan orang tersebut ada untuk mengambil perangkat dan menyiapkan ruangnya"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Siapkan profil sekarang?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tindakan ini akan memulai sesi tamu baru dan menghapus semua aplikasi serta data dari sesi saat ini"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Keluar dari mode tamu?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tindakan ini akan menghapus aplikasi dan data dari sesi tamu saat ini"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ya, jadikan sebagai admin"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Tidak, jangan jadikan sebagai admin"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Keluar"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Simpan aktivitas tamu?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Anda bisa menyimpan aktivitas sesi saat ini atau menghapus semua aplikasi &amp; data"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index ced9ec6..151b82f 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Meiri tími."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Minni tími."</string>
     <string name="cancel" msgid="5665114069455378395">"Hætta við"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Áfram"</string>
+    <string name="back" msgid="5554327870352703710">"Til baka"</string>
+    <string name="save" msgid="3745809743277153149">"Vista"</string>
     <string name="okay" msgid="949938843324579502">"Í lagi"</string>
     <string name="done" msgid="381184316122520313">"Lokið"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Vekjarar og áminningar"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Bæta nýjum notanda við?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Þú getur búið til fleiri notendur til að deila þessu tæki með öðrum. Hver notandi hefur sitt eigið svæði sem viðkomandi getur sérsniðið með forritum, veggfóðri o.s.frv. Notendur geta einnig breytt þeim stillingum tækisins sem hafa áhrif á alla notendur, t.d. Wi-Fi.\n\nÞegar þú bætir nýjum notanda við þarf sá notandi að setja upp svæðið sitt.\n\nHvaða notandi sem er getur uppfært forrit fyrir alla aðra notendur. Ekki er tryggt að stillingar á aðgengi og þjónustu flytjist yfir á nýja notandann."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Þegar þú bætir nýjum notanda við þarf sá notandi að setja upp svæðið sitt.\n\nHvaða notandi sem er getur uppfært forrit fyrir alla aðra notendur."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Gera þennan notanda að stjórnanda?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Stjórnendur hafa tiltekin réttindi sem aðrir notendur hafa ekki. Stjórnandi getur stjórnað öllum notendum, uppfært eða endurstillt þetta tæki, breytt stillingum, séð öll uppsett forrit og veitt eða afturkallað stjórnandaheimildir annarra."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Gera að stjórnanda"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Setja notanda upp núna?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Gakktu úr skugga um að notandinn geti tekið tækið og sett upp sitt svæði"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Setja upp snið núna?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Þetta opnar nýja gestalotu og eyðir öllum forritum og gögnum úr núverandi lotu"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Loka gestastillingu?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Þetta eyðir forritum og gögnum úr núverandi gestalotu"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Já, gera viðkomandi að stjórnanda"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nei, ekki gera viðkomandi að stjórnanda"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Hætta"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vista aðgerðir úr gestalotu?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Þú getur vistað aðgerðir úr núverandi lotu eða eytt öllum forritum og gögnum"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 30a79de..abf721e 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"יותר זמן."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"פחות זמן."</string>
     <string name="cancel" msgid="5665114069455378395">"ביטול"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"הבא"</string>
+    <string name="back" msgid="5554327870352703710">"חזרה"</string>
+    <string name="save" msgid="3745809743277153149">"שמירה"</string>
     <string name="okay" msgid="949938843324579502">"אישור"</string>
     <string name="done" msgid="381184316122520313">"סיום"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"שעונים מעוררים ותזכורות"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"להוסיף משתמש חדש?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"‏ניתן לשתף מכשיר זה עם אנשים אחרים על ידי יצירת משתמשים נוספים. לכל משתמש מרחב משלו, שאותו אפשר להתאים אישית בעזרת אפליקציות, טפט ופריטים נוספים. המשתמשים יכולים גם להתאים הגדרות של המכשיר כגון Wi‑Fi, שמשפיעות על כולם.\n\nכשמוסיפים משתמש חדש, על משתמש זה להגדיר את המרחב שלו.\n\nכל אחד מהמשתמשים יכול לעדכן אפליקציות לכל שאר המשתמשים. ייתכן שהגדרות ושירותים של נגישות לא יועברו למשתמש החדש."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"כשמוסיפים משתמש חדש, המשתמש הזה צריך להגדיר את המרחב שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"להגדיר את המשתמש הזה כאדמין?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"לאדמינים יש הרשאות מיוחדות שאין למשתמשים אחרים. אדמין יכול לנהל את כל המשתמשים, לעדכן את המכשיר הזה או לאפס אותו, לשנות הגדרות, לראות את כל האפליקציות המותקנות ולהעניק הרשאות אדמין לאחרים או לשלול אותן."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"הגדרה כאדמין"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"האם להגדיר משתמש עכשיו?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"כדאי לוודא שהמשתמש זמין ויכול לקחת את המכשיר ולהגדיר את המרחב שלו"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"האם להגדיר פרופיל עכשיו?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"הפעולה הזו תתחיל גלישה חדשה כאורח ותמחק את כל האפליקציות והנתונים מהסשן הנוכחי"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"לצאת ממצב אורח?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"הפעולה הזו תמחק את האפליקציות והנתונים מהגלישה הנוכחית כאורח"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"כן, להגדיר כאדמין"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"לא להגדיר כאדמין"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"יציאה"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"לשמור את פעילות האורח?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"אפשר לשמור את הפעילות מהסשן הנוכחי או למחוק את כל האפליקציות והנתונים"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 99ee13a..6e0bfec 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -174,7 +174,7 @@
     <string name="launch_defaults_some" msgid="3631650616557252926">"ზოგიერთი ნაგულისხმევი პარამეტრი დაყენებულია"</string>
     <string name="launch_defaults_none" msgid="8049374306261262709">"ნაგულისხმევი პარამეტრები არ არის დაყენებული."</string>
     <string name="tts_settings" msgid="8130616705989351312">"ტექსტის გახმოვანების პარამეტრები"</string>
-    <string name="tts_settings_title" msgid="7602210956640483039">"მეტყველების სინთეზი"</string>
+    <string name="tts_settings_title" msgid="7602210956640483039">"გახმოვანებული ტექსტის გამოტანა"</string>
     <string name="tts_default_rate_title" msgid="3964187817364304022">"მეტყველების ტემპი"</string>
     <string name="tts_default_rate_summary" msgid="3781937042151716987">"ტექსტის თხრობის სიჩქარე"</string>
     <string name="tts_default_pitch_title" msgid="6988592215554485479">"სიმაღლე"</string>
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"მეტი დრო."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"ნაკლები დრო."</string>
     <string name="cancel" msgid="5665114069455378395">"გაუქმება"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"შემდეგ"</string>
+    <string name="back" msgid="5554327870352703710">"უკან"</string>
+    <string name="save" msgid="3745809743277153149">"შენახვა"</string>
     <string name="okay" msgid="949938843324579502">"კარგი"</string>
     <string name="done" msgid="381184316122520313">"მზადაა"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"მაღვიძარები და შეხსენებები"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"დაემატოს ახალი მომხმარებელი?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"დამატებითი მომხმარებლების შექმნით, შეგიძლიათ ეს მოწყობილობა სხვებს გაუზიაროთ. ყოველ მომხმარებელს თავისი სივრცე აქვს, რომლის პერსონალიზება შეუძლია საკუთარი აპებით, ფონით და ა.შ. მომხმარებლებს აგრეთვე შეუძლიათ ისეთი პარამეტრების მორგება, როგორიცაა Wi‑Fi, რაც ყველაზე გავრცელდება.\n\nახალი მომხმარებლის დამატების შემდეგ, მომხმარებელმა საკუთარი სივრცე უნდა დააყენოს.\n\nყველა მომხმარებელი შეძლებს აპების ყველა სხვა მომხმარებლისთვის განახლებას. მარტივი წვდომის პარამეტრები/სერვისები შესაძლოა ახალ მომხმარებლებზე არ გავრცელდეს."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"ახალი მომხმარებლის დამატებისას, ამ მომხმარებელს საკუთარი სივრცის შექმნა მოუწევს.\n\nნებისმიერ მომხმარებელს შეუძლია აპები ყველა სხვა მომხმარებლისათვის განაახლოს."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"გსურთ ამ მომხმარებლის ადმინისტრატორად დანიშვნა?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"ადმინისტრატორებს აქვთ სპეციალური პრივილეგიები, დანარჩენი მომხმარებლებისგან განსხვავებით. ადმინისტრატორს შეუძლია მართოს ყველა მომხმარებელი, განაახლოს ან გადააყენოს ეს მოწყობილობა, შეცვალოს პარამეტრები, ნახოს ყველა დაინსტალირებული აპი და მიანიჭოს ან ჩამოართვას ადმინისტრატორის პრივილეგიები სხვებს."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"ადმინისტრატორად დანიშვნა"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"გსურთ მომხმარებლის პარამეტრების დაყენება?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"დარწმუნდით, რომ პირს შეუძლია მოწყობილობის აღება და საკუთარი სივრცის დაყენება"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"გსურთ დავაყენო პროფილი ახლა?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ამ ქმედებით დაიწყება სტუმრის ახალი სესია და წაიშლება ყველა აპი და მონაცემი მიმდინარე სესიიდან"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"გსურთ სტუმრის რეჟიმიდან გასვლა?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ეს ქმედება წაშლის აპებსა და მონაცემებს სტუმრის რეჟიმის მიმდინარე სესიიდან"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"დიახ, გახდეს ის ადმინისტრატორი"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"არა, არ გახდეს ის ადმინისტრატორი"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"გასვლა"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"გსურთ სტუმრის აქტივობის შენახვა?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"შეგიძლიათ შეინახოთ აქტივობა მიმდინარე სესიიდან ან წაშალოთ ყველა აპი და მონაცემი"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index c6381d6..a63dbfc 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -473,7 +473,7 @@
     <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядтау оңтайландырылды."</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Белгісіз"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Зарядталуда"</string>
-    <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Жылдам зарядталуда"</string>
+    <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Жылдам зарядтау"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Баяу зарядталуда"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Сымсыз зарядталуда"</string>
     <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Зарядталып жатыр."</string>
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Көбірек уақыт."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Азырақ уақыт."</string>
     <string name="cancel" msgid="5665114069455378395">"Бас тарту"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Келесі"</string>
+    <string name="back" msgid="5554327870352703710">"Артқа"</string>
+    <string name="save" msgid="3745809743277153149">"Сақтау"</string>
     <string name="okay" msgid="949938843324579502">"Жарайды"</string>
     <string name="done" msgid="381184316122520313">"Дайын"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Оятқыш және еске салғыш"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Жаңа пайдаланушы қосылсын ба?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Қосымша профильдер жасай отырып, бұл құрылғыны басқалармен ортақ пайдалануға болады. Әр пайдаланушы қолданбаларды, тұсқағаздарды орнатып, профилін өз қалауынша реттей алады. Сондай-ақ барлығы ортақ қолданатын Wi‑Fi сияқты параметрлерді де реттеуге болады.\n\nЖаңа пайдаланушы енгізілгенде, ол өз профилін реттеуі керек болады.\n\nКез келген пайдаланушы барлық басқа пайдаланушылар үшін қолданбаларды жаңарта алады. Арнайы мүмкіндіктерге қатысты параметрлер мен қызметтер жаңа пайдаланушыға өтпейді."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Жаңа пайдаланушыны қосқанда, сол адам өз кеңістігін реттеуі керек.\n\nКез келген пайдаланушы барлық басқа пайдаланушылар үшін қолданбаларды жаңарта алады."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Осы пайдаланушыны әкімші ету керек пе?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Әкімшілер басқа пайдаланушыларда болмайтын арнайы өкілеттерге ие. Әкімші мына әрекеттерді орындай алады: барлық пайдаланушыны басқару, осы құрылғыны жаңарту не бастапқы күйге қайтару, параметрлерді өзгерту, орнатылған құрылғының барлығын көру және әкімші өкілеттерін басқа пайдаланушыларға беру не қайтару."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Әкімші ету"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Профиль құру керек пе?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Пайдаланушы құрылғыны алып, өз профилін реттеуі керек."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Профайл қазір жасақталсын ба?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Мұндайда жаңа қонақ сеансы басталады және ағымдағы сеанстағы барлық қолданба мен дерек жойылады."</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Қонақ режимінен шығу керек пе?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ағымдағы қонақ сеансындағы барлық қолданба мен дерек жойылады."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Иә, пайдаланушы әкімші етілсін"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Жоқ, пайдаланушы әкімші етілмесін"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Шығу"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Қонақ әрекетін сақтау керек пе?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Ағымдағы сеанстағы әрекетті сақтай не барлық қолданба мен деректі жоя аласыз."</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 5444bd1..a82ffe5 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -527,7 +527,7 @@
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ម៉ោងរោទ៍ និងការរំលឹក"</string>
     <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"អនុញ្ញាតឱ្យ​កំណត់​ម៉ោងរោទ៍ និង​ការរំលឹក"</string>
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"ម៉ោងរោទ៍ និង​ការរំលឹក"</string>
-    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"អនុញ្ញាតឱ្យ​កម្មវិធីនេះ​កំណត់ម៉ោងរោទ៍ និងកំណត់កាលវិភាគសកម្មភាពដែលតម្រូវឱ្យទាន់ពេលវេលា។ ការធ្វើបែបនេះអនុញ្ញាតឱ្យកម្មវិធីនេះដំណើរការនៅផ្ទៃខាងក្រោយ ដែលអាចប្រើថ្មច្រើនជាងមុន។\n\nប្រសិនបើបិទការអនុញ្ញាតនេះ ម៉ោងរោទ៍ដែលមានស្រាប់ និងព្រឹត្តិការណ៍ផ្អែកលើពេលវេលាដែលកំណត់ដោយកម្មវិធីនេះ​នឹងមិនដំណើរការទេ។"</string>
+    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"អនុញ្ញាតឱ្យ​កម្មវិធីនេះ​កំណត់ម៉ោងរោទ៍ និងកំណត់កាលវិភាគសកម្មភាពដែលតម្រូវឱ្យទាន់ពេលវេលា។ ការធ្វើបែបនេះអនុញ្ញាតឱ្យកម្មវិធីនេះដំណើរការនៅផ្ទៃខាងក្រោយ ដែលអាចប្រើថ្មកាន់តែច្រើន។\n\nប្រសិនបើបិទការអនុញ្ញាតនេះ ម៉ោងរោទ៍ដែលមានស្រាប់ និងព្រឹត្តិការណ៍ផ្អែកលើពេលវេលាដែលកំណត់ដោយកម្មវិធីនេះ​នឹងមិនដំណើរការទេ។"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"កាលវិភាគ ម៉ោងរោទ៍ ការរំលឹក នាឡិកា"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"បើក"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"បើកមុខងារកុំរំខាន"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index f64bd53..ddeda1d 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -70,7 +70,7 @@
     <string name="wifi_limited_connection" msgid="1184778285475204682">"ಸೀಮಿತ ಸಂಪರ್ಕ"</string>
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"ಸೈನ್ ಇನ್ ಮಾಡುವ ಅಗತ್ಯವಿದೆ"</string>
-    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ಪ್ರವೇಶ ಕೇಂದ್ರ ತಾತ್ಕಾಲಿಕವಾಗಿ ಭರ್ತಿಯಾಗಿದೆ"</string>
+    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5885145407184194503">"ಆ್ಯಕ್ಸೆಸ್ ಕೇಂದ್ರ ತಾತ್ಕಾಲಿಕವಾಗಿ ಭರ್ತಿಯಾಗಿದೆ"</string>
     <string name="osu_opening_provider" msgid="4318105381295178285">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಲಾಗುತ್ತಿದೆ"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"ಸೈನ್-ಅಪ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
@@ -106,12 +106,12 @@
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ಫೋನ್ ಕರೆಗಳು"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ಫೈಲ್ ವರ್ಗಾವಣೆ"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ಇನ್‌ಪುಟ್‌ ಸಾಧನ"</string>
-    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ"</string>
+    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ಇಂಟರ್ನೆಟ್ ಆ್ಯಕ್ಸೆಸ್"</string>
     <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"ಸಂಪರ್ಕಗಳು ಹಾಗೂ ಕರೆ ಇತಿಹಾಸ ಹಂಚಿಕೊಳ್ಳುವಿಕೆ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"ಸಂಪರ್ಕಗಳು ಮತ್ತು ಕರೆ ಇತಿಹಾಸ ಹಂಚಿಕೆಗಾಗಿ ಬಳಸಿ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕ ಹಂಚಿಕೊಳ್ಳುವಿಕೆ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ಪಠ್ಯ ಸಂದೇಶಗಳು"</string>
-    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"ಸಿಮ್ ಪ್ರವೇಶ"</string>
+    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"ಸಿಮ್ ಆ್ಯಕ್ಸೆಸ್"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ಆಡಿಯೋ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ಆಡಿಯೋ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ಶ್ರವಣ ಸಾಧನಗಳು"</string>
@@ -221,7 +221,7 @@
     <string name="development_settings_not_available" msgid="355070198089140951">"ಈ ಬಳಕೆದಾರರಿಗೆ ಡೆವಲಪರ್‌ ಆಯ್ಕೆಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="vpn_settings_not_available" msgid="2894137119965668920">"VPN ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="tethering_settings_not_available" msgid="266821736434699780">"ಟೆಥರಿಂಗ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
-    <string name="apn_settings_not_available" msgid="1147111671403342300">"ಪ್ರವೇಶ ಬಿಂದು ಹೆಸರಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
+    <string name="apn_settings_not_available" msgid="1147111671403342300">"ಆ್ಯಕ್ಸೆಸ್ ಬಿಂದು ಹೆಸರಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="enable_adb" msgid="8072776357237289039">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
     <string name="enable_adb_summary" msgid="3711526030096574316">"USB ಸಂಪರ್ಕಗೊಂಡಾಗ ಡೀಬಗ್ ಮೋಡ್"</string>
     <string name="clear_adb_keys" msgid="3010148733140369917">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯ ಅಧಿಕೃತಗೊಳಿಸುವಿಕೆಗಳನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಿ"</string>
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"ಹೆಚ್ಚು ಸಮಯ."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"ಕಡಿಮೆ ಸಮಯ."</string>
     <string name="cancel" msgid="5665114069455378395">"ರದ್ದುಮಾಡಿ"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"ಮುಂದಿನದು"</string>
+    <string name="back" msgid="5554327870352703710">"ಹಿಂದಕ್ಕೆ"</string>
+    <string name="save" msgid="3745809743277153149">"ಉಳಿಸಿ"</string>
     <string name="okay" msgid="949938843324579502">"ಸರಿ"</string>
     <string name="done" msgid="381184316122520313">"ಮುಗಿದಿದೆ"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ಅಲಾರಾಮ್‌ಗಳು ಮತ್ತು ರಿಮೈಂಡರ್‌ಗಳು"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸುವುದೇ?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"ನೀವು ಹೆಚ್ಚುವರಿ ಬಳಕೆದಾರರನ್ನು ರಚಿಸುವ ಮೂಲಕ ಇತರ ಜನರ ಜೊತೆಗೆ ಈ ಸಾಧನವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು. ಪ್ರತಿ ಬಳಕೆದಾರರು ತಮ್ಮದೇ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುತ್ತಾರೆ, ಇದರಲ್ಲಿ ಅವರು ತಮ್ಮದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ವಾಲ್‌ಪೇಪರ್ ಮತ್ತು ಮುಂತಾದವುಗಳ ಮೂಲಕ ಕಸ್ಟಮೈಸ್ ಮಾಡಿಕೊಳ್ಳಬಹುದು. ಎಲ್ಲರ ಮೇಲೂ ಪರಿಣಾಮ ಬೀರುವಂತೆ ವೈ-ಫೈ ರೀತಿಯ ಸಾಧನ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬಳಕೆದಾರರು ಸರಿಹೊಂದಿಸಬಹುದು.\n\nನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಹೊಂದಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಸೇವೆಗಳು ಹೊಸ ಬಳಕೆದಾರರಿಗೆ ವರ್ಗಾವಣೆ ಆಗದಿರಬಹುದು."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸ್ಥಾಪಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"ಈ ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಾಹಕರನ್ನಾಗಿ ಮಾಡಬೇಕೆ?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"ನಿರ್ವಾಹಕರು ಇತರ ಬಳಕೆದಾರರಿಗೆ ಇಲ್ಲದ ವಿಶೇಷ ಸೌಲಭ್ಯಗಳನ್ನು ಹೊಂದಿದ್ದಾರೆ. ನಿರ್ವಾಹಕರು ಎಲ್ಲಾ ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಬಹುದು, ಈ ಸಾಧನವನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು ಅಥವಾ ರೀಸೆಟ್ ಮಾಡಬಹುದು, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಹೊಂದಿಸಬಹುದು, ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾದ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಮತ್ತು ಇತರರಿಗೆ ನಿರ್ವಾಹಕರಿಗೆ ನೀಡಿರುವ ಸೌಲಭ್ಯಗಳನ್ನು ನೀಡಬಹುದು ಅಥವಾ ಹಿಂತೆಗೆದುಕೊಳ್ಳಬಹುದು."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"ನಿರ್ವಾಹಕರನ್ನಾಗಿ ಮಾಡಿ"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"ಈಗ ಬಳಕೆದಾರರನ್ನು ಸೆಟ್ ಮಾಡುವುದೇ?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ಸಾಧನವನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಮತ್ತು ಅದರ ಸ್ಥಳವನ್ನು ಹೊಂದಿಸಲು ವ್ಯಕ್ತಿಯು ಲಭ್ಯವಿದ್ದಾರೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ಇದೀಗ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು ಹೊಂದಿಸುವುದೇ?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ಈ ಪ್ರಕ್ರಿಯೆಯು ಹೊಸ ಅತಿಥಿ ಸೆಶನ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ ಮತ್ತು ಪ್ರಸ್ತುತ ಸೆಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಹಾಗೂ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ಅತಿಥಿ ಮೋಡ್‌ನಿಂದ ನಿರ್ಗಮಿಸಬೇಕೆ?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ಈ ಪ್ರಕ್ರಿಯೆಯು ಪ್ರಸ್ತುತ ಅತಿಥಿ ಸೆಷನ್‌ನಿಂದ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"ಹೌದು, ಅವರನ್ನು ನಿರ್ವಾಹಕರನ್ನಾಗಿ ಮಾಡಿ"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"ಬೇಡ, ಅವರನ್ನು ನಿರ್ವಾಹಕರನ್ನಾಗಿ ಮಾಡಬೇಡಿ"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ನಿರ್ಗಮಿಸಿ"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ಅತಿಥಿ ಚಟುವಟಿಕೆಯನ್ನು ಉಳಿಸಬೇಕೆ?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ನೀವು ಪ್ರಸ್ತುತ ಸೆಶನ್‌ನ ಚಟುವಟಿಕೆಯನ್ನು ಉಳಿಸಬಹುದು ಅಥವಾ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಬಹುದು"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 74e1cea..cfc61d2 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"시간 늘리기"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"시간 줄이기"</string>
     <string name="cancel" msgid="5665114069455378395">"취소"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"다음"</string>
+    <string name="back" msgid="5554327870352703710">"뒤로"</string>
+    <string name="save" msgid="3745809743277153149">"저장"</string>
     <string name="okay" msgid="949938843324579502">"확인"</string>
     <string name="done" msgid="381184316122520313">"완료"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"알람 및 리마인더"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"신규 사용자를 추가할까요?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"추가 사용자를 만들어 다른 사용자와 기기를 공유할 수 있습니다. 각 사용자는 앱, 배경화면 등으로 맞춤설정할 수 있는 자신만의 공간을 갖게 됩니다. 또한 모든 사용자에게 영향을 미치는 Wi‑Fi와 같은 기기 설정도 조정할 수 있습니다.\n\n추가된 신규 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자가 앱을 업데이트할 수 있으며, 업데이트는 다른 사용자에게도 적용됩니다. 접근성 설정 및 서비스는 신규 사용자에게 이전되지 않을 수도 있습니다."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자는 다른 사용자들을 위하여 앱을 업데이트할 수 있습니다."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"이 사용자에게 관리자 권한을 부여하시겠습니까?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"관리자는 다른 사용자가 가지지 못한 특별한 권한을 보유합니다. 관리자는 모든 사용자를 관리하고, 기기를 업데이트하거나 재설정하고, 설정을 변경하고, 설치된 모든 앱을 확인하고, 다른 사용자에게 관리자 권한을 부여하거나 취소할 수 있습니다."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"관리자 권한 부여"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"지금 사용자를 설정하시겠습니까?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"사용자가 기기를 사용하여 자신의 공간을 설정할 수 있도록 하세요."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"지금 프로필을 설정하시겠습니까?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"새로운 게스트 세션이 시작되고 기존 세션의 모든 앱과 데이터가 삭제됩니다."</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"게스트 모드를 종료하시겠습니까?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"현재 게스트 세션의 앱과 데이터가 삭제됩니다."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"예, 관리자 권한을 부여합니다."</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"아니요, 관리자 권한을 부여하지 않습니다."</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"종료"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"게스트 활동을 저장하시겠습니까?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"기존 세션의 활동을 저장하거나 모든 앱과 데이터를 삭제할 수 있습니다."</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index f67e0bf..9969e1e 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -195,7 +195,7 @@
     <string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g> желеге туташууну талап кылат"</string>
     <string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g> колдоого алынган эмес"</string>
     <string name="tts_status_checking" msgid="8026559918948285013">"Текшерилүүдө…"</string>
-    <string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> жөндөөлөрдү"</string>
+    <string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> параметрлерди"</string>
     <string name="tts_engine_settings_button" msgid="477155276199968948">"Жарак тууралоолорун ачуу"</string>
     <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"Тандалган жарак"</string>
     <string name="tts_general_section_title" msgid="8919671529502364567">"Жалпы"</string>
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Көбүрөөк убакыт."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Азыраак убакыт."</string>
     <string name="cancel" msgid="5665114069455378395">"Жок"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Кийинки"</string>
+    <string name="back" msgid="5554327870352703710">"Артка"</string>
+    <string name="save" msgid="3745809743277153149">"Сактоо"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Бүттү"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ойготкучтар жана эстеткичтер"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Жаңы колдонуучу кошосузбу?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Эгер түзмөгүңүздү дагы бир адам колдонуп жаткан болсо, кошумча профилдерди түзүп коюңуз. Профилдин ээси аны өзү каалагандай тууралап, тушкагаздарды коюп, керектүү колдонмолорду орнотуп алат. Мындан тышкары, колдонуучулар түзмөктүн Wi‑Fi´ды өчүрүү/күйгүзүү сыяктуу жалпы параметрлерин өзгөртө алышат.\n\nПрофиль түзүлгөндөн кийин, аны тууралап алуу керек.\n\nЖалпы колдонмолорду баары жаңырта алат, бирок атайын мүмкүнчүлүктөр өз-өзүнчө жөндөлөт."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Жаңы колдонуучу кошулганда, ал өз мейкиндигин түзүп алышы керек.\n\nКолдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Бул колдонуучуну админ кыласызбы?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Админдердин өзгөчө укуктары бар. Админ бардык колдонуучуларды тескеп, бул түзмөктү жаңыртып же баштапкы абалга келтирип, параметрлерди өзгөртүп, орнотулган колдонмолордун баарын көрүп, башкаларга админ укуктарын берип же жокко чыгара алат."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Админ кылуу"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Профилди жөндөйсүзбү?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Өз мейкиндигин жөндөп алышы үчүн, түзмөктү колдонуучуга беришиңиз керек."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Профайл азыр түзүлсүнбү?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Бул аракет жаңы конок сеансын баштап, учурдагы сеанстагы бардык колдонмолорду жана алардагы нерселерди жок кылат"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Конок режиминен чыгасызбы?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Учурдагы конок сеансындагы бардык колдонмолор менен алардагы нерселер өчүп калат"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ооба, аны админ кылуу"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Жок, ал админ болбосун"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Чыгуу"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Коноктун аракеттерин сактайсызбы?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Учурдагы сеанстагы аракеттерди сактап же бардык колдонмолорду жана алардагы нерселерди жок кылсаңыз болот"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index c9a40f6..687ce1c 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"ເພີ່ມເວລາ."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"ຫຼຸດເວລາ."</string>
     <string name="cancel" msgid="5665114069455378395">"ຍົກເລີກ"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"ຕໍ່ໄປ"</string>
+    <string name="back" msgid="5554327870352703710">"ກັບຄືນ"</string>
+    <string name="save" msgid="3745809743277153149">"ບັນທຶກ"</string>
     <string name="okay" msgid="949938843324579502">"ຕົກລົງ"</string>
     <string name="done" msgid="381184316122520313">"ແລ້ວໆ"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ໂມງປຸກ ແລະ ການແຈ້ງເຕືອນ"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"ເພີ່ມຜູ້ໃຊ້ໃໝ່ບໍ?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"ທ່ານສາມາດໃຊ້ອຸປະກອນນີ້ຮ່ວມກັບຄົນອື່ນໄດ້ໂດຍການສ້າງຜູ້ໃຊ້ເພີ່ມເຕີມ. ຜູ້ໃຊ້ແຕ່ລະຄົນຈະມີພື້ນທີ່ຂອງຕົວເອງ, ເຊິ່ງເຂົາເຈົ້າສາມາດປັບແຕ່ງແອັບ, ຮູບພື້ນຫຼັງ ແລະ ອື່ນໆໄດ້. ຜູ້ໃຊ້ຕ່າງໆ ສາມາດປັບແຕ່ງການຕັ້ງຄ່າອຸປະກອນໄດ້ ເຊັ່ນ: Wi‑Fi ທີ່ມີຜົນກະທົບທຸກຄົນ.\n\nເມື່ອທ່ານເພີ່ມຜູ້ໃຊ້ໃໝ່, ບຸກຄົນນັ້ນຈະຕ້ອງຕັ້ງຄ່າພື້ນທີ່ຂອງເຂົາເຈົ້າກ່ອນ.\n\nຜູ້ໃຊ້ໃດກໍຕາມສາມາດອັບເດດແອັບສຳລັບຜູ້ໃຊ້ຄົນອື່ນທັງໝົດໄດ້. ການຕັ້ງຄ່າການຊ່ວຍເຂົ້າເຖິງອາດບໍ່ຖືກໂອນຍ້າຍໄປໃຫ້ຜູ້ໃຊ້ໃໝ່."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"ເມື່ອ​ທ່ານ​ເພີ່ມ​ຜູ້​ໃຊ້​ໃໝ່, ຜູ້​ໃຊ້​ນັ້ນ​ຈະ​ຕ້ອງ​ຕັ້ງ​ຄ່າ​ພື້ນ​ທີ່​ບ່ອນ​ຈັດ​ເກັບ​ຂໍ້​ມູນ​ຂອງ​ລາວ.\n\nຜູ້​ໃຊ້​ທຸກ​ຄົນ​ສາ​ມາດ​ອັບ​ເດດ​ແອັບສຳ​ລັບ​ຜູ້​ໃຊ້​ຄົນ​ອື່ນ​ທັງ​ໝົດ​ໄດ້."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"ຕັ້ງໃຫ້ຜູ້ໃຊ້ຄົນນີ້ເປັນຜູ້ເບິ່ງແຍງລະບົບບໍ?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"ຜູ້ເບິ່ງແຍງລະບົບຈະມີສິດທິພິເສດທີ່ຜູ້ໃຊ້ຄົນອື່ນບໍ່ມີ. ຜູ້ເບິ່ງແຍງລະບົບສາມາດຈັດການຜູ້ໃຊ້ທັງໝົດ, ການອັບເດດ ຫຼື ການຣີເຊັດອຸປະກອນນີ້, ການແກ້ໄຂການຕັ້ງຄ່າ, ການເບິ່ງແອັບທີ່ຕິດຕັ້ງທັງໝົດ ແລະ ໃຊ້ ຫຼື ຖອດຖອນສິດທິຜູ້ເບິ່ງແຍງລະບົບສຳລັບຄົນອື່ນໆໄດ້."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"ຕັ້ງໃຫ້ເປັນຜູ້ເບິ່ງແຍງລະບົບ"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"ຕັ້ງຄ່າຜູ້ໃຊ້ຕອນນີ້ບໍ?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ກວດ​ສອບ​ໃຫ້​ແນ່​ໃຈ​ວ່າ​ບຸກ​ຄົນ​ດັ່ງ​ກ່າວ​ສາ​ມາດ​ຮັບ​ອຸ​ປະ​ກອນ​ ແລະ ​ຕັ້ງ​ຄ່າ​ພື້ນ​ທີ່​ຂອງ​ພວກ​ເຂົາ​ໄດ້"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ຕັ້ງຄ່າໂປຣໄຟລ໌ດຽວນີ້?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ນີ້ຈະເລີ່ມໄລຍະເວລາຂອງແຂກໃໝ່ ແລະ ລຶບແອັບ ແລະ ຂໍ້ມູນທັງໝົດອອກຈາກເຊດຊັນປັດຈຸບັນ"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ອອກຈາກໂໝດແຂກບໍ?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ນີ້ຈະລຶບແອັບ ແລະ ຂໍ້ມູນອອກຈາກເຊດຊັນແຂກປັດຈຸບັນ"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"ແມ່ນ, ຕັ້ງໃຫ້ເຂົາເຈົ້າເປັນຜູ້ເບິ່ງແຍງລະບົບ"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"ບໍ່, ບໍ່ຕັ້ງໃຫ້ເຂົາເຈົ້າເປັນຜູ້ເບິ່ງແຍງລະບົບ"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ອອກ"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ບັນທຶກການເຄື່ອນໄຫວແຂກບໍ?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ທ່ານສາມາດບັນທຶກການເຄື່ອນໄຫວຈາກເຊດຊັນປັດຈຸບັນ ຫຼື ລຶບແອັບ ແລະ ຂໍ້ມູນທັງໝົດໄດ້"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 058065e..bac6306 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Daugiau laiko."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Mažiau laiko."</string>
     <string name="cancel" msgid="5665114069455378395">"Atšaukti"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Kitas"</string>
+    <string name="back" msgid="5554327870352703710">"Atgal"</string>
+    <string name="save" msgid="3745809743277153149">"Išsaugoti"</string>
     <string name="okay" msgid="949938843324579502">"Gerai"</string>
     <string name="done" msgid="381184316122520313">"Atlikta"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Signalai ir priminimai"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Pridėti naują naudotoją?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Galite bendrinti šį įrenginį su kitais žmonėmis sukūrę papildomų naudotojų. Kiekvienam naudotojui suteikiama atskira erdvė, kurią jie gali tinkinti naudodami programas, ekrano foną ir kt. Be to, naudotojai gali koreguoti įrenginio nustatymus, pvz., „Wi‑Fi“, kurie taikomi visiems.\n\nKai pridedate naują naudotoją, šis asmuo turi nusistatyti savo erdvę.\n\nBet kuris naudotojas gali atnaujinti visų kitų naudotojų programas. Pasiekiamumo nustatymai ir paslaugos gali nebūti perkeltos naujam naudotojui."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Kai pridedate naują naudotoją, šis asmuo turi nustatyti savo vietą.\n\nBet kuris naudotojas gali atnaujinti visų kitų naudotojų programas."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Nustatyti šį naudotoją kaip administratorių?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratoriai turi specialių privilegijų, kurių kiti naudotojai neturi. Administratorius gali tvarkyti visus naudotojus, atnaujinti ar iš naujo nustatyti šį įrenginį, keisti nustatymus, peržiūrėti visas įdiegtas programas ir suteikti administratoriaus privilegijas kitiems naudotojams arba jas panaikinti."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Nustatyti kaip administratorių"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Nustatyti naudotoją dabar?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Įsitikinkite, kad asmuo gali paimti įrenginį ir nustatyti savo vietą"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Nustatyti profilį dabar?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Bus pradėta nauja svečio sesija ir iš esamos sesijos bus ištrintos visos programos ir duomenys"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Išeiti iš svečio režimo?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bus ištrintos esamos svečio sesijos programos ir duomenys"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Taip, nustatyti kaip administratorių"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Ne, nenustatyti kaip administratoriaus"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Išeiti"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Išsaugoti svečio veiklą?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Galite išsaugoti esamos sesijos veiklą arba ištrinti visas programas ir duomenis"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 32d9243..d2d38fc 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Vairāk laika."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Mazāk laika."</string>
     <string name="cancel" msgid="5665114069455378395">"Atcelt"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Tālāk"</string>
+    <string name="back" msgid="5554327870352703710">"Atpakaļ"</string>
+    <string name="save" msgid="3745809743277153149">"Saglabāt"</string>
     <string name="okay" msgid="949938843324579502">"LABI"</string>
     <string name="done" msgid="381184316122520313">"Gatavs"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Signāli un atgādinājumi"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Vai pievienot jaunu lietotāju?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Varat koplietot šo ierīci ar citām personām, izveidojot papildu lietotājus. Katram lietotājam ir sava vide, kas ir pielāgojama, izmantojot lietotnes, fona tapetes u.c. Lietotāji var pielāgot arī ierīces iestatījumus, kas attiecas uz visiem lietotājiem, piemēram, Wi‑Fi.\n\nKad pievienosiet jaunu lietotāju, viņam būs jāizveido sava vide.\n\nIkviens lietotājs var atjaunināt lietotnes citu lietotāju vietā. Pieejamības iestatījumi un pakalpojumi var netikt pārsūtīti jaunajam lietotājam."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Kad pievienosiet jaunu lietotāju, viņam būs jāizveido sava vide.\n\nIkviens lietotājs var atjaunināt lietotnes citu lietotāju vietā."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Vai iestatīt šo lietotāju kā administratoru?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratoriem ir īpašas privilēģijas, kas nav citiem lietotājiem. Administrators var pārvaldīt visus lietotājus, atjaunināt vai atiestatīt šo ierīci, mainīt iestatījumus, skatīt visas instalētās lietotnes un piešķirt vai atsaukt administratora privilēģijas citiem lietotājiem."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Iestatīt kā administratoru"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Iestatīt kontu tūlīt?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Pārliecinieties, ka persona var izmantot ierīci un iestatīt savu vidi."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Vai iestatīt profilu tūlīt?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tādējādi tiks sākta jauna viesa sesijas un visas pašreizējās sesijas lietotnes un dati tiks dzēsti"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vai iziet no viesa režīma?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tādējādi tiks dzēstas pašreizējās viesa sesijas lietotnes un dati."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Jā, iestatīt kā administratoru"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nē, neiestatīt kā administratoru"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Iziet"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vai saglabāt viesa darbības?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Varat saglabāt pašreizējās sesijas darbības vai dzēst visas lietotnes un datus"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index f8a66f8..ff33f1f 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -441,7 +441,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалија (слепило за црвена и зелена)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалија (слепило за сина и жолта)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекција на бои"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Корекцијата на боите може да биде корисна кога сакате:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;да ги гледате боите попрецизно&lt;/li&gt; &lt;li&gt;&amp;nbsp;да ги отстраните боите за да се фокусирате подобро&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Корекцијата на боите може да биде корисна кога сакате:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;да ги гледате боите попрецизно&lt;/li&gt; &lt;li&gt;&amp;nbsp;да ги отстраните боите за полесно да се концентрирате&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Уште околу <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Повеќе време."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Помалку време."</string>
     <string name="cancel" msgid="5665114069455378395">"Откажи"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Следно"</string>
+    <string name="back" msgid="5554327870352703710">"Назад"</string>
+    <string name="save" msgid="3745809743277153149">"Зачувај"</string>
     <string name="okay" msgid="949938843324579502">"Во ред"</string>
     <string name="done" msgid="381184316122520313">"Готово"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Аларми и потсетници"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Да се додаде нов корисник?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Уредов може да го споделувате со други лица ако додадете дополнителни корисници. Секој корисник има сопствен простор што може да го приспособува со апликации, тапети и слично. Корисниците може да приспособуваат и поставки за уредот, како на пр., Wi‑Fi, што важат за сите.\n\nКога додавате нов корисник, тоа лице треба да го постави својот простор.\n\nСекој корисник може да ажурира апликации за сите други корисници. Поставките и услугите за пристапност не може да се префрлат на новиот корисник."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Кога додавате нов корисник, тоа лице треба да го постави својот простор.\n\nСекој корисник може да ажурира апликации за сите други корисници."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Дали да се направи корисников администратор?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Администраторите имаат посебни привилегии што другите корисници ги немаат. Администраторот може да управува со сите корисници, да го ажурира или ресетира уредов, да ги менува поставките, да ги гледа сите инсталирани апликации и да доделува или одзема администраторски привилегии за други."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Направи да биде администратор"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Ќе поставите корисник сега?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Проверете дали лицето е достапно да го земе уредот и да го постави својот простор"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Постави профил сега?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Ова ќе започне нова гостинска сесија и ќе ги избрише сите апликации и податоци од тековната сесија"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Да се излезе од режим на гостин?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ова ќе ги избрише сите апликации и податоци од тековната гостинска сесија"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Да, направи да биде администратор"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Не, не прави да биде администратори"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Излези"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Да се зачува активност на гостин?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Може да зачувате активност од тековната сесија или да ги избришете сите апликации и податоци"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 80ca5fd..f75ecaf 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Их хугацаа."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Бага хугацаа."</string>
     <string name="cancel" msgid="5665114069455378395">"Цуцлах"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Дараах"</string>
+    <string name="back" msgid="5554327870352703710">"Буцах"</string>
+    <string name="save" msgid="3745809743277153149">"Хадгалах"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Болсон"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Сэрүүлэг болон сануулагч"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Шинэ хэрэглэгч нэмэх үү?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Та нэмэлт хэрэглэгч үүсгэх замаар бусад хүмүүстэй энэ төхөөрөмжийг хуваалцаж болно. Хэрэглэгч тус бүр апп, дэлгэцийн зураг болон бусад зүйлээ өөрчлөх боломжтой хувийн орон зайтай байна. Түүнчлэн хэрэглэгч нь бүх хэрэглэгчид нөлөөлөх боломжтой Wi-Fi зэрэг төхөөрөмжийн тохиргоог өөрчлөх боломжтой.\n\nХэрэв та шинэ хэрэглэгч нэмэх бол тухайн хүн хувийн орон зайгаа бүрдүүлэх ёстой.\n\nХэрэглэгч бүр бусад бүх хэрэглэгчийн өмнөөс апп шинэчилж болно. Хандалтын тохиргоо болон үйлчилгээг шинэ хэрэглэгчид шилжүүлэх боломжгүй байж болзошгүй."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн апп-уудыг шинэчлэх боломжтой."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Энэ хэрэглэгчийг админ болгох уу?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Админууд бусад хэрэглэгчид байхгүй тусгай эрхтэй байдаг. Админ нь бүх хэрэглэгчийг удирдах, энэ төхөөрөмжийг шинэчлэх, сэргээх, тохиргоог өөрчлөх, бүх суулгасан аппыг харах болон бусад хэрэглэгчид админы эрх өгөх эсвэл эрхийг нь цуцлах боломжтой."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Админ болгох"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Хэрэглэгчийг одоо тохируулах уу?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Хэрэглэгч төхөөрөмжийг авч өөрийн профайлыг тохируулах боломжтой эсэхийг шалгана уу"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Профайлыг одоо тохируулах уу?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Энэ нь шинэ зочны харилцан үйлдэл эхлүүлж, одоогийн харилцан үйлдлээс бүх апп болон өгөгдлийг устгана"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Зочны горимоос гарах уу?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Энэ нь одоогийн зочны харилцан үйлдлээс аппууд болон өгөгдлийг устгана"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Тийм, түүнийг админ болго"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Үгүй, түүнийг админ болгохгүй"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Гарах"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Зочны үйл ажиллагааг хадгалах уу?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Та одоогийн харилцан үйлдлээс үйл ажиллагаа хадгалах эсвэл бүх апп, өгөгдлийг устгаж болно"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 3836e17..b0ce688 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"जास्त वेळ."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"कमी वेळ."</string>
     <string name="cancel" msgid="5665114069455378395">"रद्द करा"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"पुढील"</string>
+    <string name="back" msgid="5554327870352703710">"मागे जा"</string>
+    <string name="save" msgid="3745809743277153149">"सेव्ह करा"</string>
     <string name="okay" msgid="949938843324579502">"ठीक आहे"</string>
     <string name="done" msgid="381184316122520313">"पूर्ण झाले"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"अलार्म आणि रिमाइंडर"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"नवीन वापरकर्ता जोडायचा?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"अतिरिक्त वापरकर्ते तयार करून तुम्ही इतर लोकांसोबत हे डिव्हाइस शेअर करू शकता. प्रत्येक वापरकर्त्यास त्यांची स्वतःची स्पेस असते, जी ते अ‍ॅप्स, वॉलपेपर आणि यासारख्या गोष्टींनी कस्टमाइझ करू शकतात. वापरकर्ते प्रत्येकाला प्रभावित करणाऱ्या वाय-फाय सारख्या डिव्हाइस सेटिंग्ज अ‍ॅडजस्ट देखील करू शकतात.\n\nतुम्ही एक नवीन वापरकर्ता जोडता, तेव्हा त्या व्यक्तीला त्याची स्पेस सेट अप करण्याची आवश्यकता असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप अपडेट करू शकतो. अ‍ॅक्सेसिबिलिटी सेटिंग्ज आणि सेवा नवीन वापरकर्त्याला कदाचित ट्रान्सफर होणार नाहीत."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"तुम्ही एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीस त्यांचे स्थान सेट करण्याची आवश्यकता असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"या वापरकर्त्याला ॲडमिन करायचे का?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"ॲडमिनकडे खास विशेषाधिकार आहेत जे इतर वापरकर्त्यांकडे नसतात. ॲडमिन सर्व वापरकर्ते व्यवस्थापित करू शकतो, हे डिव्हाइस अपडेट करू शकतो किंवा रीसेट करू शकतो, सेटिंग्जमध्ये सुधारणा करू शकतो, सर्व इंस्टॉल केलेली अ‍ॅप्स पाहू शकतो आणि इतरांसाठी ॲडमिनचे विशेषाधिकार मंजूर करू शकतो किंवा रद्द करू शकतो."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"ॲडमिन करा"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"आता वापरकर्ता सेट करायचा?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"तो वापरकर्ता डिव्हाइसजवळ आहे आणि त्याचे स्थान सेट करण्यासाठी उपलब्ध आहे याची खात्री करा"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"आता प्रोफाईल सेट करायचा?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"हे नवीन अतिथी सत्र सुरू करेल आणि सध्याच्या सत्रातील सर्व अ‍ॅप्स व डेटा हटवेल"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"अतिथी मोडमधून बाहेर पडायचे का?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"हे सध्याच्या अतिथी सत्रातील अ‍ॅप्स आणि डेटा हटवेल"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"होय, त्यांना ॲडमिन करा"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"नाही, त्यांना ॲडमिन करू नका"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"बाहेर पडा"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"अतिथी अ‍ॅक्टिव्हिटी सेव्ह करायची का?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"सध्याच्या सत्रातील अ‍ॅक्टिव्हिटी सेव्ह करू किंवा सर्व अ‍ॅप्स व डेटा हटवू शकता"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 2c3bb50..eadc124 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Lagi masa."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Kurang masa."</string>
     <string name="cancel" msgid="5665114069455378395">"Batal"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Seterusnya"</string>
+    <string name="back" msgid="5554327870352703710">"Kembali"</string>
+    <string name="save" msgid="3745809743277153149">"Simpan"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Selesai"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Penggera dan peringatan"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Tambah pengguna baharu?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Anda boleh berkongsi peranti ini dengan orang lain dengan membuat pengguna tambahan. Setiap pengguna mempunyai ruang mereka sendiri, yang boleh diperibadikan dengan apl, kertas dinding dan sebagainya. Pengguna juga boleh melaraskan tetapan peranti seperti Wi-Fi yang akan memberi kesan kepada semua orang.\n\nApabila anda menambah pengguna baharu, orang itu perlu menyediakan ruang mereka.\n\nMana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain. Tetapan dan perkhidmatan kebolehaksesan tidak boleh dipindahkan kepada pengguna baharu."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Apabila anda menambah pengguna baharu, orang itu perlu menyediakan ruang mereka.\n\nMana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Jadikan pengguna ini pentadbir?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Pentadbir mempunyai keistimewaan khas yang tiada pada pengguna lain. Pentadbir boleh mengurus semua pengguna, mengemaskinikan atau menetapkan semula peranti ini, mengubah suai tetapan, melihat semua apl yang telah dipasang dan memberikan atau membatalkan keistimewaan pentadbir untuk pengguna lain."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Jadikan pentadbir"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Sediakan pengguna sekarang?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Pastikan orang itu tersedia untuk mengambil peranti dan menyediakan ruangan"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Sediakan profil sekarang?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tindakan ini akan memulakan sesi tetamu baharu dan memadamkan semua apl dan data daripada sesi semasa"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Keluar daripada mod tetamu?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tindakan ini akan memadamkan apl dan data daripada sesi tetamu semasa"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ya, jadikan mereka pentadbir"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Tidak, jangan jadikan mereka pentadbir"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Keluar"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Simpan aktiviti tetamu?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Anda boleh menyimpan aktiviti daripada sesi semasa atau memadamkan semua apl dan data"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index e09afe5..975e6d5 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"အချိန်တိုးရန်။"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"အချိန်လျှော့ရန်။"</string>
     <string name="cancel" msgid="5665114069455378395">"မလုပ်တော့"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"ရှေ့သို့"</string>
+    <string name="back" msgid="5554327870352703710">"နောက်သို့"</string>
+    <string name="save" msgid="3745809743277153149">"သိမ်းရန်"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"ပြီးပြီ"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"နှိုးစက်နှင့် သတိပေးချက်များ"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"အသုံးပြုသူအသစ် ထည့်မလား။"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"နောက်ထပ် အသုံးပြုသူများ ထည့်သွင်းခြင်းဖြင့် ဤစက်ပစ္စည်းကို အခြားသူများနှင့် မျှဝေအသုံးပြုနိုင်သည်။ အသုံးပြုသူတိုင်းသည် မိမိတို့ကိုယ်ပိုင်နေရာ ရရှိမည်ဖြစ်ပြီး အက်ပ်၊ နောက်ခံပုံနှင့် အခြားအရာတို့ဖြင့် စိတ်ကြိုက်ပြင်ဆင်နိုင်ပါမည်။ အားလုံးကို အကျိုးသက်ရောက်မှု ရှိစေနိုင်သည့် Wi-Fi ကဲ့သို့ ဆက်တင်များကိုလည်း ချိန်ညှိနိုင်ပါမည်။\n\nအသုံးပြုသူအသစ် ထည့်သည့်အခါ ထိုသူသည် မိမိ၏ကိုယ်ပိုင်နေရာကို သတ်မှတ်ရပါမည်။\n\nအသုံးပြုသူ မည်သူမဆို အခြားအသုံးပြုသူများအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်နိုင်သည်။ အများသုံးစွဲနိုင်မှုဆက်တင်များနှင့် ဝန်ဆောင်မှုများကို အသုံးပြုသူအသစ်ထံသို့ လွှဲပြောင်းပေးမည် မဟုတ်ပါ။"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"သင်က အသုံးပြုသူ အသစ် တစ်ဦးကို ထည့်ပေးလိုက်လျှင်၊ ထိုသူသည် ၎င်း၏ နေရာကို သတ်မှတ်စီစဉ်ရန် လိုအပ်မည်။\n\n အသုံးပြုသူ မည်သူမဆို ကျန်အသုံးပြုသူ အားလုံးတို့အတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်ပေးနိုင်သည်။"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"ဤအသုံးပြုသူကို စီမံခန့်ခွဲသူအဖြစ် သတ်မှတ်မလား။"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"စီမံခန့်ခွဲသူများ၌ အခြားအသုံးပြုသူများတွင်မရှိသော အထူးဆောင်ရွက်ခွင့်များရှိသည်။ စီမံခန့်ခွဲသူက အသုံးပြုသူအားလုံးကို စီမံခြင်း၊ ဤစက်ပစ္စည်းကို အပ်ဒိတ်လုပ်ခြင်း (သို့) ပြင်ဆင်သတ်မှတ်ခြင်း၊ ဆက်တင်များပြင်ဆင်ခြင်း၊ ထည့်သွင်းထားသောအက်ပ်အားလုံးကို ကြည့်ခြင်းနှင့် အခြားသူများအတွက် စီမံခန့်ခွဲသူ ဆောင်ရွက်ခွင့်များပေးခြင်း (သို့) ရုပ်သိမ်းခြင်းတို့ လုပ်နိုင်သည်။"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"စီမံခန့်ခွဲသူအဖြစ် သတ်မှတ်ရန်"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"အသုံးပြုသူကို ယခုသတ်မှတ်မလား။"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ထိုသူသည် ကိရိယာကိုယူ၍ ၎င်းတို့၏နေရာများကို ယခုသတ်မှတ်နိုင်ရမည်"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ယခု ကိုယ်ရေးအချက်အလက်ကို အစီအမံလုပ်မည်လား?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"၎င်းသည် ဧည့်သည် စက်ရှင်အသစ်ကို စတင်မည်ဖြစ်ပြီး လက်ရှိစက်ရှင်မှ အက်ပ်နှင့် ဒေတာအားလုံးကို ဖျက်ပါမည်"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ဧည့်သည်မုဒ်မှ ထွက်မလား။"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"၎င်းသည် လက်ရှိဧည့်သည် စက်ရှင်မှ အက်ပ်နှင့် ဒေတာအားလုံးကို ဖျက်လိုက်ပါမည်"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"စီမံခန့်ခွဲသူအဖြစ် သတ်မှတ်ရန်"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"စီမံခန့်ခွဲသူအဖြစ် မသတ်မှတ်ပါနှင့်"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ထွက်ရန်"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ဧည့်သည်လုပ်ဆောင်ချက် သိမ်းမလား။"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"လက်ရှိစက်ရှင်မှ လုပ်ဆောင်ချက် သိမ်းနိုင်သည် (သို့) အက်ပ်နှင့် ဒေတာအားလုံး ဖျက်နိုင်သည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index c550e3e..f507f6d 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mer tid."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Mindre tid."</string>
     <string name="cancel" msgid="5665114069455378395">"Avbryt"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Neste"</string>
+    <string name="back" msgid="5554327870352703710">"Tilbake"</string>
+    <string name="save" msgid="3745809743277153149">"Lagre"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Ferdig"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmer og påminnelser"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Vil du legge til en ny bruker?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dele denne enheten med andre folk ved å opprette flere brukere. Hver bruker har sin egen plass de kan tilpasse med apper, bakgrunner og annet. Brukere kan også justere enhetsinnstillinger, for eksempel Wifi, som påvirker alle.\n\nNår du legger til en ny bruker, må vedkommende angi innstillinger for plassen sin.\n\nAlle brukere kan oppdatere apper for alle andre brukere. Innstillinger og tjenester for tilgjengelighet overføres kanskje ikke til den nye brukeren."</string>
     <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>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Vil du gjøre denne brukeren til administrator?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratorer har spesielle rettigheter som ikke andre brukere har. Administratorer kan administrere alle brukere, oppdatere og tilbakestille denne enheten, endre innstillinger, se alle installerte apper, gi administratorrettigheter til andre samt oppheve andres administratorrettigheter."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Gjør til administrator"</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>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Dette starter en ny gjesteøkt og sletter alle apper og data fra den gjeldende økten"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vil du avslutte gjestemodus?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Dette sletter apper og data fra den gjeldende gjesteøkten"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ja, gjør til administrator"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nei, ikke gjør til administrator"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Avslutt"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vil du lagre gjesteaktivitet?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Du kan lagre aktivitet fra den gjeldende økten eller slette alle apper og data"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 9421e71..19bb0f0 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"थप समय।"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"कम समय।"</string>
     <string name="cancel" msgid="5665114069455378395">"रद्द गर्नुहोस्"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"अर्को"</string>
+    <string name="back" msgid="5554327870352703710">"पछाडि"</string>
+    <string name="save" msgid="3745809743277153149">"सेभ गर्नुहोस्"</string>
     <string name="okay" msgid="949938843324579502">"ठिक छ"</string>
     <string name="done" msgid="381184316122520313">"सम्पन्न भयो"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"अलार्म र रिमाइन्डरहरू"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"नयाँ प्रयोगकर्ता थप्ने हो?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"तपाईं थप प्रयोगकर्ताहरू सिर्जना गरेर ती प्रयोगकर्तालाई यो डिभाइस प्रयोग गर्न दिन सक्नुहुन्छ। हरेक प्रयोगकर्ताको आफ्नै ठाउँ हुन्छ। उनीहरू यो ठाउँमा आफ्नै एप, वालपेपर आदिका लागि प्रयोग गर्न सक्छन्। उनीहरू सबैजनालाई असर पार्ने Wi-Fi जस्ता डिभाइसका सेटिङहरू पनि परिवर्तन गर्न सक्छन्।\n\nतपाईंले नयाँ प्रयोगकर्ता थप्दा उक्त व्यक्तिले आफ्नो ठाउँ सेटअप गर्नु पर्ने हुन्छ।\n\nसबै प्रयोगकर्ता अन्य सबै प्रयोगकर्ताले प्रयोग गर्ने एपहरू अद्यावधिक गर्न सक्छन्। तर पहुँचसम्बन्धी सेटिङ तथा सेवाहरू नयाँ प्रयोगकर्तामा नसर्न सक्छ।"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"तपाईंले नयाँ प्रयोगकर्ता थप्नुभयो भने ती प्रयोगकर्ताले आफ्नो स्पेस सेट गर्नु पर्ने हुन्छ।\n\nसबै प्रयोगकर्ताले अरू प्रयोगकर्ताका एपहरू अपडेट गर्न सक्छन्।"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"यी प्रयोगकर्तालाई एड्मिन बनाउने हो?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"एड्मिनहरूसँग अन्य प्रयोगकर्तासँग नभएका विशेषाधिकारहरू हुन्छन्। एड्मिन सबै प्रयोगकर्ताहरूलाई व्यवस्थापन गर्न, यो डिभाइस अपडेट वा रिसेट गर्न, सेटिङ परिमार्जन गर्न, इन्स्टल गरिएका सबै एपहरू हेर्न र अरूलाई एड्मिनका विशेषाधिकारहरू दिन वा अरूलाई दिइएका एड्मिनका विशेषाधिकारहरू खारेज गर्न सक्नुहुन्छ।"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"एड्मिन बनाउनुहोस्"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"अहिले प्रयोगकर्ता सेटअप गर्ने हो?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"यी व्यक्ति यन्त्र यो डिभाइस चलाउन र आफ्नो ठाउँ सेट गर्न उपलब्ध छन् भन्ने कुरा सुनिश्चित गर्नुहोस्"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"अहिले प्रोफाइल सेटअप गर्ने हो?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"यसो गर्नाले नयाँ अतिथि सत्र सुरु हुने छ र हालको अतिथि सत्रका सबै एप तथा डेटा मेटिने छ"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"अतिथि मोडबाट बाहिरिने हो?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"यसो गर्नाले हालको अतिथि सत्रका एप तथा डेटा मेटिने छ"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"अँ, उहाँलाई एड्मिन बनाउनुहोस्"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"अहँ, उहाँलाई एड्मिन नबनाउनुहोस्"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"बाहिरिनुहोस्"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"अतिथि सत्रमा गरिएका क्रियाकलाप सेभ गर्ने हो?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"तपाईं हालको सत्रमा गरिएका क्रियाकलाप सेभ गर्न वा सबै एप तथा डेटा मेटाउन सक्नुहुन्छ"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 2cad755c..546d672 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Meer tijd."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Minder tijd."</string>
     <string name="cancel" msgid="5665114069455378395">"Annuleren"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Volgende"</string>
+    <string name="back" msgid="5554327870352703710">"Terug"</string>
+    <string name="save" msgid="3745809743277153149">"Opslaan"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Klaar"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Wekkers en herinneringen"</string>
@@ -579,12 +576,9 @@
     <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 hun eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Deze gebruiker beheerder maken?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Beheerders hebben speciale rechten die andere gebruikers niet hebben. Een beheerder kan alle gebruikers beheren, dit apparaat updaten of resetten, instellingen wijzigen, alle geïnstalleerde apps bekijken en beheerdersrechten toekennen of intrekken voor anderen."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Beheerder maken"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Gebruiker nu instellen?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Zorg ervoor dat de persoon het apparaat kan overnemen om een profiel in te stellen"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Profiel nu instellen?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Hiermee start een nieuwe gastsessie en worden alle apps en gegevens van de huidige sessie verwijderd"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Gastmodus sluiten?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Hierdoor worden apps en gegevens van de huidige gastsessie verwijderd"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ja, beheerder maken"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nee, geen beheerder maken"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sluiten"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Gastactiviteit opslaan?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Sla activiteit van de huidige sessie op of verwijder alle apps en gegevens"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 2c667c3..f9520d8 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"ଅଧିକ ସମୟ।"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"କମ୍ ସମୟ।"</string>
     <string name="cancel" msgid="5665114069455378395">"ବାତିଲ"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"ପରବର୍ତ୍ତୀ"</string>
+    <string name="back" msgid="5554327870352703710">"ପଛକୁ ଫେରନ୍ତୁ"</string>
+    <string name="save" msgid="3745809743277153149">"ସେଭ କରନ୍ତୁ"</string>
     <string name="okay" msgid="949938843324579502">"ଠିକ୍‌ ଅଛି"</string>
     <string name="done" msgid="381184316122520313">"ହୋଇଗଲା"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ଆଲାରାମ୍ ଏବଂ ରିମାଇଣ୍ଡରଗୁଡ଼ିକ"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"ନୂତନ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବେ?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"ଅତିରିକ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଯୋଗ କରି ଆପଣ ଏହି ଡିଭାଇସକୁ ଅନ୍ୟ ଲୋକମାନଙ୍କ ସହିତ ସେୟାର କରିପାରିବେ। ପ୍ରତ୍ୟେକ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନିଜର ସ୍ପେସ୍ ଅଛି ଯାହାକୁ ସେମାନେ ଆପ, ୱାଲପେପର୍ ଓ ଏପରି ଅନେକ କିଛି ସହିତ କଷ୍ଟମାଇଜ କରିପାରିବେ। ଉପଯୋଗକର୍ତ୍ତା ୱାଇ-ଫାଇ ଭଳି ଡିଭାଇସ ସେଟିଂସକୁ ମଧ୍ୟ ଆଡଜଷ୍ଟ କରିପାରିବେ ଯାହା ସମସ୍ତଙ୍କୁ ପ୍ରଭାବିତ କରିଥାଏ। \n\nଯେତେବେଳେ ଆପଣ ଗୋଟିଏ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବେ, ସେତେବେଳେ ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ନିଜର ସ୍ପେସ୍‌କୁ ସେଟ‌ଅପ କରିବାକୁ ପଡ଼ିବ। \n\nଅନ୍ୟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଆପକୁ ଅପଡେଟ କରିପାରିବେ। ଆକ୍ସେସିବିଲିଟୀ ସେଟିଂସ ଏବଂ ସେବାଗୁଡ଼ିକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ସ୍ଥାନାନ୍ତର ହୋ‌ଇନପାରେ।"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"ଆପଣ ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବା ବେଳେ, ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ତାଙ୍କ ସ୍ପେସ ସେଟ ଅପ କରିବାକୁ ପଡ଼ିବ।\n\nଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ, ଆପଗୁଡ଼ିକୁ ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଅପଡେଟ କରିପାରିବେ।"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"ଏହି ୟୁଜରଙ୍କୁ ଜଣେ ଆଡମିନ କରିବେ?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"ଆଡମିନମାନଙ୍କର ବିଶେଷ ଅଧିକାରଗୁଡ଼ିକ ଥାଏ ଯାହା ଅନ୍ୟ ୟୁଜରମାନଙ୍କର ନଥାଏ। ଜଣେ ଆଡମିନ ସମସ୍ତ ୟୁଜରଙ୍କୁ ପରିଚାଳନା କରିପାରିବେ, ଏହି ଡିଭାଇସକୁ ଅପଡେଟ କିମ୍ବା ରିସେଟ କରିପାରିବେ, ସେଟିଂସ ପରିବର୍ତ୍ତନ କରିପାରିବେ, ଇନଷ୍ଟଲ କରାଯାଇଥିବା ସମସ୍ତ ଆପ୍ସ ଦେଖିପାରିବେ ଏବଂ ଅନ୍ୟମାନଙ୍କ ପାଇଁ ଆଡମିନ ବିଶେଷ ଅଧିକାରଗୁଡ଼ିକୁ ଅନୁମତି ଦେଇପାରିବେ କିମ୍ବା ପ୍ରତ୍ୟାହାର କରିପାରିବେ।"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"ଆଡମିନ କରନ୍ତୁ"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"ଏବେ ଉପଯୋଗକର୍ତ୍ତା ସେଟଅପ କରିବେ?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ ଯେ, ବ୍ୟକ୍ତି ଜଣକ ଡିଭାଇସ୍‌ ଓ ନିଜର ସ୍ଥାନ ସେଟଅପ୍‌ କରିବା ପାଇଁ ଉପଲବ୍ଧ ଅଛନ୍ତି।"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ପ୍ରୋଫାଇଲ୍‌କୁ ଏବେ ସେଟ୍‌ କରିବେ?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ଏହା ଏକ ନୂଆ ଅତିଥି ସେସନ ଆରମ୍ଭ କରିବ ଏବଂ ବର୍ତ୍ତମାନର ସେସନରୁ ସମସ୍ତ ଆପ୍ସ ଏବଂ ଡାଟାକୁ ଡିଲିଟ କରିବ"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ଅତିଥି ମୋଡରୁ ବାହାରି ଯିବେ?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ଏହା ବର୍ତ୍ତମାନର ଅତିଥି ସେସନରୁ ଆପ୍ସ ଏବଂ ଡାଟାକୁ ଡିଲିଟ କରିବ"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"ହଁ, ତାଙ୍କୁ ଜଣେ ଆଡମିନ କରନ୍ତୁ"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"ନା, ତାଙ୍କୁ ଜଣେ ଆଡମିନ କରନ୍ତୁ ନାହିଁ"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ବାହାରି ଯାଆନ୍ତୁ"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ଅତିଥି କାର୍ଯ୍ୟକଳାପ ସେଭ କରିବେ?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ଆପଣ ଏବେର ସେସନରୁ କାର୍ଯ୍ୟକଳାପକୁ ସେଭ କରିପାରିବେ ବା ସବୁ ଆପ୍ସ ଓ ଡାଟାକୁ ଡିଲିଟ କରିପାରିବେ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 068d695..14567b4 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"ਹੋਰ ਸਮਾਂ।"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"ਘੱਟ ਸਮਾਂ।"</string>
     <string name="cancel" msgid="5665114069455378395">"ਰੱਦ ਕਰੋ"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"ਅੱਗੇ"</string>
+    <string name="back" msgid="5554327870352703710">"ਪਿੱਛੇ ਜਾਓ"</string>
+    <string name="save" msgid="3745809743277153149">"ਰੱਖਿਅਤ ਕਰੋ"</string>
     <string name="okay" msgid="949938843324579502">"ਠੀਕ ਹੈ"</string>
     <string name="done" msgid="381184316122520313">"ਹੋ ਗਿਆ"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"ਕੀ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨਾ ਹੈ?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"ਤੁਸੀਂ ਵਾਧੂ ਵਰਤੋਂਕਾਰ ਬਣਾ ਕੇ ਹੋਰਾਂ ਲੋਕਾਂ ਨਾਲ ਇਹ ਡੀਵਾਈਸ ਸਾਂਝਾ ਕਰ ਸਕਦੇ ਹੋ। ਹਰੇਕ ਵਰਤੋਂਕਾਰ ਦੀ ਆਪਣੀ ਖੁਦ ਦੀ ਜਗ੍ਹਾ ਹੁੰਦੀ ਹੈ, ਜਿਸਨੂੰ ਉਹ ਐਪਾਂ ਅਤੇ ਵਾਲਪੇਪਰ ਆਦਿ ਨਾਲ ਵਿਉਂਤਬੱਧ ਕਰ ਸਕਦੇ ਹਨ। ਵਰਤੋਂਕਾਰ ਵਾਈ-ਫਾਈ ਵਰਗੀਆਂ ਡੀਵਾਈਸ ਸੈਟਿੰਗਾਂ ਨੂੰ ਵੀ ਵਿਵਸਥਿਤ ਕਰ ਸਕਦੇ ਹਨ, ਜਿਸ ਨਾਲ ਹਰੇਕ ਵਰਤੋਂਕਾਰ \'ਤੇ ਅਸਰ ਪੈਂਦਾ ਹੈ।\n\nਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸੈੱਟ ਅੱਪ ਕਰਨੀ ਪੈਂਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਬਾਕੀ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ। ਸ਼ਾਇਦ ਪਹੁੰਚਯੋਗਤਾ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਨੂੰ ਕਿਸੇ ਨਵੇਂ ਵਰਤੋਂਕਾਰ ਨੂੰ ਟ੍ਰਾਂਸਫਰ ਨਾ ਕੀਤਾ ਜਾ ਸਕੇ।"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"ਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸੈੱਟਅੱਪ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਹੋਰ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"ਕੀ ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਪ੍ਰਸ਼ਾਸਕ ਬਣਾਉਣਾ ਹੈ?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"ਪ੍ਰਸ਼ਾਸਕਾਂ ਕੋਲ ਵਿਸ਼ੇਸ਼ ਅਧਿਕਾਰ ਹੁੰਦੇ ਹਨ ਜੋ ਹੋਰ ਵਰਤੋਂਕਾਰਾਂ ਕੋਲ ਨਹੀਂ ਹੁੰਦੇ। ਇੱਕ ਪ੍ਰਸ਼ਾਸਕ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦਾ ਹੈ, ਇਸ ਡੀਵਾਈਸ ਨੂੰ ਅੱਪਡੇਟ ਜਾਂ ਰੀਸੈੱਟ ਕਰ ਸਕਦਾ ਹੈ, ਸੈਟਿੰਗਾਂ ਨੂੰ ਸੋਧ ਸਕਦਾ ਹੈ, ਸਾਰੀਆਂ ਸਥਾਪਤ ਐਪਾਂ ਨੂੰ ਦੇਖ ਸਕਦਾ ਹੈ, ਅਤੇ ਦੂਜਿਆਂ ਲਈ ਪ੍ਰਸ਼ਾਸਕ ਦੇ ਅਧਿਕਾਰਾਂ ਨੂੰ ਮਨਜ਼ੂਰ ਜਾਂ ਰੱਦ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"ਪ੍ਰਸ਼ਾਸਕ ਬਣਾਓ"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"ਕੀ ਹੁਣ ਵਰਤੋਂਕਾਰ ਸੈੱਟ ਅੱਪ ਕਰਨਾ ਹੈ?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਵਿਅਕਤੀ ਡੀਵਾਈਸ ਵਰਤਣ ਅਤੇ ਆਪਣੀ ਜਗ੍ਹਾ ਦੇ ਸੈੱਟ ਅੱਪ ਲਈ ਉਪਲਬਧ ਹੈ"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ਕੀ ਹੁਣ ਪ੍ਰੋਫਾਈਲ ਸੈੱਟ ਅੱਪ ਕਰਨੀ ਹੈ?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ਇਸ ਨਾਲ ਨਵਾਂ ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਸ਼ੁਰੂ ਹੋ ਜਾਵੇਗਾ ਅਤੇ ਮੌਜੂਦਾ ਸੈਸ਼ਨ ਦੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ਕੀ ਮਹਿਮਾਨ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਣਾ ਹੈ?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ਇਸ ਨਾਲ ਮੌਜੂਦਾ ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਦੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"ਹਾਂ, ਉਨ੍ਹਾਂ ਨੂੰ ਪ੍ਰਸ਼ਾਸਕ ਬਣਾਓ"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"ਨਹੀਂ, ਉਨ੍ਹਾਂ ਨੂੰ ਪ੍ਰਸ਼ਾਸਕ ਨਾ ਬਣਾਓ"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ਬਾਹਰ ਜਾਓ"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ਕੀ ਮਹਿਮਾਨ ਸਰਗਰਮੀ ਰੱਖਿਅਤ ਕਰਨੀ ਹੈ?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ਤੁਸੀਂ ਮੌਜੂਦਾ ਸੈਸ਼ਨ ਦੀ ਸਰਗਰਮੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰ ਸਕਦੇ ਹੋ ਜਾਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index f8c2c97..7e51a95 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Więcej czasu."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Mniej czasu."</string>
     <string name="cancel" msgid="5665114069455378395">"Anuluj"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Dalej"</string>
+    <string name="back" msgid="5554327870352703710">"Wstecz"</string>
+    <string name="save" msgid="3745809743277153149">"Zapisz"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Gotowe"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmy i przypomnienia"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Dodać nowego użytkownika?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Z tego urządzenia możesz korzystać wraz z innymi osobami, dodając na nim konta użytkowników. Każdy użytkownik ma własne miejsce na swoje aplikacje, tapety i inne dane. Może też zmieniać ustawienia, które wpływają na wszystkich użytkowników urządzenia (np. Wi‑Fi).\n\nGdy dodasz nowego użytkownika, musi on skonfigurować swoje miejsce na dane.\n\nKażdy użytkownik może aktualizować aplikacje w imieniu wszystkich pozostałych użytkowników. Ułatwienia dostępu i usługi mogą nie zostać przeniesione na konto nowego użytkownika."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Gdy dodasz nowego użytkownika, musi on skonfigurować swoją przestrzeń.\n\nKażdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Przyznać temu użytkownikowi uprawnienia administratora?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratorzy mają specjalne uprawnienia, którymi nie dysponują pozostali użytkownicy. Administrator może zarządzać wszystkimi użytkownikami, aktualizować i resetować urządzenie, modyfikować ustawienia, wyświetlać wszystkie zainstalowane aplikacje oraz przyznawać uprawnienia administratora innym użytkownikom i je wycofywać."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Przyznaj uprawnienia administratora"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Skonfigurować ustawienia dla użytkownika?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Upewnij się, że ta osoba jest w pobliżu i może skonfigurować swój profil"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Skonfigurować teraz profil?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Zostanie uruchomiona nowa sesja gościa. Wszystkie aplikacje i dane z obecnej sesji zostaną usunięte."</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Zamknąć tryb gościa?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Wszystkie aplikacje i dane z obecnej sesji gościa zostaną usunięte."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Tak, przyznaj uprawnienia administratora"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nie, nie przyznawaj uprawnień administratora"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Zamknij"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Zapisać aktywność gościa?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Możesz zapisać aktywność z obecnej sesji lub usunąć wszystkie aplikacje i dane"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index f6ffce0..0e7eae5 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -542,9 +542,9 @@
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Até você desativar"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Agora"</string>
-    <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este smartphone"</string>
+    <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este telefone"</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>
+    <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telefone"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
     <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>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 8751ba2..76c9b47 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mais tempo."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Menos tempo."</string>
     <string name="cancel" msgid="5665114069455378395">"Cancelar"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Seguinte"</string>
+    <string name="back" msgid="5554327870352703710">"Anterior"</string>
+    <string name="save" msgid="3745809743277153149">"Guardar"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Concluir"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes e lembretes"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Adicionar novo utilizador?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Pode partilhar este dispositivo com outras pessoas ao criar utilizadores adicionais. Cada utilizador possui o seu próprio espaço, que pode ser personalizado com apps, imagens de fundo, etc. Os utilizadores também podem ajustar as definições do dispositivo, como o Wi‑Fi, que afetam os restantes utilizadores.\n\nAo adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar apps para todos os outros utilizadores. Os serviços e as definições de acessibilidade podem não ser transferidos para o novo utilizador."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar aplicações para todos os outros utilizadores."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Definir este utilizador como um administrador?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Os administradores têm privilégios especiais que outros utilizadores não têm. Um administrador pode gerir todos os utilizadores, atualizar ou repor este dispositivo, modificar definições, ver todas as apps instaladas e revogar ou conceder privilégios de administrador a outras pessoas."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Definir como administrador"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Configurar o utilizador agora?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Certifique-se de que a pessoa está disponível para levar o dispositivo e configurar o seu espaço"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Configurar perfil agora?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Esta ação inicia uma nova sessão de convidado e elimina todas as apps e dados da sessão atual"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sair do modo convidado?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Esta ação elimina as apps e os dados da sessão de convidado atual"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Sim, definir como administrador"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Não, não definir como administrador"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sair"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Guardar atividade de convidado?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Pode guardar a atividade da sessão atual ou eliminar todas as apps e dados"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index f6ffce0..0e7eae5 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -542,9 +542,9 @@
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Até você desativar"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Agora"</string>
-    <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este smartphone"</string>
+    <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este telefone"</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>
+    <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telefone"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
     <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>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index ae9f1aa..f1f004f 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mai mult timp."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Mai puțin timp."</string>
     <string name="cancel" msgid="5665114069455378395">"Anulează"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Înainte"</string>
+    <string name="back" msgid="5554327870352703710">"Înapoi"</string>
+    <string name="save" msgid="3745809743277153149">"Salvează"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Gata"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarme și mementouri"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Adaugi un utilizator nou?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Poți să permiți accesul la acest dispozitiv altor persoane creând utilizatori suplimentari. Fiecare utilizator are propriul spațiu, pe care îl poate personaliza cu aplicații, imagini de fundal etc. De asemenea, utilizatorii pot ajusta setările dispozitivului, cum ar fi setările pentru Wi-Fi, care îi afectează pe toți ceilalți utilizatori.\n\nDupă ce adaugi un utilizator nou, acesta trebuie să-și configureze spațiul.\n\nOricare dintre utilizatori poate actualiza aplicațiile pentru toți ceilalți utilizatori. Este posibil ca setările de accesibilitate și serviciile să nu se transfere la noul utilizator."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Când adaugi un utilizator nou, acesta trebuie să-și configureze spațiul.\n\nOrice utilizator poate actualiza aplicațiile pentru toți ceilalți utilizatori."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Setezi acest utilizator ca administrator?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratorii au privilegii speciale în plus față de alți utilizatori. Un administrator poate să gestioneze toți utilizatorii, să actualizeze sau să reseteze dispozitivul, să modifice setările, să vadă toate aplicațiile instalate și să acorde sau să revoce privilegiile de administrator pentru alții."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Setează ca administrator"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Configurezi utilizatorul acum?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Asigură-te că utilizatorul are posibilitatea de a prelua dispozitivul și de a-și configura spațiul"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Configurezi profilul acum?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Astfel, va începe o nouă sesiune pentru invitați și se vor șterge toate aplicațiile și datele din sesiunea actuală"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Ieși din modul pentru invitați?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Se vor șterge toate aplicațiile și datele din sesiunea pentru invitați actuală"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Setează ca administrator"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nu seta ca administrator"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Ieși"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Salvezi activitatea invitatului?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Salvează activitatea din sesiunea actuală sau șterge aplicațiile și datele"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 96179d7..b56e1d49 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Увеличить продолжительность"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Уменьшить продолжительность"</string>
     <string name="cancel" msgid="5665114069455378395">"Отмена"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Далее"</string>
+    <string name="back" msgid="5554327870352703710">"Назад"</string>
+    <string name="save" msgid="3745809743277153149">"Сохранить"</string>
     <string name="okay" msgid="949938843324579502">"ОК"</string>
     <string name="done" msgid="381184316122520313">"Готово"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Будильники и напоминания"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Добавить пользователя?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Если этим устройством пользуются сразу несколько человек, для каждого из них можно создать отдельный профиль – практически собственное пространство со своими приложениями, обоями и т. д. При этом из профиля можно поменять и настройки устройства, общие для всех, например выбрать сеть Wi-Fi.\n\nКогда вы добавляете нового пользователя, ему нужно настроить свой профиль.\n\nОбновлять общие приложения может любой пользователь, однако специальные возможности настраиваются индивидуально."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"После создания профиля его потребуется настроить.\n\nЛюбой пользователь устройства может обновлять приложения для всех аккаунтов."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Назначить этого пользователя администратором?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"У администраторов права шире, чем у других пользователей. Администратор может управлять всеми пользователями, обновлять и сбрасывать это устройство, менять настройки, просматривать установленные приложения, а также предоставлять и отзывать права администратора."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Назначить администратором"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Настроить профиль?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Вам потребуется передать устройство пользователю, чтобы он мог настроить свой профиль."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Настроить профиль?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"При этом начнется новый гостевой сеанс, а все данные и приложения предыдущего сеанса будут удалены."</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Выйти из гостевого режима?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Все приложения и данные текущего гостевого сеанса будут удалены."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Предоставить права администратора"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Не предоставлять права администратора"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Выйти"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Сохранить историю сеанса?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Сохраните историю текущего сеанса или удалите данные и приложения."</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 8dfe489..609d47a 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"වේලාව වැඩියෙන්."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"වේලාව අඩුවෙන්."</string>
     <string name="cancel" msgid="5665114069455378395">"අවලංගු කරන්න"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"මීළඟ"</string>
+    <string name="back" msgid="5554327870352703710">"ආපසු"</string>
+    <string name="save" msgid="3745809743277153149">"සුරකින්න"</string>
     <string name="okay" msgid="949938843324579502">"හරි"</string>
     <string name="done" msgid="381184316122520313">"නිමයි"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"එලාම සහ සිහිකැඳවීම්"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"අලුත් පරිශීලකයෙක් එක් කරන්නද?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"අමතර පරිශීලකයින් නිර්මාණය කිරීම මඟින් වෙනත් පුද්ගලයන් සමඟ මෙම උපාංගය ඔබට බෙදා ගත හැකිය. සෑම පරිශීලකයෙක්ටම ඔවුන්ගේම යෙදුම්, වෝල්පේපර, සහ වෙනත් ඒවා අභිරුචි කළ හැකි තමන්ට අයිති ඉඩක් ඇත. පරිශීලකයින්ට Wi‑Fi වැනි සෑම දෙනාටම බලපාන උපාංග සැකසීම්ද සීරුමාරු කළ හැක.\n\nඔබ නව පරිශීලකයෙකු එක් කළ විට ඔවුන්ගේ ඉඩ එම පුද්ගලයා සකසා ගත යුතු වේ.\n\nඕනෑම පරිශීලකයෙකුට අනෙක් සියලු පරිශීලකයන් සඳහා යෙදුම් යාවත්කාලීන කළ හැකිය. ප්‍රවේශයතා සැකසීම් සහ සේවා නව පරිශීලකයා වෙත මාරු නොකරනු ඇත."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"ඔබ අලුත් පරිශීලකයෙක් එකතු කරන විට, එම පුද්ගලයා ඔහුගේ වැඩ කරන ඉඩ සකසා ගත යුතුය.\n\nසියළුම අනෙක් පරිශීලකයින් සඳහා ඕනෑම පරිශීලකයෙකුට යාවත්කාලීන කළ හැක."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"මෙම පරිශීලකයා පරිපාලකයෙකු කරන්න ද?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"පරිපාලකයින්ට වෙනත් පරිශීලකයින්ට නොමැති විශේෂ වරප්‍රසාද ඇත. පරිපාලකයෙකුට සියලු පරිශීලකයින් කළමනාකරණය කිරීමට, මෙම උපාංගය යාවත්කාලීන කිරීමට හෝ යළි සැකසීමට, සැකසීම් වෙනස් කිරීමට, ස්ථාපිත සියලු යෙදුම් බැලීමට, සහ අනෙකුත් අය සඳහා පරිපාලක වරප්‍රසාද ප්‍රදානය කිරීමට හෝ අහෝසි කිරීමට හැක."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"පරිපාලක කරන්න"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"දැන් පරිශීලකයා සකසන්නද?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"උපාංගය ලබාගෙන තමන්ගේ ඉඩ සකසා ගැනීමට අදාළ පුද්ගලයා සිටින බව තහවුරු කරගන්න"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"දැන් පැතිකඩ සකසන්නද?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"මෙය නව ආගන්තුක සැසියක් ආරම්භ කර වත්මන් සැසියෙන් සියලු යෙදුම් සහ දත්ත මකනු ඇත"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ආගන්තුක ප්‍රකාරයෙන් පිටවන්නද?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"මෙය වත්මන් ආගන්තුක සැසියෙන් යෙදුම් සහ දත්ත මකනු ඇත"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"ඔව්, ඔවුන්ව පරිපාලකයෙකු කරන්න"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"නැහැ, ඔවුන්ව පරිපාලකයෙකු නොකරන්න"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"පිටවන්න"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ආගන්තුක ක්‍රියාකාරකම් සුරකින්නද?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ඔබට වත්මන් සැසියෙන් ක්‍රියාකාරකම් සුරැකීමට හෝ සියලු යෙදුම් සහ දත්ත මැකීමට හැකිය"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index f5cfb95..a15c5bf 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Më shumë kohë."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Më pak kohë."</string>
     <string name="cancel" msgid="5665114069455378395">"Anulo"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Tjetri"</string>
+    <string name="back" msgid="5554327870352703710">"Prapa"</string>
+    <string name="save" msgid="3745809743277153149">"Ruaj"</string>
     <string name="okay" msgid="949938843324579502">"Në rregull"</string>
     <string name="done" msgid="381184316122520313">"U krye"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmet dhe alarmet rikujtuese"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Të shtohet përdorues i ri?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Mund ta ndash këtë pajisje me persona të tjerë duke krijuar përdorues shtesë. Çdo përdorues ka hapësirën e vet, të cilën mund ta personalizojë me aplikacione, me imazhin e sfondit etj. Përdoruesit mund të rregullojnë po ashtu cilësimet e pajisjes, si Wi‑Fi, të cilat ndikojnë te të gjithë.\n\nKur shton një përdorues të ri, ai person duhet të konfigurojë hapësirën e vet.\n\nÇdo përdorues mund t\'i përditësojë aplikacionet për të gjithë përdoruesit e tjerë. Cilësimet e qasshmërisë dhe shërbimet mund të mos transferohen te përdoruesi i ri."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Kur shton një përdorues të ri, ai person duhet të konfigurojë hapësirën e vet.\n\nÇdo përdorues mund t\'i përditësojë aplikacionet për të gjithë përdoruesit e tjerë."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Të bëhet administrator ky përdorues?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratorët kanë privilegje të veçanta që nuk i kanë përdoruesit e tjerë. Një administrator mund të menaxhojë të gjithë përdoruesit, të përditësojë ose të rivendosë këtë pajisje, të modifikojë cilësimet, të shikojë të gjitha aplikacionet e instaluara dhe të japë ose të revokojë privilegjet e administratorit për të tjerët."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Bëje administrator"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Të konfig. përdoruesi tani?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Sigurohu që personi të jetë i gatshëm të marrë pajisjen dhe të caktojë hapësirën e vet"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Të konfigurohet tani profili?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Kjo do të fillojë një sesion të ri për vizitorë dhe do të fshijë të gjitha aplikacionet dhe të dhënat nga sesioni aktual"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Të hiqet modaliteti \"vizitor\"?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Kjo do të fshijë aplikacionet dhe të dhënat nga sesioni aktual për vizitorë"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Po, bëje administrator"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Jo, mos e bëj administrator"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Dil"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Të ruhet aktiviteti i vizitorit?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Ruaj aktivitetin nga sesioni aktual ose fshi të gjitha aplikacionet e të dhënat"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 7bd5267..54b21de 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Више времена."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Мање времена."</string>
     <string name="cancel" msgid="5665114069455378395">"Откажи"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Даље"</string>
+    <string name="back" msgid="5554327870352703710">"Назад"</string>
+    <string name="save" msgid="3745809743277153149">"Сачувај"</string>
     <string name="okay" msgid="949938843324579502">"Потврди"</string>
     <string name="done" msgid="381184316122520313">"Готово"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Аларми и подсетници"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Додајете новог корисника?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Овај уређај можете да делите са другим људима ако направите још корисника. Сваки корисник има сопствени простор, који може да прилагођава помоћу апликација, позадине и слично. Корисници могу да прилагођавају и подешавања уређаја која утичу на свакога, попут Wi‑Fi-ја.\n\nКада додате новог корисника, та особа треба да подеси сопствени простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике. Подешавања и услуге приступачности не могу да се преносе на новог корисника."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Када додате новог корисника, та особа треба да подеси сопствени простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Желите да поставите овог корисника за администратора?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Администратори имају посебне привилегије које остали корисници немају. Администратор може да управља свим корисницима, ажурира или ресетује овај уређај, прилагођава подешавања, прегледа све инсталиране апликације и додељује или опозива привилегије администратора за друге."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Постави за администратора"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Подешавате корисника?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Та особа треба да узме уређај и подеси свој простор"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Желите ли да одмах подесите профил?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Тиме ћете покренути нову сесију госта и избрисати све апликације и податке из актуелне сесије"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Излазите из режима госта?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Тиме ћете избрисати све апликације и податке из актуелне сесије госта"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Да, постави га за администратора"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Не, не постављај га за администратора"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Изађи"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Сачуваћете активности госта?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Сачувајте активности из актуелне сесије или избришите све апликације и податке"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 177eae4..ea416c5 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Längre tid."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Kortare tid."</string>
     <string name="cancel" msgid="5665114069455378395">"Avbryt"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Nästa"</string>
+    <string name="back" msgid="5554327870352703710">"Tillbaka"</string>
+    <string name="save" msgid="3745809743277153149">"Spara"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Klar"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarm och påminnelser"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Lägga till ny användare?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dela enheten med andra om du skapar flera användare. Alla användare får sitt eget utrymme som de kan anpassa som de vill med appar, bakgrund och så vidare. Användarna kan även ändra enhetsinställningar som påverkar alla, till exempel wifi.\n\nNär du lägger till en ny användare måste han eller hon konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning. Tillgänglighetsinställningar och tjänster kanske inte överförs till den nya användaren."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Vill du göra denna användare till administratör?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratörer har särskilda behörigheter som andra användare inte har. En administratör kan hantera alla användare, uppdatera eller återställa den här enheten, ändra inställningar, se alla installerade appar och bevilja eller återkalla administratörsbehörigheter för andra."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Gör till administratör"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Konfigurera användare nu?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Kontrollera att personen finns tillgänglig för att konfigurera sitt utrymme på enheten"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Vill du konfigurera en profil nu?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"En ny gästsession startas och alla appar och all data från den pågående sessionen raderas"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vill du avsluta gästläget?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Appar och data från den pågående gästsessionen raderas"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ja, gör till administratör"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Nej, gör inte till administratör"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Avsluta"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vill du spara gästaktivitet?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Du kan spara aktivitet från den pågående sessionen eller radera appar och data"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 6784aa5..c0c977f 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -486,7 +486,7 @@
     <string name="disabled" msgid="8017887509554714950">"Imezimwa"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Imeruhusiwa"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Hairuhusiwi"</string>
-    <string name="install_other_apps" msgid="3232595082023199454">"Kuweka programu zisizojulikana"</string>
+    <string name="install_other_apps" msgid="3232595082023199454">"Kusakinisha programu zisizojulikana"</string>
     <string name="home" msgid="973834627243661438">"Ukurasa wa Kwanza wa Mipangilio"</string>
   <string-array name="battery_labels">
     <item msgid="7878690469765357158">"0%"</item>
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Muda zaidi."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Muda kidogo."</string>
     <string name="cancel" msgid="5665114069455378395">"Ghairi"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Endelea"</string>
+    <string name="back" msgid="5554327870352703710">"Rudi nyuma"</string>
+    <string name="save" msgid="3745809743277153149">"Hifadhi"</string>
     <string name="okay" msgid="949938843324579502">"Sawa"</string>
     <string name="done" msgid="381184316122520313">"Nimemaliza"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ving\'ora na vikumbusho"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Ungependa kuongeza mtumiaji?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Unaweza kutumia kifaa hiki pamoja na watu wengine kwa kuongeza watumiaji wa ziada. Kila mtumiaji ana nafasi yake mwenyewe, ambayo anaweza kuweka programu, mandhari na vipengee vingine anavyopenda. Watumiaji pia wanaweza kurekebisha mipangilio ya kifaa inayoathiri kila mtu kama vile Wi-Fi.\n\nUnapomwongeza mtumiaji mpya, mtu huyo anahitaji kujitayarishia nafasi yake.\n\nMtumiaji yeyote anaweza kuwasasishia watumiaji wengine wote programu. Huenda mipangilio na huduma za ufikivu zisihamishiwe mtumiaji mgeni."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Mtumiaji mpya utakayemwongeza atahitaji kujitayarishia nafasi yake.\n\nMtumiaji yoyote anaweza kusasisha programu kwa niaba ya wengine wote."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Ungependa kumruhusu mtumiaji huyu awe msimamizi?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Wasimamizi wana ruhusa maalum ambazo watumiaji wengine hawana. Msimamizi anaweza kudhibiti watumiaji wote, kusasisha au kuweka upya mipangilio ya kifaa hiki, kubadilisha mipangilio, kuangalia programu zote zilizosakinishwa na kuteua au kubatilisha uteuzi wa watumiaji wengine kuwa wasimamizi."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Mruhusu awe msimamizi"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Mtumiaji aongezwe sasa?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Hakikisha kuwa mtu huyu anaweza kuchukua kifaa na kujitayarishia nafasi yake"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Ungependa kuweka wasifu sasa?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Hatua hii itaanzisha upya kipindi cha mgeni na kufuta programu na data yote kwenye kipindi cha sasa"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Utafunga matumizi ya wageni?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Hatua hii itafuta programu na data kutoka kwenye kipindi cha mgeni cha sasa"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ndiyo, mruhusu awe msimamizi"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Hapana, usimruhusu awe msimamizi"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Funga"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Utahifadhi shughuli za mgeni?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Unaweza kuhifadhi shughuli kutoka kipindi cha sasa au kufuta programu na data yote"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 76344cb..0ec7322 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"நேரத்தை அதிகரிக்கும்."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"நேரத்தைக் குறைக்கும்."</string>
     <string name="cancel" msgid="5665114069455378395">"ரத்துசெய்"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"அடுத்து"</string>
+    <string name="back" msgid="5554327870352703710">"பின்செல்"</string>
+    <string name="save" msgid="3745809743277153149">"சேமி"</string>
     <string name="okay" msgid="949938843324579502">"சரி"</string>
     <string name="done" msgid="381184316122520313">"முடிந்தது"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"அலாரங்களும் நினைவூட்டல்களும்"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"புதியவரைச் சேர்க்கவா?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"கூடுதல் பயனர்களை உருவாக்குவதன் மூலம், பிறருடன் இந்தச் சாதனத்தைப் பகிர்ந்துகொள்ளலாம். ஒவ்வொரு பயனருக்கும் அவர்களுக்கென ஒரு இடம் இருக்கும், அதில் அவர்கள் ஆப்ஸ், வால்பேப்பர் மற்றும் பலவற்றைப் பயன்படுத்திப் பிரத்தியேகப்படுத்தலாம். வைஃபை போன்ற மற்ற சாதன அமைப்புகளைப் பயனர்கள் மாற்றலாம், இந்த மாற்றம் அனைவருக்கும் பொருந்தும்.\n\nநீங்கள் புதிய பயனரைச் சேர்க்கும்போது, அவர் தனக்கான இடத்தை அமைக்க வேண்டும்.\n\nஎந்தவொரு பயனரும், பிற எல்லாப் பயனர்களுக்குமான ஆப்ஸைப் புதுப்பிக்கலாம். அணுகல்தன்மை அமைப்புகளையும் சேவைகளையும், புதிய பயனருக்கு இடமாற்ற முடியாமல் போகலாம்."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"புதியவரைச் சேர்க்கும் போது, அவர் தனக்கான இடத்தை அமைக்க வேண்டும்.\n\nஇருக்கும் ஆப்ஸை எவரும் புதுப்பிக்கலாம்."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"இந்தப் பயனரை நிர்வாகியாக்கவா?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"மற்ற பயனர்களுக்கு இல்லாத சிறப்புரிமைகள் நிர்வாகிகளுக்கு உண்டு. நிர்வாகி அனைத்துப் பயனர்களையும் நிர்வகிக்கலாம், இந்தச் சாதனத்தைப் புதுப்பிக்கலாம் அல்லது ரீசெட் செய்யலாம், அமைப்புகளை மாற்றலாம், நிறுவப்பட்ட அனைத்து ஆப்ஸையும் பார்க்கலாம், பிறருக்கு நிர்வாகி சிறப்புரிமைகளை வழங்கலாம் அல்லது அகற்றலாம்."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"நிர்வாகியாக்கு"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"இப்போது பயனரை அமைக்கவா?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"இந்தச் சாதனத்தை இவர் பயன்படுத்தும் நிலையிலும், அவருக்கான அமைப்புகளை அவரே செய்து கொள்பவராகவும் இருக்க வேண்டும்."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"இப்போது சுயவிவரத்தை அமைக்கவா?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"புதிய கெஸ்ட் அமர்வு தொடங்கப்படும், மேலும் தற்போதைய கெஸ்ட் அமர்வின் ஆப்ஸ் மற்றும் தரவு அனைத்தும் நீக்கப்படும்"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"கெஸ்ட் முறையிலிருந்து வெளியேறவா?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"தற்போதைய கெஸ்ட் அமர்வின் ஆப்ஸ் மற்றும் தரவு அனைத்தும் நீக்கப்படும்"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"ஆம். அவரை நிர்வாகியாக்கு"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"இல்லை. அவரை நிர்வாகியாக்காதே"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"வெளியேறு"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"கெஸ்ட் செயல்பாடுகளைச் சேமிக்கவா?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"தற்போதைய அமர்வின் செயல்பாடுகளைச் சேமிக்கலாம் அல்லது ஆப்ஸையும் தரவையும் நீக்கலாம்"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 54545c1b6..b0218e0 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"เวลามากขึ้น"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"เวลาน้อยลง"</string>
     <string name="cancel" msgid="5665114069455378395">"ยกเลิก"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"ถัดไป"</string>
+    <string name="back" msgid="5554327870352703710">"กลับ"</string>
+    <string name="save" msgid="3745809743277153149">"บันทึก"</string>
     <string name="okay" msgid="949938843324579502">"ตกลง"</string>
     <string name="done" msgid="381184316122520313">"เสร็จสิ้น"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"การปลุกและการช่วยเตือน"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"ต้องการเพิ่มผู้ใช้ใหม่ใช่ไหม"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"คุณมีสิทธิ์แชร์อุปกรณ์นี้กับผู้อื่นได้โดยการเพิ่มผู้ใช้ แต่ละคนจะมีพื้นที่ของตนเองซึ่งปรับใช้กับแอป วอลเปเปอร์ และรายการอื่นๆ ได้ อีกทั้งยังปรับการตั้งค่าอุปกรณ์ได้ด้วย เช่น Wi‑Fi ซึ่งจะมีผลกับทุกคน\n\nเมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตน\n\nผู้ใช้ทุกคนมีสิทธิ์อัปเดตแอปให้ผู้ใช้รายอื่น การตั้งค่าและบริการสำหรับการช่วยเหลือพิเศษอาจโอนไปยังผู้ใช้ใหม่ไม่ได้"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"เมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตนเอง\n\nผู้ใช้ทุกคนสามารถอัปเดตแอปสำหรับผู้ใช้รายอื่นได้"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"กำหนดให้ผู้ใช้รายนี้เป็นผู้ดูแลระบบไหม"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"ผู้ดูแลระบบจะได้รับสิทธิ์พิเศษที่ผู้ใช้รายอื่นๆ ไม่มี ผู้ดูแลระบบสามารถจัดการผู้ใช้ทั้งหมด อัปเดตหรือรีเซ็ตอุปกรณ์นี้ แก้ไขการตั้งค่า ดูแอปที่ติดตั้งทั้งหมด ตลอดจนให้หรือเพิกถอนสิทธิ์ของผู้ดูแลระบบสำหรับคนอื่นๆ ได้"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"กำหนดให้เป็นผู้ดูแลระบบ"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"ตั้งค่าผู้ใช้เลยไหม"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"ตรวจสอบว่าบุคคลดังกล่าวสามารถนำอุปกรณ์ไปตั้งค่าพื้นที่ของตนได้"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"หากต้องการตั้งค่าโปรไฟล์ทันที"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"การดำเนินการนี้จะเริ่มเซสชันผู้ใช้ชั่วคราวใหม่ และจะลบแอปและข้อมูลทั้งหมดจากเซสชันปัจจุบัน"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ออกจากโหมดผู้ใช้ชั่วคราวไหม"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"การดำเนินการนี้จะลบแอปและข้อมูลออกจากเซสชันผู้ใช้ชั่วคราวในปัจจุบัน"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"ใช่ กำหนดให้เป็นผู้ดูแลระบบ"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"ไม่ อย่ากำหนดให้เป็นผู้ดูแลระบบ"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ออก"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"บันทึกกิจกรรมของผู้ใช้ชั่วคราวไหม"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"คุณสามารถบันทึกกิจกรรมจากเซสชันปัจจุบันหรือจะลบแอปและข้อมูลทั้งหมดก็ได้"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 6e23eba..93356c1 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -479,7 +479,7 @@
     <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Nagcha-charge"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Hindi nagcha-charge"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Nakakonekta, hindi nagcha-charge"</string>
-    <string name="battery_info_status_full" msgid="1339002294876531312">"Nasingil"</string>
+    <string name="battery_info_status_full" msgid="1339002294876531312">"Charged"</string>
     <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Puno ang Baterya"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Pinapamahalaan ng admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kinokontrol ng Pinaghihigpitang Setting"</string>
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Dagdagan ang oras."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Bawasan ang oras."</string>
     <string name="cancel" msgid="5665114069455378395">"Kanselahin"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Susunod"</string>
+    <string name="back" msgid="5554327870352703710">"Bumalik"</string>
+    <string name="save" msgid="3745809743277153149">"I-save"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Tapos na"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Mga alarm at paalala"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Magdagdag ng bagong user?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Puwede mong ibahagi ang device na ito sa ibang tao sa pamamagitan ng paggawa ng mga karagdagang user. May sariling espasyo ang bawat user na maaari nilang i-customize gamit ang mga app, wallpaper, at iba pa. Puwede ring isaayos ng mga user ang mga setting ng device tulad ng Wi‑Fi na nakakaapekto sa lahat.\n\nKapag nagdagdag ka ng bagong user, kailangang i-set up ng taong iyon ang kanyang espasyo.\n\nMaaaring mag-update ng mga app ang sinumang user para sa lahat ng iba pang user. Maaaring hindi malipat sa bagong user ang mga setting at serbisyo sa pagiging naa-access."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Kapag nagdagdag ka ng bagong user, kailangang i-set up ng taong iyon ang kanyang espasyo.\n\nAng sinumang user ay puwedeng mag-update ng mga app para sa lahat ng iba pang user."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Gawing admin ang user na ito?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"May mga espesyal na pribilehiyo ang mga admin na wala ang ibang user. Magagawa ng isang admin na pamahalaan ang lahat ng user, i-update o i-reset ang device na ito, baguhin ang mga settng, tingnan ang lahat ng naka-install na app, at magbigay o magbawi ng mga pribilehiyo ng admin sa iba."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Gawing admin"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"I-set up ang user ngayon?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Tiyaking available ang tao na kunin ang device at i-set up ang kanyang space"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Mag-set up ng profile ngayon?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Magsisimula ito ng bagong session ng bisita at made-delete ang lahat ng app at data mula sa kasalukuyang session"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Umalis sa guest mode?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ide-delete nito ang mga app at data mula sa kasalukuyang session ng bisita"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Oo, gawin siyang admin"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Hindi, huwag siyang gawing admin"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Umalis"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"I-save ang aktibidad ng bisita?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puwedeng i-save ang aktibidad ng session ngayon o i-delete lahat ng app at data"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 6187ad2..e3ac243 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Daha uzun süre."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Daha kısa süre."</string>
     <string name="cancel" msgid="5665114069455378395">"İptal"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Sonraki"</string>
+    <string name="back" msgid="5554327870352703710">"Geri"</string>
+    <string name="save" msgid="3745809743277153149">"Kaydet"</string>
     <string name="okay" msgid="949938843324579502">"Tamam"</string>
     <string name="done" msgid="381184316122520313">"Bitti"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmlar ve hatırlatıcılar"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Yeni kullanıcı eklensin mi?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Ek kullanıcılar oluşturarak bu cihazı başkalarıyla paylaşabilirsiniz. Her kullanıcının uygulamalarla, duvar kağıdıyla ve başka ayarlarla özelleştirebileceği kendi alanı olur. Kullanıcılar ayrıca kablosuz ağ gibi herkesi etkileyen cihaz ayarlarını değiştirebilirler.\n\nYeni bir kullanıcı eklediğinizde, ilgili kişinin kendi alanını ayarlaması gerekir.\n\nHer kullanıcı diğer tüm kullanıcılar için uygulamaları güncelleyebilir. Erişilebilirlik ayarları ve hizmetleri yeni kullanıcıya aktarılamayabilir."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Yeni bir kullanıcı eklediğinizde, bu kişinin kendi alanını ayarlaması gerekir.\n\nHerhangi bir kullanıcı, diğer tüm kullanıcılar için uygulamaları güncelleyebilir."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Bu kullanıcı yönetici yapılsın mı?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Yöneticiler diğer kullanıcıların sahip olmadığı özel ayrıcalıklara sahiptir. Yöneticiler tüm kullanıcıları yönetebilir, bu cihazı güncelleyebilir veya sıfırlayabilir, ayarları değiştirebilir, yüklü tüm uygulamaları görebilir ve başkalarına yönetici ayrıcalıkları verebilir veya mevcut ayrıcalıkları iptal edebilir."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Yönetici yap"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Kullanıcı şimdi ayarlansın mı?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"İlgili kişinin cihazı almak ve kendi alanını ayarlamak için müsait olduğundan emin olun"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Profil şimdi yapılandırılsın mı?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Bu işlem, yeni bir misafir oturumu başlatarak mevcut oturumdaki tüm uygulamaları ve verileri siler"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Misafir modundan çıkılsın mı?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bu işlem mevcut misafir oturumundaki tüm uygulamaları ve verileri siler"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Evet, onu yönetici yap"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Hayır, onu yönetici yapma"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Çık"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Misafir etkinliği kaydedilsin mi?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Oturumdaki etkinliği kaydedebilir ya da tüm uygulama ve verileri silebilirsiniz"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 96708ff..7fab889 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Більше часу."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Менше часу."</string>
     <string name="cancel" msgid="5665114069455378395">"Скасувати"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Далі"</string>
+    <string name="back" msgid="5554327870352703710">"Назад"</string>
+    <string name="save" msgid="3745809743277153149">"Зберегти"</string>
     <string name="okay" msgid="949938843324579502">"ОК"</string>
     <string name="done" msgid="381184316122520313">"Готово"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Будильники й нагадування"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Додати нового користувача?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Цим пристроєм можуть користуватися кілька людей. Для цього потрібно створити додаткові профілі. Власник профілю може налаштувати його на свій смак: вибрати фоновий малюнок, установити потрібні додатки тощо. Користувачі також можуть налаштовувати певні параметри пристрою (як-от Wi-Fi), які застосовуватимуться до решти профілів.\n\nПісля створення новий профіль потрібно налаштувати.\n\nБудь-який користувач пристрою може оновлювати додатки для решти користувачів. Налаштування спеціальних можливостей і сервісів можуть не передаватися новому користувачеві."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Користувач має налаштувати свій профіль після створення.\n\nБудь-який користувач пристрою може оновлювати додатки для решти користувачів."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Надати цьому користувачу права адміністратора?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Адміністратори, на відміну від звичайних користувачів, мають спеціальні права. Вони можуть керувати всіма користувачами, оновлювати, скидати чи змінювати налаштування цього пристрою, переглядати всі встановлені додатки, а також надавати іншим користувачам права адміністратора або відкликати їх."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Надати права адміністратора"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Створити користувача зараз?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Переконайтеся, що користувач може взяти пристрій і налаштувати профіль"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Налаштувати профіль зараз?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Почнеться новий сеанс у режимі гостя, а всі додатки й дані з поточного сеансу буде видалено"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Вийти з режиму гостя?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Усі додатки й дані з поточного сеансу в режимі гостя буде видалено."</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Так, надати права адміністратора"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Ні, не надавати прав адміністратора"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Вийти"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Зберегти дії в режимі гостя?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Ви можете зберегти дії з поточного сеансу або видалити всі додатки й дані"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 5917a32..83a65e6 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"زیادہ وقت۔"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"کم وقت۔"</string>
     <string name="cancel" msgid="5665114069455378395">"منسوخ کریں"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"آگے جائیں"</string>
+    <string name="back" msgid="5554327870352703710">"پیچھے جائیں"</string>
+    <string name="save" msgid="3745809743277153149">"محفوظ کریں"</string>
     <string name="okay" msgid="949938843324579502">"ٹھیک ہے"</string>
     <string name="done" msgid="381184316122520313">"ہو گیا"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"الارمز اور یاد دہانیاں"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"نیا صارف شامل کریں؟"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"‏آپ اضافی صارفین تخلیق کر کے دوسرے لوگوں کے ساتھ اس آلہ کا اشتراک کر سکتے ہیں۔ ہر صارف کے پاس اپنی جگہ ہوتی ہے، جسے وہ ایپس، وال پیپر وغیرہ کے ساتھ حسب ضرورت بنا سکتا ہے۔ صارفین Wi‑Fi جیسی آلے کی ترتیبات کو ایڈجسٹ بھی کر سکتے ہیں جس کا اثر ہر کسی پر ہوتا ہے۔\n\nجب آپ ایک نیا صارف شامل کرتے ہیں، تو اسے اپنی جگہ سیٹ اپ کرنا پڑتی ہے۔\n\nکوئی بھی صارف دیگر تمام صارفین کیلئے ایپس اپ ڈیٹ کر سکتا ہے۔ رسائی کی ترتیبات اور سروسز کو نئے صارف کو منتقل نہیں کیا جا سکتا۔"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"جب آپ ایک نیا صارف شامل کرتے ہیں تو اس شخص کو اپنی جگہ کو ترتیب دینے کی ضرورت ہوتی ہے\n\nکوئی بھی صارف دیگر سبھی صارفین کیلئے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"اس صارف کو منتظم بنائیں؟"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"منتظمین کے پاس خصوصی مراعات ہیں جو دوسرے صارفین کو حاصل نہیں ہیں۔ ایک منتظم تمام صارفین کا نظم کر سکتا ہے، اس آلہ کو اپ ڈیٹ یا ری سیٹ کر سکتا ہے، ترتیبات میں ترمیم کر سکتا ہے، تمام انسٹال کردہ ایپس دیکھ سکتا ہے اور دوسروں کے لیے منتظم کی مراعات دے سکتا ہے یا انہیں منسوخ کر سکتا ہے۔"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"منتظم بنائیں"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"صارف کو ابھی سیٹ اپ کریں؟"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"یقینی بنائیں کہ وہ شخص آلہ لینے اور اپنی جگہ کو سیٹ اپ کرنے کیلئے دستیاب ہے"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"پروفائل کو ابھی ترتیب دیں؟"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"اس سے ایک نیا مہمان سیشن شروع ہو گا اور موجودہ سیشن سے تمام ایپس اور ڈیٹا حذف ہو جائے گا"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"مہمان وضع سے باہر نکلیں؟"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"یہ موجودہ مہمان سیشن سے ایپس اور ڈیٹا کو حذف کر دے گا"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"ہاں انہیں منتظم بنائیں"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"نہیں، انہیں منتظم نہ بنائیں"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"باہر نکلیں"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"مہمان کی سرگرمی محفوظ کریں؟"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"آپ موجودہ سیشن سے سرگرمی کو محفوظ یا تمام ایپس اور ڈیٹا کو حذف کر سکتے ہیں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index b32222c..e5bca65 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Ko‘proq vaqt."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Kamroq vaqt."</string>
     <string name="cancel" msgid="5665114069455378395">"Bekor qilish"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Keyingisi"</string>
+    <string name="back" msgid="5554327870352703710">"Orqaga"</string>
+    <string name="save" msgid="3745809743277153149">"Saqlash"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Tayyor"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Signal va eslatmalar"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Foydalanuvchi qo‘shilsinmi?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Bu qurilmadan bir necha kishi alohida foydalanuvchilar qo‘shib foydalanishi mumkin. Har bir foydalanuvchiga diskda joy ajratiladi, tayinlangan hajm ilovalar, ekran foni rasmi, va hokazolarga taqsimlanishi mumkin. Foydalanuvchilar Wi-Fi kabi sozlamalarni o‘zgartirsa, qolganlarda ham aks etishi mumkin. \n\nYangi profil qo‘shilgach, uni sozlash lozim.\n\nQurilmaning istalgan foydalanuvchisi ilovalarni barcha hisoblar uchun yangilashi mumkin. Qulayliklar sozlamalari va xizmatlar yangi foydalanuvchiga o‘tkazilmasligi mumkin."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Yangi profil qo‘shilgach, uni sozlash lozim.\n\nQurilmaning istalgan foydalanuvchisi ilovalarni barcha hisoblar uchun yangilashi mumkin."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Bu foydalanuvchiga administrator huquqi berilsinmi?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Administratorlarga boshqa foydalanuvchilarda boʻlmagan huquqlar beriladi Administrator barcha foydalanuvchilarni boshqarishi, bu qurilmani yangilashi yoki qayta oʻrnatishi, sozlamalarni oʻzgartirishi, barcha oʻrnatilgan ilovalarni koʻrishi va boshqalarga administrator huquqlarini berishi yoki bekor qilishi mumkin."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Administrator sifatida tayinlash"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Profil hozir sozlansinmi?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Agar foydalanuvchi profilini hozir sozlay olmasa, keyinroq ham sozlab olishi mumkin."</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Profil hozir sozlansinmi?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Bunda yangi mehmon seansi ishga tushadi va joriy seans ilova va maʼlumotlari tozalanadi"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Mehmon rejimidan chiqasizmi?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bunda joriy mehmon seansidagi ilova va ularning maʼlumotlari tozalanadi"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Ha ularga administrator huquqi berilsin"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Ha ularga administrator huquqi berilmasin"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Chiqish"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Mehmon faoliyati saqlansinmi?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Joriy seansdagi faoliyatni saqlash yoki barcha ilova va maʼlumotlarni oʻchirib tashlashingiz mumkin"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 0d24ea9..704b5a8 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Nhiều thời gian hơn."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Ít thời gian hơn."</string>
     <string name="cancel" msgid="5665114069455378395">"Hủy"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Tiếp theo"</string>
+    <string name="back" msgid="5554327870352703710">"Quay lại"</string>
+    <string name="save" msgid="3745809743277153149">"Lưu"</string>
     <string name="okay" msgid="949938843324579502">"OK"</string>
     <string name="done" msgid="381184316122520313">"Xong"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Chuông báo và lời nhắc"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Thêm người dùng mới?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Bạn có thể chia sẻ thiết bị này với người khác bằng cách tạo thêm người dùng. Mỗi người dùng sẽ có không gian riêng của mình. Họ có thể tùy chỉnh không gian riêng đó bằng các ứng dụng, hình nền, v.v. Người dùng cũng có thể điều chỉnh các tùy chọn cài đặt thiết bị có ảnh hưởng đến tất cả mọi người, chẳng hạn như Wi‑Fi.\n\nKhi bạn thêm người dùng mới, họ cần thiết lập không gian của mình.\n\nMọi người dùng đều có thể cập nhật ứng dụng cho tất cả người dùng khác. Các dịch vụ và các tùy chọn cài đặt hỗ trợ tiếp cận có thể không chuyển sang người dùng mới."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Khi bạn thêm người dùng mới, họ cần thiết lập không gian của mình.\n\nMọi người dùng đều có thể cập nhật ứng dụng cho tất cả người dùng khác."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Đặt người dùng này làm quản trị viên?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Quản trị viên có các đặc quyền mà những người dùng khác không có. Một quản trị viên có thể quản lý toàn bộ người dùng, cập nhật hoặc đặt lại thiết bị này, sửa đổi chế độ cài đặt, xem tất cả các ứng dụng đã cài đặt và cấp hoặc thu hồi đặc quyền của quản trị viên đối với những người khác."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Đặt làm quản trị viên"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Thiết lập người dùng ngay bây giờ?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Đảm bảo người dùng có mặt để tự thiết lập không gian của mình trên thiết bị"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Thiết lập tiểu sử ngay bây giờ?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Thao tác này sẽ bắt đầu một phiên khách mới và xoá mọi ứng dụng cũng như dữ liệu trong phiên hiện tại"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Thoát khỏi chế độ khách?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Thao tác này sẽ xoá các ứng dụng và dữ liệu trong phiên khách hiện tại"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Có, đặt người này làm quản trị viên"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Không, không đặt người này làm quản trị viên"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Thoát"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Lưu hoạt động ở chế độ khách?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Bạn có thể lưu hoạt động trong phiên hiện tại hoặc xoá mọi ứng dụng và dữ liệu"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 7cf8968..052840d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"增加时间。"</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"减少时间。"</string>
     <string name="cancel" msgid="5665114069455378395">"取消"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"继续"</string>
+    <string name="back" msgid="5554327870352703710">"返回"</string>
+    <string name="save" msgid="3745809743277153149">"保存"</string>
     <string name="okay" msgid="949938843324579502">"确定"</string>
     <string name="done" msgid="381184316122520313">"完成"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"闹钟和提醒"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"要添加新用户吗?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"创建新用户后,您就能够与其他人共用此设备。每位用户都有自己的专属空间,而且在自己的个人空间内还可以自行安装自己想要的应用、设置壁纸等。此外,用户还可以调整会影响所有用户的设备设置(例如 WLAN 设置)。\n\n当您添加新用户后,该用户需要自行设置个人空间。\n\n任何用户都可以为所有其他用户更新应用。无障碍功能设置和服务可能无法转移给新用户。"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"当您添加新用户后,该用户需要自行设置个人空间。\n\n任何用户都可以为所有其他用户更新应用。"</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"将此用户设为管理员?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"管理员拥有其他用户没有的特殊权限。管理员可以管理所有用户、更新或重置此设备、修改设置、查看所有已安装的应用,以及授予或撤消其他用户的管理员权限。"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"设为管理员"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"要现在设置该用户吗?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"请让相应用户操作设备并设置他们自己的空间。"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"要立即设置个人资料吗?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"此操作会开始新的访客会话,并删除当前会话中的所有应用和数据"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"要退出访客模式吗?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"此操作会删除当前访客会话中的所有应用和数据"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"是,将其设为管理员"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"不,不要将其设为管理员"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"退出"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"要保存访客活动记录吗?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"您可以保存当前会话中的活动记录,也可以删除所有应用和数据"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 3ef92cf..9d7050c 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -139,7 +139,7 @@
     <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"配對"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"配對"</string>
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"取消"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"一旦配對成功,即可存取您的通訊錄和通話記錄。"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"一旦配對成功,即可存取你的通訊錄和通話記錄。"</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 配對。"</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 配對,因為 PIN 碼或密鑰不正確。"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"無法與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 通訊。"</string>
@@ -187,8 +187,8 @@
     <string name="tts_play_example_summary" msgid="634044730710636383">"播放簡短的語音合成例子"</string>
     <string name="tts_install_data_title" msgid="1829942496472751703">"安裝語音資料"</string>
     <string name="tts_install_data_summary" msgid="3608874324992243851">"安裝語音合成所需的語音資料"</string>
-    <string name="tts_engine_security_warning" msgid="3372432853837988146">"這個語音合成引擎可能會收集您輸入的所有語音,包括密碼和信用卡號等個人資料。這個引擎來自「<xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>」引擎,是否要使用這個語音合成引擎?"</string>
-    <string name="tts_engine_network_required" msgid="8722087649733906851">"您需要操作正常的網絡連線,才能使用文字轉語音功能輸出這種語言。"</string>
+    <string name="tts_engine_security_warning" msgid="3372432853837988146">"這個語音合成引擎可能會收集你輸入的所有語音,包括密碼和信用卡號等個人資料。這個引擎來自「<xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>」引擎,是否要使用這個語音合成引擎?"</string>
+    <string name="tts_engine_network_required" msgid="8722087649733906851">"你需要操作正常的網絡連線,才能使用文字轉語音功能輸出這種語言。"</string>
     <string name="tts_default_sample_string" msgid="6388016028292967973">"這是語音合成例子"</string>
     <string name="tts_status_title" msgid="8190784181389278640">"預設語言狀態"</string>
     <string name="tts_status_ok" msgid="8583076006537547379">"全面支援<xliff:g id="LOCALE">%1$s</xliff:g>"</string>
@@ -308,7 +308,7 @@
     <string name="select_logd_size_title" msgid="1604578195914595173">"記錄器緩衝區空間"</string>
     <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"選取每個記錄緩衝區的記錄器空間"</string>
     <string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"要清除記錄器的持久儲存空間嗎?"</string>
-    <string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"當我們不再使用持久記錄器進行監察,便需要清除您裝置上的記錄器資料。"</string>
+    <string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"當我們不再使用持久記錄器進行監察,便需要清除你裝置上的記錄器資料。"</string>
     <string name="select_logpersist_title" msgid="447071974007104196">"在裝置持久儲存記錄器資料"</string>
     <string name="select_logpersist_dialog_title" msgid="7745193591195485594">"選擇記錄緩衝區,以便將資料持久儲存在裝置中"</string>
     <string name="select_usb_configuration_title" msgid="6339801314922294586">"選取 USB 設定"</string>
@@ -319,12 +319,12 @@
     <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"即使 Wi‑Fi 已啟用,仍永遠啟用流動數據 (可快速切換網絡)。"</string>
     <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"使用網絡共享硬件加速功能 (如果可用)"</string>
     <string name="adb_warning_title" msgid="7708653449506485728">"允許 USB 偵錯嗎?"</string>
-    <string name="adb_warning_message" msgid="8145270656419669221">"USB 偵錯是針對應用程式開發而設計的功能,可讓您在電腦與裝置間複製資料、不用通知即可在裝置上安裝應用程式,以及讀取記錄資料。"</string>
+    <string name="adb_warning_message" msgid="8145270656419669221">"USB 偵錯是針對應用程式開發而設計的功能,可讓你在電腦與裝置間複製資料、不用通知即可在裝置上安裝應用程式,以及讀取記錄資料。"</string>
     <string name="adbwifi_warning_title" msgid="727104571653031865">"要啟用無線偵錯嗎?"</string>
-    <string name="adbwifi_warning_message" msgid="8005936574322702388">"無線偵錯僅適用於開發用途,可讓您在電腦和裝置之間複製資料、為裝置安裝應用程式而不提出通知,以及讀取記錄資料。"</string>
+    <string name="adbwifi_warning_message" msgid="8005936574322702388">"無線偵錯僅適用於開發用途,可讓你在電腦和裝置之間複製資料、為裝置安裝應用程式而不提出通知,以及讀取記錄資料。"</string>
     <string name="adb_keys_warning_message" msgid="2968555274488101220">"要針對先前授權的所有電腦撤銷 USB 偵錯存取權嗎?"</string>
     <string name="dev_settings_warning_title" msgid="8251234890169074553">"允許開發設定?"</string>
-    <string name="dev_settings_warning_message" msgid="37741686486073668">"這些設定僅供開發用途,可能會導致您的裝置及應用程式損毀或運作不正常。"</string>
+    <string name="dev_settings_warning_message" msgid="37741686486073668">"這些設定僅供開發用途,可能會導致你的裝置及應用程式損毀或運作不正常。"</string>
     <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"透過 USB 驗證應用程式"</string>
     <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"透過 ADB/ADT 檢查安裝的應用程式有否有害的行為。"</string>
     <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"系統將顯示沒有名稱 (只有 MAC 位址) 的藍牙裝置"</string>
@@ -441,17 +441,17 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"紅色弱視 (紅綠)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"藍色弱視 (藍黃)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"色彩校正"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"「色彩校正」功能適用於以下情況::&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;您想讓裝置顯示更準確的色彩&lt;/li&gt; &lt;li&gt;&amp;nbsp;您想移除色彩以提高專注力&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"「色彩校正」功能適用於以下情況::&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;你想讓裝置顯示更準確的色彩&lt;/li&gt; &lt;li&gt;&amp;nbsp;你想移除色彩以提高專注力&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1076561255466053220">"還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根據您的使用情況,還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
-    <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"根據您的使用情況,還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根據你的使用情況,還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"根據你的使用情況,還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="563438403581662942">"根據您的使用情況 (<xliff:g id="LEVEL">%2$s</xliff:g>),電量剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"根據您的使用情況,電量剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_enhanced" msgid="563438403581662942">"根據你的使用情況 (<xliff:g id="LEVEL">%2$s</xliff:g>),電量剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"根據你的使用情況,電量剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by" msgid="4113180890060388350">"電量剩餘約 <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_discharge_by_only" msgid="92545648425937000">"電量大約可用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_short" msgid="5883041507426914446">"還可用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
@@ -508,8 +508,8 @@
     <string name="active_input_method_subtypes" msgid="4232680535471633046">"可用的輸入法"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"使用系統語言"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"無法開啟 <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> 的設定"</string>
-    <string name="ime_security_warning" msgid="6547562217880551450">"這個輸入法可能會收集您輸入的所有文字,包括密碼和信用卡號碼等個人資料。這個輸入法由 <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> 應用程式提供,您要使用嗎?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"注意:重新啟動後,您必須解鎖手機,才可開始使用此應用程式"</string>
+    <string name="ime_security_warning" msgid="6547562217880551450">"這個輸入法可能會收集你輸入的所有文字,包括密碼和信用卡號碼等個人資料。這個輸入法由 <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> 應用程式提供,你要使用嗎?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"注意:重新啟動後,你必須解鎖手機,才可開始使用此應用程式"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"IMS 註冊狀態"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"已註冊"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"未註冊"</string>
@@ -534,13 +534,13 @@
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"只限優先"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"除非您預先關閉此功能,否則您不會聽到下一個<xliff:g id="WHEN">%1$s</xliff:g>的鬧鐘響鬧"</string>
-    <string name="zen_alarm_warning" msgid="245729928048586280">"您不會聽到下一個<xliff:g id="WHEN">%1$s</xliff:g>的鬧鐘響鬧"</string>
+    <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"除非你預先關閉此功能,否則你不會聽到下一個<xliff:g id="WHEN">%1$s</xliff:g>的鬧鐘響鬧"</string>
+    <string name="zen_alarm_warning" msgid="245729928048586280">"你不會聽到下一個<xliff:g id="WHEN">%1$s</xliff:g>的鬧鐘響鬧"</string>
     <string name="alarm_template" msgid="3346777418136233330">"時間:<xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="6382760514842998629">"時間:<xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"持續時間"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"每次都詢問"</string>
-    <string name="zen_mode_forever" msgid="3339224497605461291">"直至您關閉為止"</string>
+    <string name="zen_mode_forever" msgid="3339224497605461291">"直至你關閉為止"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string>
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"此手機"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"此平板電腦"</string>
@@ -570,15 +570,15 @@
     <string name="delete_blob_text" msgid="2819192607255625697">"刪除共用資料"</string>
     <string name="delete_blob_confirmation_text" msgid="7807446938920827280">"確定要刪除此共用資料嗎?"</string>
     <string name="user_add_user_item_summary" msgid="5748424612724703400">"使用者擁有自己的應用程式和內容"</string>
-    <string name="user_add_profile_item_summary" msgid="5418602404308968028">"您可以限制透過您的帳戶存取應用程式和內容"</string>
+    <string name="user_add_profile_item_summary" msgid="5418602404308968028">"你可以限制透過你的帳戶存取應用程式和內容"</string>
     <string name="user_add_user_item_title" msgid="2394272381086965029">"使用者"</string>
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"限制存取的個人檔案"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"新增使用者?"</string>
-    <string name="user_add_user_message_long" msgid="1527434966294733380">"您可以建立其他使用者,與他人共用這部裝置。每位使用者都有屬於自己的空間,並可以自訂應用程式、桌布等等。此外,使用者也可以調整會影響所有人的裝置設定,例如 Wi‑Fi 設定。\n\n新加入的使用者需要自行設定個人空間。\n\n任何使用者都可以為所有其他使用者更新應用程式。無障礙功能設定和服務則未必適用於新的使用者。"</string>
+    <string name="user_add_user_message_long" msgid="1527434966294733380">"你可以建立其他使用者,與他人共用這部裝置。每位使用者都有屬於自己的空間,並可以自訂應用程式、桌布等等。此外,使用者也可以調整會影響所有人的裝置設定,例如 Wi‑Fi 設定。\n\n新加入的使用者需要自行設定個人空間。\n\n任何使用者都可以為所有其他使用者更新應用程式。無障礙功能設定和服務則未必適用於新的使用者。"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"新增的使用者需要自行設定個人空間。\n\n任何使用者都可以為其他所有使用者更新應用程式。"</string>
-    <string name="user_grant_admin_title" msgid="5157031020083343984">"要將這位使用者設為管理員嗎?"</string>
-    <string name="user_grant_admin_message" msgid="1673791931033486709">"管理員具備其他使用者沒有的權限,例如可管理所有使用者、更新或重設這部裝置、修改設定、查看所有已安裝的應用程式,以及將管理員權限授予他人,或撤銷他人的管理員權限。"</string>
-    <string name="user_grant_admin_button" msgid="5441486731331725756">"設為管理員"</string>
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"要指定此使用者為管理員嗎?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"管理員擁有其他使用者沒有的特殊權限。管理員可管理所有使用者、更新或重設此裝置、修改設定、查看所有已安裝的應用程式,以及對其他使用者授予或撤銷管理員權限。"</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"指定為管理員"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"立即設定使用者?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"請確保對方現在可以在裝置上設定自己的空間"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"立即設定個人檔案?"</string>
@@ -589,7 +589,7 @@
     <string name="user_new_profile_name" msgid="2405500423304678841">"新個人檔案"</string>
     <string name="user_info_settings_title" msgid="6351390762733279907">"使用者資料"</string>
     <string name="profile_info_settings_title" msgid="105699672534365099">"個人檔案資料"</string>
-    <string name="user_need_lock_message" msgid="4311424336209509301">"建立限制存取的個人檔案前,您必須先設定上鎖畫面來保護您的應用程式和個人資料。"</string>
+    <string name="user_need_lock_message" msgid="4311424336209509301">"建立限制存取的個人檔案前,你必須先設定上鎖畫面來保護你的應用程式和個人資料。"</string>
     <string name="user_set_lock_button" msgid="1427128184982594856">"設定上鎖畫面"</string>
     <string name="user_switch_to_user" msgid="6975428297154968543">"切換至<xliff:g id="USER_NAME">%s</xliff:g>"</string>
     <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"正在建立新使用者…"</string>
@@ -610,19 +610,19 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"此操作會開始新的訪客工作階段,並刪除目前工作階段的所有應用程式和資料"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"要結束訪客模式嗎?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"此操作會刪除目前訪客工作階段中的所有應用程式和資料"</string>
-    <string name="grant_admin" msgid="4323199171790522574">"是,將這位使用者設為管理員"</string>
-    <string name="not_grant_admin" msgid="3557849576157702485">"否,不要將這位使用者設為管理員"</string>
+    <string name="grant_admin" msgid="4323199171790522574">"是,指定他為管理員"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"否,不要指定他為管理員"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"結束"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"要儲存訪客活動嗎?"</string>
-    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"您可儲存目前工作階段中的活動或刪除所有應用程式和資料"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"你可儲存目前工作階段中的活動或刪除所有應用程式和資料"</string>
     <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"刪除"</string>
     <string name="guest_exit_save_data_button" msgid="3690974510644963547">"儲存"</string>
     <string name="guest_exit_button" msgid="5774985819191803960">"結束訪客模式"</string>
     <string name="guest_reset_button" msgid="2515069346223503479">"重設訪客工作階段"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"結束訪客模式"</string>
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"結束時將會刪除所有活動"</string>
-    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"您可以在結束時儲存或刪除活動"</string>
-    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"重設可立即刪除工作階段活動,或者您可以在結束時儲存或刪除活動"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"你可以在結束時儲存或刪除活動"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"重設可立即刪除工作階段活動,或者你可以在結束時儲存或刪除活動"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"揀相"</string>
@@ -633,7 +633,7 @@
     <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"裝置預設設定"</string>
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string>
-    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"您的裝置必須重新開機,才能套用此變更。請立即重新開機或取消。"</string>
+    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"你的裝置必須重新開機,才能套用此變更。請立即重新開機或取消。"</string>
     <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"有線耳機"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"開啟"</string>
     <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"關閉"</string>
@@ -671,7 +671,7 @@
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"預設"</string>
     <string name="turn_screen_on_title" msgid="3266937298097573424">"開啟螢幕"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"允許開啟螢幕"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"允許應用程式開啟螢幕。應用程式獲授權後,可在您未有明確表明意圖的情況下隨時開啟螢幕。"</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"允許應用程式開啟螢幕。應用程式獲授權後,可在你未有明確表明意圖的情況下隨時開啟螢幕。"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"要停止廣播「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"如要廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止廣播目前的內容"</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 18d19dd..35d6947 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -519,12 +519,9 @@
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Isikhathi esiningi."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Isikhathi esincane."</string>
     <string name="cancel" msgid="5665114069455378395">"Khansela"</string>
-    <!-- no translation found for next (2699398661093607009) -->
-    <skip />
-    <!-- no translation found for back (5554327870352703710) -->
-    <skip />
-    <!-- no translation found for save (3745809743277153149) -->
-    <skip />
+    <string name="next" msgid="2699398661093607009">"Okulandelayo"</string>
+    <string name="back" msgid="5554327870352703710">"Emuva"</string>
+    <string name="save" msgid="3745809743277153149">"Londoloza"</string>
     <string name="okay" msgid="949938843324579502">"KULUNGILE"</string>
     <string name="done" msgid="381184316122520313">"Kwenziwe"</string>
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ama-alamu nezikhumbuzi"</string>
@@ -579,12 +576,9 @@
     <string name="user_add_user_title" msgid="5457079143694924885">"Engeza umsebenzisi omusha?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Manje ungabelana ngale divayisi nabanye abantu ngokudala abasebenzisi abangeziwe. Umsebenzisi ngamunye unesikhala sakhe, angakwazi ukusenza ngendlela ayifisayo ngezinhlelo zokusebenza, isithombe sangemuva, njalo njalo. Abasebenzisi bangalungisa izilungiselelo zedivayisi ezifana ne-Wi-Fi ezithinta wonke umuntu.\n\nUma ungeza umsebenzisi omusha, loyo muntu kumele asethe isikhala sakhe.\n\nNoma imuphi umsebenzisi angabuyekeza izinhlelo zokusebenza kubo bonke abanye abasebenzisi. Izilungiselelo zokufinyelela kungenzeka zingadluliselwa kumsebenzisi omusha."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Uma ungeza umsebenzisi omusha, loyo muntu udinga ukusetha isikhala sakhe.\n\nNoma yimuphi umsebenzisi angabuyekeza izinhlelo zokusebenza kubo bonke abasebenzisi."</string>
-    <!-- no translation found for user_grant_admin_title (5157031020083343984) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_message (1673791931033486709) -->
-    <skip />
-    <!-- no translation found for user_grant_admin_button (5441486731331725756) -->
-    <skip />
+    <string name="user_grant_admin_title" msgid="5157031020083343984">"Yenza lo msebenzisi abe umphathi?"</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Abalawuli banamalungelo akhethekile abanye abasebenzisi abangenawo. Umlawuli angaphatha bonke abasebenzisi, abuyekeze noma asethe kabusha le divayisi, alungise amasethingi, abone wonke ama-app afakiwe, futhi anikeze noma ahoxise amalungelo okuphatha kwabanye."</string>
+    <string name="user_grant_admin_button" msgid="5441486731331725756">"Yenza umphathi"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Setha umsebenzisi manje?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Qinisekisa ukuthi umuntu uyatholakala ukuze athathe idivayisi futhi asethe isikhala sakhe"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Setha iphrofayela manje?"</string>
@@ -616,10 +610,8 @@
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Lokhu kuzoqala isikhathi sesihambeli esisha futhi kusule wonke ama-app nedatha kusuka esikhathini samanje"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Phuma kumodi yesihambeli?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Lokhu kuzosula ama-app nedatha kusuka esikhathini sesihambeli samanje"</string>
-    <!-- no translation found for grant_admin (4323199171790522574) -->
-    <skip />
-    <!-- no translation found for not_grant_admin (3557849576157702485) -->
-    <skip />
+    <string name="grant_admin" msgid="4323199171790522574">"Yebo, benze abaphathi"</string>
+    <string name="not_grant_admin" msgid="3557849576157702485">"Cha, ungabenzi abaphathi"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Phuma"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Londoloza umsebenzi wesihambeli?"</string>
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Ungalondoloza umsebenzi kusuka esikhathini samanje noma usule wonke ama-app nedatha"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 5e8f3a1..fe89883 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -734,7 +734,10 @@
 
     private AppEntry getEntryLocked(ApplicationInfo info) {
         int userId = UserHandle.getUserId(info.uid);
-        AppEntry entry = mEntriesMap.get(userId).get(info.packageName);
+        AppEntry entry = null;
+        if (mEntriesMap.contains(userId)) {
+            entry = mEntriesMap.get(userId).get(info.packageName);
+        }
         if (DEBUG) {
             Log.i(TAG, "Looking up entry of pkg " + info.packageName + ": " + entry);
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java b/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
index 3c45112..dae48db 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
@@ -17,6 +17,7 @@
 package com.android.settingslib.applications;
 
 import android.app.AppGlobals;
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -94,6 +95,10 @@
 
     }
 
+    public @Nullable String getSummary() {
+        return this.summary;
+    }
+
     @Override
     public Drawable loadIcon() {
         final IconDrawableFactory factory = IconDrawableFactory.newInstance(mContext);
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverLogging.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverLogging.java
index 5326e73..daa3616 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverLogging.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverLogging.java
@@ -32,9 +32,13 @@
     public static final String EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED_REASON =
             "extra_power_save_mode_manual_enabled_reason";
 
+    /** Record the event while enabling power save mode manually. */
+    public static final String EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED =
+            "extra_power_save_mode_manual_enabled";
+
     /** Broadcast action to record battery saver manual enabled reason. */
-    public static final String ACTION_SAVER_MANUAL_ENABLED_REASON =
-            "com.android.settingslib.fuelgauge.ACTION_SAVER_MANUAL_ENABLED_REASON";
+    public static final String ACTION_SAVER_STATE_MANUAL_UPDATE =
+            "com.android.settingslib.fuelgauge.ACTION_SAVER_STATE_MANUAL_UPDATE";
 
     /** An interface for the battery saver manual enable reason. */
     @Retention(RetentionPolicy.SOURCE)
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index e28ada4..c9540c7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -16,7 +16,8 @@
 
 package com.android.settingslib.fuelgauge;
 
-import static com.android.settingslib.fuelgauge.BatterySaverLogging.ACTION_SAVER_MANUAL_ENABLED_REASON;
+import static com.android.settingslib.fuelgauge.BatterySaverLogging.ACTION_SAVER_STATE_MANUAL_UPDATE;
+import static com.android.settingslib.fuelgauge.BatterySaverLogging.EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED;
 import static com.android.settingslib.fuelgauge.BatterySaverLogging.EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED_REASON;
 import static com.android.settingslib.fuelgauge.BatterySaverLogging.SaverManualEnabledReason;
 
@@ -152,9 +153,8 @@
                     sendSystemUiBroadcast(context, ACTION_SHOW_AUTO_SAVER_SUGGESTION,
                             confirmationExtras);
                 }
-                recordBatterySaverEnabledReason(context, reason);
             }
-
+            recordBatterySaverEnabledReason(context, enable, reason);
             return true;
         }
         return false;
@@ -185,11 +185,12 @@
         return true;
     }
 
-    private static void recordBatterySaverEnabledReason(Context context,
+    private static void recordBatterySaverEnabledReason(Context context, boolean enable,
             @SaverManualEnabledReason int reason) {
-        final Bundle enabledReasonExtras = new Bundle(1);
+        final Bundle enabledReasonExtras = new Bundle(2);
         enabledReasonExtras.putInt(EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED_REASON, reason);
-        sendSystemUiBroadcast(context, ACTION_SAVER_MANUAL_ENABLED_REASON, enabledReasonExtras);
+        enabledReasonExtras.putBoolean(EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED, enable);
+        sendSystemUiBroadcast(context, ACTION_SAVER_STATE_MANUAL_UPDATE, enabledReasonExtras);
     }
 
     private static void sendSystemUiBroadcast(Context context, String action, Bundle extras) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index 45c0d78..adaf4a1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -14,7 +14,9 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
@@ -26,6 +28,8 @@
 import android.net.NetworkRequest;
 import android.net.NetworkScoreManager;
 import android.net.ScoredNetwork;
+import android.net.TransportInfo;
+import android.net.vcn.VcnTransportInfo;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiNetworkScoreCache;
@@ -34,8 +38,9 @@
 import android.os.Looper;
 import android.provider.Settings;
 
+import androidx.annotation.Nullable;
+
 import com.android.settingslib.R;
-import com.android.settingslib.Utils;
 
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
@@ -46,6 +51,7 @@
 /**
  * Track status of Wi-Fi for the Sys UI.
  */
+@SuppressLint("MissingPermission")
 public class WifiStatusTracker {
     private static final int HISTORY_SIZE = 32;
     private static final SimpleDateFormat SSDF = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
@@ -66,8 +72,9 @@
     private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
             .clearCapabilities()
             .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build();
+            .addTransportType(TRANSPORT_WIFI)
+            .addTransportType(TRANSPORT_CELLULAR)
+            .build();
     private final NetworkCallback mNetworkCallback =
             new NetworkCallback(NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) {
         // Note: onCapabilitiesChanged is guaranteed to be called "immediately" after onAvailable
@@ -75,18 +82,10 @@
         @Override
         public void onCapabilitiesChanged(
                 Network network, NetworkCapabilities networkCapabilities) {
-            boolean isVcnOverWifi = false;
-            boolean isWifi = false;
-            WifiInfo wifiInfo = null;
-            if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
-                wifiInfo = Utils.tryGetWifiInfoForVcn(networkCapabilities);
-                isVcnOverWifi = (wifiInfo != null);
-            } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
-                wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
-                isWifi = true;
-            }
+            WifiInfo wifiInfo = getMainOrUnderlyingWifiInfo(networkCapabilities);
+            boolean isWifi = connectionIsWifi(networkCapabilities, wifiInfo);
             // As long as it is a WiFi network, we will log it in the dumpsys for debugging.
-            if (isVcnOverWifi || isWifi) {
+            if (isWifi) {
                 String log = new StringBuilder()
                         .append(SSDF.format(System.currentTimeMillis())).append(",")
                         .append("onCapabilitiesChanged: ")
@@ -303,17 +302,8 @@
             return;
         }
         NetworkCapabilities networkCapabilities;
-        isDefaultNetwork = false;
-        if (mDefaultNetworkCapabilities != null) {
-            boolean isWifi = mDefaultNetworkCapabilities.hasTransport(
-                    NetworkCapabilities.TRANSPORT_WIFI);
-            boolean isVcnOverWifi = mDefaultNetworkCapabilities.hasTransport(
-                    NetworkCapabilities.TRANSPORT_CELLULAR)
-                            && (Utils.tryGetWifiInfoForVcn(mDefaultNetworkCapabilities) != null);
-            if (isWifi || isVcnOverWifi) {
-                isDefaultNetwork = true;
-            }
-        }
+        isDefaultNetwork = mDefaultNetworkCapabilities != null
+                && connectionIsWifi(mDefaultNetworkCapabilities);
         if (isDefaultNetwork) {
             // Wifi is connected and the default network.
             networkCapabilities = mDefaultNetworkCapabilities;
@@ -352,6 +342,70 @@
                 ? null : AccessPoint.getSpeedLabel(mContext, scoredNetwork, rssi);
     }
 
+    @Nullable
+    private WifiInfo getMainOrUnderlyingWifiInfo(NetworkCapabilities networkCapabilities) {
+        WifiInfo mainWifiInfo = getMainWifiInfo(networkCapabilities);
+        if (mainWifiInfo != null) {
+            return mainWifiInfo;
+        }
+
+        // Only CELLULAR networks may have underlying wifi information that's relevant to SysUI,
+        // so skip the underlying network check if it's not CELLULAR.
+        if (!networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
+            return mainWifiInfo;
+        }
+
+        List<Network> underlyingNetworks = networkCapabilities.getUnderlyingNetworks();
+        if (underlyingNetworks == null) {
+            return null;
+        }
+
+        // Some connections, like VPN connections, may have underlying networks that are
+        // eventually traced to a wifi or carrier merged connection. So, check those underlying
+        // networks for possible wifi information as well. See b/225902574.
+        for (Network underlyingNetwork : underlyingNetworks) {
+            NetworkCapabilities underlyingNetworkCapabilities =
+                    mConnectivityManager.getNetworkCapabilities(underlyingNetwork);
+            WifiInfo underlyingWifiInfo = getMainWifiInfo(underlyingNetworkCapabilities);
+            if (underlyingWifiInfo != null) {
+                return underlyingWifiInfo;
+            }
+        }
+
+        return null;
+    }
+
+    @Nullable
+    private WifiInfo getMainWifiInfo(NetworkCapabilities networkCapabilities) {
+        boolean canHaveWifiInfo = networkCapabilities.hasTransport(TRANSPORT_WIFI)
+                || networkCapabilities.hasTransport(TRANSPORT_CELLULAR);
+        if (!canHaveWifiInfo) {
+            return null;
+        }
+
+        TransportInfo transportInfo = networkCapabilities.getTransportInfo();
+        if (transportInfo instanceof VcnTransportInfo) {
+            // This VcnTransportInfo logic is copied from
+            // [com.android.settingslib.Utils.tryGetWifiInfoForVcn]. It's copied instead of
+            // re-used because it makes the logic here clearer.
+            return ((VcnTransportInfo) transportInfo).getWifiInfo();
+        } else if (transportInfo instanceof WifiInfo) {
+            return (WifiInfo) transportInfo;
+        } else {
+            return null;
+        }
+    }
+
+    private boolean connectionIsWifi(NetworkCapabilities networkCapabilities) {
+        return connectionIsWifi(
+                networkCapabilities,
+                getMainOrUnderlyingWifiInfo(networkCapabilities));
+    }
+
+    private boolean connectionIsWifi(NetworkCapabilities networkCapabilities, WifiInfo wifiInfo) {
+        return wifiInfo != null || networkCapabilities.hasTransport(TRANSPORT_WIFI);
+    }
+
     /** Refresh the status label on Locale changed. */
     public void refreshLocale() {
         updateStatusLabel();
diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp
index d463170..ff3eeec 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -30,7 +30,10 @@
 
     certificate: "platform",
 
-    srcs: ["src/**/*.java"],
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
 
     libs: [
         "android.test.runner",
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
index fdefcde..52c2a87 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
@@ -114,6 +114,21 @@
     }
 
     @Test
+    public void updateSetting_twiceWithSameValue_persistedValueDifferent_persistsAgain() {
+        mManager.updateSetting(/* deviceState= */ 1, /* rotationLocked= */ true);
+        // This persists a different setting than what was set above. It simulates the persisted
+        // setting being changed from a different process.
+        persistSettings("0:1:1:2:2:2");
+        mNumSettingsChanges = 0;
+
+        // Updating again with the same value as in the first line of the test should persist the
+        // setting, as it is different to what is actually persisted.
+        mManager.updateSetting(/* deviceState= */ 1, /* rotationLocked= */ true);
+
+        assertThat(mNumSettingsChanges).isEqualTo(1);
+    }
+
+    @Test
     public void getSettableDeviceStates_returnsExpectedValuesInOriginalOrder() {
         when(mMockResources.getStringArray(
                 R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/PosturesHelperTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/PosturesHelperTest.kt
new file mode 100644
index 0000000..d91c2fa
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/PosturesHelperTest.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.settingslib.devicestate
+
+import android.content.Context
+import android.content.res.Resources
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_HALF_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNFOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNKNOWN
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.R
+import com.google.common.truth.Expect
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+private const val DEVICE_STATE_UNKNOWN = 0
+private const val DEVICE_STATE_CLOSED = 1
+private const val DEVICE_STATE_HALF_FOLDED = 2
+private const val DEVICE_STATE_OPEN = 3
+private const val DEVICE_STATE_REAR_DISPLAY = 4
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PosturesHelperTest {
+
+    @get:Rule val expect: Expect = Expect.create()
+
+    @Mock private lateinit var context: Context
+
+    @Mock private lateinit var resources: Resources
+
+    private lateinit var posturesHelper: PosturesHelper
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        whenever(context.resources).thenReturn(resources)
+        whenever(resources.getIntArray(R.array.config_foldedDeviceStates))
+            .thenReturn(intArrayOf(DEVICE_STATE_CLOSED))
+        whenever(resources.getIntArray(R.array.config_halfFoldedDeviceStates))
+            .thenReturn(intArrayOf(DEVICE_STATE_HALF_FOLDED))
+        whenever(resources.getIntArray(R.array.config_openDeviceStates))
+            .thenReturn(intArrayOf(DEVICE_STATE_OPEN))
+        whenever(resources.getIntArray(R.array.config_rearDisplayDeviceStates))
+            .thenReturn(intArrayOf(DEVICE_STATE_REAR_DISPLAY))
+
+        posturesHelper = PosturesHelper(context)
+    }
+
+    @Test
+    fun deviceStateToPosture_mapsCorrectly() {
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_CLOSED))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_FOLDED)
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_HALF_FOLDED))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_HALF_FOLDED)
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_OPEN))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_UNFOLDED)
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_REAR_DISPLAY))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY)
+        expect
+            .that(posturesHelper.deviceStateToPosture(DEVICE_STATE_UNKNOWN))
+            .isEqualTo(DEVICE_STATE_ROTATION_KEY_UNKNOWN)
+    }
+
+    @Test
+    fun postureToDeviceState_mapsCorrectly() {
+        expect
+            .that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_FOLDED))
+            .isEqualTo(DEVICE_STATE_CLOSED)
+        expect
+            .that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_HALF_FOLDED))
+            .isEqualTo(DEVICE_STATE_HALF_FOLDED)
+        expect
+            .that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_UNFOLDED))
+            .isEqualTo(DEVICE_STATE_OPEN)
+        expect
+            .that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY))
+            .isEqualTo(DEVICE_STATE_REAR_DISPLAY)
+        expect.that(posturesHelper.postureToDeviceState(DEVICE_STATE_ROTATION_KEY_UNKNOWN)).isNull()
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
index 96e64ea..1d081d7 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
@@ -89,6 +89,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 import java.util.UUID;
 
@@ -801,4 +802,21 @@
         assertThat(nonPrimaryUserApp1.shouldShowInPersonalTab(um, appInfo1.uid)).isTrue();
         assertThat(nonPrimaryUserApp2.shouldShowInPersonalTab(um, appInfo2.uid)).isFalse();
     }
+
+    @Test
+    public void getEntry_validUserId_shouldReturnEntry() {
+        mApplicationsState.mEntriesMap.put(/* userId= */ 0, new HashMap<>());
+        addApp(PKG_1, /* id= */ 1);
+
+        assertThat(mApplicationsState.getEntry(PKG_1, /* userId= */ 0).info.packageName)
+                .isEqualTo(PKG_1);
+    }
+
+    @Test
+    public void getEntry_invalidUserId_shouldReturnNull() {
+        mApplicationsState.mEntriesMap.put(/* userId= */ 0, new HashMap<>());
+        addApp(PKG_1, /* id= */ 1);
+
+        assertThat(mApplicationsState.getEntry(PKG_1, /* userId= */ -1)).isNull();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
index 7a26f76..80301c0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
@@ -16,14 +16,16 @@
 
 package com.android.settingslib.fuelgauge;
 
+import static com.android.settingslib.fuelgauge.BatterySaverLogging.ACTION_SAVER_STATE_MANUAL_UPDATE;
 import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_UNKNOWN;
+import static com.android.settingslib.fuelgauge.BatterySaverUtils.ACTION_SHOW_AUTO_SAVER_SUGGESTION;
+import static com.android.settingslib.fuelgauge.BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION;
 import static com.android.settingslib.fuelgauge.BatterySaverUtils.KEY_NO_SCHEDULE;
 import static com.android.settingslib.fuelgauge.BatterySaverUtils.KEY_PERCENTAGE;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.times;
@@ -40,10 +42,13 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 
+import java.util.List;
+
 @RunWith(RobolectricTestRunner.class)
 public class BatterySaverUtilsTest {
     private static final int BATTERY_SAVER_THRESHOLD_1 = 15;
@@ -68,7 +73,7 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_enable_firstCall_needWarning() {
+    public void testSetPowerSaveMode_enableWithWarning_firstCall_needConfirmationWarning() {
         Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
         Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
         Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
@@ -76,9 +81,12 @@
         assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, true, true,
                 SAVER_ENABLED_UNKNOWN)).isFalse();
 
-        verify(mMockContext, times(1)).sendBroadcast(any(Intent.class));
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockContext, times(1)).sendBroadcast(intentCaptor.capture());
         verify(mMockPowerManager, times(0)).setPowerSaveModeEnabled(anyBoolean());
 
+        assertThat(intentCaptor.getValue().getAction()).isEqualTo(
+                ACTION_SHOW_START_SAVER_CONFIRMATION);
         // They shouldn't have changed.
         assertEquals(-1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
         assertEquals(-1,
@@ -88,7 +96,7 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_enable_secondCall_needWarning() {
+    public void testSetPowerSaveMode_enableWithWarning_secondCall_expectUpdateIntent() {
         // Already acked.
         Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
         Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
@@ -97,8 +105,12 @@
         assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, true, true,
                 SAVER_ENABLED_UNKNOWN)).isTrue();
 
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockContext, times(1)).sendBroadcast(intentCaptor.capture());
         verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(true));
 
+        assertThat(intentCaptor.getValue().getAction()).isEqualTo(
+                ACTION_SAVER_STATE_MANUAL_UPDATE);
         assertEquals(1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
         assertEquals(1,
                 Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
@@ -107,7 +119,7 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_enable_thridCall_needWarning() {
+    public void testSetPowerSaveMode_enableWithWarning_thirdCall_expectUpdateIntent() {
         // Already acked.
         Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
         Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
@@ -116,8 +128,12 @@
         assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, true, true,
                 SAVER_ENABLED_UNKNOWN)).isTrue();
 
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockContext, times(1)).sendBroadcast(intentCaptor.capture());
         verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(true));
 
+        assertThat(intentCaptor.getValue().getAction()).isEqualTo(
+                ACTION_SAVER_STATE_MANUAL_UPDATE);
         assertEquals(1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
         assertEquals(1,
                 Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
@@ -126,7 +142,31 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_enable_firstCall_noWarning() {
+    public void testSetPowerSaveMode_enableWithWarning_5thCall_needAutoSuggestionWarning() {
+        // Already acked.
+        Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
+        Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
+        Secure.putInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, 3);
+
+        assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, true, true,
+                SAVER_ENABLED_UNKNOWN)).isTrue();
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockContext, times(2)).sendBroadcast(intentCaptor.capture());
+        verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(true));
+
+        List<Intent> values = intentCaptor.getAllValues();
+        assertThat(values.get(0).getAction()).isEqualTo(ACTION_SHOW_AUTO_SAVER_SUGGESTION);
+        assertThat(values.get(1).getAction()).isEqualTo(ACTION_SAVER_STATE_MANUAL_UPDATE);
+        assertEquals(1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+        assertEquals(1,
+                Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+        assertEquals(4,
+                Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
+    }
+
+    @Test
+    public void testSetPowerSaveMode_enableWithoutWarning_expectUpdateIntent() {
         Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
         Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
         Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
@@ -134,8 +174,12 @@
         assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, true, false,
                 SAVER_ENABLED_UNKNOWN)).isTrue();
 
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockContext, times(1)).sendBroadcast(intentCaptor.capture());
         verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(true));
 
+        assertThat(intentCaptor.getValue().getAction()).isEqualTo(
+                ACTION_SAVER_STATE_MANUAL_UPDATE);
         assertEquals(1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
         assertEquals(1,
                 Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
@@ -143,43 +187,13 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_disable_firstCall_noWarning() {
-        Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
-        Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
-        Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
-
-        // When disabling, needFirstTimeWarning doesn't matter.
-        assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, false, false,
-                SAVER_ENABLED_UNKNOWN)).isTrue();
-
-        verify(mMockContext, times(0)).sendBroadcast(any(Intent.class));
-        verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(false));
-
-        assertEquals(-1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
-        assertEquals(-1,
-                Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
-        assertEquals(-2,
-                Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
+    public void testSetPowerSaveMode_disableWithoutWarning_expectUpdateIntent() {
+        verifyDisablePowerSaveMode(/* needFirstTimeWarning= */ false);
     }
 
     @Test
-    public void testSetPowerSaveMode_disable_firstCall_needWarning() {
-        Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
-        Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
-        Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
-
-        // When disabling, needFirstTimeWarning doesn't matter.
-        assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, false, true,
-                SAVER_ENABLED_UNKNOWN)).isTrue();
-
-        verify(mMockContext, times(0)).sendBroadcast(any(Intent.class));
-        verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(false));
-
-        assertEquals(-1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
-        assertEquals(-1,
-                Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
-        assertEquals(-2,
-                Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
+    public void testSetPowerSaveMode_disableWithWarning_expectUpdateIntent() {
+        verifyDisablePowerSaveMode(/* needFirstTimeWarning= */ true);
     }
 
     @Test
@@ -256,4 +270,26 @@
                 .isEqualTo(20);
 
     }
+
+    private void verifyDisablePowerSaveMode(boolean needFirstTimeWarning) {
+        Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
+        Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
+        Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
+
+        // When disabling, needFirstTimeWarning doesn't matter.
+        assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, false, needFirstTimeWarning,
+                SAVER_ENABLED_UNKNOWN)).isTrue();
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockContext, times(1)).sendBroadcast(intentCaptor.capture());
+        verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(false));
+
+        assertThat(intentCaptor.getValue().getAction()).isEqualTo(
+                ACTION_SAVER_STATE_MANUAL_UPDATE);
+        assertEquals(-1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+        assertEquals(-1,
+                Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+        assertEquals(-2,
+                Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java
index dc7e313d..6e975cf 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java
@@ -40,6 +40,8 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 
+import java.util.Arrays;
+
 @RunWith(RobolectricTestRunner.class)
 public class WifiStatusTrackerTest {
     @Mock Context mContext;
@@ -48,13 +50,32 @@
     @Mock ConnectivityManager mConnectivityManager;
     @Mock Runnable mCallback;
 
+    private WifiStatusTracker mWifiStatusTracker;
+
     private final ArgumentCaptor<ConnectivityManager.NetworkCallback>
             mNetworkCallbackCaptor =
             ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
 
+    private final ArgumentCaptor<ConnectivityManager.NetworkCallback>
+            mDefaultNetworkCallbackCaptor =
+            ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+
+        mWifiStatusTracker = new WifiStatusTracker(
+                mContext,
+                mWifiManager,
+                mNetworkScoreManager,
+                mConnectivityManager,
+                mCallback);
+        mWifiStatusTracker.setListening(true);
+
+        verify(mConnectivityManager)
+                .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any());
+        verify(mConnectivityManager)
+                .registerDefaultNetworkCallback(mDefaultNetworkCallbackCaptor.capture(), any());
     }
 
     /**
@@ -62,13 +83,6 @@
      */
     @Test
     public void testWifiInfoClearedOnPrimaryNetworkLost() {
-        WifiStatusTracker wifiStatusTracker = new WifiStatusTracker(mContext, mWifiManager,
-                mNetworkScoreManager, mConnectivityManager, mCallback);
-        wifiStatusTracker.setListening(true);
-
-        verify(mConnectivityManager)
-                .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any());
-
         // Trigger a validation callback for the primary Wifi network.
         WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
         when(primaryWifiInfo.makeCopy(anyLong())).thenReturn(primaryWifiInfo);
@@ -86,8 +100,8 @@
         mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
 
         // Verify primary wifi info is the one being used.
-        assertThat(wifiStatusTracker.connected).isTrue();
-        assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi);
+        assertThat(mWifiStatusTracker.connected).isTrue();
+        assertThat(mWifiStatusTracker.rssi).isEqualTo(primaryRssi);
 
         // Trigger a validation callback for the non-primary Wifi network.
         WifiInfo nonPrimaryWifiInfo = Mockito.mock(WifiInfo.class);
@@ -106,20 +120,189 @@
         mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(nonPrimaryNetwork, nonPrimaryCap);
 
         // Verify primary wifi info is still the one being used.
-        assertThat(wifiStatusTracker.connected).isTrue();
-        assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi);
+        assertThat(mWifiStatusTracker.connected).isTrue();
+        assertThat(mWifiStatusTracker.rssi).isEqualTo(primaryRssi);
 
         // Lose the non-primary network.
         mNetworkCallbackCaptor.getValue().onLost(nonPrimaryNetwork);
 
         // Verify primary wifi info is still the one being used.
-        assertThat(wifiStatusTracker.connected).isTrue();
-        assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi);
+        assertThat(mWifiStatusTracker.connected).isTrue();
+        assertThat(mWifiStatusTracker.rssi).isEqualTo(primaryRssi);
 
         // Lose the primary network.
         mNetworkCallbackCaptor.getValue().onLost(primaryNetwork);
 
         // Verify we aren't connected anymore.
-        assertThat(wifiStatusTracker.connected).isFalse();
+        assertThat(mWifiStatusTracker.connected).isFalse();
+    }
+
+    @Test
+    public void isCarrierMerged_typicalWifi_false() {
+        WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+        when(primaryWifiInfo.isPrimary()).thenReturn(true);
+
+        NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+        when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)).thenReturn(true);
+        when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo);
+
+        Network primaryNetwork = Mockito.mock(Network.class);
+        int primaryNetworkId = 1;
+        when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+        mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+        assertThat(mWifiStatusTracker.isCarrierMerged).isFalse();
+    }
+
+    @Test
+    public void isCarrierMerged_typicalCellular_false() {
+        NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+        when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
+
+        Network primaryNetwork = Mockito.mock(Network.class);
+        int primaryNetworkId = 1;
+        when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+        mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+        assertThat(mWifiStatusTracker.isCarrierMerged).isFalse();
+    }
+
+    @Test
+    public void isCarrierMerged_cellularCarrierMergedWifi_true() {
+        WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+        when(primaryWifiInfo.isPrimary()).thenReturn(true);
+        when(primaryWifiInfo.isCarrierMerged()).thenReturn(true);
+
+        NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+        when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
+        when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo);
+
+        Network primaryNetwork = Mockito.mock(Network.class);
+        int primaryNetworkId = 1;
+        when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+        mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+        assertThat(mWifiStatusTracker.isCarrierMerged).isTrue();
+    }
+
+    /** Test for b/225902574. */
+    @Test
+    public void isCarrierMerged_cellularWithUnderlyingCarrierMergedWifi_true() {
+        WifiInfo underlyingCarrierMergedInfo = Mockito.mock(WifiInfo.class);
+        when(underlyingCarrierMergedInfo.isPrimary()).thenReturn(true);
+        when(underlyingCarrierMergedInfo.isCarrierMerged()).thenReturn(true);
+
+        NetworkCapabilities underlyingNetworkCapabilities = Mockito.mock(NetworkCapabilities.class);
+        when(underlyingNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
+                .thenReturn(true);
+        when(underlyingNetworkCapabilities.getTransportInfo())
+                .thenReturn(underlyingCarrierMergedInfo);
+
+        Network underlyingNetwork = Mockito.mock(Network.class);
+        when(mConnectivityManager.getNetworkCapabilities(underlyingNetwork))
+                .thenReturn(underlyingNetworkCapabilities);
+
+        NetworkCapabilities mainCapabilities = Mockito.mock(NetworkCapabilities.class);
+        when(mainCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
+                .thenReturn(true);
+        when(mainCapabilities.getTransportInfo()).thenReturn(null);
+        when(mainCapabilities.getUnderlyingNetworks())
+                .thenReturn(Arrays.asList(underlyingNetwork));
+
+        Network primaryNetwork = Mockito.mock(Network.class);
+        int primaryNetworkId = 1;
+        when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+        mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, mainCapabilities);
+
+        assertThat(mWifiStatusTracker.isCarrierMerged).isTrue();
+    }
+
+    @Test
+    public void isDefaultNetwork_typicalWifi_true() {
+        WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+        when(primaryWifiInfo.isPrimary()).thenReturn(true);
+
+        NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+        when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)).thenReturn(true);
+        when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo);
+
+        Network primaryNetwork = Mockito.mock(Network.class);
+        int primaryNetworkId = 1;
+        when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+        mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+        assertThat(mWifiStatusTracker.isDefaultNetwork).isTrue();
+    }
+
+    @Test
+    public void isDefaultNetwork_typicalCellular_false() {
+        NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+        when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
+
+        Network primaryNetwork = Mockito.mock(Network.class);
+        int primaryNetworkId = 1;
+        when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+        mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+        assertThat(mWifiStatusTracker.isDefaultNetwork).isFalse();
+    }
+
+    @Test
+    public void isDefaultNetwork_cellularCarrierMergedWifi_true() {
+        WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+        when(primaryWifiInfo.isPrimary()).thenReturn(true);
+        when(primaryWifiInfo.isCarrierMerged()).thenReturn(true);
+
+        NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+        when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
+        when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo);
+
+        Network primaryNetwork = Mockito.mock(Network.class);
+        int primaryNetworkId = 1;
+        when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+        mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+        assertThat(mWifiStatusTracker.isDefaultNetwork).isTrue();
+    }
+
+    /** Test for b/225902574. */
+    @Test
+    public void isDefaultNetwork_cellularWithUnderlyingCarrierMergedWifi_true() {
+        WifiInfo underlyingCarrierMergedInfo = Mockito.mock(WifiInfo.class);
+        when(underlyingCarrierMergedInfo.isPrimary()).thenReturn(true);
+        when(underlyingCarrierMergedInfo.isCarrierMerged()).thenReturn(true);
+
+        NetworkCapabilities underlyingNetworkCapabilities = Mockito.mock(NetworkCapabilities.class);
+        when(underlyingNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
+                .thenReturn(true);
+        when(underlyingNetworkCapabilities.getTransportInfo())
+                .thenReturn(underlyingCarrierMergedInfo);
+
+        Network underlyingNetwork = Mockito.mock(Network.class);
+        when(mConnectivityManager.getNetworkCapabilities(underlyingNetwork))
+                .thenReturn(underlyingNetworkCapabilities);
+
+        NetworkCapabilities mainCapabilities = Mockito.mock(NetworkCapabilities.class);
+        when(mainCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
+                .thenReturn(true);
+        when(mainCapabilities.getTransportInfo()).thenReturn(null);
+        when(mainCapabilities.getUnderlyingNetworks())
+                .thenReturn(Arrays.asList(underlyingNetwork));
+
+        Network primaryNetwork = Mockito.mock(Network.class);
+        int primaryNetworkId = 1;
+        when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+        mDefaultNetworkCallbackCaptor.getValue()
+                .onCapabilitiesChanged(primaryNetwork, mainCapabilities);
+
+        assertThat(mWifiStatusTracker.isDefaultNetwork).isTrue();
     }
 }
diff --git a/packages/SettingsProvider/res/values-ky/strings.xml b/packages/SettingsProvider/res/values-ky/strings.xml
index 7ab6582..830182b 100644
--- a/packages/SettingsProvider/res/values-ky/strings.xml
+++ b/packages/SettingsProvider/res/values-ky/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4567566098528588863">"Жөндөөлөрдү сактоо"</string>
+    <string name="app_label" msgid="4567566098528588863">"Параметрлерди сактоо"</string>
     <string name="wifi_softap_config_change" msgid="5688373762357941645">"Байланыш түйүнү  параметрлери өзгөрдү"</string>
     <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Чоо-жайын билүү үчүн басыңыз"</string>
 </resources>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index e4cc9f1..6a5535d 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -100,6 +100,5 @@
         Settings.System.CAMERA_FLASH_NOTIFICATION,
         Settings.System.SCREEN_FLASH_NOTIFICATION,
         Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR,
-        Settings.System.SMOOTH_DISPLAY
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 4b72063..85623b2 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -226,6 +226,5 @@
         VALIDATORS.put(System.CAMERA_FLASH_NOTIFICATION, BOOLEAN_VALIDATOR);
         VALIDATORS.put(System.SCREEN_FLASH_NOTIFICATION, BOOLEAN_VALIDATOR);
         VALIDATORS.put(System.SCREEN_FLASH_NOTIFICATION_COLOR, ANY_INTEGER_VALIDATOR);
-        VALIDATORS.put(System.SMOOTH_DISPLAY, BOOLEAN_VALIDATOR);
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index d1bd5e6..46b45d1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -34,7 +34,6 @@
 
 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.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
 import static com.android.providers.settings.SettingsState.FALLBACK_FILE_SUFFIX;
 import static com.android.providers.settings.SettingsState.getTypeFromKey;
 import static com.android.providers.settings.SettingsState.getUserIdFromKey;
@@ -5674,7 +5673,7 @@
                             providers.addAll(Arrays.asList(resources.getStringArray(resourceId)));
                         } catch (Resources.NotFoundException e) {
                             Slog.w(LOG_TAG,
-                                    "Get default array Cred Provider not found: " + e.toString());
+                                "Get default array Cred Provider not found: " + e.toString());
                         }
                         try {
                             final String storedValue = resources.getString(resourceId);
@@ -5683,7 +5682,7 @@
                             }
                         } catch (Resources.NotFoundException e) {
                             Slog.w(LOG_TAG,
-                                    "Get default Cred Provider not found: " + e.toString());
+                                "Get default Cred Provider not found: " + e.toString());
                         }
 
                         if (!providers.isEmpty()) {
@@ -5732,8 +5731,8 @@
                     final Setting currentSetting = secureSettings
                             .getSettingLocked(Settings.Secure.CREDENTIAL_SERVICE);
                     if (currentSetting.isNull()) {
-                        final int resourceId = com.android.internal.R.array
-                                .config_defaultCredentialProviderService;
+                        final int resourceId =
+                            com.android.internal.R.array.config_defaultCredentialProviderService;
                         final Resources resources = getContext().getResources();
                         // If the config has not be defined we might get an exception.
                         final List<String> providers = new ArrayList<>();
@@ -5741,7 +5740,7 @@
                             providers.addAll(Arrays.asList(resources.getStringArray(resourceId)));
                         } catch (Resources.NotFoundException e) {
                             Slog.w(LOG_TAG,
-                                    "Get default array Cred Provider not found: " + e.toString());
+                                "Get default array Cred Provider not found: " + e.toString());
                         }
 
                         if (!providers.isEmpty()) {
@@ -5840,44 +5839,12 @@
                     currentVersion = 218;
                 }
 
-                // v218: Convert Smooth Display and Force Peak Refresh Rate to a boolean
                 if (currentVersion == 218) {
-                    final String peakRefreshRateSettingName = "peak_refresh_rate";
-                    final String minRefreshRateSettingName = "min_refresh_rate";
-
-                    final SettingsState systemSettings = getSystemSettingsLocked(userId);
-                    final Setting peakRefreshRateSetting =
-                            systemSettings.getSettingLocked(peakRefreshRateSettingName);
-                    final Setting minRefreshRateSetting =
-                            systemSettings.getSettingLocked(minRefreshRateSettingName);
-
-                    float peakRefreshRate = DEFAULT_REFRESH_RATE;
-                    float minRefreshRate = 0;
-                    try {
-                        if (!peakRefreshRateSetting.isNull()) {
-                            peakRefreshRate = Float.parseFloat(peakRefreshRateSetting.getValue());
-                        }
-                    } catch (NumberFormatException e) {
-                        // Do nothing. Overwrite with default value.
-                    }
-                    try {
-                        if (!minRefreshRateSetting.isNull()) {
-                            minRefreshRate = Float.parseFloat(minRefreshRateSetting.getValue());
-                        }
-                    } catch (NumberFormatException e) {
-                        // Do nothing. Overwrite with default value.
-                    }
-
-                    systemSettings.deleteSettingLocked(peakRefreshRateSettingName);
-                    systemSettings.deleteSettingLocked(minRefreshRateSettingName);
-
-                    systemSettings.insertSettingLocked(Settings.System.SMOOTH_DISPLAY,
-                            peakRefreshRate > DEFAULT_REFRESH_RATE ? "1" : "0", /* tag= */ null,
-                            /* makeDefault= */ false, SettingsState.SYSTEM_PACKAGE_NAME);
-                    systemSettings.insertSettingLocked(Settings.System.FORCE_PEAK_REFRESH_RATE,
-                            minRefreshRate > 0 ? "1" : "0", /* tag= */ null,
-                            /* makeDefault= */ false, SettingsState.SYSTEM_PACKAGE_NAME);
-
+                    // Version 219: Removed
+                    // TODO(b/211737588): Back up the Smooth Display setting
+                    // Future upgrades to the `peak_refresh_rate` and `min_refresh_rate` settings
+                    // should account for the database in a non-upgraded and upgraded (change id:
+                    // Ib2cb2dd100f06f5452083b7606109a486e795a0e) state.
                     currentVersion = 219;
                 }
 
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 36aa2ac..706666c 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -97,7 +97,8 @@
                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS, // bug?
                     Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, // used for debugging only
                     Settings.System.DESKTOP_MODE, // developer setting for internal prototyping
-                    Settings.System.FORCE_PEAK_REFRESH_RATE, // depends on hardware capabilities
+                    Settings.System.MIN_REFRESH_RATE, // depends on hardware capabilities
+                    Settings.System.PEAK_REFRESH_RATE, // depends on hardware capabilities
                     Settings.System.SCREEN_BRIGHTNESS_FLOAT,
                     Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
                     Settings.System.MULTI_AUDIO_FOCUS_ENABLED // form-factor/OEM specific
diff --git a/packages/Shell/res/values-am/strings.xml b/packages/Shell/res/values-am/strings.xml
index fe1f228..6cc13ec 100644
--- a/packages/Shell/res/values-am/strings.xml
+++ b/packages/Shell/res/values-am/strings.xml
@@ -25,9 +25,9 @@
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"የሳንካ ሪፖርቱ ከትንሽ ጊዜ በኋላ በስልኩ ላይ ይመጣል"</string>
     <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"የሳንካ ሪፖርትዎን ለማጋራት ይምረጡ"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"የሳንካ ሪፖርትዎን ለማጋራት መታ ያድርጉ"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገጽ ለማጋራት ይምረጡ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገጽ ለማጋራት መታ ያድርጉ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገጽ ለማጋራት መታ ያድርጉ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገፅ ለማጋራት ይምረጡ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገፅ ለማጋራት መታ ያድርጉ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገፅ ለማጋራት መታ ያድርጉ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"የሳንካ ሪፖርቶች ከተለያዩ የስርዓቱ የምዝግብ ማስታወሻ ፋይሎች የመጣ ውሂብ ይዘዋል፣ እነዚህም እርስዎ ሚስጥራዊነት ያለው ብለው የሚቆጥሯቸው (እንደ የመተግበሪያ አጠቃቀም እና የአካባቢ ውሂብ ያለ) ሊያካትቱ ይችላሉ። የሳንካ ሪፖርቶች ለሚያምኗቸው ሰዎች እና መተግበሪያዎች ብቻ ያጋሩ።"</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"ዳግም አታሳይ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"የሳንካ ሪፖርቶች"</string>
@@ -35,9 +35,9 @@
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"የሳንካ ሪፖርት ዝርዝሮችን ወደ ዚፕ ፋይል ማከል አልተቻለም"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ያልተሰየመ"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"ዝርዝሮች"</string>
-    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ቅጽበታዊ ገጽ እይታ"</string>
-    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ቅጽበታዊ ገጽ እይታ በተሳካ ሁኔታ ተነስቷል"</string>
-    <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ቅጽበታዊ ገጽ እይታ ሊነሳ አይችልም"</string>
+    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ቅጽበታዊ ገፅ እይታ"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ቅጽበታዊ ገፅ እይታ በተሳካ ሁኔታ ተነስቷል"</string>
+    <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ቅጽበታዊ ገፅ እይታ ሊነሳ አይችልም"</string>
     <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> ዝርዝሮች"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"የፋይል ስም"</string>
     <string name="bugreport_info_title" msgid="2306030793918239804">"የሳንካ ርዕስ"</string>
diff --git a/packages/Shell/res/values-zh-rHK/strings.xml b/packages/Shell/res/values-zh-rHK/strings.xml
index ccbea4d..91b1770 100644
--- a/packages/Shell/res/values-zh-rHK/strings.xml
+++ b/packages/Shell/res/values-zh-rHK/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"選擇以分享錯誤報告 (不包含螢幕擷取畫面),或等待螢幕畫面擷取完成"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕按以分享錯誤報告 (不包含螢幕擷圖),或等待螢幕畫面擷取完成"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕按以分享錯誤報告 (不包含螢幕擷圖),或等待螢幕畫面擷取完成"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"錯誤報告包含來自系統多個記錄檔案的資料,並可能涉及對您而言敏感的資料 (例如應用程式使用情況和位置資料)。您只應與信任的人和應用程式分享錯誤報告。"</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"錯誤報告包含來自系統多個記錄檔案的資料,並可能涉及對你而言敏感的資料 (例如應用程式使用情況和位置資料)。你只應與信任的人和應用程式分享錯誤報告。"</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"不要再顯示"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"無法讀取錯誤報告檔案"</string>
diff --git a/packages/SimAppDialog/res/values-zh-rHK/strings.xml b/packages/SimAppDialog/res/values-zh-rHK/strings.xml
index bc490f0..7897987 100644
--- a/packages/SimAppDialog/res/values-zh-rHK/strings.xml
+++ b/packages/SimAppDialog/res/values-zh-rHK/strings.xml
@@ -19,8 +19,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="8898068901680117589">"Sim App Dialog"</string>
     <string name="install_carrier_app_title" msgid="334729104862562585">"啟動流動服務"</string>
-    <string name="install_carrier_app_description" msgid="4014303558674923797">"為確保新的 SIM 卡正常運作,您必須先安裝「<xliff:g id="ID_1">%1$s</xliff:g>」應用程式"</string>
-    <string name="install_carrier_app_description_default" msgid="7356830245205847840">"為確保新的 SIM 卡正常運作,您必須先安裝流動網絡供應商應用程式"</string>
+    <string name="install_carrier_app_description" msgid="4014303558674923797">"為確保新的 SIM 卡正常運作,你必須先安裝「<xliff:g id="ID_1">%1$s</xliff:g>」應用程式"</string>
+    <string name="install_carrier_app_description_default" msgid="7356830245205847840">"為確保新的 SIM 卡正常運作,你必須先安裝流動網絡供應商應用程式"</string>
     <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"暫時不要"</string>
     <string name="install_carrier_app_download_action" msgid="7859229305958538064">"下載應用程式"</string>
 </resources>
diff --git a/packages/SoundPicker/res/values-fi/strings.xml b/packages/SoundPicker/res/values-fi/strings.xml
index 9f64f83..fcda098 100644
--- a/packages/SoundPicker/res/values-fi/strings.xml
+++ b/packages/SoundPicker/res/values-fi/strings.xml
@@ -18,7 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="ringtone_default" msgid="798836092118824500">"Oletussoittoääni"</string>
     <string name="notification_sound_default" msgid="8133121186242636840">"Ilmoituksen oletusääni"</string>
-    <string name="alarm_sound_default" msgid="4787646764557462649">"Herätyksen oletusääni"</string>
+    <string name="alarm_sound_default" msgid="4787646764557462649">"Hälytyksen oletusääni"</string>
     <string name="add_ringtone_text" msgid="6642389991738337529">"Lisää soittoääni"</string>
     <string name="add_alarm_text" msgid="3545497316166999225">"Lisää hälytys"</string>
     <string name="add_notification_text" msgid="4431129543300614788">"Lisää ilmoitus"</string>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 865b0df..e6bbf97 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -173,7 +173,6 @@
         "androidx.palette_palette",
         "androidx.legacy_legacy-preference-v14",
         "androidx.leanback_leanback",
-        "androidx.tracing_tracing",
         "androidx.slice_slice-core",
         "androidx.slice_slice-view",
         "androidx.slice_slice-builders",
@@ -228,26 +227,35 @@
 filegroup {
     name: "SystemUI-tests-robolectric-pilots",
     srcs: [
+        /* Keyguard converted tests */
         // 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/MuteQuickAffordanceConfigTest.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/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt",
         "tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt",
         "tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.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/KeyguardLongPressInteractorTest.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/PrimaryBouncerCallbackInteractorTest.kt",
         "tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
         // ui
         "tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt",
@@ -256,8 +264,14 @@
         "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",
+        "tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt",
+        // Keyguard helper
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt",
+        "tests/src/com/android/systemui/dump/LogBufferHelper.kt",
+        "tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java",
+        "tests/src/com/android/systemui/keyguard/domain/quickaffordance/FakeKeyguardQuickAffordanceRegistry.kt",
 
-        // Biometric
+        /* Biometric converted tests */
         "tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt",
         "tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt",
         "tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 24de487..c8eb4b4 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -695,7 +695,9 @@
             android:relinquishTaskIdentity="true"
             android:configChanges=
                 "screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
-            android:visibleToInstantApps="true"/>
+            android:visibleToInstantApps="true"
+            android:exported="false"
+            android:permission="android.permission.MANAGE_MEDIA_PROJECTION"/>
 
         <!-- started from TvNotificationPanel -->
         <activity
@@ -966,21 +968,7 @@
                  android:permission="android.permission.BIND_JOB_SERVICE"/>
 
         <!-- region Note Task -->
-        <activity
-            android:name=".notetask.shortcut.CreateNoteTaskShortcutActivity"
-            android:enabled="false"
-            android:exported="true"
-            android:excludeFromRecents="true"
-            android:resizeableActivity="false"
-            android:theme="@android:style/Theme.NoDisplay"
-            android:label="@string/note_task_button_label"
-            android:icon="@drawable/ic_note_task_shortcut_widget">
-
-            <intent-filter>
-                <action android:name="android.intent.action.CREATE_SHORTCUT" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
+        <service android:name=".notetask.NoteTaskControllerUpdateService" />
 
         <activity
             android:name=".notetask.shortcut.LaunchNoteTaskActivity"
@@ -1004,6 +992,18 @@
             android:excludeFromRecents="true"
             android:resizeableActivity="false"
             android:theme="@android:style/Theme.NoDisplay" />
+
+        <activity
+            android:name=".notetask.LaunchNotesRoleSettingsTrampolineActivity"
+            android:exported="true"
+            android:excludeFromRecents="true"
+            android:resizeableActivity="false"
+            android:theme="@android:style/Theme.NoDisplay" >
+            <intent-filter>
+                <action android:name="com.android.systemui.action.MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
         <!-- endregion -->
 
         <!-- started from ControlsRequestReceiver -->
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 77ddc6e..1ce3472 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -55,6 +55,7 @@
 madym@google.com
 mankoff@google.com
 mateuszc@google.com
+mgalhardo@google.com
 michaelmikhil@google.com
 michschn@google.com
 mkephart@google.com
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-am/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-am/strings.xml
index f215e85..0aeb410 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-am/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-am/strings.xml
@@ -2,25 +2,25 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="accessibility_menu_service_name" msgid="730136711554740131">"የተደራሽነት ምናሌ"</string>
-    <string name="accessibility_menu_intro" msgid="3164193281544042394">"የተደራሽነት ምናሌ መሣሪያዎን ለመቆጣጠር ትልቅ የማያ ገጽ ላይ ምናሌን ያቀርባል። የእርስዎን መሣሪያ መቆለፍ፣ ድምፅን እና ብሩህነትን መቆጣጠር፣ ቅጽበታዊ ገጽ ዕይታዎችን ማንሳት እና ተጨማሪ ነገሮችን ማድረግ ይችላሉ።"</string>
+    <string name="accessibility_menu_intro" msgid="3164193281544042394">"የተደራሽነት ምናሌ መሣሪያዎን ለመቆጣጠር ትልቅ የማያ ገፅ ላይ ምናሌን ያቀርባል። የእርስዎን መሣሪያ መቆለፍ፣ ድምፅን እና ብሩህነትን መቆጣጠር፣ ቅጽበታዊ ገፅ ዕይታዎችን ማንሳት እና ተጨማሪ ነገሮችን ማድረግ ይችላሉ።"</string>
     <string name="assistant_label" msgid="6796392082252272356">"ረዳት"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"ረዳት"</string>
     <string name="a11y_settings_label" msgid="3977714687248445050">"የተደራሽነት ቅንብሮች"</string>
     <string name="power_label" msgid="7699720321491287839">"ኃይል"</string>
     <string name="power_utterance" msgid="7444296686402104807">"የኃይል አማራጮች"</string>
     <string name="recent_apps_label" msgid="6583276995616385847">"የቅርብ ጊዜ መተግበሪያዎች"</string>
-    <string name="lockscreen_label" msgid="648347953557887087">"ማያ ገጽ ቁልፍ"</string>
+    <string name="lockscreen_label" msgid="648347953557887087">"ማያ ገፅ ቁልፍ"</string>
     <string name="quick_settings_label" msgid="2999117381487601865">"ፈጣን ቅንብሮች"</string>
     <string name="notifications_label" msgid="6829741046963013567">"ማሳወቂያዎች"</string>
-    <string name="screenshot_label" msgid="863978141223970162">"ቅጽበታዊ ገጽ እይታ"</string>
-    <string name="screenshot_utterance" msgid="1430760563401895074">"ቅጽበታዊ ገጽ እይታን ያነሳል"</string>
+    <string name="screenshot_label" msgid="863978141223970162">"ቅጽበታዊ ገፅ እይታ"</string>
+    <string name="screenshot_utterance" msgid="1430760563401895074">"ቅጽበታዊ ገፅ እይታን ያነሳል"</string>
     <string name="volume_up_label" msgid="8592766918780362870">"ድምፅ ጨምር"</string>
     <string name="volume_down_label" msgid="8574981863656447346">"ድምፅ ቀንስ"</string>
     <string name="brightness_up_label" msgid="8010753822854544846">"ብሩህነት ጨምር"</string>
     <string name="brightness_down_label" msgid="7115662941913272072">"ብሩህነት ቀንስ"</string>
-    <string name="previous_button_content_description" msgid="840869171117765966">"ወደ ቀዳሚው ማያ ገጽ ይሂዱ"</string>
-    <string name="next_button_content_description" msgid="6810058269847364406">"ወደ ቀጣዩ ማያ ገጽ ይሂዱ"</string>
-    <string name="accessibility_menu_description" msgid="4458354794093858297">"የተደራሽነት ምናሌ መሣሪያዎን ለመቆጣጠር ትልቅ የማያ ገጽ ላይ ምናሌን ያቀርባል። የእርስዎን መሣሪያ መቆለፍ፣ ድምፅን እና ብሩህነትን መቆጣጠር፣ ቅጽበታዊ ገጽ ዕይታዎችን ማንሳት እና ተጨማሪ ነገሮችን ማድረግ ይችላሉ።"</string>
+    <string name="previous_button_content_description" msgid="840869171117765966">"ወደ ቀዳሚው ማያ ገፅ ይሂዱ"</string>
+    <string name="next_button_content_description" msgid="6810058269847364406">"ወደ ቀጣዩ ማያ ገፅ ይሂዱ"</string>
+    <string name="accessibility_menu_description" msgid="4458354794093858297">"የተደራሽነት ምናሌ መሣሪያዎን ለመቆጣጠር ትልቅ የማያ ገፅ ላይ ምናሌን ያቀርባል። የእርስዎን መሣሪያ መቆለፍ፣ ድምፅን እና ብሩህነትን መቆጣጠር፣ ቅጽበታዊ ገፅ ዕይታዎችን ማንሳት እና ተጨማሪ ነገሮችን ማድረግ ይችላሉ።"</string>
     <string name="accessibility_menu_summary" msgid="340071398148208130">"መሣሪያውን በትልቅ ምናሌ በኩል ይቆጣጠሩ"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"የተደራሽነት ምናሌ ቅንብሮች"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ትልቅ አዝራሮች"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-cs/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-cs/strings.xml
index c0d9d45..e5dd693 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-cs/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-cs/strings.xml
@@ -21,7 +21,7 @@
     <string name="previous_button_content_description" msgid="840869171117765966">"Zpět na předchozí obrazovku"</string>
     <string name="next_button_content_description" msgid="6810058269847364406">"Přejít na další obrazovku"</string>
     <string name="accessibility_menu_description" msgid="4458354794093858297">"Nabídka usnadnění přístupu zobrazuje na obrazovce velkou nabídku k ovládání zařízení. Můžete zamknout zařízení, upravit hlasitost a jas, pořídit snímek obrazovky apod."</string>
-    <string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládejte zařízení pomocí velké nabídky"</string>
+    <string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládat zařízení pomocí velké nabídky"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavení nabídky usnadnění přístupu"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Velká tlačítka"</string>
     <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zvětšit tlačítka v nabídce přístupnosti"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
index 1715d56..87a9503 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="accessibility_menu_service_name" msgid="730136711554740131">"menu Accessibilité"</string>
+    <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu Accessibilité"</string>
     <string name="accessibility_menu_intro" msgid="3164193281544042394">"Le menu Accessibilité propose un grand espace à l\'écran à l\'aide duquel vous pouvez contrôler votre appareil. Utilisez-le pour verrouiller votre appareil, régler le volume et la luminosité, prendre des captures d\'écran et plus."</string>
     <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml
index 10c6169..140caff 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu d\'accessibilité"</string>
+    <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu Accessibilité"</string>
     <string name="accessibility_menu_intro" msgid="3164193281544042394">"Le menu d\'accessibilité s\'affiche en grand sur votre écran pour vous permettre de contrôler votre appareil. Vous pouvez verrouiller votre appareil, ajuster le volume et la luminosité, réaliser des captures d\'écran, et plus encore."</string>
     <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
@@ -21,7 +21,7 @@
     <string name="previous_button_content_description" msgid="840869171117765966">"Revenir à l\'écran précédent"</string>
     <string name="next_button_content_description" msgid="6810058269847364406">"Accéder à l\'écran suivant"</string>
     <string name="accessibility_menu_description" msgid="4458354794093858297">"Le menu d\'accessibilité s\'affiche en grand sur votre écran pour vous permettre de contrôler votre appareil. Vous pouvez verrouiller votre appareil, ajuster le volume et la luminosité, réaliser des captures d\'écran, et plus encore."</string>
-    <string name="accessibility_menu_summary" msgid="340071398148208130">"Contrôlez votre appareil via un grand menu"</string>
+    <string name="accessibility_menu_summary" msgid="340071398148208130">"Contrôler l\'appareil via un grand menu"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Paramètres du menu d\'accessibilité"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Boutons de grande taille"</string>
     <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Augmenter la taille des boutons du menu d\'accessibilité"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-my/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-my/strings.xml
index dacd68a..1097f87 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-my/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-my/strings.xml
@@ -21,7 +21,7 @@
     <string name="previous_button_content_description" msgid="840869171117765966">"ယခင် မျက်နှာပြင်သို့ သွားရန်"</string>
     <string name="next_button_content_description" msgid="6810058269847364406">"နောက်မျက်နှာပြင်သို့ ဆက်သွားရန်"</string>
     <string name="accessibility_menu_description" msgid="4458354794093858297">"‘အများသုံးနိုင်မှု မီနူး’ တွင် သင့်စက်ပစ္စည်းကို စီမံရန် ကြီးမားသည့်ဖန်သားပြင်မီနူး ပါဝင်သည်။ စက်ပစ္စည်းလော့ခ်ချခြင်း၊ အသံအတိုးအကျယ်နှင့် အလင်းအမှောင် ထိန်းချုပ်ခြင်း၊ ဖန်သားပြင်ဓာတ်ပုံရိုက်ခြင်း စသည်တို့ ပြုလုပ်နိုင်သည်။"</string>
-    <string name="accessibility_menu_summary" msgid="340071398148208130">"ကြီးမားသည့်မီးနူးဖြင့် စက်ပစ္စည်းကို စီမံနိုင်သည်"</string>
+    <string name="accessibility_menu_summary" msgid="340071398148208130">"ကြီးမားသည့်မီနူးဖြင့် စက်ပစ္စည်းကို စီမံနိုင်သည်"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"အများသုံးနိုင်မှု မီနူးဆက်တင်များ"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ခလုတ်အကြီးများ"</string>
     <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"\'အများသုံးနိုင်မှု မီနူး ခလုတ်များ\' ၏ အရွယ်အစားတိုးရန်"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
index c4bf89a..c29002b 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
@@ -21,7 +21,7 @@
     <string name="previous_button_content_description" msgid="840869171117765966">"Prejsť na predchádzajúcu obrazovku"</string>
     <string name="next_button_content_description" msgid="6810058269847364406">"Prejsť na ďalšiu obrazovku"</string>
     <string name="accessibility_menu_description" msgid="4458354794093858297">"Ponuka dostupnosti spustí na obrazovke telefónu veľkú ponuku, pomocou ktorej môžete ovládať svoje zariadenie. Môžete ho uzamknúť, ovládať hlasitosť a jas, vytvárať snímky obrazovky a mnoho ďalšieho."</string>
-    <string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládajte zariadenie pomocou veľkej ponuky"</string>
+    <string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládať zariadenie pomocou veľkej ponuky"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavenia ponuky dostupnosti"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Veľké tlačidlá"</string>
     <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zväčšiť tlačidlá ponuky dostupnosti"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rHK/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rHK/strings.xml
index 9f4033c..fed2e9c 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rHK/strings.xml
@@ -2,7 +2,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="accessibility_menu_service_name" msgid="730136711554740131">"無障礙功能選單"</string>
-    <string name="accessibility_menu_intro" msgid="3164193281544042394">"「無障礙功能選單」是螢幕上的大型選單,用來控制裝置,方便您鎖定裝置、控制音量和亮度、擷取螢幕畫面及執行其他功能。"</string>
+    <string name="accessibility_menu_intro" msgid="3164193281544042394">"「無障礙功能選單」是螢幕上的大型選單,用來控制裝置,方便你鎖定裝置、控制音量和亮度、擷取螢幕畫面及執行其他功能。"</string>
     <string name="assistant_label" msgid="6796392082252272356">"Google 助理"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Google 助理"</string>
     <string name="a11y_settings_label" msgid="3977714687248445050">"無障礙功能設定"</string>
@@ -20,7 +20,7 @@
     <string name="brightness_down_label" msgid="7115662941913272072">"調暗亮度"</string>
     <string name="previous_button_content_description" msgid="840869171117765966">"前往上一個畫面"</string>
     <string name="next_button_content_description" msgid="6810058269847364406">"前往下一個畫面"</string>
-    <string name="accessibility_menu_description" msgid="4458354794093858297">"「無障礙功能選單」是螢幕上的大型選單,用來控制裝置,方便您鎖定裝置、控制音量和亮度、擷取螢幕截圖及執行其他功能。"</string>
+    <string name="accessibility_menu_description" msgid="4458354794093858297">"「無障礙功能選單」是螢幕上的大型選單,用來控制裝置,方便你鎖定裝置、控制音量和亮度、擷取螢幕截圖及執行其他功能。"</string>
     <string name="accessibility_menu_summary" msgid="340071398148208130">"透過大型選單控制裝置"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"無障礙功能選單設定"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"大按鈕"</string>
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index 296c2ae..94b3740 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -436,8 +436,8 @@
         }
 
         @BinderThread
-        override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {
-            context.mainExecutor.execute { delegate.onAnimationCancelled(isKeyguardOccluded) }
+        override fun onAnimationCancelled() {
+            context.mainExecutor.execute { delegate.onAnimationCancelled() }
         }
     }
 
@@ -744,7 +744,7 @@
         }
 
         @UiThread
-        override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {
+        override fun onAnimationCancelled() {
             if (timedOut) {
                 return
             }
@@ -754,7 +754,7 @@
             removeTimeout()
 
             animation?.cancel()
-            controller.onLaunchAnimationCancelled(newKeyguardOccludedState = isKeyguardOccluded)
+            controller.onLaunchAnimationCancelled()
         }
 
         private fun IRemoteAnimationFinishedCallback.invoke() {
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
index 337408b..d465962 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
@@ -26,5 +26,5 @@
     )
 
     /** Called on the UI thread when a signal is received to cancel the animation. */
-    @UiThread fun onAnimationCancelled(isKeyguardOccluded: Boolean)
+    @UiThread fun onAnimationCancelled()
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
index 3ee97be..9346a2f 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
@@ -24,12 +24,30 @@
 import android.graphics.Typeface
 import android.graphics.fonts.Font
 import android.text.Layout
+import android.text.TextPaint
 import android.util.LruCache
 
 private const val DEFAULT_ANIMATION_DURATION: Long = 300
 private const val TYPEFACE_CACHE_MAX_ENTRIES = 5
 
 typealias GlyphCallback = (TextAnimator.PositionedGlyph, Float) -> Unit
+
+interface TypefaceVariantCache {
+    fun getTypefaceForVariant(fvar: String, targetPaint: TextPaint): Typeface?
+}
+
+class TypefaceVariantCacheImpl() : TypefaceVariantCache {
+    private val cache = LruCache<String, Typeface>(TYPEFACE_CACHE_MAX_ENTRIES)
+    override fun getTypefaceForVariant(fvar: String, targetPaint: TextPaint): Typeface? {
+        cache.get(fvar)?.let {
+            return it
+        }
+
+        targetPaint.fontVariationSettings = fvar
+        return targetPaint.typeface?.also { cache.put(fvar, it) }
+    }
+}
+
 /**
  * This class provides text animation between two styles.
  *
@@ -56,9 +74,19 @@
  * ```
  * </code> </pre>
  */
-class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) {
+class TextAnimator(
+    layout: Layout,
+    private val invalidateCallback: () -> Unit,
+) {
+    var typefaceCache: TypefaceVariantCache = TypefaceVariantCacheImpl()
+        get() = field
+        set(value) {
+            field = value
+            textInterpolator.typefaceCache = value
+        }
+
     // Following two members are for mutable for testing purposes.
-    public var textInterpolator: TextInterpolator = TextInterpolator(layout)
+    public var textInterpolator: TextInterpolator = TextInterpolator(layout, typefaceCache)
     public var animator: ValueAnimator =
         ValueAnimator.ofFloat(1f).apply {
             duration = DEFAULT_ANIMATION_DURATION
@@ -68,9 +96,7 @@
             }
             addListener(
                 object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator?) {
-                        textInterpolator.rebase()
-                    }
+                    override fun onAnimationEnd(animation: Animator?) = textInterpolator.rebase()
                     override fun onAnimationCancel(animation: Animator?) = textInterpolator.rebase()
                 }
             )
@@ -116,8 +142,6 @@
 
     private val fontVariationUtils = FontVariationUtils()
 
-    private val typefaceCache = LruCache<String, Typeface>(TYPEFACE_CACHE_MAX_ENTRIES)
-
     fun updateLayout(layout: Layout) {
         textInterpolator.layout = layout
     }
@@ -220,12 +244,8 @@
         }
 
         if (!fvar.isNullOrBlank()) {
-            textInterpolator.targetPaint.typeface = typefaceCache.get(fvar) ?: run {
-                textInterpolator.targetPaint.fontVariationSettings = fvar
-                textInterpolator.targetPaint.typeface?.also {
-                    typefaceCache.put(fvar, textInterpolator.targetPaint.typeface)
-                }
-            }
+            textInterpolator.targetPaint.typeface =
+                typefaceCache.getTypefaceForVariant(fvar, textInterpolator.targetPaint)
         }
 
         if (color != null) {
@@ -304,7 +324,8 @@
             weight = weight,
             width = width,
             opticalSize = opticalSize,
-            roundness = roundness,)
+            roundness = roundness,
+        )
         setTextStyle(
             fvar = fvar,
             textSize = textSize,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
index 23f16f2..79189bc 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
@@ -28,8 +28,10 @@
 import java.lang.Math.max
 
 /** Provide text style linear interpolation for plain text. */
-class TextInterpolator(layout: Layout) {
-
+class TextInterpolator(
+    layout: Layout,
+    var typefaceCache: TypefaceVariantCache,
+) {
     /**
      * Returns base paint used for interpolation.
      *
@@ -215,12 +217,14 @@
                 run.fontRuns.forEach { fontRun ->
                     fontRun.baseFont =
                         fontInterpolator.lerp(fontRun.baseFont, fontRun.targetFont, progress)
-                    val tmpFontVariationsArray = mutableListOf<FontVariationAxis>()
-                    fontRun.baseFont.axes.forEach {
-                        tmpFontVariationsArray.add(FontVariationAxis(it.tag, it.styleValue))
-                    }
-                    basePaint.fontVariationSettings =
+                    val fvar = run {
+                        val tmpFontVariationsArray = mutableListOf<FontVariationAxis>()
+                        fontRun.baseFont.axes.forEach {
+                            tmpFontVariationsArray.add(FontVariationAxis(it.tag, it.styleValue))
+                        }
                         FontVariationAxis.toFontVariationSettings(tmpFontVariationsArray)
+                    }
+                    basePaint.typeface = typefaceCache.getTypefaceForVariant(fvar, basePaint)
                 }
             }
         }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
index 9d1dd1b..3a19990 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
@@ -22,12 +22,11 @@
 import android.annotation.SuppressLint
 import android.content.Context
 import android.graphics.Canvas
-import android.graphics.Rect
 import android.text.Layout
 import android.text.TextUtils
 import android.text.format.DateFormat
 import android.util.AttributeSet
-import android.util.MathUtils
+import android.util.MathUtils.constrainedMap
 import android.widget.TextView
 import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.animation.GlyphCallback
@@ -40,8 +39,6 @@
 import java.util.Calendar
 import java.util.Locale
 import java.util.TimeZone
-import kotlin.math.max
-import kotlin.math.min
 
 /**
  * Displays the time with the hour positioned above the minutes. (ie: 09 above 30 is 9:30)
@@ -478,122 +475,56 @@
         pw.println("    time=$time")
     }
 
-    fun moveForSplitShade(fromRect: Rect, toRect: Rect, fraction: Float) {
-        // Do we need to cancel an in-flight animation?
-        // Need to also check against 0.0f here; we can sometimes get two calls with fraction == 0,
-        // which trips up the check otherwise.
-        if (lastSeenAnimationProgress != 1.0f &&
-                lastSeenAnimationProgress != 0.0f &&
-                fraction == 0.0f) {
-            // New animation, but need to stop the old one. Figure out where each glyph currently
-            // is in relation to the box position. After that, use the leading digit's current
-            // position as the stop target.
-            currentAnimationNeededStop = true
+    private val moveToCenterDelays
+        get() = if (isLayoutRtl) MOVE_LEFT_DELAYS else MOVE_RIGHT_DELAYS
 
-            // We assume that the current glyph offsets would be relative to the "from" position.
-            val moveAmount = toRect.left - fromRect.left
+    private val moveToSideDelays
+        get() = if (isLayoutRtl) MOVE_RIGHT_DELAYS else MOVE_LEFT_DELAYS
 
-            // Remap the current glyph offsets to be relative to the new "end" position, and figure
-            // out the start/end positions for the stop animation.
-            for (i in 0 until NUM_DIGITS) {
-                glyphOffsets[i] = -moveAmount + glyphOffsets[i]
-                animationCancelStartPosition[i] = glyphOffsets[i]
-            }
-
-            // Use the leading digit's offset as the stop position.
-            if (toRect.left > fromRect.left) {
-                // It _was_ moving left
-                animationCancelStopPosition = glyphOffsets[0]
-            } else {
-                // It was moving right
-                animationCancelStopPosition = glyphOffsets[1]
-            }
-        }
-
-        // Is there a cancellation in progress?
-        if (currentAnimationNeededStop && fraction < ANIMATION_CANCELLATION_TIME) {
-            val animationStopProgress = MathUtils.constrainedMap(
-                    0.0f, 1.0f, 0.0f, ANIMATION_CANCELLATION_TIME, fraction
-            )
-
-            // One of the digits has already stopped.
-            val animationStopStep = 1.0f / (NUM_DIGITS - 1)
-
-            for (i in 0 until NUM_DIGITS) {
-                val stopAmount = if (toRect.left > fromRect.left) {
-                    // It was moving left (before flipping)
-                    MOVE_LEFT_DELAYS[i] * animationStopStep
-                } else {
-                    // It was moving right (before flipping)
-                    MOVE_RIGHT_DELAYS[i] * animationStopStep
-                }
-
-                // Leading digit stops immediately.
-                if (stopAmount == 0.0f) {
-                    glyphOffsets[i] = animationCancelStopPosition
-                } else {
-                    val actualStopAmount = MathUtils.constrainedMap(
-                            0.0f, 1.0f, 0.0f, stopAmount, animationStopProgress
+    /**
+     * Offsets the glyphs of the clock for the step clock animation.
+     *
+     * The animation makes the glyphs of the clock move at different speeds, when the clock is
+     * moving horizontally.
+     *
+     * @param clockStartLeft the [getLeft] position of the clock, before it started moving.
+     * @param clockMoveDirection the direction in which it is moving. A positive number means right,
+     *   and negative means left.
+     * @param moveFraction fraction of the clock movement. 0 means it is at the beginning, and 1
+     *   means it finished moving.
+     */
+    fun offsetGlyphsForStepClockAnimation(
+            clockStartLeft: Int,
+            clockMoveDirection: Int,
+            moveFraction: Float
+    ) {
+        val isMovingToCenter = if (isLayoutRtl) clockMoveDirection < 0 else clockMoveDirection > 0
+        val currentMoveAmount = left - clockStartLeft
+        val digitOffsetDirection = if (isLayoutRtl) -1 else 1
+        for (i in 0 until NUM_DIGITS) {
+            // The delay for the digit, in terms of fraction (i.e. the digit should not move
+            // during 0.0 - 0.1).
+            val digitInitialDelay =
+                    if (isMovingToCenter) {
+                        moveToCenterDelays[i] * MOVE_DIGIT_STEP
+                    } else {
+                        moveToSideDelays[i] * MOVE_DIGIT_STEP
+                    }
+            val digitFraction =
+                    MOVE_INTERPOLATOR.getInterpolation(
+                            constrainedMap(
+                                    0.0f,
+                                    1.0f,
+                                    digitInitialDelay,
+                                    digitInitialDelay + AVAILABLE_ANIMATION_TIME,
+                                    moveFraction
+                            )
                     )
-                    val easedProgress = MOVE_INTERPOLATOR.getInterpolation(actualStopAmount)
-                    val glyphMoveAmount =
-                            animationCancelStopPosition - animationCancelStartPosition[i]
-                    glyphOffsets[i] =
-                            animationCancelStartPosition[i] + glyphMoveAmount * easedProgress
-                }
-            }
-        } else {
-            // Normal part of the animation.
-            // Do we need to remap the animation progress to take account of the cancellation?
-            val actualFraction = if (currentAnimationNeededStop) {
-                MathUtils.constrainedMap(
-                        0.0f, 1.0f, ANIMATION_CANCELLATION_TIME, 1.0f, fraction
-                )
-            } else {
-                fraction
-            }
-
-            val digitFractions = (0 until NUM_DIGITS).map {
-                // The delay for each digit, in terms of fraction (i.e. the digit should not move
-                // during 0.0 - 0.1).
-                val initialDelay = if (toRect.left > fromRect.left) {
-                    MOVE_RIGHT_DELAYS[it] * MOVE_DIGIT_STEP
-                } else {
-                    MOVE_LEFT_DELAYS[it] * MOVE_DIGIT_STEP
-                }
-
-                val f = MathUtils.constrainedMap(
-                        0.0f, 1.0f,
-                        initialDelay, initialDelay + AVAILABLE_ANIMATION_TIME,
-                        actualFraction
-                )
-                MOVE_INTERPOLATOR.getInterpolation(max(min(f, 1.0f), 0.0f))
-            }
-
-            // Was there an animation halt?
-            val moveAmount = if (currentAnimationNeededStop) {
-                // Only need to animate over the remaining space if the animation was aborted.
-                -animationCancelStopPosition
-            } else {
-                toRect.left.toFloat() - fromRect.left.toFloat()
-            }
-
-            for (i in 0 until NUM_DIGITS) {
-                glyphOffsets[i] = -moveAmount + (moveAmount * digitFractions[i])
-            }
+            val moveAmountForDigit = currentMoveAmount * digitFraction
+            val moveAmountDeltaForDigit = moveAmountForDigit - currentMoveAmount
+            glyphOffsets[i] = digitOffsetDirection * moveAmountDeltaForDigit
         }
-
         invalidate()
-
-        if (fraction == 1.0f) {
-            // Reset
-            currentAnimationNeededStop = false
-        }
-
-        lastSeenAnimationProgress = fraction
-
-        // Ensure that the actual clock container is always in the "end" position.
-        this.setLeftTopRightBottom(toRect.left, toRect.top, toRect.right, toRect.bottom)
     }
 
     // DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often.
@@ -647,9 +578,6 @@
         private const val NUM_DIGITS = 4
         private const val DIGITS_PER_LINE = 2
 
-        // How much of "fraction" to spend on canceling the animation, if needed
-        private const val ANIMATION_CANCELLATION_TIME = 0f
-
         // Delays. Each digit's animation should have a slight delay, so we get a nice
         // "stepping" effect. When moving right, the second digit of the hour should move first.
         // When moving left, the first digit of the hour should move first. The lists encode
@@ -668,6 +596,6 @@
 
         // Total available transition time for each digit, taking into account the step. If step is
         // 0.1, then digit 0 would animate over 0.0 - 0.7, making availableTime 0.7.
-        private val AVAILABLE_ANIMATION_TIME = 1.0f - MOVE_DIGIT_STEP * (NUM_DIGITS - 1)
+        private const val AVAILABLE_ANIMATION_TIME = 1.0f - MOVE_DIGIT_STEP * (NUM_DIGITS - 1)
     }
 }
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 34adcc7..b0c0240 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
@@ -151,6 +151,7 @@
                             { str1 = id },
                             { "Clock Id conflict on load: $str1 is double registered" }
                         )
+                        manager.unloadPlugin()
                         continue
                     }
 
@@ -403,12 +404,14 @@
         }
 
         scope.launch(bgDispatcher) {
+            Log.i(TAG, "verifyLoadedProviders: ${availableClocks.size}")
             if (keepAllLoaded) {
                 // Enforce that all plugins are loaded if requested
                 for ((_, info) in availableClocks) {
                     info.manager?.loadPlugin()
                 }
                 isVerifying.set(false)
+                Log.i(TAG, "verifyLoadedProviders: keepAllLoaded=true, load all")
                 return@launch
             }
 
@@ -419,16 +422,21 @@
                     info.manager?.unloadPlugin()
                 }
                 isVerifying.set(false)
+                Log.i(TAG, "verifyLoadedProviders: currentClock unavailable, unload all")
                 return@launch
             }
 
             val currentManager = currentClock.manager
             currentManager?.loadPlugin()
+            Log.i(TAG, "verifyLoadedProviders: load ${currentClock.metadata.clockId}")
 
             for ((_, info) in availableClocks) {
                 val manager = info.manager
                 if (manager != null && manager.isLoaded && currentManager != manager) {
+                    Log.i(TAG, "verifyLoadedProviders: unload ${info.metadata.clockId}")
                     manager.unloadPlugin()
+                } else {
+                    Log.i(TAG, "verifyLoadedProviders: skip unload of ${info.metadata.clockId}")
                 }
             }
             isVerifying.set(false)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index 3fda83d..2cc3600 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -189,8 +189,9 @@
             view.setLayoutParams(lp)
         }
 
-        fun moveForSplitShade(fromRect: Rect, toRect: Rect, fraction: Float) {
-            view.moveForSplitShade(fromRect, toRect, fraction)
+        /** See documentation at [AnimatableClockView.offsetGlyphsForStepClockAnimation]. */
+        fun offsetGlyphsForStepClockAnimation(fromLeft: Int, direction: Int, fraction: Float) {
+            view.offsetGlyphsForStepClockAnimation(fromLeft, direction, fraction)
         }
     }
 
@@ -277,8 +278,8 @@
         dozeFraction: Float,
         foldFraction: Float,
     ) : DefaultClockAnimations(view, dozeFraction, foldFraction) {
-        override fun onPositionUpdated(fromRect: Rect, toRect: Rect, fraction: Float) {
-            largeClock.moveForSplitShade(fromRect, toRect, fraction)
+        override fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float) {
+            largeClock.offsetGlyphsForStepClockAnimation(fromLeft, direction, fraction)
         }
     }
 
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardQuickAffordancePreviewConstants.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
similarity index 86%
rename from packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardQuickAffordancePreviewConstants.kt
rename to packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
index bf922bc..08ee602 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardQuickAffordancePreviewConstants.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
@@ -17,7 +17,9 @@
 
 package com.android.systemui.shared.quickaffordance.shared.model
 
-object KeyguardQuickAffordancePreviewConstants {
+object KeyguardPreviewConstants {
+    const val MESSAGE_ID_HIDE_SMART_SPACE = 1111
+    const val KEY_HIDE_SMART_SPACE = "hide_smart_space"
     const val MESSAGE_ID_SLOT_SELECTED = 1337
     const val KEY_SLOT_ID = "slot_id"
     const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id"
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/DynamicColor.java b/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/DynamicColor.java
index e6b2c2f..e839d9b 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/DynamicColor.java
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/DynamicColor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -71,12 +71,11 @@
      * The base constructor for DynamicColor.
      *
      * <p>Functional arguments allow overriding without risks that come with subclasses. _Strongly_
-     * prefer using one of the static convenience constructors. This class is arguably too flexible
-     * to
+     * prefer using one of the static convenience constructors. This class is arguably too
+     * flexible to
      * ensure it can support any scenario.
      *
-     * <p>For example, the default behavior of adjust tone at max contrast to be at a 7.0 ratio
-     * with
+     * <p>For example, the default behavior of adjust tone at max contrast to be at a 7.0 ratio with
      * its background is principled and matches a11y guidance. That does not mean it's the desired
      * approach for _every_ design system, and every color pairing, always, in every case.
      *
@@ -89,23 +88,23 @@
      *                            lower and raise contrast are
      *                            made.
      * @param toneMinContrast     given DynamicScheme, return tone in HCT/L* in L*a*b* this color
-     *                            should
-     *                            be at minimum contrast. See toneMinContrastDefault for the default
-     *                            behavior, and strongly
+     *                           should
+     *                            be at minimum contrast. See toneMinContrastDefault for the
+     *                            default behavior, and strongly
      *                            consider using it unless you have strong opinions on a11y. The
      *                            static constructors use it.
      * @param toneMaxContrast     given DynamicScheme, return tone in HCT/L* in L*a*b* this color
-     *                            should
-     *                            be at maximum contrast. See toneMaxContrastDefault for the default
-     *                            behavior, and strongly
+     *                           should
+     *                            be at maximum contrast. See toneMaxContrastDefault for the
+     *                            default behavior, and strongly
      *                            consider using it unless you have strong opinions on a11y. The
      *                            static constructors use it.
      * @param toneDeltaConstraint given DynamicScheme, return a ToneDeltaConstraint instance that
      *                            describes a requirement that this DynamicColor must always have
      *                            some difference in tone/L*
      *                            from another DynamicColor.<br>
-     *                            Unlikely to be useful unless a design system has some distortions
-     *                            where colors that don't
+     *                            Unlikely to be useful unless a design system has some
+     *                            distortions where colors that don't
      *                            have a background/foreground relationship must have _some_
      *                            difference in tone, yet, not
      *                            enough difference to create meaningful contrast.
@@ -164,8 +163,8 @@
      * <p>If the design system uses the same hex code on multiple backgrounds, define that in
      * multiple
      * DynamicColors so that the background is accurate for each one. If you define a DynamicColor
-     * with one background, and actually use it on another, DynamicColor can't guarantee contrast.
-     * For
+     * with one background, and actually use it on another, DynamicColor can't guarantee contrast
+     * . For
      * example, if you use a color on both black and white, increasing the contrast on one
      * necessarily
      * decreases contrast of the other.
@@ -195,8 +194,8 @@
      *                            for contrast, given a background, colors can adjust to
      *                            increase/decrease contrast.
      * @param toneDeltaConstraint Function that provides a ToneDeltaConstraint given DynamicScheme.
-     *                            Useful for ensuring lightness difference between colors that don't
-     *                            _require_ contrast or
+     *                            Useful for ensuring lightness difference between colors that
+     *                            don't _require_ contrast or
      *                            have a formal background/foreground relationship.
      */
     public static DynamicColor fromArgb(
@@ -212,17 +211,17 @@
      * Create a DynamicColor.
      *
      * @param palette Function that provides a TonalPalette given DynamicScheme. A TonalPalette is
-     *                defined by a hue and chroma, so this replaces the need to specify hue/chroma.
-     *                By providing
+     *                defined by a hue and chroma, so this replaces the need to specify
+     *                hue/chroma. By providing
      *                a tonal palette, when contrast adjustments are made, intended chroma can be
      *                preserved. For
      *                example, at T/L* 90, there is a significant limit to the amount of chroma.
      *                There is no
-     *                colorful red, a red that light is pink. By preserving the _intended_ chroma if
-     *                lightness
+     *                colorful red, a red that light is pink. By preserving the _intended_ chroma
+     *                if lightness
      *                lowers for contrast adjustments, the intended chroma is restored.
-     * @param tone    Function that provides a tone given DynamicScheme. (useful for dark vs. light
-     *                mode)
+     * @param tone    Function that provides a tone given DynamicScheme. (useful for dark vs.
+     *                light mode)
      */
     public static DynamicColor fromPalette(
             Function<DynamicScheme, TonalPalette> palette, Function<DynamicScheme, Double> tone) {
@@ -232,16 +231,16 @@
     /**
      * Create a DynamicColor.
      *
-     * @param palette    Function that provides a TonalPalette given DynamicScheme. A TonalPalette
-     *                   is
+     * @param palette    Function that provides a TonalPalette given DynamicScheme. A
+     *                   TonalPalette is
      *                   defined by a hue and chroma, so this replaces the need to specify
      *                   hue/chroma. By providing
-     *                   a tonal palette, when contrast adjustments are made, intended chroma can be
-     *                   preserved. For
-     *                   example, at T/L* 90, there is a significant limit to the amount of chroma.
-     *                   There is no
-     *                   colorful red, a red that light is pink. By preserving the _intended_ chroma
-     *                   if lightness
+     *                   a tonal palette, when contrast adjustments are made, intended chroma can
+     *                   be preserved. For
+     *                   example, at T/L* 90, there is a significant limit to the amount of
+     *                   chroma. There is no
+     *                   colorful red, a red that light is pink. By preserving the _intended_
+     *                   chroma if lightness
      *                   lowers for contrast adjustments, the intended chroma is restored.
      * @param tone       Function that provides a tone given DynamicScheme. (useful for dark vs.
      *                   light mode)
@@ -261,12 +260,12 @@
      *
      * @param palette             Function that provides a TonalPalette given DynamicScheme. A
      *                            TonalPalette is
-     *                            defined by a hue and chroma, so this replaces the need to specify
-     *                            hue/chroma. By providing
+     *                            defined by a hue and chroma, so this replaces the need to
+     *                            specify hue/chroma. By providing
      *                            a tonal palette, when contrast adjustments are made, intended
      *                            chroma can be preserved. For
-     *                            example, at T/L* 90, there is a significant limit to the amount of
-     *                            chroma. There is no
+     *                            example, at T/L* 90, there is a significant limit to the amount
+     *                            of chroma. There is no
      *                            colorful red, a red that light is pink. By preserving the
      *                            _intended_ chroma if lightness
      *                            lowers for contrast adjustments, the intended chroma is restored.
@@ -277,8 +276,8 @@
      *                            for contrast, given a background, colors can adjust to
      *                            increase/decrease contrast.
      * @param toneDeltaConstraint Function that provides a ToneDeltaConstraint given DynamicScheme.
-     *                            Useful for ensuring lightness difference between colors that don't
-     *                            _require_ contrast or
+     *                            Useful for ensuring lightness difference between colors that
+     *                            don't _require_ contrast or
      *                            have a formal background/foreground relationship.
      */
     public static DynamicColor fromPalette(
@@ -297,96 +296,6 @@
                 toneDeltaConstraint);
     }
 
-    /** Returns the ARGB (i.e. hex code) representation of the resolved color given scheme. */
-    public int getArgb(DynamicScheme scheme) {
-        final int argb = getHct(scheme).toInt();
-        if (opacity == null) {
-            return argb;
-        }
-        final double percentage = opacity.apply(scheme);
-        final int alpha = MathUtils.clampInt(0, 255, (int) Math.round(percentage * 255));
-        return (argb & 0x00ffffff) | (alpha << 24);
-    }
-
-    /** Returns the HCT representation of the resolved color given scheme. */
-    public Hct getHct(DynamicScheme scheme) {
-        final Hct cachedAnswer = hctCache.get(scheme);
-        if (cachedAnswer != null) {
-            return cachedAnswer;
-        }
-        // This is crucial for aesthetics: we aren't simply the taking the standard color
-        // and changing its tone for contrast. Rather, we find the tone for contrast, then
-        // use the specified chroma from the palette to construct a new color.
-        //
-        // For example, this enables colors with standard tone of T90, which has limited chroma, to
-        // "recover" intended chroma as contrast increases.
-        final Hct answer = Hct.from(hue.apply(scheme), chroma.apply(scheme), getTone(scheme));
-        // NOMUTANTS--trivial test with onerous dependency injection requirement.
-        if (hctCache.size() > 4) {
-            hctCache.clear();
-        }
-        // NOMUTANTS--trivial test with onerous dependency injection requirement.
-        hctCache.put(scheme, answer);
-        return answer;
-    }
-
-    /** Returns the tone in HCT, ranging from 0 to 100, of the resolved color given scheme. */
-    public double getTone(DynamicScheme scheme) {
-        double answer = tone.apply(scheme);
-
-        final boolean decreasingContrast = scheme.contrastLevel < 0.0;
-        if (scheme.contrastLevel != 0.0) {
-            final double startTone = tone.apply(scheme);
-            final double endTone =
-                    decreasingContrast ? toneMinContrast.apply(scheme) : toneMaxContrast.apply(
-                            scheme);
-            final double delta = (endTone - startTone) * Math.abs(scheme.contrastLevel);
-            answer = delta + startTone;
-        }
-
-        final DynamicColor bgDynamicColor = background == null ? null : background.apply(scheme);
-        double minRatio = Contrast.RATIO_MIN;
-        double maxRatio = Contrast.RATIO_MAX;
-        if (bgDynamicColor != null) {
-            final boolean bgHasBg =
-                    bgDynamicColor.background != null && bgDynamicColor.background.apply(scheme)
-                            != null;
-            final double standardRatio =
-                    Contrast.ratioOfTones(tone.apply(scheme), bgDynamicColor.tone.apply(scheme));
-            if (decreasingContrast) {
-                final double minContrastRatio =
-                        Contrast.ratioOfTones(
-                                toneMinContrast.apply(scheme),
-                                bgDynamicColor.toneMinContrast.apply(scheme));
-                minRatio = bgHasBg ? minContrastRatio : 1.0;
-                maxRatio = standardRatio;
-            } else {
-                final double maxContrastRatio =
-                        Contrast.ratioOfTones(
-                                toneMaxContrast.apply(scheme),
-                                bgDynamicColor.toneMaxContrast.apply(scheme));
-                minRatio = bgHasBg ? min(maxContrastRatio, standardRatio) : 1.0;
-                maxRatio = bgHasBg ? max(maxContrastRatio, standardRatio) : 21.0;
-            }
-        }
-
-        final double finalMinRatio = minRatio;
-        final double finalMaxRatio = maxRatio;
-        final double finalAnswer = answer;
-        answer =
-                calculateDynamicTone(
-                        scheme,
-                        this.tone,
-                        (dynamicColor) -> dynamicColor.getTone(scheme),
-                        (a, b) -> finalAnswer,
-                        (s) -> bgDynamicColor,
-                        toneDeltaConstraint,
-                        (s) -> finalMinRatio,
-                        (s) -> finalMaxRatio);
-
-        return answer;
-    }
-
     /**
      * The default algorithm for calculating the tone of a color at minimum contrast.<br>
      * If the original contrast ratio was >= 7.0, reach contrast 4.5.<br>
@@ -475,8 +384,8 @@
      * <p>It enforces important properties:<br>
      * #1. Desired contrast ratio is reached.<br>
      * As contrast increases from standard to max, the tones involved should always be at least the
-     * standard ratio. For example, if a button is T90, and button text is T0, and the button is T0
-     * at
+     * standard ratio. For example, if a button is T90, and button text is T0, and the button is
+     * T0 at
      * max contrast, the button text cannot simply linearly interpolate from T0 to T100, or at some
      * point they'll both be at the same tone.
      *
@@ -489,8 +398,7 @@
      *
      * <p>#3. Ensure tone delta with another color.<br>
      * In design systems, there may be colors that don't have a pure background/foreground
-     * relationship, but, do require different tones for visual differentiation.
-     * ToneDeltaConstraint
+     * relationship, but, do require different tones for visual differentiation. ToneDeltaConstraint
      * models this requirement, and DynamicColor enforces it.
      */
     public static double calculateDynamicTone(
@@ -596,13 +504,16 @@
         final boolean preferLighter = tonePrefersLightForeground(bgTone);
 
         if (preferLighter) {
-            // "Negligible difference" handles an edge case where the initial contrast ratio is high
+            // "Neglible difference" handles an edge case where the initial contrast ratio is high
             // (ex. 13.0), and the ratio passed to the function is that high ratio, and both the
-            // lighter and darker ratio fails to pass that ratio.
+            // lighter
+            // and darker ratio fails to pass that ratio.
             //
             // This was observed with Tonal Spot's On Primary Container turning black momentarily
-            // between high and max contrast in light mode. PC's standard tone was T90, OPC's was
-            // T10, it was light mode, and the contrast level was 0.6568521221032331.
+            // between
+            // high and max contrast in light mode. PC's standard tone was T90, OPC's was T10, it
+            // was
+            // light mode, and the contrast level was 0.6568521221032331.
             final boolean negligibleDifference =
                     Math.abs(lighterRatio - darkerRatio) < 0.1 && lighterRatio < ratio
                             && darkerRatio < ratio;
@@ -634,13 +545,109 @@
      * <p>T60 used as to create the smallest discontinuity possible when skipping down to T49 in
      * order
      * to ensure light foregrounds.
+     *
+     * <p>Since `tertiaryContainer` in dark monochrome scheme requires a tone of 60, it should
+     * not be
+     * adjusted. Therefore, 60 is excluded here.
      */
     public static boolean tonePrefersLightForeground(double tone) {
-        return Math.round(tone) <= 60;
+        return Math.round(tone) < 60;
     }
 
-    /** Tones less than ~T50 always permit white at 4.5 contrast. */
+    /**
+     * Tones less than ~T50 always permit white at 4.5 contrast.
+     */
     public static boolean toneAllowsLightForeground(double tone) {
         return Math.round(tone) <= 49;
     }
+
+    public int getArgb(DynamicScheme scheme) {
+        final int argb = getHct(scheme).toInt();
+        if (opacity == null) {
+            return argb;
+        }
+        final double percentage = opacity.apply(scheme);
+        final int alpha = MathUtils.clampInt(0, 255, (int) Math.round(percentage * 255));
+        return (argb & 0x00ffffff) | (alpha << 24);
+    }
+
+    public Hct getHct(DynamicScheme scheme) {
+        final Hct cachedAnswer = hctCache.get(scheme);
+        if (cachedAnswer != null) {
+            return cachedAnswer;
+        }
+        // This is crucial for aesthetics: we aren't simply the taking the standard color
+        // and changing its tone for contrast. Rather, we find the tone for contrast, then
+        // use the specified chroma from the palette to construct a new color.
+        //
+        // For example, this enables colors with standard tone of T90, which has limited chroma, to
+        // "recover" intended chroma as contrast increases.
+        final Hct answer = Hct.from(hue.apply(scheme), chroma.apply(scheme), getTone(scheme));
+        // NOMUTANTS--trivial test with onerous dependency injection requirement.
+        if (hctCache.size() > 4) {
+            hctCache.clear();
+        }
+        // NOMUTANTS--trivial test with onerous dependency injection requirement.
+        hctCache.put(scheme, answer);
+        return answer;
+    }
+
+    /**
+     * Returns the tone in HCT, ranging from 0 to 100, of the resolved color given scheme.
+     */
+    public double getTone(DynamicScheme scheme) {
+        double answer = tone.apply(scheme);
+
+        final boolean decreasingContrast = scheme.contrastLevel < 0.0;
+        if (scheme.contrastLevel != 0.0) {
+            final double startTone = tone.apply(scheme);
+            final double endTone =
+                    decreasingContrast ? toneMinContrast.apply(scheme) : toneMaxContrast.apply(
+                            scheme);
+            final double delta = (endTone - startTone) * Math.abs(scheme.contrastLevel);
+            answer = delta + startTone;
+        }
+
+        final DynamicColor bgDynamicColor = background == null ? null : background.apply(scheme);
+        double minRatio = Contrast.RATIO_MIN;
+        double maxRatio = Contrast.RATIO_MAX;
+        if (bgDynamicColor != null) {
+            final boolean bgHasBg =
+                    bgDynamicColor.background != null && bgDynamicColor.background.apply(scheme)
+                            != null;
+            final double standardRatio =
+                    Contrast.ratioOfTones(tone.apply(scheme), bgDynamicColor.tone.apply(scheme));
+            if (decreasingContrast) {
+                final double minContrastRatio =
+                        Contrast.ratioOfTones(
+                                toneMinContrast.apply(scheme),
+                                bgDynamicColor.toneMinContrast.apply(scheme));
+                minRatio = bgHasBg ? minContrastRatio : 1.0;
+                maxRatio = standardRatio;
+            } else {
+                final double maxContrastRatio =
+                        Contrast.ratioOfTones(
+                                toneMaxContrast.apply(scheme),
+                                bgDynamicColor.toneMaxContrast.apply(scheme));
+                minRatio = bgHasBg ? min(maxContrastRatio, standardRatio) : 1.0;
+                maxRatio = bgHasBg ? max(maxContrastRatio, standardRatio) : 21.0;
+            }
+        }
+
+        final double finalMinRatio = minRatio;
+        final double finalMaxRatio = maxRatio;
+        final double finalAnswer = answer;
+        answer =
+                calculateDynamicTone(
+                        scheme,
+                        this.tone,
+                        (dynamicColor) -> dynamicColor.getTone(scheme),
+                        (a, b) -> finalAnswer,
+                        (s) -> bgDynamicColor,
+                        toneDeltaConstraint,
+                        (s) -> finalMinRatio,
+                        (s) -> finalMaxRatio);
+
+        return answer;
+    }
 }
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java b/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java
index 5212e8e..21218a2 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java
@@ -22,7 +22,7 @@
 import com.android.systemui.monet.scheme.DynamicScheme;
 import com.android.systemui.monet.scheme.Variant;
 
-/** Named colors, otherwise known as tokens, or roles, in the Material Design system. */
+/** Named colors, otherwise known as tokens, or roles, in the Material Design system.*/
 // Prevent lint for Function.apply not being available on Android before API level 14 (4.0.1).
 // "AndroidJdkLibsChecker" for Function, "NewApi" for Function.apply().
 // A java_library Bazel rule with an Android constraint cannot skip these warnings without this
@@ -33,341 +33,54 @@
     private static final double CONTAINER_ACCENT_TONE_DELTA = 15.0;
 
 
-    private MaterialDynamicColors() {
+    public MaterialDynamicColors() {
     }
 
-    public static DynamicColor highestSurface(DynamicScheme s) {
-        return s.isDark ? surfaceBright : surfaceDim;
-    }
-
-    public static final DynamicColor background =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 98.0);
-
-    public static final DynamicColor onBackground =
-            DynamicColor.fromPalette(
-                    (s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0, (s) -> background);
-
-    public static final DynamicColor surface =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 98.0);
-
-    public static final DynamicColor surfaceInverse =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 30.0);
-
-    public static final DynamicColor surfaceBright =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 24.0 : 98.0);
-
-    public static final DynamicColor surfaceDim =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 87.0);
-
-    public static final DynamicColor surfaceSub2 =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 4.0 : 100.0);
-
-    public static final DynamicColor surfaceSub1 =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 96.0);
-
-    public static final DynamicColor surfaceContainer =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 12.0 : 94.0);
-
-    public static final DynamicColor surfaceAdd1 =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 17.0 : 92.0);
-
-    public static final DynamicColor surfaceAdd2 =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 22.0 : 90.0);
-
-    public static final DynamicColor onSurface =
-            DynamicColor.fromPalette(
-                    (s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0,
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor onSurfaceInverse =
-            DynamicColor.fromPalette(
-                    (s) -> s.neutralPalette, (s) -> s.isDark ? 20.0 : 95.0, (s) -> surfaceInverse);
-
-    public static final DynamicColor surfaceVariant =
-            DynamicColor.fromPalette((s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 90.0);
-
-    public static final DynamicColor onSurfaceVariant =
-            DynamicColor.fromPalette(
-                    (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 80.0 : 30.0,
-                    (s) -> surfaceVariant);
-
-    public static final DynamicColor outline =
-            DynamicColor.fromPalette(
-                    (s) -> s.neutralVariantPalette, (s) -> 50.0, (s) -> highestSurface(s));
-
-    public static final DynamicColor outlineVariant =
-            DynamicColor.fromPalette(
-                    (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 80.0,
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor primaryContainer =
-            DynamicColor.fromPalette(
-                    (s) -> s.primaryPalette,
-                    (s) -> {
-                        if (!isFidelity(s)) {
-                            return s.isDark ? 30.0 : 90.0;
-                        }
-                        return performAlbers(s.sourceColorHct, s);
-                    },
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor onPrimaryContainer =
-            DynamicColor.fromPalette(
-                    (s) -> s.primaryPalette,
-                    (s) -> {
-                        if (!isFidelity(s)) {
-                            return s.isDark ? 90.0 : 10.0;
-                        }
-                        return DynamicColor.contrastingTone(primaryContainer.tone.apply(s), 4.5);
-                    },
-                    (s) -> primaryContainer,
-                    null);
-
-    public static final DynamicColor primary =
-            DynamicColor.fromPalette(
-                    (s) -> s.primaryPalette,
-                    (s) -> s.isDark ? 80.0 : 40.0,
-                    (s) -> highestSurface(s),
-                    (s) ->
-                            new ToneDeltaConstraint(
-                                    CONTAINER_ACCENT_TONE_DELTA,
-                                    primaryContainer,
-                                    s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
-
-    public static final DynamicColor primaryInverse =
-            DynamicColor.fromPalette(
-                    (s) -> s.primaryPalette, (s) -> s.isDark ? 40.0 : 80.0, (s) -> surfaceInverse);
-
-    public static final DynamicColor onPrimary =
-            DynamicColor.fromPalette(
-                    (s) -> s.primaryPalette, (s) -> s.isDark ? 20.0 : 100.0, (s) -> primary);
-
-    public static final DynamicColor secondaryContainer =
-            DynamicColor.fromPalette(
-                    (s) -> s.secondaryPalette,
-                    (s) -> {
-                        final double initialTone = s.isDark ? 30.0 : 90.0;
-                        if (!isFidelity(s)) {
-                            return initialTone;
-                        }
-                        double answer =
-                                findDesiredChromaByTone(
-                                        s.secondaryPalette.getHue(),
-                                        s.secondaryPalette.getChroma(),
-                                        initialTone,
-                                        !s.isDark);
-                        answer = performAlbers(s.secondaryPalette.getHct(answer), s);
-                        return answer;
-                    },
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor onSecondaryContainer =
-            DynamicColor.fromPalette(
-                    (s) -> s.secondaryPalette,
-                    (s) -> {
-                        if (!isFidelity(s)) {
-                            return s.isDark ? 90.0 : 10.0;
-                        }
-                        return DynamicColor.contrastingTone(secondaryContainer.tone.apply(s), 4.5);
-                    },
-                    (s) -> secondaryContainer);
-
-    public static final DynamicColor secondary =
-            DynamicColor.fromPalette(
-                    (s) -> s.secondaryPalette,
-                    (s) -> s.isDark ? 80.0 : 40.0,
-                    (s) -> highestSurface(s),
-                    (s) ->
-                            new ToneDeltaConstraint(
-                                    CONTAINER_ACCENT_TONE_DELTA,
-                                    secondaryContainer,
-                                    s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
-
-    public static final DynamicColor onSecondary =
-            DynamicColor.fromPalette(
-                    (s) -> s.secondaryPalette, (s) -> s.isDark ? 20.0 : 100.0, (s) -> secondary);
-
-    public static final DynamicColor tertiaryContainer =
-            DynamicColor.fromPalette(
-                    (s) -> s.tertiaryPalette,
-                    (s) -> {
-                        if (!isFidelity(s)) {
-                            return s.isDark ? 30.0 : 90.0;
-                        }
-                        final double albersTone =
-                                performAlbers(s.tertiaryPalette.getHct(s.sourceColorHct.getTone()),
-                                        s);
-                        final Hct proposedHct = s.tertiaryPalette.getHct(albersTone);
-                        return DislikeAnalyzer.fixIfDisliked(proposedHct).getTone();
-                    },
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor onTertiaryContainer =
-            DynamicColor.fromPalette(
-                    (s) -> s.tertiaryPalette,
-                    (s) -> {
-                        if (!isFidelity(s)) {
-                            return s.isDark ? 90.0 : 10.0;
-                        }
-                        return DynamicColor.contrastingTone(tertiaryContainer.tone.apply(s), 4.5);
-                    },
-                    (s) -> tertiaryContainer);
-
-    public static final DynamicColor tertiary =
-            DynamicColor.fromPalette(
-                    (s) -> s.tertiaryPalette,
-                    (s) -> s.isDark ? 80.0 : 40.0,
-                    (s) -> highestSurface(s),
-                    (s) ->
-                            new ToneDeltaConstraint(
-                                    CONTAINER_ACCENT_TONE_DELTA,
-                                    tertiaryContainer,
-                                    s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
-
-    public static final DynamicColor onTertiary =
-            DynamicColor.fromPalette(
-                    (s) -> s.tertiaryPalette, (s) -> s.isDark ? 20.0 : 100.0, (s) -> tertiary);
-
-    public static final DynamicColor errorContainer =
-            DynamicColor.fromPalette(
-                    (s) -> s.errorPalette, (s) -> s.isDark ? 30.0 : 90.0, (s) -> highestSurface(s));
-
-    public static final DynamicColor onErrorContainer =
-            DynamicColor.fromPalette(
-                    (s) -> s.errorPalette, (s) -> s.isDark ? 90.0 : 10.0, (s) -> errorContainer);
-
-    public static final DynamicColor error =
-            DynamicColor.fromPalette(
-                    (s) -> s.errorPalette,
-                    (s) -> s.isDark ? 80.0 : 40.0,
-                    (s) -> highestSurface(s),
-                    (s) ->
-                            new ToneDeltaConstraint(
-                                    CONTAINER_ACCENT_TONE_DELTA,
-                                    errorContainer,
-                                    s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
-
-    public static final DynamicColor onError =
-            DynamicColor.fromPalette((s) -> s.errorPalette, (s) -> s.isDark ? 20.0 : 100.0,
-                    (s) -> error);
-
-    public static final DynamicColor primaryFixed =
-            DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> 90.0,
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor primaryFixedDarker =
-            DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> 80.0,
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor onPrimaryFixed =
-            DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> 10.0,
-                    (s) -> primaryFixedDarker);
-
-    public static final DynamicColor onPrimaryFixedVariant =
-            DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> 30.0,
-                    (s) -> primaryFixedDarker);
-
-    public static final DynamicColor secondaryFixed =
-            DynamicColor.fromPalette((s) -> s.secondaryPalette, (s) -> 90.0,
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor secondaryFixedDarker =
-            DynamicColor.fromPalette((s) -> s.secondaryPalette, (s) -> 80.0,
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor onSecondaryFixed =
-            DynamicColor.fromPalette((s) -> s.secondaryPalette, (s) -> 10.0,
-                    (s) -> secondaryFixedDarker);
-
-    public static final DynamicColor onSecondaryFixedVariant =
-            DynamicColor.fromPalette((s) -> s.secondaryPalette, (s) -> 30.0,
-                    (s) -> secondaryFixedDarker);
-
-    public static final DynamicColor tertiaryFixed =
-            DynamicColor.fromPalette((s) -> s.tertiaryPalette, (s) -> 90.0,
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor tertiaryFixedDarker =
-            DynamicColor.fromPalette((s) -> s.tertiaryPalette, (s) -> 80.0,
-                    (s) -> highestSurface(s));
-
-    public static final DynamicColor onTertiaryFixed =
-            DynamicColor.fromPalette((s) -> s.tertiaryPalette, (s) -> 10.0,
-                    (s) -> tertiaryFixedDarker);
-
-    public static final DynamicColor onTertiaryFixedVariant =
-            DynamicColor.fromPalette((s) -> s.tertiaryPalette, (s) -> 30.0,
-                    (s) -> tertiaryFixedDarker);
-
     /**
      * These colors were present in Android framework before Android U, and used by MDC controls.
      * They
      * should be avoided, if possible. It's unclear if they're used on multiple backgrounds, and if
-     * they are, they can't be adjusted for contrast.* For now, they will be set with no
-     * background,
+     * they are, they can't be adjusted for contrast.* For now, they will be set with no background,
      * and those won't adjust for contrast, avoiding issues.
      *
-     * <p>* For example, if the same color is on a white background _and_ black background, there's
-     * no
+     * <p>* For example, if the same color is on a white background _and_ black background,
+     * there's no
      * way to increase contrast with either without losing contrast with the other.
      */
     // colorControlActivated documented as colorAccent in M3 & GM3.
     // colorAccent documented as colorSecondary in M3 and colorPrimary in GM3.
     // Android used Material's Container as Primary/Secondary/Tertiary at launch.
     // Therefore, this is a duplicated version of Primary Container.
-    public static final DynamicColor controlActivated =
-            DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> s.isDark ? 30.0 : 90.0, null);
+    public static DynamicColor controlActivated() {
+        return DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> s.isDark ? 30.0 : 90.0, null);
+    }
 
-    // colorControlNormal documented as textColorSecondary in M3 & GM3.
-    // In Material, textColorSecondary points to onSurfaceVariant in the non-disabled state,
-    // which is Neutral Variant T30/80 in light/dark.
-    public static final DynamicColor controlNormal =
-            DynamicColor.fromPalette((s) -> s.neutralVariantPalette, (s) -> s.isDark ? 80.0 : 30.0);
+    // Compatibility Keys Colors for Android
+    public static DynamicColor primaryPaletteKeyColor() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette, (s) -> s.primaryPalette.getKeyColor().getTone());
+    }
 
-    // colorControlHighlight documented, in both M3 & GM3:
-    // Light mode: #1f000000 dark mode: #33ffffff.
-    // These are black and white with some alpha.
-    // 1F hex = 31 decimal; 31 / 255 = 12% alpha.
-    // 33 hex = 51 decimal; 51 / 255 = 20% alpha.
-    // DynamicColors do not support alpha currently, and _may_ not need it for this use case,
-    // depending on how MDC resolved alpha for the other cases.
-    // Returning black in dark mode, white in light mode.
-    public static final DynamicColor controlHighlight =
-            new DynamicColor(
-                    s -> 0.0,
-                    s -> 0.0,
-                    s -> s.isDark ? 100.0 : 0.0,
-                    s -> s.isDark ? 0.20 : 0.12,
-                    null,
-                    scheme ->
-                            DynamicColor.toneMinContrastDefault(
-                                    (s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
-                    scheme ->
-                            DynamicColor.toneMaxContrastDefault(
-                                    (s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
-                    null);
+    public static DynamicColor secondaryPaletteKeyColor() {
+        return DynamicColor.fromPalette(
+                (s) -> s.secondaryPalette, (s) -> s.secondaryPalette.getKeyColor().getTone());
+    }
 
-    // textColorPrimaryInverse documented, in both M3 & GM3, documented as N10/N90.
-    public static final DynamicColor textPrimaryInverse =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
+    public static DynamicColor tertiaryPaletteKeyColor() {
+        return DynamicColor.fromPalette(
+                (s) -> s.tertiaryPalette, (s) -> s.tertiaryPalette.getKeyColor().getTone());
+    }
 
-    // textColorSecondaryInverse and textColorTertiaryInverse both documented, in both M3 & GM3, as
-    // NV30/NV80
-    public static final DynamicColor textSecondaryAndTertiaryInverse =
-            DynamicColor.fromPalette((s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 80.0);
+    public static DynamicColor neutralPaletteKeyColor() {
+        return DynamicColor.fromPalette(
+                (s) -> s.neutralPalette, (s) -> s.neutralPalette.getKeyColor().getTone());
+    }
 
-    // textColorPrimaryInverseDisableOnly documented, in both M3 & GM3, as N10/N90
-    public static final DynamicColor textPrimaryInverseDisableOnly =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
-
-    // textColorSecondaryInverse and textColorTertiaryInverse in disabled state both documented,
-    // in both M3 & GM3, as N10/N90
-    public static final DynamicColor textSecondaryAndTertiaryInverseDisabled =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
-
-    // textColorHintInverse documented, in both M3 & GM3, as N10/N90
-    public static final DynamicColor textHintInverse =
-            DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
+    public static DynamicColor neutralVariantPaletteKeyColor() {
+        return DynamicColor.fromPalette(
+                (s) -> s.neutralVariantPalette,
+                (s) -> s.neutralVariantPalette.getKeyColor().getTone());
+    }
 
     private static ViewingConditions viewingConditionsForAlbers(DynamicScheme scheme) {
         return ViewingConditions.defaultWithBackgroundLstar(scheme.isDark ? 30.0 : 80.0);
@@ -377,6 +90,10 @@
         return scheme.variant == Variant.FIDELITY || scheme.variant == Variant.CONTENT;
     }
 
+    private static boolean isMonochrome(DynamicScheme scheme) {
+        return scheme.variant == Variant.MONOCHROME;
+    }
+
     static double findDesiredChromaByTone(
             double hue, double chroma, double tone, boolean byDecreasingTone) {
         double answer = tone;
@@ -416,34 +133,456 @@
         }
     }
 
-    // Compatibility mappings for Android
-    public static final DynamicColor surfaceContainerLow = surfaceSub1;
-    public static final DynamicColor surfaceContainerLowest = surfaceSub2;
-    public static final DynamicColor surfaceContainerHigh = surfaceAdd1;
-    public static final DynamicColor surfaceContainerHighest = surfaceAdd2;
-    public static final DynamicColor primaryFixedDim = primaryFixedDarker;
-    public static final DynamicColor secondaryFixedDim = secondaryFixedDarker;
-    public static final DynamicColor tertiaryFixedDim = tertiaryFixedDarker;
+    public static DynamicColor highestSurface(DynamicScheme s) {
+        return s.isDark ? surfaceBright() : surfaceDim();
+    }
 
-    // Compatibility Keys Colors for Android
-    public static final DynamicColor primaryPaletteKeyColor =
-            DynamicColor.fromPalette(
-                    (s) -> s.primaryPalette, (s) -> s.primaryPalette.getKeyColor().getTone());
+    public static DynamicColor background() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 98.0);
+    }
 
-    public static final DynamicColor secondaryPaletteKeyColor =
-            DynamicColor.fromPalette(
-                    (s) -> s.secondaryPalette, (s) -> s.secondaryPalette.getKeyColor().getTone());
+    public static DynamicColor onBackground() {
+        return DynamicColor.fromPalette(
+                (s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0, (s) -> background());
+    }
 
-    public static final DynamicColor tertiaryPaletteKeyColor =
-            DynamicColor.fromPalette(
-                    (s) -> s.tertiaryPalette, (s) -> s.tertiaryPalette.getKeyColor().getTone());
+    public static DynamicColor surface() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 98.0);
+    }
 
-    public static final DynamicColor neutralPaletteKeyColor =
-            DynamicColor.fromPalette(
-                    (s) -> s.neutralPalette, (s) -> s.neutralPalette.getKeyColor().getTone());
+    public static DynamicColor inverseSurface() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 20.0);
+    }
 
-    public static final DynamicColor neutralVariantPaletteKeyColor =
-            DynamicColor.fromPalette(
-                    (s) -> s.neutralVariantPalette,
-                    (s) -> s.neutralVariantPalette.getKeyColor().getTone());
+    public static DynamicColor surfaceBright() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 24.0 : 98.0);
+    }
+
+    public static DynamicColor surfaceDim() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 87.0);
+    }
+
+    public static DynamicColor surfaceContainerLowest() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 4.0 : 100.0);
+    }
+
+    public static DynamicColor surfaceContainerLow() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 96.0);
+    }
+
+    public static DynamicColor surfaceContainer() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 12.0 : 94.0);
+    }
+
+    public static DynamicColor surfaceContainerHigh() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 17.0 : 92.0);
+    }
+
+    public static DynamicColor surfaceContainerHighest() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 22.0 : 90.0);
+    }
+
+    public static DynamicColor onSurface() {
+        return DynamicColor.fromPalette(
+                (s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0,
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor inverseOnSurface() {
+        return DynamicColor.fromPalette(
+                (s) -> s.neutralPalette, (s) -> s.isDark ? 20.0 : 95.0, (s) -> inverseSurface());
+    }
+
+    public static DynamicColor surfaceVariant() {
+        return DynamicColor.fromPalette((s) -> s.neutralVariantPalette,
+                (s) -> s.isDark ? 30.0 : 90.0);
+    }
+
+    public static DynamicColor onSurfaceVariant() {
+        return DynamicColor.fromPalette(
+                (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 80.0 : 30.0,
+                (s) -> surfaceVariant());
+    }
+
+    public static DynamicColor outline() {
+        return DynamicColor.fromPalette(
+                (s) -> s.neutralVariantPalette, (s) -> 50.0, MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor outlineVariant() {
+        return DynamicColor.fromPalette(
+                (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 80.0,
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor primaryContainer() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette,
+                (s) -> {
+                    if (isFidelity(s)) {
+                        return performAlbers(s.sourceColorHct, s);
+                    }
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 85.0 : 25.0;
+                    }
+                    return s.isDark ? 30.0 : 90.0;
+                },
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor onPrimaryContainer() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette,
+                (s) -> {
+                    if (isFidelity(s)) {
+                        return DynamicColor.contrastingTone(primaryContainer().tone.apply(s), 4.5);
+                    }
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 0.0 : 100.0;
+                    }
+                    return s.isDark ? 90.0 : 10.0;
+                },
+                (s) -> primaryContainer(),
+                null);
+    }
+
+    public static DynamicColor primary() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 100.0 : 0.0;
+                    }
+                    return s.isDark ? 80.0 : 40.0;
+                },
+                MaterialDynamicColors::highestSurface,
+                (s) ->
+                        new ToneDeltaConstraint(
+                                CONTAINER_ACCENT_TONE_DELTA,
+                                primaryContainer(),
+                                s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
+    }
+
+    public static DynamicColor inversePrimary() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette, (s) -> s.isDark ? 40.0 : 80.0, (s) -> inverseSurface());
+    }
+
+    public static DynamicColor onPrimary() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 10.0 : 90.0;
+                    }
+                    return s.isDark ? 20.0 : 100.0;
+                },
+                (s) -> primary());
+    }
+
+    public static DynamicColor secondaryContainer() {
+        return DynamicColor.fromPalette(
+                (s) -> s.secondaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 30.0 : 85.0;
+                    }
+                    final double initialTone = s.isDark ? 30.0 : 90.0;
+                    if (!isFidelity(s)) {
+                        return initialTone;
+                    }
+                    double answer =
+                            findDesiredChromaByTone(
+                                    s.secondaryPalette.getHue(),
+                                    s.secondaryPalette.getChroma(),
+                                    initialTone,
+                                    !s.isDark);
+                    answer = performAlbers(s.secondaryPalette.getHct(answer), s);
+                    return answer;
+                },
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor onSecondaryContainer() {
+        return DynamicColor.fromPalette(
+                (s) -> s.secondaryPalette,
+                (s) -> {
+                    if (!isFidelity(s)) {
+                        return s.isDark ? 90.0 : 10.0;
+                    }
+                    return DynamicColor.contrastingTone(secondaryContainer().tone.apply(s), 4.5);
+                },
+                (s) -> secondaryContainer());
+    }
+
+    public static DynamicColor secondary() {
+        return DynamicColor.fromPalette(
+                (s) -> s.secondaryPalette,
+                (s) -> s.isDark ? 80.0 : 40.0,
+                MaterialDynamicColors::highestSurface,
+                (s) ->
+                        new ToneDeltaConstraint(
+                                CONTAINER_ACCENT_TONE_DELTA,
+                                secondaryContainer(),
+                                s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
+    }
+
+    public static DynamicColor onSecondary() {
+        return DynamicColor.fromPalette(
+                (s) -> s.secondaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 10.0 : 100.0;
+                    }
+                    return s.isDark ? 20.0 : 100.0;
+                },
+                (s) -> secondary());
+    }
+
+    public static DynamicColor tertiaryContainer() {
+        return DynamicColor.fromPalette(
+                (s) -> s.tertiaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 60.0 : 49.0;
+                    }
+                    if (!isFidelity(s)) {
+                        return s.isDark ? 30.0 : 90.0;
+                    }
+                    final double albersTone =
+                            performAlbers(s.tertiaryPalette.getHct(s.sourceColorHct.getTone()), s);
+                    final Hct proposedHct = s.tertiaryPalette.getHct(albersTone);
+                    return DislikeAnalyzer.fixIfDisliked(proposedHct).getTone();
+                },
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor onTertiaryContainer() {
+        return DynamicColor.fromPalette(
+                (s) -> s.tertiaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 0.0 : 100.0;
+                    }
+                    if (!isFidelity(s)) {
+                        return s.isDark ? 90.0 : 10.0;
+                    }
+                    return DynamicColor.contrastingTone(tertiaryContainer().tone.apply(s), 4.5);
+                },
+                (s) -> tertiaryContainer());
+    }
+
+    public static DynamicColor tertiary() {
+        return DynamicColor.fromPalette(
+                (s) -> s.tertiaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 90.0 : 25.0;
+                    }
+                    return s.isDark ? 80.0 : 40.0;
+                },
+                MaterialDynamicColors::highestSurface,
+                (s) ->
+                        new ToneDeltaConstraint(
+                                CONTAINER_ACCENT_TONE_DELTA,
+                                tertiaryContainer(),
+                                s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
+    }
+
+    public static DynamicColor onTertiary() {
+        return DynamicColor.fromPalette(
+                (s) -> s.tertiaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 10.0 : 90.0;
+                    }
+                    return s.isDark ? 20.0 : 100.0;
+                },
+                (s) -> tertiary());
+    }
+
+    public static DynamicColor errorContainer() {
+        return DynamicColor.fromPalette(
+                (s) -> s.errorPalette, (s) -> s.isDark ? 30.0 : 90.0,
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor onErrorContainer() {
+        return DynamicColor.fromPalette(
+                (s) -> s.errorPalette, (s) -> s.isDark ? 90.0 : 10.0, (s) -> errorContainer());
+    }
+
+    public static DynamicColor error() {
+        return DynamicColor.fromPalette(
+                (s) -> s.errorPalette,
+                (s) -> s.isDark ? 80.0 : 40.0,
+                MaterialDynamicColors::highestSurface,
+                (s) ->
+                        new ToneDeltaConstraint(
+                                CONTAINER_ACCENT_TONE_DELTA,
+                                errorContainer(),
+                                s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
+    }
+
+    public static DynamicColor onError() {
+        return DynamicColor.fromPalette(
+                (s) -> s.errorPalette, (s) -> s.isDark ? 20.0 : 100.0, (s) -> error());
+    }
+
+    public static DynamicColor primaryFixed() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 100.0 : 10.0;
+                    }
+                    return 90.0;
+                },
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor primaryFixedDim() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 90.0 : 20.0;
+                    }
+                    return 80.0;
+                },
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor onPrimaryFixed() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 10.0 : 90.0;
+                    }
+                    return 10.0;
+                },
+                (s) -> primaryFixedDim());
+    }
+
+    public static DynamicColor onPrimaryFixedVariant() {
+        return DynamicColor.fromPalette(
+                (s) -> s.primaryPalette,
+                (s) -> {
+                    if (isMonochrome(s)) {
+                        return s.isDark ? 30.0 : 70.0;
+                    }
+                    return 30.0;
+                },
+                (s) -> primaryFixedDim());
+    }
+
+    public static DynamicColor secondaryFixed() {
+        return DynamicColor.fromPalette(
+                (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 80.0 : 90.0,
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor secondaryFixedDim() {
+        return DynamicColor.fromPalette(
+                (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 70.0 : 80.0,
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor onSecondaryFixed() {
+        return DynamicColor.fromPalette(
+                (s) -> s.secondaryPalette, (s) -> 10.0, (s) -> secondaryFixedDim());
+    }
+
+    public static DynamicColor onSecondaryFixedVariant() {
+        return DynamicColor.fromPalette(
+                (s) -> s.secondaryPalette,
+                (s) -> isMonochrome(s) ? 25.0 : 30.0,
+                (s) -> secondaryFixedDim());
+    }
+
+    public static DynamicColor tertiaryFixed() {
+        return DynamicColor.fromPalette(
+                (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 40.0 : 90.0,
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor tertiaryFixedDim() {
+        return DynamicColor.fromPalette(
+                (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 30.0 : 80.0,
+                MaterialDynamicColors::highestSurface);
+    }
+
+    public static DynamicColor onTertiaryFixed() {
+        return DynamicColor.fromPalette(
+                (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 90.0 : 10.0,
+                (s) -> tertiaryFixedDim());
+    }
+
+    public static DynamicColor onTertiaryFixedVariant() {
+        return DynamicColor.fromPalette(
+                (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 70.0 : 30.0,
+                (s) -> tertiaryFixedDim());
+    }
+
+    // colorControlNormal documented as textColorSecondary in M3 & GM3.
+    // In Material, textColorSecondary points to onSurfaceVariant in the non-disabled state,
+    // which is Neutral Variant T30/80 in light/dark.
+    public static DynamicColor controlNormal() {
+        return DynamicColor.fromPalette((s) -> s.neutralVariantPalette,
+                (s) -> s.isDark ? 80.0 : 30.0);
+    }
+
+    // colorControlHighlight documented, in both M3 & GM3:
+    // Light mode: #1f000000 dark mode: #33ffffff.
+    // These are black and white with some alpha.
+    // 1F hex = 31 decimal; 31 / 255 = 12% alpha.
+    // 33 hex = 51 decimal; 51 / 255 = 20% alpha.
+    // DynamicColors do not support alpha currently, and _may_ not need it for this use case,
+    // depending on how MDC resolved alpha for the other cases.
+    // Returning black in dark mode, white in light mode.
+    public static DynamicColor controlHighlight() {
+        return new DynamicColor(
+                s -> 0.0,
+                s -> 0.0,
+                s -> s.isDark ? 100.0 : 0.0,
+                s -> s.isDark ? 0.20 : 0.12,
+                null,
+                scheme ->
+
+                        DynamicColor.toneMinContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null,
+                                scheme, null),
+                scheme ->
+                        DynamicColor.toneMaxContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null,
+                                scheme, null),
+                null);
+    }
+
+    // textColorPrimaryInverse documented, in both M3 & GM3, documented as N10/N90.
+    public static DynamicColor textPrimaryInverse() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
+    }
+
+    // textColorSecondaryInverse and textColorTertiaryInverse both documented, in both M3 & GM3, as
+    // NV30/NV80
+    public static DynamicColor textSecondaryAndTertiaryInverse() {
+        return DynamicColor.fromPalette((s) -> s.neutralVariantPalette,
+                (s) -> s.isDark ? 30.0 : 80.0);
+    }
+
+    // textColorPrimaryInverseDisableOnly documented, in both M3 & GM3, as N10/N90
+    public static DynamicColor textPrimaryInverseDisableOnly() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
+    }
+
+    // textColorSecondaryInverse and textColorTertiaryInverse in disabled state both documented,
+    // in both M3 & GM3, as N10/N90
+    public static DynamicColor textSecondaryAndTertiaryInverseDisabled() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
+    }
+
+    // textColorHintInverse documented, in both M3 & GM3, as N10/N90
+    public static DynamicColor textHintInverse() {
+        return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
+    }
 }
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/scheme/SchemeTonalSpot.java b/packages/SystemUI/monet/src/com/android/systemui/monet/scheme/SchemeTonalSpot.java
index 8480684..cc6b492 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/scheme/SchemeTonalSpot.java
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/scheme/SchemeTonalSpot.java
@@ -32,7 +32,7 @@
                 TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 16.0),
                 TonalPalette.fromHueAndChroma(
                         MathUtils.sanitizeDegreesDouble(sourceColorHct.getHue() + 60.0), 24.0),
-                TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 4.0),
+                TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 6.0),
                 TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 8.0));
     }
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index 6d4dbf6..33c7c11 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -102,6 +102,33 @@
     void dismissKeyguardThenExecute(OnDismissAction action, @Nullable Runnable cancel,
             boolean afterKeyguardGone, @Nullable String customMessage);
 
+    /** Starts an activity and dismisses keyguard. */
+    void startActivityDismissingKeyguard(Intent intent,
+            boolean onlyProvisioned,
+            boolean dismissShade,
+            boolean disallowEnterPictureInPictureWhileLaunching,
+            Callback callback,
+            int flags,
+            @Nullable ActivityLaunchAnimator.Controller animationController,
+            UserHandle userHandle);
+
+    /** Execute a runnable after dismissing keyguard. */
+    void executeRunnableDismissingKeyguard(Runnable runnable,
+            Runnable cancelAction,
+            boolean dismissShade,
+            boolean afterKeyguardGone,
+            boolean deferred);
+
+    /** Execute a runnable after dismissing keyguard. */
+    void executeRunnableDismissingKeyguard(
+            Runnable runnable,
+            Runnable cancelAction,
+            boolean dismissShade,
+            boolean afterKeyguardGone,
+            boolean deferred,
+            boolean willAnimateOnKeyguard,
+            @Nullable String customMessage);
+
     interface Callback {
         void onActivityStarted(int resultCode);
     }
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 8ef2d80..ca3e710 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -141,8 +141,16 @@
     /** Runs the battery animation (if any). */
     fun charge() {}
 
-    /** Move the clock, for example, if the notification tray appears in split-shade mode. */
-    fun onPositionUpdated(fromRect: Rect, toRect: Rect, fraction: Float) {}
+    /**
+     * Runs when the clock's position changed during the move animation.
+     *
+     * @param fromLeft the [View.getLeft] position of the clock, before it started moving.
+     * @param direction the direction in which it is moving. A positive number means right, and
+     *   negative means left.
+     * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
+     *   it finished moving.
+     */
+    fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float) {}
 
     /**
      * Runs when swiping clock picker, swipingFraction: 1.0 -> clock is scaled up in the preview,
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
index 436145e..3244eb4 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
@@ -131,7 +131,8 @@
     /**
      * A rounded corner clipping that makes QS feel as if it were behind everything.
      */
-    void setFancyClipping(int top, int bottom, int cornerRadius, boolean visible);
+    void setFancyClipping(int leftInset, int top, int rightInset, int bottom, int cornerRadius,
+            boolean visible, boolean fullWidth);
 
     /**
      * @return if quick settings is fully collapsed currently
diff --git a/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml b/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
index 08c66a2..47641ee 100644
--- a/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
+++ b/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <item android:color="?androidprv:attr/colorAccentSecondaryVariant"/>
+    <item android:color="?androidprv:attr/materialColorSecondaryFixedDim"/>
 </selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
index 0764273..5e7cf3e 100644
--- a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
+++ b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
@@ -19,7 +19,7 @@
     android:color="?attr/wallpaperTextColorSecondary">
     <item android:id="@android:id/background">
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/colorAccentTertiary"/>
+            <solid android:color="?androidprv:attr/materialColorTertiaryFixed"/>
             <corners android:radius="24dp"/>
         </shape>
     </item>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
index 67fd5b9..83736e9 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
@@ -19,6 +19,7 @@
 
 <!-- This contains disable eSim buttons shared by sim_pin/sim_puk screens -->
 <com.android.keyguard.KeyguardEsimArea xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/keyguard_disable_esim"
     style="@style/Keyguard.TextView"
     android:layout_width="wrap_content"
@@ -26,8 +27,8 @@
     android:background="@drawable/kg_bouncer_secondary_button"
     android:drawablePadding="10dp"
     android:drawableStart="@drawable/ic_no_sim"
-    android:drawableTint="?android:attr/textColorPrimary"
+    android:drawableTint="?androidprv:attr/materialColorOnSurface"
     android:text="@string/disable_carrier_button_text"
-    android:textColor="?android:attr/textColorPrimary"
+    android:textColor="?androidprv:attr/materialColorOnSurface"
     android:textSize="@dimen/kg_status_line_font_size"
     android:visibility="gone" />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
index 426cfaf..751b07a 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
@@ -19,13 +19,14 @@
 
 <com.android.keyguard.KeyguardSecurityContainer
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/keyguard_security_container"
+    android:background="?androidprv:attr/materialColorSurfaceContainer"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:paddingTop="@dimen/keyguard_lock_padding"
+    android:paddingTop="@dimen/status_bar_height"
     android:importantForAccessibility="yes"> <!-- Needed because TYPE_WINDOW_STATE_CHANGED is sent
                                                   from this view when bouncer is shown -->
     <com.android.keyguard.KeyguardSecurityViewFlipper
diff --git a/packages/SystemUI/res-keyguard/layout/status_bar_mobile_signal_group_inner.xml b/packages/SystemUI/res-keyguard/layout/status_bar_mobile_signal_group_inner.xml
index 29832a0..934fa6f 100644
--- a/packages/SystemUI/res-keyguard/layout/status_bar_mobile_signal_group_inner.xml
+++ b/packages/SystemUI/res-keyguard/layout/status_bar_mobile_signal_group_inner.xml
@@ -30,7 +30,7 @@
 
         <FrameLayout
             android:id="@+id/inout_container"
-            android:layout_height="17dp"
+            android:layout_height="@*android:dimen/status_bar_system_icon_intrinsic_size"
             android:layout_width="wrap_content"
             android:layout_gravity="center_vertical">
             <ImageView
@@ -39,24 +39,25 @@
                 android:layout_width="wrap_content"
                 android:src="@drawable/ic_activity_down"
                 android:visibility="gone"
-                android:paddingEnd="2dp"
+                android:paddingEnd="2sp"
                 />
             <ImageView
                 android:id="@+id/mobile_out"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 android:src="@drawable/ic_activity_up"
-                android:paddingEnd="2dp"
+                android:paddingEnd="2sp"
                 android:visibility="gone"
                 />
         </FrameLayout>
         <ImageView
             android:id="@+id/mobile_type"
-            android:layout_height="wrap_content"
+            android:layout_height="@dimen/status_bar_mobile_signal_size"
             android:layout_width="wrap_content"
             android:layout_gravity="center_vertical"
-            android:paddingStart="2.5dp"
-            android:paddingEnd="1dp"
+            android:adjustViewBounds="true"
+            android:paddingStart="2.5sp"
+            android:paddingEnd="1sp"
             android:visibility="gone" />
         <Space
             android:id="@+id/mobile_roaming_space"
@@ -70,14 +71,14 @@
             android:layout_gravity="center_vertical">
             <com.android.systemui.statusbar.AnimatedImageView
                 android:id="@+id/mobile_signal"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
+                android:layout_height="@dimen/status_bar_mobile_signal_size"
+                android:layout_width="@dimen/status_bar_mobile_signal_size"
                 systemui:hasOverlappingRendering="false"
                 />
             <ImageView
                 android:id="@+id/mobile_roaming"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
+                android:layout_width="@dimen/status_bar_mobile_signal_size"
+                android:layout_height="@dimen/status_bar_mobile_signal_size"
                 android:src="@drawable/stat_sys_roaming"
                 android:contentDescription="@string/data_connection_roaming"
                 android:visibility="gone" />
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index 686891f..5ecf15a 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -31,8 +31,8 @@
     <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • বেতাঁৰৰ জৰিয়তে চাৰ্জ কৰি থকা হৈছে"</string>
     <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চাৰ্জ কৰি থকা হৈছে"</string>
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চ্চার্জ কৰি থকা হৈছে"</string>
-    <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্ৰুত গতিৰে চ্চাৰ্জ কৰি থকা হৈছে"</string>
-    <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • লাহে লাহে চ্চাৰ্জ কৰি থকা হৈছে"</string>
+    <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্ৰুত গতিৰে চাৰ্জ কৰি থকা হৈছে"</string>
+    <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • লাহে লাহে চাৰ্জ কৰি থকা হৈছে"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • বেটাৰী সুৰক্ষিত কৰিবলৈ চাৰ্জিং অপ্টিমাইজ কৰা হৈছে"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চাৰ্জিঙৰ আনুষংগিক সামগ্ৰীত সমস্যা হৈছে"</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক কৰিবলৈ মেনু টিপক।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index 6e2dd24..fb18f1a 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -27,7 +27,7 @@
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Unesite lozinku"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"Unesite lozinku"</string>
     <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Nevažeća kartica."</string>
-    <string name="keyguard_charged" msgid="5478247181205188995">"Napunjena je"</string>
+    <string name="keyguard_charged" msgid="5478247181205188995">"Napunjeno"</string>
     <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bežično punjenje"</string>
     <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Puni se"</string>
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Puni se"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index 42965f6..da1c52b 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -124,5 +124,5 @@
     <string name="clock_title_default" msgid="6342735240617459864">"Стандартен"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Балонен"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Аналогов"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Отключете устройството си, за да продължите"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Отключете устройството, за да продължите"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 4e168e4..05fcced 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -21,14 +21,11 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Gib deine PIN ein"</string>
-    <!-- no translation found for keyguard_enter_pin (8114529922480276834) -->
-    <skip />
+    <string name="keyguard_enter_pin" msgid="8114529922480276834">"Gib die PIN ein"</string>
     <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Muster eingeben"</string>
-    <!-- no translation found for keyguard_enter_pattern (7616595160901084119) -->
-    <skip />
+    <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Zeichne das Muster"</string>
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Passwort eingeben"</string>
-    <!-- no translation found for keyguard_enter_password (6483623792371009758) -->
-    <skip />
+    <string name="keyguard_enter_password" msgid="6483623792371009758">"Gib das Passwort ein"</string>
     <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Ungültige Karte."</string>
     <string name="keyguard_charged" msgid="5478247181205188995">"Aufgeladen"</string>
     <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kabelloses Laden"</string>
@@ -58,68 +55,38 @@
     <string name="error_disable_esim_msg" msgid="2441188596467999327">"Die eSim kann aufgrund eines Fehlers nicht deaktiviert werden."</string>
     <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Eingabe"</string>
     <string name="kg_wrong_pattern" msgid="5907301342430102842">"Falsches Muster"</string>
-    <!-- no translation found for kg_wrong_pattern_try_again (3603524940234151881) -->
-    <skip />
+    <string name="kg_wrong_pattern_try_again" msgid="3603524940234151881">"Muster ist falsch. Versuche es noch einmal."</string>
     <string name="kg_wrong_password" msgid="4143127991071670512">"Falsches Passwort"</string>
-    <!-- no translation found for kg_wrong_password_try_again (6602878676125765920) -->
-    <skip />
+    <string name="kg_wrong_password_try_again" msgid="6602878676125765920">"Passwort ist falsch. Versuche es noch einmal."</string>
     <string name="kg_wrong_pin" msgid="4160978845968732624">"Falsche PIN"</string>
-    <!-- no translation found for kg_wrong_pin_try_again (3129729383303430190) -->
-    <skip />
-    <!-- no translation found for kg_wrong_input_try_fp_suggestion (3143861542242024833) -->
-    <skip />
-    <!-- no translation found for kg_fp_not_recognized (5183108260932029241) -->
-    <skip />
-    <!-- no translation found for bouncer_face_not_recognized (1666128054475597485) -->
-    <skip />
-    <!-- no translation found for kg_bio_try_again_or_pin (4752168242723808390) -->
-    <skip />
-    <!-- no translation found for kg_bio_try_again_or_password (1473132729225398039) -->
-    <skip />
-    <!-- no translation found for kg_bio_try_again_or_pattern (4867893307468801501) -->
-    <skip />
-    <!-- no translation found for kg_bio_too_many_attempts_pin (5850845723433047605) -->
-    <skip />
-    <!-- no translation found for kg_bio_too_many_attempts_password (5551690347827728042) -->
-    <skip />
-    <!-- no translation found for kg_bio_too_many_attempts_pattern (736884689355181602) -->
-    <skip />
-    <!-- no translation found for kg_unlock_with_pin_or_fp (5635161174698729890) -->
-    <skip />
-    <!-- no translation found for kg_unlock_with_password_or_fp (2251295907826814237) -->
-    <skip />
-    <!-- no translation found for kg_unlock_with_pattern_or_fp (2391870539909135046) -->
-    <skip />
-    <!-- no translation found for kg_prompt_after_dpm_lock (6002804765868345917) -->
-    <skip />
-    <!-- no translation found for kg_prompt_after_user_lockdown_pin (5374732179740050373) -->
-    <skip />
-    <!-- no translation found for kg_prompt_after_user_lockdown_password (9097968458291129795) -->
-    <skip />
-    <!-- no translation found for kg_prompt_after_user_lockdown_pattern (215072203613597906) -->
-    <skip />
-    <!-- no translation found for kg_prompt_unattended_update (8223448855578632202) -->
-    <skip />
-    <!-- no translation found for kg_prompt_pin_auth_timeout (5868644725126275245) -->
-    <skip />
-    <!-- no translation found for kg_prompt_password_auth_timeout (5809110458491920871) -->
-    <skip />
-    <!-- no translation found for kg_prompt_pattern_auth_timeout (1860605401869262178) -->
-    <skip />
-    <!-- no translation found for kg_prompt_auth_timeout (6620679830980315048) -->
-    <skip />
-    <!-- no translation found for kg_face_locked_out (2751559491287575) -->
-    <skip />
-    <!-- no translation found for kg_fp_locked_out (6228277682396768830) -->
-    <skip />
-    <!-- no translation found for kg_trust_agent_disabled (5400691179958727891) -->
-    <skip />
-    <!-- no translation found for kg_primary_auth_locked_out_pin (5492230176361601475) -->
-    <skip />
-    <!-- no translation found for kg_primary_auth_locked_out_pattern (8266214607346180952) -->
-    <skip />
-    <!-- no translation found for kg_primary_auth_locked_out_password (6170245108400198659) -->
-    <skip />
+    <string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"PIN ist falsch. Versuche es noch einmal.."</string>
+    <string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"Oder Gerät per Fingerabdruck entsperren"</string>
+    <string name="kg_fp_not_recognized" msgid="5183108260932029241">"Fingerabdruck nicht erkannt"</string>
+    <string name="bouncer_face_not_recognized" msgid="1666128054475597485">"Gesicht nicht erkannt"</string>
+    <string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"Bitte noch einmal versuchen oder PIN eingeben"</string>
+    <string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"Bitte noch einmal versuchen oder Passwort eingeben"</string>
+    <string name="kg_bio_try_again_or_pattern" msgid="4867893307468801501">"Bitte noch einmal versuchen oder Muster zeichnen"</string>
+    <string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"Nach zu vielen Versuchen wird die PIN abgefragt"</string>
+    <string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"Nach zu vielen Versuchen wird das Passwort abgefragt"</string>
+    <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"Nach zu vielen Versuchen wird das Muster abgefragt"</string>
+    <string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"Entsperrung mit PIN/Fingerabdruck"</string>
+    <string name="kg_unlock_with_password_or_fp" msgid="2251295907826814237">"Entsperrung mit Passwort/Fingerabdruck"</string>
+    <string name="kg_unlock_with_pattern_or_fp" msgid="2391870539909135046">"Entsperrung mit Muster/Fingerabdruck"</string>
+    <string name="kg_prompt_after_dpm_lock" msgid="6002804765868345917">"Gerät vom Admin aus Sicherheitsgründen gesperrt"</string>
+    <string name="kg_prompt_after_user_lockdown_pin" msgid="5374732179740050373">"Nach einer Sperre muss die PIN eingegeben werden"</string>
+    <string name="kg_prompt_after_user_lockdown_password" msgid="9097968458291129795">"Nach einer Sperre muss das Passwort eingegeben werden"</string>
+    <string name="kg_prompt_after_user_lockdown_pattern" msgid="215072203613597906">"Nach einer Sperre muss das Muster gezeichnet werden"</string>
+    <string name="kg_prompt_unattended_update" msgid="8223448855578632202">"Update wird installiert, wenn das Gerät inaktiv ist"</string>
+    <string name="kg_prompt_pin_auth_timeout" msgid="5868644725126275245">"Zusätzliche Sicherheitsmaßnahme erforderlich. Die PIN wurde länger nicht genutzt."</string>
+    <string name="kg_prompt_password_auth_timeout" msgid="5809110458491920871">"Zusätzliche Sicherheitsmaßnahme erforderlich. Passwort wurde länger nicht genutzt."</string>
+    <string name="kg_prompt_pattern_auth_timeout" msgid="1860605401869262178">"Zusätzliche Sicherheitsmaßnahme erforderlich. Muster wurde länger nicht genutzt."</string>
+    <string name="kg_prompt_auth_timeout" msgid="6620679830980315048">"Zusätzliche Sicherheitsmaßnahme erforderlich. Gerät wurde länger nicht entsperrt."</string>
+    <string name="kg_face_locked_out" msgid="2751559491287575">"Entsperrung mit Gesicht geht nicht. Zu oft versucht."</string>
+    <string name="kg_fp_locked_out" msgid="6228277682396768830">"Entsperrung mit Finger geht nicht. Zu oft versucht."</string>
+    <string name="kg_trust_agent_disabled" msgid="5400691179958727891">"Trust Agent nicht verfügbar"</string>
+    <string name="kg_primary_auth_locked_out_pin" msgid="5492230176361601475">"Zu viele Versuche mit falscher PIN"</string>
+    <string name="kg_primary_auth_locked_out_pattern" msgid="8266214607346180952">"Zu viele Versuche mit falschem Muster"</string>
+    <string name="kg_primary_auth_locked_out_password" msgid="6170245108400198659">"Zu viele Versuche mit falschem Passwort"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{In # Sekunde noch einmal versuchen.}other{In # Sekunden noch einmal versuchen.}}"</string>
     <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Gib die SIM-PIN ein"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Gib die SIM-PIN für \"<xliff:g id="CARRIER">%1$s</xliff:g>\" ein."</string>
@@ -142,12 +109,9 @@
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Fehler beim Entsperren der SIM-Karte mithilfe des PUK-Codes."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Eingabemethode wechseln"</string>
     <string name="airplane_mode" msgid="2528005343938497866">"Flugmodus"</string>
-    <!-- no translation found for kg_prompt_reason_restart_pattern (3321211830602827742) -->
-    <skip />
-    <!-- no translation found for kg_prompt_reason_restart_pin (2672166323886110512) -->
-    <skip />
-    <!-- no translation found for kg_prompt_reason_restart_password (3967993994418885887) -->
-    <skip />
+    <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"Nach Geräteneustart ist das Muster erforderlich"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"Nach Geräteneustart ist die PIN erforderlich"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"Nach Geräteneustart ist das Passwort erforderlich"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"Verwende für mehr Sicherheit stattdessen dein Muster"</string>
     <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"Verwende für mehr Sicherheit stattdessen deine PIN"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"Verwende für mehr Sicherheit stattdessen dein Passwort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index bef6105..ef1e3f19 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -22,7 +22,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Saisissez le code d\'accès"</string>
     <string name="keyguard_enter_pin" msgid="8114529922480276834">"Saisissez le code"</string>
-    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Tracez le schéma"</string>
+    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Tracez votre schéma"</string>
     <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Dessinez un schéma"</string>
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Saisissez votre mot de passe"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"Saisissez le mot de passe"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 05bd2ba..28d1910 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -124,5 +124,5 @@
     <string name="clock_title_default" msgid="6342735240617459864">"デフォルト"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"バブル"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"アナログ"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"続行するにはデバイスのロックを解除してください"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"続行するにはデバイスのロックを解除します"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index 3060cb2..c979641 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -124,5 +124,5 @@
     <string name="clock_title_default" msgid="6342735240617459864">"ნაგულისხმევი"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ბუშტი"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ანალოგური"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"გასაგრძელებლად განბლოკეთ თქვენი მოწყობილობა"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"გასაგრძელებლად განბლოკეთ მოწყობილობა"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index ecf8350..97658c1 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -31,7 +31,7 @@
     <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Сымсыз зарядталуда"</string>
     <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядталып жатыр."</string>
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядталуда"</string>
-    <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жылдам зарядталуда"</string>
+    <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жылдам зарядтау"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Баяу зарядталуда"</string>
     <string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны қорғау үшін зарядтау оңтайландырылды"</string>
     <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядтау құрылғысына қатысты мәселе туындады."</string>
@@ -124,5 +124,5 @@
     <string name="clock_title_default" msgid="6342735240617459864">"Әдепкі"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Көпіршік"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Аналогтық"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Жалғастыру үшін құрылғының құлпын ашыңыз"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Жалғастыру үшін құлыпты ашыңыз"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 79ef007..e08ffae 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -22,7 +22,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"PIN кодуңузду киргизиңиз"</string>
     <string name="keyguard_enter_pin" msgid="8114529922480276834">"PIN кодду киргизиңиз"</string>
-    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Графикалык ачкычты киргизиңиз"</string>
+    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Графикалык ачкычты тартыңыз"</string>
     <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Графикалык ачкчты тартңыз"</string>
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Сырсөзүңүздү киргизиңиз"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"Сырсөздү киргизиңиз"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index 9e64abe6..deb6a15 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -27,7 +27,7 @@
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"ປ້ອນລະຫັດຜ່ານຂອງທ່ານ"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"ໃສ່ລະຫັດຜ່ານ"</string>
     <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"ບັດບໍ່ຖືກຕ້ອງ."</string>
-    <string name="keyguard_charged" msgid="5478247181205188995">"ສາກເຕັມແລ້ວ."</string>
+    <string name="keyguard_charged" msgid="5478247181205188995">"ສາກເຕັມແລ້ວ"</string>
     <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳ​ລັງ​ສາກ​ໄຟໄຮ້​ສາຍ"</string>
     <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກໄຟ"</string>
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index d2f7f08..c4df119 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -124,5 +124,5 @@
     <string name="clock_title_default" msgid="6342735240617459864">"Numatytasis"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Debesėlis"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analoginis"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Įrenginio atrakinimas norint tęsti"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Atrakinkite įrenginį norėdami tęsti"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index 4b215ae..abb175b 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -22,7 +22,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"आफ्नो PIN प्रविष्टि गर्नुहोस्"</string>
     <string name="keyguard_enter_pin" msgid="8114529922480276834">"PIN हाल्नुहोस्"</string>
-    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"आफ्नो ढाँचा प्रविष्टि गर्नुहोस्"</string>
+    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"प्याटर्न हाल्नुहोस्"</string>
     <string name="keyguard_enter_pattern" msgid="7616595160901084119">"प्याटर्न कोर्नुहोस्"</string>
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"आफ्नो पासवर्ड प्रविष्ट गर्नु…"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"पासवर्ड हाल्नुहोस्"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index 1fcde86..3be5b7f 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -124,5 +124,5 @@
     <string name="clock_title_default" msgid="6342735240617459864">"Domyślna"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bąbelkowy"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogowy"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Odblokuj urządzenie, aby kontynuować"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Aby przejść dalej, odblokuj urządzenie"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index b12c9d3..08bf30d 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -22,7 +22,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Zadajte PIN"</string>
     <string name="keyguard_enter_pin" msgid="8114529922480276834">"Zadajte PIN"</string>
-    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Zadajte vzor"</string>
+    <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Zadajte svoj vzor"</string>
     <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Nakreslite vzor"</string>
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Zadajte heslo"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"Zadajte heslo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index bded34a..cabf94f 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -27,7 +27,7 @@
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Унесите лозинку"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"Унесите лозинку"</string>
     <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Неважећа картица."</string>
-    <string name="keyguard_charged" msgid="5478247181205188995">"Напуњена је"</string>
+    <string name="keyguard_charged" msgid="5478247181205188995">"Напуњено"</string>
     <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Бежично пуњење"</string>
     <string name="keyguard_plugged_in_dock" msgid="2122073051904360987">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуни се"</string>
     <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуни се"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index 20a0360..ba40a65 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -73,9 +73,9 @@
     <string name="kg_unlock_with_password_or_fp" msgid="2251295907826814237">"使用密碼或指紋解鎖"</string>
     <string name="kg_unlock_with_pattern_or_fp" msgid="2391870539909135046">"使用解鎖圖案或指紋解鎖"</string>
     <string name="kg_prompt_after_dpm_lock" msgid="6002804765868345917">"為提高安全性,公司政策已鎖定裝置"</string>
-    <string name="kg_prompt_after_user_lockdown_pin" msgid="5374732179740050373">"需要輸入 PIN 才能解除禁閉模式"</string>
-    <string name="kg_prompt_after_user_lockdown_password" msgid="9097968458291129795">"需要輸入密碼解才能解除禁閉模式"</string>
-    <string name="kg_prompt_after_user_lockdown_pattern" msgid="215072203613597906">"需要畫出解鎖圖案才能解除禁閉模式"</string>
+    <string name="kg_prompt_after_user_lockdown_pin" msgid="5374732179740050373">"需要輸入 PIN 才能解除鎖定"</string>
+    <string name="kg_prompt_after_user_lockdown_password" msgid="9097968458291129795">"需要輸入密碼解才能解除鎖定"</string>
+    <string name="kg_prompt_after_user_lockdown_pattern" msgid="215072203613597906">"需要畫出解鎖圖案才能解除鎖定"</string>
     <string name="kg_prompt_unattended_update" msgid="8223448855578632202">"裝置會在閒置時安裝更新"</string>
     <string name="kg_prompt_pin_auth_timeout" msgid="5868644725126275245">"需要加強安全設定:已有一段時間沒有使用 PIN。"</string>
     <string name="kg_prompt_password_auth_timeout" msgid="5809110458491920871">"需要加強安全設定:已有一段時間沒有使用密碼。"</string>
@@ -98,13 +98,13 @@
     <string name="kg_sim_unlock_progress_dialog_message" msgid="1123048780346295748">"正在解鎖 SIM 卡…"</string>
     <string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"請輸入 4 至 8 位數的 PIN 碼。"</string>
     <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK 碼應由 8 個或以上數字組成。"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM 卡 PIN 碼不正確,您現在必須聯絡流動網絡供應商為您的裝置解鎖。"</string>
-    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM 卡的 PIN 碼不正確,您還可以再試 # 次。如果仍然輸入錯誤,您必須聯絡流動網絡供應商解鎖您的裝置。}other{SIM 卡的 PIN 碼不正確,您還可以再試 # 次。}}"</string>
-    <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM 卡無法使用,請聯絡您的流動網絡供應商。"</string>
-    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM 卡的 PUK 碼不正確,您還可以再試 # 次。如果仍然輪入錯誤,SIM 卡將永久無法使用。}other{SIM 卡的 PUK 碼不正確,您還可以再試 # 次。如果仍然輪入錯誤,SIM 卡將永久無法使用。}}"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"你已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"你已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM 卡 PIN 碼不正確,你現在必須聯絡流動網絡供應商為你的裝置解鎖。"</string>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM 卡的 PIN 碼不正確,你還可以再試 # 次。如果仍然輸入錯誤,你必須聯絡流動網絡供應商解鎖你的裝置。}other{SIM 卡的 PIN 碼不正確,你還可以再試 # 次。}}"</string>
+    <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM 卡無法使用,請聯絡你的流動網絡供應商。"</string>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM 卡的 PUK 碼不正確,你還可以再試 # 次。如果仍然輪入錯誤,SIM 卡將永久無法使用。}other{SIM 卡的 PUK 碼不正確,你還可以再試 # 次。如果仍然輪入錯誤,SIM 卡將永久無法使用。}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"無法使用 SIM 卡 PIN 碼解鎖!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"無法使用 SIM 卡 PUK 碼解鎖!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"轉換輸入方法"</string>
@@ -119,8 +119,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"使用者已手動將裝置上鎖"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"未能識別"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"如要使用「面孔解鎖」,請在「設定」開啟相機存取權"</string>
-    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{輸入 SIM 卡的 PIN,您還可以再試 # 次。如果仍然輸入錯誤,您必須聯絡流動網絡供應商解鎖您的裝置。}other{輸入 SIM 卡的 PIN。您還可以再試 # 次。}}"</string>
-    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 # 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請向流動網絡供應商查詢。}other{SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 # 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請向流動網絡供應商查詢。}}"</string>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{輸入 SIM 卡的 PIN,你還可以再試 # 次。如果仍然輸入錯誤,你必須聯絡流動網絡供應商解鎖你的裝置。}other{輸入 SIM 卡的 PIN。你還可以再試 # 次。}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM 卡已停用。請輸入 PUK 碼以繼續進行。你還可以再試 # 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請向流動網絡供應商查詢。}other{SIM 卡已停用。請輸入 PUK 碼以繼續進行。你還可以再試 # 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請向流動網絡供應商查詢。}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"預設"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"泡泡"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"指針"</string>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 04dffb6..4d289eb 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -22,9 +22,10 @@
     <!-- Keyguard PIN pad styles -->
     <style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
         <item name="android:textSize">@dimen/kg_status_line_font_size</item>
+        <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
     </style>
     <style name="Keyguard.TextView.EmergencyButton" parent="Theme.SystemUI">
-        <item name="android:textColor">?androidprv:attr/textColorOnAccent</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnTertiaryFixed</item>
         <item name="android:textSize">16sp</item>
         <item name="android:background">@drawable/kg_emergency_button_background</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
diff --git a/packages/SystemUI/res-product/values-es/strings.xml b/packages/SystemUI/res-product/values-es/strings.xml
index b13018b..744761d 100644
--- a/packages/SystemUI/res-product/values-es/strings.xml
+++ b/packages/SystemUI/res-product/values-es/strings.xml
@@ -47,5 +47,5 @@
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloquea el tablet para ver más opciones"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloquea el dispositivo para ver más opciones"</string>
     <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Reproduciendo en este teléfono"</string>
-    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Reproduciendo en este tablet"</string>
+    <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Reproduciendo en esta tablet"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-zh-rHK/strings.xml b/packages/SystemUI/res-product/values-zh-rHK/strings.xml
index 9e55398..85f482a 100644
--- a/packages/SystemUI/res-product/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-product/values-zh-rHK/strings.xml
@@ -26,20 +26,20 @@
     <string name="keyguard_missing_sim_message" product="tablet" msgid="408124574073032188">"平板電腦中沒有 SIM 卡。"</string>
     <string name="keyguard_missing_sim_message" product="default" msgid="2605468359948247208">"手機中沒有 SIM 卡。"</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"PIN 碼不符"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將重設此平板電腦,而所有平板電腦資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將重設此手機,而所有手機資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將重設此平板電腦,而所有平板電腦資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將重設此手機,而所有手機資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="302165994845009232">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將重設此平板電腦,而所有平板電腦資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將重設此手機,而所有手機資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將重設此平板電腦,而所有平板電腦資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將重設此手機,而所有手機資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此使用者,而所有使用者資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"你嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你透過電郵帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"你已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求你透過電郵帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於平板電腦邊緣凸起的音量按鈕旁。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於裝置邊緣凸起的音量按鈕旁。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於手機邊緣凸起的音量按鈕旁。"</string>
diff --git a/packages/SystemUI/res-product/values-zh-rTW/strings.xml b/packages/SystemUI/res-product/values-zh-rTW/strings.xml
index ae512e0..c0f75c7 100644
--- a/packages/SystemUI/res-product/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-product/values-zh-rTW/strings.xml
@@ -42,7 +42,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"你的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會要求你透過電子郵件帳戶將手機解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在平板電腦側邊凸起的音量按鈕旁。"</string>
     <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在裝置側邊凸起的音量按鈕旁。"</string>
-    <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在手機側邊凸起的音量按鈕旁。"</string>
+    <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在手機側邊凸起的音量鍵旁。"</string>
     <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"解鎖手機可查看更多選項"</string>
     <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"解鎖平板電腦可查看更多選項"</string>
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"解鎖裝置可查看更多選項"</string>
diff --git a/packages/SystemUI/res/drawable/dream_overlay_assistant_attention_indicator.xml b/packages/SystemUI/res/drawable/dream_overlay_assistant_attention_indicator.xml
index dad2cdf8e..54bdf18 100644
--- a/packages/SystemUI/res/drawable/dream_overlay_assistant_attention_indicator.xml
+++ b/packages/SystemUI/res/drawable/dream_overlay_assistant_attention_indicator.xml
@@ -13,20 +13,30 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-
-<vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="56dp"
     android:height="24dp"
     android:viewportWidth="56"
     android:viewportHeight="24">
-    <group>
-        <clip-path
-            android:pathData="M12 0H44C50.6274 0 56 5.37258 56 12C56 18.6274 50.6274 24 44 24H12C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0Z"
-            />
+    <path
+        android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z"
+        android:fillColor="#ffffff"/>
+    <group
+        android:scaleX="0.8"
+        android:scaleY="0.8"
+        android:translateY="2"
+        android:translateX="18">
         <path
-            android:pathData="M0 0V24H56V0"
-            android:fillColor="#FFFFFF"
-            />
+            android:pathData="M21.5,9C22.3284,9 23,8.3284 23,7.5C23,6.6716 22.3284,6 21.5,6C20.6716,6 20,6.6716 20,7.5C20,8.3284 20.6716,9 21.5,9Z"
+            android:fillColor="#000000"/>
+        <path
+            android:pathData="M17,14C18.6569,14 20,12.6569 20,11C20,9.3432 18.6569,8 17,8C15.3431,8 14,9.3432 14,11C14,12.6569 15.3431,14 17,14Z"
+            android:fillColor="#000000"/>
+        <path
+            android:pathData="M17,22C18.933,22 20.5,20.433 20.5,18.5C20.5,16.567 18.933,15 17,15C15.067,15 13.5,16.567 13.5,18.5C13.5,20.433 15.067,22 17,22Z"
+            android:fillColor="#000000"/>
+        <path
+            android:pathData="M7,14C10.3137,14 13,11.3137 13,8C13,4.6863 10.3137,2 7,2C3.6863,2 1,4.6863 1,8C1,11.3137 3.6863,14 7,14Z"
+            android:fillColor="#000000"/>
     </group>
-</vector>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_note_task_shortcut_keyguard.xml b/packages/SystemUI/res/drawable/ic_note_task_shortcut_keyguard.xml
index ee8d4883..a35504f 100644
--- a/packages/SystemUI/res/drawable/ic_note_task_shortcut_keyguard.xml
+++ b/packages/SystemUI/res/drawable/ic_note_task_shortcut_keyguard.xml
@@ -16,16 +16,12 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="24dp"
     android:height="24dp"
-    android:viewportHeight="24"
-    android:viewportWidth="24">
+    android:viewportWidth="24"
+    android:viewportHeight="24">
     <path
-        android:fillAlpha="1"
-        android:fillColor="@android:color/white"
-        android:fillType="nonZero"
-        android:pathData="M17.6258,4.96L19.0358,6.37L7.4058,18.01L5.9958,16.6L17.6258,4.96ZM16.1358,3.62L4.1258,15.63L3.0158,19.83C2.9058,20.45 3.3858,21 3.9958,21C4.0558,21 4.1058,21 4.1658,20.99L8.3658,19.88L20.3758,7.86C20.7758,7.46 20.9958,6.93 20.9958,6.37C20.9958,5.81 20.7758,5.28 20.3758,4.88L19.1058,3.61C18.7158,3.22 18.1858,3 17.6258,3C17.0658,3 16.5358,3.22 16.1358,3.62Z" />
+        android:pathData="M23.41,6L22,4.59C21.63,4.21 21.12,4 20.59,4C20.06,4 19.55,4.21 19.18,4.59L11.39,12.38L9.09,14.68L8.04,18.9C8.01,18.96 8,19.04 8,19.11C8,19.6 8.4,20 8.89,20C8.96,20 9.04,19.99 9.11,19.97L13.33,18.92L15.63,16.62L23.42,8.83C23.79,8.45 24,7.94 24,7.41C24,6.88 23.79,6.37 23.41,6ZM14.21,15.21L13.21,16.21L11.8,14.8L12.8,13.8L20.59,6L22,7.41L14.21,15.21Z"
+        android:fillColor="@android:color/white"/>
     <path
-        android:fillAlpha="1"
-        android:fillColor="@android:color/white"
-        android:fillType="nonZero"
-        android:pathData="M20.1936,15.3369C20.3748,16.3837 19.9151,17.5414 18.8846,18.7597C19.1546,18.872 19.4576,18.9452 19.7724,18.9867C20.0839,19.0278 20.3683,19.0325 20.5749,19.0266C20.6772,19.0236 20.7578,19.0181 20.8101,19.0138C20.8362,19.0116 20.855,19.0097 20.8657,19.0085L20.8754,19.0074L20.875,19.0075C21.4217,18.9385 21.9214,19.325 21.9918,19.8718C22.0624,20.4195 21.6756,20.9208 21.1279,20.9914L21,19.9996C21.1279,20.9914 21.1265,20.9916 21.1265,20.9916L21.1249,20.9918L21.1211,20.9923L21.1107,20.9935L21.0795,20.997C21.0542,20.9998 21.0199,21.0032 20.9775,21.0067C20.8929,21.0138 20.7753,21.0216 20.6323,21.0257C20.3481,21.0339 19.9533,21.0279 19.5109,20.9695C18.873,20.8854 18.0393,20.6793 17.3106,20.1662C16.9605,20.3559 16.5876,20.4952 16.2299,20.6003C15.5742,20.7927 14.8754,20.8968 14.2534,20.9534C13.6801,21.0055 13.4553,21.0037 13.1015,21.0008C13.0689,21.0005 13.0352,21.0002 13,21H12.8594C12.8214,21.0002 12.785,21.0006 12.7504,21.0009C12.6524,21.0019 12.5683,21.0027 12.5,21H12.0562C12.0277,21.0003 12.0054,21.0006 11.9926,21.001L11.9751,21H9L11,19H11.9795C11.9929,18.9997 12.0064,18.9997 12.0199,19H12.4117C12.4534,18.9996 12.4864,18.9995 12.5,19H12.9675C12.977,18.9999 12.9878,18.9999 13,19C13.0446,19.0003 13.0859,19.0007 13.1249,19.0011C13.4259,19.0038 13.591,19.0054 14.0723,18.9616C14.6201,18.9118 15.1795,18.8242 15.6665,18.6813C15.753,18.6559 15.8346,18.6295 15.9114,18.6022C15.0315,17.2981 14.7125,16.1044 15.015,15.0829C15.4095,13.7511 16.6784,13.2418 17.7026,13.2864C18.7262,13.3309 19.954,13.9529 20.1936,15.3369ZM16.9327,15.6508C16.873,15.8523 16.8651,16.3878 17.4697,17.334C18.2007,16.4284 18.2585,15.8839 18.2229,15.6781C18.1939,15.5108 18.0297,15.3025 17.6157,15.2845C17.2025,15.2665 16.9885,15.4626 16.9327,15.6508Z" />
+        android:pathData="M6.688,20C2.047,20 0.333,18.65 0.333,16C0.333,13.61 2.439,12.474 5.713,12C6.792,11.844 7.344,11.397 7.344,10.927C7.344,9.625 4.679,9.705 3.833,9.667V7.667C3.833,7.667 6.792,7.667 8.208,8.729C8.932,9.272 9.333,9.979 9.333,11.05C9.333,12.52 8.281,13.677 5.713,13.885C4.017,14.023 2.333,14.52 2.333,16C2.333,17.33 4.013,18 7.333,18L6.688,20Z"
+        android:fillColor="@android:color/white"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget.xml b/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget.xml
index 7590182..860fc7d 100644
--- a/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget.xml
+++ b/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget.xml
@@ -13,19 +13,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportHeight="24"
-    android:viewportWidth="24">
-    <path
-        android:fillAlpha="1"
-        android:fillColor="#636C6F"
-        android:fillType="nonZero"
-        android:pathData="M17.6258,4.96L19.0358,6.37L7.4058,18.01L5.9958,16.6L17.6258,4.96ZM16.1358,3.62L4.1258,15.63L3.0158,19.83C2.9058,20.45 3.3858,21 3.9958,21C4.0558,21 4.1058,21 4.1658,20.99L8.3658,19.88L20.3758,7.86C20.7758,7.46 20.9958,6.93 20.9958,6.37C20.9958,5.81 20.7758,5.28 20.3758,4.88L19.1058,3.61C18.7158,3.22 18.1858,3 17.6258,3C17.0658,3 16.5358,3.22 16.1358,3.62Z" />
-    <path
-        android:fillAlpha="1"
-        android:fillColor="#636C6F"
-        android:fillType="nonZero"
-        android:pathData="M20.1936,15.3369C20.3748,16.3837 19.9151,17.5414 18.8846,18.7597C19.1546,18.872 19.4576,18.9452 19.7724,18.9867C20.0839,19.0278 20.3683,19.0325 20.5749,19.0266C20.6772,19.0236 20.7578,19.0181 20.8101,19.0138C20.8362,19.0116 20.855,19.0097 20.8657,19.0085L20.8754,19.0074L20.875,19.0075C21.4217,18.9385 21.9214,19.325 21.9918,19.8718C22.0624,20.4195 21.6756,20.9208 21.1279,20.9914L21,19.9996C21.1279,20.9914 21.1265,20.9916 21.1265,20.9916L21.1249,20.9918L21.1211,20.9923L21.1107,20.9935L21.0795,20.997C21.0542,20.9998 21.0199,21.0032 20.9775,21.0067C20.8929,21.0138 20.7753,21.0216 20.6323,21.0257C20.3481,21.0339 19.9533,21.0279 19.5109,20.9695C18.873,20.8854 18.0393,20.6793 17.3106,20.1662C16.9605,20.3559 16.5876,20.4952 16.2299,20.6003C15.5742,20.7927 14.8754,20.8968 14.2534,20.9534C13.6801,21.0055 13.4553,21.0037 13.1015,21.0008C13.0689,21.0005 13.0352,21.0002 13,21H12.8594C12.8214,21.0002 12.785,21.0006 12.7504,21.0009C12.6524,21.0019 12.5683,21.0027 12.5,21H12.0562C12.0277,21.0003 12.0054,21.0006 11.9926,21.001L11.9751,21H9L11,19H11.9795C11.9929,18.9997 12.0064,18.9997 12.0199,19H12.4117C12.4534,18.9996 12.4864,18.9995 12.5,19H12.9675C12.977,18.9999 12.9878,18.9999 13,19C13.0446,19.0003 13.0859,19.0007 13.1249,19.0011C13.4259,19.0038 13.591,19.0054 14.0723,18.9616C14.6201,18.9118 15.1795,18.8242 15.6665,18.6813C15.753,18.6559 15.8346,18.6295 15.9114,18.6022C15.0315,17.2981 14.7125,16.1044 15.015,15.0829C15.4095,13.7511 16.6784,13.2418 17.7026,13.2864C18.7262,13.3309 19.954,13.9529 20.1936,15.3369ZM16.9327,15.6508C16.873,15.8523 16.8651,16.3878 17.4697,17.334C18.2007,16.4284 18.2585,15.8839 18.2229,15.6781C18.1939,15.5108 18.0297,15.3025 17.6157,15.2845C17.2025,15.2665 16.9885,15.4626 16.9327,15.6508Z" />
-</vector>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_note_task_shortcut_widget_background" />
+    <foreground android:drawable="@drawable/ic_note_task_shortcut_widget_foreground" />
+</adaptive-icon>
diff --git a/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget_background.xml b/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget_background.xml
new file mode 100644
index 0000000..9f98f07
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget_background.xml
@@ -0,0 +1,24 @@
+<?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="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+  <path
+      android:pathData="M0,0h108v108h-108z"
+      android:fillColor="#0B57D0"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget_foreground.xml b/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget_foreground.xml
new file mode 100644
index 0000000..fcb3ef4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_note_task_shortcut_widget_foreground.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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+  <path
+      android:pathData="M74.92,43L72.33,40.42C71.65,39.72 70.72,39.33 69.75,39.33C68.78,39.33 67.84,39.72 67.16,40.42L52.88,54.7L48.67,58.91L46.74,66.65C46.69,66.76 46.67,66.91 46.67,67.04C46.67,67.93 47.4,68.67 48.3,68.67C48.43,68.67 48.57,68.65 48.7,68.61L56.44,66.69L60.65,62.47L74.94,48.19C75.61,47.49 76,46.56 76,45.58C76,44.61 75.61,43.68 74.92,43ZM58.05,59.88L56.22,61.72L53.63,59.13L55.47,57.3L69.75,43L72.33,45.58L58.05,59.88Z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M44.26,68.67C35.75,68.67 32.61,66.19 32.61,61.33C32.61,56.95 36.47,54.87 42.47,54C44.45,53.71 45.46,52.89 45.46,52.03C45.46,49.65 40.58,49.79 39.03,49.72V46.06C39.03,46.06 44.45,46.06 47.05,48C48.37,49 49.11,50.3 49.11,52.26C49.11,54.95 47.18,57.07 42.47,57.46C39.36,57.71 36.28,58.62 36.28,61.33C36.28,63.77 39.36,65 45.44,65L44.26,68.67Z"
+      android:fillColor="#ffffff"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml b/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml
index a0ceb81..fe76ba7 100644
--- a/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml
+++ b/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml
@@ -26,7 +26,7 @@
     </item>
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/materialColorOnBackground" />
+            <solid android:color="?androidprv:attr/materialColorSecondaryFixed" />
             <corners android:radius="@dimen/keyguard_affordance_fixed_radius" />
         </shape>
     </item>
diff --git a/packages/SystemUI/res/layout/auth_credential_password_view.xml b/packages/SystemUI/res/layout/auth_credential_password_view.xml
index 021ebe6..33f1b10 100644
--- a/packages/SystemUI/res/layout/auth_credential_password_view.xml
+++ b/packages/SystemUI/res/layout/auth_credential_password_view.xml
@@ -23,40 +23,47 @@
     android:orientation="vertical"
     android:theme="?app:attr/lockPinPasswordStyle">
 
-    <RelativeLayout
+    <ScrollView
         android:id="@+id/auth_credential_header"
-        style="?headerStyle"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="wrap_content">
 
-        <ImageView
-            android:id="@+id/icon"
-            style="?headerIconStyle"
-            android:layout_alignParentLeft="true"
-            android:layout_alignParentTop="true"
-            android:contentDescription="@null"/>
-
-        <TextView
-            android:id="@+id/title"
-            style="?titleTextAppearance"
-            android:layout_below="@id/icon"
+        <RelativeLayout
+            style="?headerStyle"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+            android:layout_height="wrap_content">
 
-        <TextView
-            android:id="@+id/subtitle"
-            style="?subTitleTextAppearance"
-            android:layout_below="@id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+            <ImageView
+                android:id="@+id/icon"
+                style="?headerIconStyle"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentTop="true"
+                android:contentDescription="@null" />
 
-        <TextView
-            android:id="@+id/description"
-            style="?descriptionTextAppearance"
-            android:layout_below="@id/subtitle"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
-    </RelativeLayout>
+            <TextView
+                android:id="@+id/title"
+                style="?titleTextAppearance"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/icon" />
+
+            <TextView
+                android:id="@+id/subtitle"
+                style="?subTitleTextAppearance"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/title" />
+
+            <TextView
+                android:id="@+id/description"
+                style="?descriptionTextAppearance"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/subtitle" />
+
+        </RelativeLayout>
+
+    </ScrollView>
 
     <LinearLayout
         android:id="@+id/auth_credential_input"
diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml
index 441f963..e989372 100644
--- a/packages/SystemUI/res/layout/combined_qs_header.xml
+++ b/packages/SystemUI/res/layout/combined_qs_header.xml
@@ -126,8 +126,7 @@
     <com.android.systemui.battery.BatteryMeterView
         android:id="@+id/batteryRemainingIcon"
         android:layout_width="wrap_content"
-        android:layout_height="@dimen/large_screen_shade_header_min_height"
-        app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
+        android:layout_height="0dp"
         app:layout_constrainedWidth="true"
         app:textAppearance="@style/TextAppearance.QS.Status"
         app:layout_constraintStart_toEndOf="@id/statusIcons"
diff --git a/packages/SystemUI/res/layout/screen_record_dialog.xml b/packages/SystemUI/res/layout/screen_record_dialog.xml
index ab38dd2..ae052502 100644
--- a/packages/SystemUI/res/layout/screen_record_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_record_dialog.xml
@@ -49,13 +49,13 @@
                     android:layout_height="wrap_content"
                     android:textAppearance="?android:attr/textAppearanceLarge"
                     android:fontFamily="@*android:string/config_headlineFontFamily"
-                    android:text="@string/screenrecord_start_label"
+                    android:text="@string/screenrecord_permission_dialog_title"
                     android:layout_marginTop="22dp"
                     android:layout_marginBottom="15dp"/>
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:text="@string/screenrecord_description"
+                    android:text="@string/screenrecord_permission_dialog_warning_entire_screen"
                     android:textAppearance="?android:attr/textAppearanceSmall"
                     android:textColor="?android:textColorSecondary"
                     android:gravity="center"
@@ -168,7 +168,7 @@
                     android:layout_height="wrap_content"
                     android:layout_weight="0"
                     android:layout_gravity="end"
-                    android:text="@string/screenrecord_start"
+                    android:text="@string/screenrecord_continue"
                     style="@style/Widget.Dialog.Button" />
             </LinearLayout>
         </LinearLayout>
diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml
index bd71989..0d86e0a 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog.xml
@@ -63,7 +63,7 @@
             android:id="@+id/text_warning"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:text="@string/screenrecord_description"
+            android:text="@string/screenrecord_permission_dialog_warning_entire_screen"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:textColor="?android:textColorSecondary"
             android:gravity="start"
@@ -76,7 +76,7 @@
             android:orientation="horizontal"
             android:layout_marginTop="@dimen/screenrecord_buttons_margin_top">
             <TextView
-                android:id="@+id/button_cancel"
+                android:id="@android:id/button2"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_weight="0"
@@ -87,11 +87,11 @@
                 android:layout_height="match_parent"
                 android:layout_weight="1"/>
             <TextView
-                android:id="@+id/button_start"
+                android:id="@android:id/button1"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_weight="0"
-                android:text="@string/screenrecord_start"
+                android:text="@string/screenrecord_continue"
                 style="@style/Widget.Dialog.Button" />
         </LinearLayout>
     </LinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml b/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml
index 0ea0653..473ab08 100644
--- a/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml
+++ b/packages/SystemUI/res/layout/status_bar_wifi_group_inner.xml
@@ -24,11 +24,11 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:gravity="center_vertical"
-        android:layout_marginStart="2.5dp"
+        android:layout_marginStart="2.5sp"
     >
         <FrameLayout
                 android:id="@+id/inout_container"
-                android:layout_height="17dp"
+                android:layout_height="@*android:dimen/status_bar_system_icon_intrinsic_size"
                 android:layout_width="wrap_content"
                 android:gravity="center_vertical" >
             <ImageView
@@ -37,14 +37,14 @@
                 android:layout_width="wrap_content"
                 android:src="@drawable/ic_activity_down"
                 android:visibility="gone"
-                android:paddingEnd="2dp"
+                android:paddingEnd="2sp"
             />
             <ImageView
                 android:id="@+id/wifi_out"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 android:src="@drawable/ic_activity_up"
-                android:paddingEnd="2dp"
+                android:paddingEnd="2sp"
                 android:visibility="gone"
             />
         </FrameLayout>
@@ -62,7 +62,7 @@
         <View
             android:id="@+id/wifi_signal_spacer"
             android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
-            android:layout_height="4dp"
+            android:layout_height="4sp"
             android:visibility="gone" />
 
         <!-- Looks like CarStatusBar uses this... -->
@@ -75,7 +75,7 @@
         <View
             android:id="@+id/wifi_airplane_spacer"
             android:layout_width="@dimen/status_bar_airplane_spacer_width"
-            android:layout_height="4dp"
+            android:layout_height="4sp"
             android:visibility="gone"
         />
     </com.android.keyguard.AlphaOptimizedLinearLayout>
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index fe9542b..d9fe949 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -101,7 +101,6 @@
     </LinearLayout>
 
     <FrameLayout android:id="@+id/keyguard_bouncer_container"
-        android:paddingTop="@dimen/status_bar_height"
         android:layout_height="match_parent"
         android:layout_width="match_parent"
         android:layout_weight="1"
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json
new file mode 100644
index 0000000..49c1c40
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json
@@ -0,0 +1 @@
+{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Landscape_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-129,"s":[-67]},{"t":-29,"s":[0]}],"ix":10},"p":{"a":0,"k":[-75.352,41.307,0],"ix":2,"l":2},"a":{"a":0,"k":[94.648,211.307,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.72,-5.642],[0,0],[-9.394,-0.562],[-0.298,-0.038]],"o":[[-5.153,4.329],[3.882,-16.05],[0.31,0.019],[-0.044,0.75]],"v":[[0.863,12.222],[-8.931,14.755],[8.005,-15.108],[8.931,-15.021]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[81.486,130.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 9","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.459,6.045],[-5.153,4.329],[-0.044,0.75],[3.116,-24.664],[5.23,-22.052],[8.666,11.92],[-2.9,9.135]],"o":[[0,0],[6.72,-5.642],[12.723,1.335],[-2.369,18.762],[-13.993,-5.333],[2.255,-5.502],[1.843,-5.815]],"v":[[-9.99,-18.348],[-0.196,-20.881],[7.872,-48.124],[21.578,-9.331],[12.104,48.124],[-22.574,21.555],[-14.791,-0.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82.545,163.184],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 8","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"black circle matte 4","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"black circle matte 5","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".grey700","cl":"grey700","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json
new file mode 100644
index 0000000..9ea0d35
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json
@@ -0,0 +1 @@
+{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Portrait_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 3","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-2,"ix":10},"p":{"a":0,"k":[260.134,83.782,0],"ix":2,"l":2},"a":{"a":0,"k":[302.634,38.782,0],"ix":1,"l":2},"s":{"a":0,"k":[178,178,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.262,5.076],[0,0],[-0.424,-7.095],[-0.028,-0.225]],"o":[[3.269,-3.892],[-12.123,2.932],[0.015,0.234],[0.567,-0.034]],"v":[[9.232,0.652],[11.145,-6.746],[-11.412,6.046],[-11.346,6.746]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[241.281,55.033],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.565,-1.102],[3.269,-3.892],[0.566,-0.033],[-18.63,2.353],[-16.656,3.951],[9.004,6.546],[6.9,-2.19]],"o":[[0,0],[-4.262,5.076],[1.008,9.61],[14.171,-1.79],[-4.028,-10.569],[-4.156,1.703],[-4.392,1.392]],"v":[[-13.858,-7.546],[-15.771,-0.148],[-36.349,5.946],[-7.047,16.299],[36.349,9.142],[16.281,-17.051],[-0.156,-11.172]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[266.285,55.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 4","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"black circle matte 4","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"black circle matte 5","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey700","cl":"grey700","parent":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json
new file mode 100644
index 0000000..f2b2593
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json
@@ -0,0 +1 @@
+{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Portrait_Reverse_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-75.352,41.307,0],"ix":2,"l":2},"a":{"a":0,"k":[94.648,211.307,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.72,-5.642],[0,0],[-9.394,-0.562],[-0.298,-0.038]],"o":[[-5.153,4.329],[3.882,-16.05],[0.31,0.019],[-0.044,0.75]],"v":[[0.863,12.222],[-8.931,14.755],[8.005,-15.108],[8.931,-15.021]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[81.486,130.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 9","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.459,6.045],[-5.153,4.329],[-0.044,0.75],[3.116,-24.664],[5.23,-22.052],[8.666,11.92],[-2.9,9.135]],"o":[[0,0],[6.72,-5.642],[12.723,1.335],[-2.369,18.762],[-13.993,-5.333],[2.255,-5.502],[1.843,-5.815]],"v":[[-9.99,-18.348],[-0.196,-20.881],[7.872,-48.124],[21.578,-9.331],[12.104,48.124],[-22.574,21.555],[-14.791,-0.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82.545,163.184],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 8","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"black circle matte 4","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"black circle matte 5","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".grey700","cl":"grey700","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 4d43b19..e7c7068 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"As jy met jou volgende poging \'n verkeerde patroon invoer, sal jou werkprofiel en die data daarvan uitgevee word."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"As jy met jou volgende poging \'n verkeerde PIN invoer, sal jou werkprofiel en die data daarvan uitgevee word."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"As jy met jou volgende poging \'n verkeerde wagwoord invoer, sal jou werkprofiel en die data daarvan uitgevee word."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Raak die vingerafdruksensor"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Kan nie gesig herken nie. Gebruik eerder vingerafdruk."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skakel oor na werkprofiel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Maak toe"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Pasmaak sluitskerm"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ontsluit om sluitskerm te pasmaak"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-fi is nie beskikbaar nie"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera is geblokkeer"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera en mikrofoon is geblokkeer"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofoon is geblokkeer"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioriteitmodus is aan"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent-aandag is aan"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Stel versteknotasapp in Instellings"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 8adb782..7a452c3 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -68,37 +68,37 @@
     <string name="usb_port_enabled" msgid="531823867664717018">"ኃይል መሙያዎችን እና ተጨማሪ መሣሪያዎችን ፈልጎ ለማግኘት የነቃ የዩኤስቢ ወደብ"</string>
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"ዩኤስቢ አንቃ"</string>
     <string name="learn_more" msgid="4690632085667273811">"የበለጠ ለመረዳት"</string>
-    <string name="global_action_screenshot" msgid="2760267567509131654">"ቅጽበታዊ ገጽ እይታ"</string>
+    <string name="global_action_screenshot" msgid="2760267567509131654">"ቅጽበታዊ ገፅ እይታ"</string>
     <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"መክፈትን አራዝም ተሰናክሏል"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ምስል ተልኳል"</string>
-    <string name="screenshot_saving_title" msgid="2298349784913287333">"ቅጽበታዊ ገጽ እይታ በማስቀመጥ ላይ..."</string>
-    <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ቅጽበታዊ ገጽ እይታን ወደ የስራ መገለጫ በማስቀመጥ ላይ…"</string>
-    <string name="screenshot_saved_title" msgid="8893267638659083153">"ቅጽበታዊ ገጽ እይታ ተቀምጧል"</string>
-    <string name="screenshot_failed_title" msgid="3259148215671936891">"ቅጽበታዊ ገጽ ዕይታን ማስቀመጥ አልተቻለም"</string>
-    <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"ቅጽበታዊ ገጽ እይታ ከመቀመጡ በፊት መሣሪያ መከፈት አለበት"</string>
-    <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ቅጽበታዊ ገጽ ዕይታን እንደገና ማንሳት ይሞክሩ"</string>
-    <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ቅጽበታዊ ገጽ እይታን ማስቀመጥ አልተቻለም"</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ቅጽበታዊ ገጽ እይታዎችን ማንሳት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም"</string>
-    <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ቅጽበታዊ ገጽ እይታዎችን ማንሳት በእርስዎ አይቲ አስተዳዳሪ ታግዷል"</string>
+    <string name="screenshot_saving_title" msgid="2298349784913287333">"ቅጽበታዊ ገፅ እይታ በማስቀመጥ ላይ..."</string>
+    <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ቅጽበታዊ ገፅ እይታን ወደ የስራ መገለጫ በማስቀመጥ ላይ…"</string>
+    <string name="screenshot_saved_title" msgid="8893267638659083153">"ቅጽበታዊ ገፅ እይታ ተቀምጧል"</string>
+    <string name="screenshot_failed_title" msgid="3259148215671936891">"ቅጽበታዊ ገፅ ዕይታን ማስቀመጥ አልተቻለም"</string>
+    <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"ቅጽበታዊ ገፅ እይታ ከመቀመጡ በፊት መሣሪያ መከፈት አለበት"</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ቅጽበታዊ ገፅ ዕይታን እንደገና ማንሳት ይሞክሩ"</string>
+    <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ቅጽበታዊ ገፅ እይታን ማስቀመጥ አልተቻለም"</string>
+    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ቅጽበታዊ ገፅ እይታዎችን ማንሳት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም"</string>
+    <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ቅጽበታዊ ገፅ እይታዎችን ማንሳት በእርስዎ አይቲ አስተዳዳሪ ታግዷል"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"አርትዕ ያድርጉ"</string>
-    <string name="screenshot_edit_description" msgid="3333092254706788906">"ቅጽበታዊ ገጽ ዕይታን አርትዕ ያድርጉ"</string>
-    <string name="screenshot_share_description" msgid="2861628935812656612">"ቅጽበታዊ ገጽ እይታን ያጋሩ"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"ቅጽበታዊ ገፅ ዕይታን አርትዕ ያድርጉ"</string>
+    <string name="screenshot_share_description" msgid="2861628935812656612">"ቅጽበታዊ ገፅ እይታን ያጋሩ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ተጨማሪ ይቅረጹ"</string>
-    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ቅጽበታዊ ገጽ ዕይታን አሰናብት"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ቅጽበታዊ ገፅ ዕይታን አሰናብት"</string>
     <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"የስራ መገለጫ መልዕክትን ያሰናብታል"</string>
-    <string name="screenshot_preview_description" msgid="7606510140714080474">"የቅጽበታዊ ገጽ ዕይታ ቅድመ-ዕይታ"</string>
+    <string name="screenshot_preview_description" msgid="7606510140714080474">"የቅጽበታዊ ገፅ ዕይታ ቅድመ-ዕይታ"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"የላይ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"የታች ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"የግራ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"የቀኝ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
     <string name="screenshot_work_profile_notification" msgid="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="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>
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"የማያ ገፅ ቀረጻን በማሰናዳት ላይ"</string>
+    <string name="screenrecord_channel_description" msgid="4147077128486138351">"ለአንድ የማያ ገፅ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"መቅረጽ ይጀመር?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"እየቀረጹ ሳለ የAndroid ስርዓት በማያ ገጽዎ ላይ የሚታይ ወይም በመሣሪያዎ ላይ የሚጫወት ማንኛውም ሚስጥራዊነት ያለው መረጃን መያዝ ይችላል። ይህ የይለፍ ቃላትን፣ የክፍያ መረጃን፣ ፎቶዎችን፣ መልዕክቶችን እና ኦዲዮን ያካትታል።"</string>
     <string name="screenrecord_option_entire_screen" msgid="1732437834603426934">"መላው ማያ ገጹን ቅረጽ"</string>
@@ -114,13 +114,13 @@
     <string name="screenrecord_start" msgid="330991441575775004">"ጀምር"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"ማያ ገጽን በመቅረጽ ላይ"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"ማያ ገጽን እና ኦዲዮን በመቅረጽ ላይ"</string>
-    <string name="screenrecord_taps_label" msgid="1595690528298857649">"በማያ ገጽ ላይ ያሉ ንክኪዎችን አሳይ"</string>
+    <string name="screenrecord_taps_label" msgid="1595690528298857649">"በማያ ገፅ ላይ ያሉ ንክኪዎችን አሳይ"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"አቁም"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"አጋራ"</string>
-    <string name="screenrecord_save_title" msgid="1886652605520893850">"የማያ ገጽ ቀረጻ ተቀምጧል"</string>
+    <string name="screenrecord_save_title" msgid="1886652605520893850">"የማያ ገፅ ቀረጻ ተቀምጧል"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"ለመመልከት መታ ያድርጉ"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"የማያ ገጽ ቀረጻን መሰረዝ ላይ ስህተት"</string>
-    <string name="screenrecord_start_error" msgid="2200660692479682368">"የማያ ገጽ ቀረጻን መጀመር ላይ ስህተት"</string>
+    <string name="screenrecord_delete_error" msgid="2870506119743013588">"የማያ ገፅ ቀረጻን መሰረዝ ላይ ስህተት"</string>
+    <string name="screenrecord_start_error" msgid="2200660692479682368">"የማያ ገፅ ቀረጻን መጀመር ላይ ስህተት"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"ተመለስ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"መነሻ"</string>
     <string name="accessibility_menu" msgid="2701163794470513040">"ምናሌ"</string>
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"በሚቀጥለው ሙከራ ላይ ትክክል ያልሆነ ሥርዓተ ጥለት ካስገቡ የእርስዎ የሥራ መገለጫ እና ውሂቡ ይሰረዛሉ።"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"በሚቀጥለው ሙከራ ላይ ትክክል ያልሆነ ፒን ካስገቡ የእርስዎ የሥራ መገለጫ እና ውሂቡ ይሰረዛሉ።"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"በሚቀጥለው ሙከራ ላይ ትክክል ያልሆነ የይለፍ ቃል ካስገቡ የእርስዎ የሥራ መገለጫ እና ውሂቡ ይሰረዛሉ።"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"የጣት አሻራ ዳሳሹን ይንኩ"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"መልክን መለየት አልተቻለም። በምትኩ የጣት አሻራ ይጠቀሙ።"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -198,10 +226,10 @@
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"የማሳወቂያ ጥላ።"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ፈጣን ቅንብሮች።"</string>
     <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"ፈጣን ቅንብሮች እና የማሳወቂያ ጥላ።"</string>
-    <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ማያ ገጽ ቆልፍ።"</string>
-    <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"የስራ ማያ ገጽ ቁልፍ"</string>
+    <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ማያ ገፅ ቆልፍ።"</string>
+    <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"የስራ ማያ ገፅ ቁልፍ"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ዝጋ"</string>
-    <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ሙሉ ለሙሉ ጸጥታ"</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ሙሉ ለሙሉ ፀጥታ"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ማንቂያዎች ብቻ"</string>
     <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"አትረብሽ።"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ብሉቱዝ።"</string>
@@ -209,7 +237,7 @@
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"ማንቂያ ለ<xliff:g id="TIME">%s</xliff:g> ተዋቅሯል።"</string>
     <string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"ተጨማሪ ጊዜ።"</string>
     <string name="accessibility_quick_settings_less_time" msgid="9110364286464977870">"ያነሰ ጊዜ።"</string>
-    <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"ማያ ገጽ መውሰድ ቆሟል።"</string>
+    <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"ማያ ገፅ መውሰድ ቆሟል።"</string>
     <string name="accessibility_brightness" msgid="5391187016177823721">"ብሩህነት ያሳዩ"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"የተንቀሳቃሽ ስልክ ውሂብ ባለበት ቆሟል"</string>
     <string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"ውሂብ ላፍታ ቆሟል"</string>
@@ -220,10 +248,10 @@
     <string name="accessibility_clear_all" msgid="970525598287244592">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# ተጨማሪ ማሳወቂያ ከውስጥ አለ።}one{# ተጨማሪ ማሳወቂያ ከውስጥ አለ።}other{# ተጨማሪ ማሳወቂያዎች ከውስጥ አሉ።}}"</string>
-    <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ማያ ገጽ በወርድ ገፅ አቀማመጥ ተቆልፏል።"</string>
-    <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ማያ ገጽ በቁም ገፅ አቀማመጥ ተቆልፏል።"</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ማያ ገፅ በወርድ ገፅ አቀማመጥ ተቆልፏል።"</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ማያ ገፅ በቁም ገፅ አቀማመጥ ተቆልፏል።"</string>
     <string name="dessert_case" msgid="9104973640704357717">"የማወራረጃ ምግቦች መያዣ"</string>
-    <string name="start_dreams" msgid="9131802557946276718">"የማያ ገጽ ማቆያ"</string>
+    <string name="start_dreams" msgid="9131802557946276718">"የማያ ገፅ ማቆያ"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"ኤተርኔት"</string>
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"አትረብሽ"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ብሉቱዝ"</string>
@@ -237,7 +265,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"በራስ ሰር አሽከርክር"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ማያ ገጽን በራስ-አሽከርክር"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"አካባቢ"</string>
-    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"የማያ ገጽ ማቆያ"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"የማያ ገፅ ማቆያ"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"የካሜራ መዳረሻ"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"የማይክሮፎን መዳረሻ"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ይገኛል"</string>
@@ -250,7 +278,7 @@
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"አውታረ መረቦች አይገኙም"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"ምንም የWi-Fi  አውታረ መረቦች የሉም"</string>
     <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"በማብራት ላይ..."</string>
-    <string name="quick_settings_cast_title" msgid="2279220930629235211">"የማያ ገጽ መውሰድ"</string>
+    <string name="quick_settings_cast_title" msgid="2279220930629235211">"የማያ ገፅ መውሰድ"</string>
     <string name="quick_settings_casting" msgid="1435880708719268055">"በመውሰድ ላይ"</string>
     <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"ያልተሰየመ መሣሪያ"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"ምንም መሣሪያዎች አይገኙም"</string>
@@ -355,11 +383,11 @@
     <string name="phone_hint" msgid="6682125338461375925">"ለስልክ ከአዶ ላይ ጠረግ ያድርጉ"</string>
     <string name="voice_hint" msgid="7476017460191291417">"ለድምጽ ረዳት ከአዶ ጠረግ ያድርጉ"</string>
     <string name="camera_hint" msgid="4519495795000658637">"ለካሜራ ከአዶ ላይ ጠረግ ያድርጉ"</string>
-    <string name="interruption_level_none_with_warning" msgid="8394434073508145437">"አጠቃላይ ጸጥታ። ይህ በተጨማሪ ማያ ገጽ አንባቢን ፀጥ ያደርጋል።"</string>
-    <string name="interruption_level_none" msgid="219484038314193379">"ሙሉ ለሙሉ ጸጥታ"</string>
+    <string name="interruption_level_none_with_warning" msgid="8394434073508145437">"አጠቃላይ ፀጥታ። ይህ በተጨማሪ ማያ ገፅ አንባቢን ፀጥ ያደርጋል።"</string>
+    <string name="interruption_level_none" msgid="219484038314193379">"ሙሉ ለሙሉ ፀጥታ"</string>
     <string name="interruption_level_priority" msgid="661294280016622209">"ቅድሚያ የሚሰጠው ብቻ"</string>
     <string name="interruption_level_alarms" msgid="2457850481335846959">"ማንቂያዎች ብቻ"</string>
-    <string name="interruption_level_none_twoline" msgid="8579382742855486372">"ሙሉ ለሙሉ\nጸጥታ"</string>
+    <string name="interruption_level_none_twoline" msgid="8579382742855486372">"ሙሉ ለሙሉ\nፀጥታ"</string>
     <string name="interruption_level_priority_twoline" msgid="8523482736582498083">"ቅድሚያ ተሰጪ\nብቻ"</string>
     <string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"ማንቂያዎች\nብቻ"</string>
     <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • በገመድ-አልባ ኃይል በመሙላት ላይ • በ<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ውስጥ ይሞላል"</string>
@@ -382,12 +410,12 @@
     <string name="user_remove_user_title" msgid="9124124694835811874">"ተጠቃሚ ይወገድ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ሁሉም የዚህ ተጠቃሚ መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"አስወግድ"</string>
-    <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> በእርስዎ ማያ ገጽ ላይ ያለን ወይም በእርስዎ መሣሪያ ላይ በመጫወት ላይ ያለን ሁሉንም መረጃ በቀረጻ ወይም casting ላይ እያለ መዳረሻ ይኖረዋል። ይህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ ፎቶዎች፣ መልዕክቶች እና እርስዎ የሚጫውቱት ኦዲዮን የመሳሰለ መረጃን ያካትታል።"</string>
-    <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ይህን ተግባር የሚያቀርበው አገልግሎት በእርስዎ ማያ ገጽ ላይ ያለን ወይም በእርስዎ መሣሪያ ላይ በመጫወት ላይ ያለን ሁሉንም መረጃ በቀረጻ ወይም casting ላይ እያለ መዳረሻ ይኖረዋል። ይህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ ፎቶዎች፣ መልዕክቶች እና እርስዎ የሚጫውቱት ኦዲዮን የመሳሰለ መረጃን ያካትታል።"</string>
+    <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> በእርስዎ ማያ ገፅ ላይ ያለን ወይም በእርስዎ መሣሪያ ላይ በመጫወት ላይ ያለን ሁሉንም መረጃ በቀረጻ ወይም casting ላይ እያለ መዳረሻ ይኖረዋል። ይህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ ፎቶዎች፣ መልዕክቶች እና እርስዎ የሚጫውቱት ኦዲዮን የመሳሰለ መረጃን ያካትታል።"</string>
+    <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ይህን ተግባር የሚያቀርበው አገልግሎት በእርስዎ ማያ ገፅ ላይ ያለን ወይም በእርስዎ መሣሪያ ላይ በመጫወት ላይ ያለን ሁሉንም መረጃ በቀረጻ ወይም casting ላይ እያለ መዳረሻ ይኖረዋል። ይህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ ፎቶዎች፣ መልዕክቶች እና እርስዎ የሚጫውቱት ኦዲዮን የመሳሰለ መረጃን ያካትታል።"</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ቀረጻ ወይም cast ማድረግ ይጀምር?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"ከ<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ጋር ቀረጻ ወይም casting ይጀምር?"</string>
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> እንዲያጋራ ወይም እንዲቀርጽ ይፈቀድለት?"</string>
-    <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"መላው ማያ ገጽ"</string>
+    <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"መላው ማያ ገፅ"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"አንድ ነጠላ መተግበሪያ"</string>
     <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"ሲያጋሩ፣ ሲቀርጹ ወይም cast ሲያደርጉ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> በማያ ገጽዎ ላይ ለሚታይ ወይም በመሣሪያዎ ላይ ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ በይለፍ ቃላት፣ በክፍያ ዝርዝሮች፣ በመልዕክቶች ወይም በሌሎች ልዩ ጥንቃቄ የሚያስፈልጋቸው መረጃዎች ላይ ጥንቃቄ ያድርጉ።"</string>
     <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"አንድን መተግበሪያ ሲያጋሩ፣ ሲቀርጹ ወይም cast ሲያደርጉ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> በዚያ መተግበሪያ ላይ ለሚታይ ወይም ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ በይለፍ ቃላት፣ በክፍያ ዝርዝሮች፣ በመልዕክቶች ወይም በሌሎች ልዩ ጥንቃቄ የሚያስፈልጋቸው መረጃዎች ላይ ጥንቃቄ ያድርጉ።"</string>
@@ -397,7 +425,7 @@
     <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"ሲያጋሩ፣ ሲቀርጹ ወይም cast ሲያደርጉ ይህ መተግበሪያ በማያ ገጽዎ ላይ ለሚታይ ወይም በመሣሪያዎ ላይ ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ በይለፍ ቃላት፣ በክፍያ ዝርዝሮች፣ በመልዕክቶች ወይም በሌሎች ልዩ ጥንቃቄ የሚያስፈልጋቸው መረጃዎች ላይ ጥንቃቄ ያድርጉ።"</string>
     <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"አንድን መተግበሪያ ሲያጋሩ፣ ሲቀርጹ ወይም cast ሲያደርጉ ይህ መተግበሪያ በዚያ መተግበሪያ ላይ ለሚታይ ወይም ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ በይለፍ ቃላት፣ በክፍያ ዝርዝሮች፣ በመልዕክቶች ወይም በሌሎች ልዩ ጥንቃቄ የሚያስፈልጋቸው መረጃዎች ላይ ጥንቃቄ ያድርጉ።"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"በእርስዎ የአይቲ አስተዳዳሪ ታግዷል"</string>
-    <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"የማያ ገጽ ቀረጻ በመሣሪያ መመሪያ ተሰናክሏል"</string>
+    <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"የማያ ገፅ ቀረጻ በመሣሪያ መመሪያ ተሰናክሏል"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ሁሉንም አጽዳ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ያቀናብሩ"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ታሪክ"</string>
@@ -450,7 +478,7 @@
     <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"የእርስዎ ግላዊ መተግበሪያዎች በ<xliff:g id="VPN_APP">%1$s</xliff:g> በኩል ከበይነመረብ ጋር ተገናኝተዋል። ኢሜይሎችን እና የአሰሳ ውሂብን ጨምሮ የአውታረ መረብ እንቅስቃሴዎ ለVPN አቅራቢዎ ይታያል።"</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"የቪፒኤን ቅንብሮችን ይክፈቱ"</string>
-    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው። ወላጅዎ የሚጠቀሙባቸውን መተግበሪያዎች፣ አካባቢዎን እና የማያ ገጽ ጊዜዎን የመሳሰሉ መረጃዎችን ማየት እና ማስተዳደር ይችላል።"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው። ወላጅዎ የሚጠቀሙባቸውን መተግበሪያዎች፣ አካባቢዎን እና የማያ ገፅ ጊዜዎን የመሳሰሉ መረጃዎችን ማየት እና ማስተዳደር ይችላል።"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"በ TrustAgent እንደተከፈተ ቀርቷል"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>። <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
@@ -538,7 +566,7 @@
     <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"አብራ"</string>
     <string name="tuner_full_importance_settings" msgid="1388025816553459059">"የኃይል ማሳወቂያ መቆጣጠሪያዎች"</string>
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"በርቷል - መልክ ላይ የተመሠረተ"</string>
-    <string name="power_notification_controls_description" msgid="1334963837572708952">"በኃይል ማሳወቂያ መቆጣጠሪያዎች አማካኝነት የአንድ መተግበሪያ ማሳወቂያዎች የአስፈላጊነት ደረጃ ከ0 እስከ 5 ድረስ ማዘጋጀት ይችላሉ። \n\n"<b>"ደረጃ 5"</b>" \n- በማሳወቂያ ዝርዝሩ አናት ላይ አሳይ \n- የሙሉ ማያ ገጽ ማቋረጥን ፍቀድ \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 4"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ከልክል \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 3"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ከልክል \n- በፍጹም አጮልቀው አይምልከቱ \n\n"<b>"ደረጃ 2"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ እና ንዝረትን በፍጹም አይኑር \n\n"<b>"ደረጃ 1"</b>" \n- የሙሉ ማያ ገጽ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ ወይም ንዝረትን በፍጹም አያደርጉ \n- ከመቆለፊያ ገጽ እና የሁኔታ አሞሌ ይደብቁ \n- በማሳወቂያ ዝርዝር ግርጌ ላይ አሳይ \n\n"<b>"ደረጃ 0"</b>" \n- ሁሉንም የመተግበሪያው ማሳወቂያዎች ያግዱ"</string>
+    <string name="power_notification_controls_description" msgid="1334963837572708952">"በኃይል ማሳወቂያ መቆጣጠሪያዎች አማካኝነት የአንድ መተግበሪያ ማሳወቂያዎች የአስፈላጊነት ደረጃ ከ0 እስከ 5 ድረስ ማዘጋጀት ይችላሉ። \n\n"<b>"ደረጃ 5"</b>" \n- በማሳወቂያ ዝርዝሩ አናት ላይ አሳይ \n- የሙሉ ማያ ገፅ ማቋረጥን ፍቀድ \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 4"</b>" \n- የሙሉ ማያ ገፅ ማቋረጥን ከልክል \n- ሁልጊዜ አጮልቀው ይመልከቱ \n\n"<b>"ደረጃ 3"</b>" \n- የሙሉ ማያ ገፅ ማቋረጥን ከልክል \n- በፍጹም አጮልቀው አይምልከቱ \n\n"<b>"ደረጃ 2"</b>" \n- የሙሉ ማያ ገፅ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ እና ንዝረትን በፍጹም አይኑር \n\n"<b>"ደረጃ 1"</b>" \n- የሙሉ ማያ ገፅ ማቋረጥን ይከልክሉ \n- በፍጹም አጮልቀው አይመልከቱ \n- ድምፅ ወይም ንዝረትን በፍጹም አያደርጉ \n- ከመቆለፊያ ገፅ እና የሁኔታ አሞሌ ይደብቁ \n- በማሳወቂያ ዝርዝር ግርጌ ላይ አሳይ \n\n"<b>"ደረጃ 0"</b>" \n- ሁሉንም የመተግበሪያው ማሳወቂያዎች ያግዱ"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"ተከናውኗል"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ተግብር"</string>
     <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ማሳወቂያዎችን አጥፋ"</string>
@@ -554,10 +582,10 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;ሁኔታ:&lt;/b&gt; ወደ ዝምታ ዝቅ ተደርጓል"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;ሁኔታ:&lt;/b&gt; ክፍተኛ ደረጃ ተሰጥቶታል"</string>
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;ሁኔታ:&lt;/b&gt; ዝቅተኛ ደረጃ ተሰጥቶታል"</string>
-    <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል"</string>
-    <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል"</string>
-    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ አትረብሽን ያቋርጣል"</string>
-    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገጽ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል፣ አትረብሽን ያቋርጣል"</string>
+    <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገፅ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል"</string>
+    <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገፅ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገፅ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ አትረብሽን ያቋርጣል"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገፅ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል፣ አትረብሽን ያቋርጣል"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ቅድሚያ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> የውይይት ባህሪያትን አይደግፍም"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"እነዚህ ማሳወቂያዎች ሊሻሻሉ አይችሉም።"</string>
@@ -604,8 +632,8 @@
     <string name="keyboard_key_media_previous" msgid="5637875709190955351">"ቀዳሚ"</string>
     <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"ወደኋላ አጠንጥን"</string>
     <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"በፍጥነት አሳልፍ"</string>
-    <string name="keyboard_key_page_up" msgid="173914303254199845">"ገጽ ወደ ላይ"</string>
-    <string name="keyboard_key_page_down" msgid="9035902490071829731">"ገጽ ወደ ታች"</string>
+    <string name="keyboard_key_page_up" msgid="173914303254199845">"ገፅ ወደ ላይ"</string>
+    <string name="keyboard_key_page_down" msgid="9035902490071829731">"ገፅ ወደ ታች"</string>
     <string name="keyboard_key_forward_del" msgid="5325501825762733459">"ሰርዝ"</string>
     <string name="keyboard_key_move_home" msgid="3496502501803911971">"መነሻ"</string>
     <string name="keyboard_key_move_end" msgid="99190401463834854">"መጨረሻ"</string>
@@ -629,10 +657,10 @@
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"መተግበሪያዎችን ይክፈቱ"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"የአሁኑ መተግበሪያ"</string>
     <string name="group_system_access_notification_shade" msgid="7116898151485382275">"የማሳወቂያ ጥላ መዳረሻ"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"ሙሉ ቅጽበታዊ ገጽ እይታ ያነሳል"</string>
+    <string name="group_system_full_screenshot" msgid="7389040853798023211">"ሙሉ ቅጽበታዊ ገፅ እይታ ያነሳል"</string>
     <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"የሥርዓት / የመተግበሪያ አቋራጮች ዝርዝር መዳረሻ"</string>
     <string name="group_system_go_back" msgid="8838454003680364227">"ተመለስ፦ ወደ ቀዳሚው ሁኔታ ይመለሳል (ተመለስ አዝራር)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"የመነሻ ማያ ገጽ መዳረሻ"</string>
+    <string name="group_system_access_home_screen" msgid="1857344316928441909">"የመነሻ ማያ ገፅ መዳረሻ"</string>
     <string name="group_system_overview_open_apps" msgid="6897128761003265350">"የክፍት መተግበሪያዎች አጠቃላይ እይታ"</string>
     <string name="group_system_cycle_forward" msgid="9202444850838205990">"የቅርብ ጊዜ መተግበሪያዎች ላይ ዑደት ያደርጋል (ወደ ፊት)"</string>
     <string name="group_system_cycle_back" msgid="5163464503638229131">"የቅርብ ጊዜ መተግበሪያዎች ላይ ዑደት ያደርጋል (ወደ ኋላ)"</string>
@@ -640,13 +668,13 @@
     <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"የተግባር አሞሌን ይደብቃል እና (እንደገና) ያሳያል"</string>
     <string name="group_system_access_system_settings" msgid="7961639365383008053">"የሥርዓት ቅንብሮች መዳረሻ"</string>
     <string name="group_system_access_google_assistant" msgid="1186152943161483864">"የGoogle ረዳት መዳረሻ"</string>
-    <string name="group_system_lock_screen" msgid="7391191300363416543">"ማያ ገጽ ቁልፍ"</string>
+    <string name="group_system_lock_screen" msgid="7391191300363416543">"ማያ ገፅ ቁልፍ"</string>
     <string name="group_system_quick_memo" msgid="2914234890158583919">"ለፈጣን ማስታወሻ የማስታወሻዎች መተግበሪያን ያወጣል"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"የሥርዓት ብዙ ተግባራትን በተመሳሳይ ጊዜ ማከናወን"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"ለአርኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገጽ ይገባል"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"ለኤልኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገጽ ይገባል"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"ከየተከፈለ ማያ ገጽ ወደ ሙሉ ገጽ ዕይታ ይቀይራል"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"በተከፈለ ማያ ገጽ ወቅት፦ መተግበሪያን ከአንዱ ወደ ሌላው ይተካል"</string>
+    <string name="system_multitasking_rhs" msgid="6593269428880305699">"ለአርኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገፅ ይገባል"</string>
+    <string name="system_multitasking_lhs" msgid="8839380725557952846">"ለኤልኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገፅ ይገባል"</string>
+    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"ከየተከፈለ ማያ ገፅ ወደ ሙሉ ገፅ ዕይታ ይቀይራል"</string>
+    <string name="system_multitasking_replace" msgid="844285282472557186">"በተከፈለ ማያ ገፅ ወቅት፦ መተግበሪያን ከአንዱ ወደ ሌላው ይተካል"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ግቤት"</string>
     <string name="input_switch_input_language_next" msgid="3394291576873633793">"የግቤት ቋንቋን ይቀይራል (ቀጣይ ቋንቋ)"</string>
     <string name="input_switch_input_language_previous" msgid="8823659252918609216">"ግቤት ቋንቋን ይቀይራል (ቀዳሚ ቋንቋ)"</string>
@@ -737,8 +765,8 @@
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"የ<xliff:g id="ID_1">%s</xliff:g> ቅንብሮችን ክፈት።"</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"የቅንብሮድ ቅደም-ተከተል አርትዕ።"</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"የኃይል ምናሌ"</string>
-    <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ገጽ <xliff:g id="ID_1">%1$d</xliff:g> ከ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
-    <string name="tuner_lock_screen" msgid="2267383813241144544">"ማያ ገጽ ቁልፍ"</string>
+    <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ገፅ <xliff:g id="ID_1">%1$d</xliff:g> ከ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
+    <string name="tuner_lock_screen" msgid="2267383813241144544">"ማያ ገፅ ቁልፍ"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"ስልክ በሙቀት ምክንያት ጠፍቷል"</string>
     <string name="thermal_shutdown_message" msgid="6142269839066172984">"የእርስዎ ስልክ በመደበኛ ሁኔታ እየሠራ ነው።\nለተጨማሪ መረጃ መታ ያድርጉ"</string>
     <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"የእርስዎ ስልክ በጣም ግሎ ነበር፣ ስለዚህ እንዲቀዘቅዝ ጠፍቷል። የእርስዎ ስልክ አሁን በመደበኝነት እያሄደ ነው።\n\nየሚከተሉትን ካደረጉ የእርስዎ በጣም ሊግል ይችላል፦\n	• ኃይል በጣም የሚጠቀሙ መተግበሪያዎችን (እንደ ጨዋታ፣ ቪዲዮ ወይም የአሰሳ መተግበሪያዎች ያሉ) ከተጠቀሙ\n	• ትላልቅ ፋይሎችን ካወረዱ ወይም ከሰቀሉ\n	• ስልክዎን በከፍተኛ ሙቀት ውስጥ ከተጠቀሙ"</string>
@@ -766,7 +794,7 @@
     <string name="tuner_app" msgid="6949280415826686972">"የ<xliff:g id="APP">%1$s</xliff:g> መተግበሪያ"</string>
     <string name="notification_channel_alerts" msgid="3385787053375150046">"ማንቂያዎች"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ባትሪ"</string>
-    <string name="notification_channel_screenshot" msgid="7665814998932211997">"ቅጽበታዊ ገጽ እይታዎች"</string>
+    <string name="notification_channel_screenshot" msgid="7665814998932211997">"ቅጽበታዊ ገፅ እይታዎች"</string>
     <string name="notification_channel_instant" msgid="7556135423486752680">"ቅጽበታዊ መተግበሪያዎች"</string>
     <string name="notification_channel_setup" msgid="7660580986090760350">"ውቅረት"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ማከማቻ"</string>
@@ -836,7 +864,7 @@
     <string name="accessibility_control_move_left" msgid="8156206978511401995">"ወደ ግራ ውሰድ"</string>
     <string name="accessibility_control_move_right" msgid="8926821093629582888">"ወደ ቀኝ ውሰድ"</string>
     <string name="magnification_mode_switch_description" msgid="2698364322069934733">"የማጉላት ማብሪያ/ማጥፊያ"</string>
-    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ሙሉ ገጽ እይታን ያጉሉ"</string>
+    <string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ሙሉ ገፅ እይታን ያጉሉ"</string>
     <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"የማያ ገጹን ክፍል አጉላ"</string>
     <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"የማጉያ ቅንብሮችን ክፈት"</string>
     <string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"መጠን ለመቀየር ጠርዙን ይዘው ይጎትቱ"</string>
@@ -854,7 +882,7 @@
     <string name="accessibility_magnification_medium" msgid="6994632616884562625">"መካከለኛ"</string>
     <string name="accessibility_magnification_small" msgid="8144502090651099970">"ትንሽ"</string>
     <string name="accessibility_magnification_large" msgid="6602944330021308774">"ትልቅ"</string>
-    <string name="accessibility_magnification_fullscreen" msgid="5043514702759201964">"ሙሉ ገጽ ዕይታ"</string>
+    <string name="accessibility_magnification_fullscreen" msgid="5043514702759201964">"ሙሉ ገፅ ዕይታ"</string>
     <string name="accessibility_magnification_done" msgid="263349129937348512">"ተከናውኗል"</string>
     <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"አርትዕ"</string>
     <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"የማጉያ መስኮት ቅንብሮች"</string>
@@ -902,9 +930,9 @@
     <string name="controls_dialog_remove" msgid="3775288002711561936">"አስወግድ"</string>
     <string name="controls_dialog_message" msgid="342066938390663844">"በ<xliff:g id="APP">%s</xliff:g> የተጠቆመ"</string>
     <string name="controls_tile_locked" msgid="731547768182831938">"መሣሪያ ተቆልፏል"</string>
-    <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ከማያ ገጽ ቆልፍ ላይ መሳሪያዎች ይታዩ እና ይቆጣጠሩ?"</string>
-    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ለውጫዊ መሳሪያዎችዎ መቆጣጠሪያዎችን ወደ ማያ ገጽ ቆልፍ ማከል ይችላሉ።\n\nየእርስዎ መሣሪያ መተግበሪያ የእርስዎን ስልክ ወይም ጡባዊ ሳይከፍቱ አንዳንድ መሣሪያዎችን እንዲቆጣጠሩ ሊፈቅድልዎ ይችላል።\n\nበቅንብሮች ውስጥ በማንኛውም ጊዜ ለውጦችን ማድረግ ይችላሉ።"</string>
-    <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"መሳሪያዎች ከማያ ገጽ ቆልፍ ይቆጣጠሩ?"</string>
+    <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ከማያ ገፅ ቆልፍ ላይ መሳሪያዎች ይታዩ እና ይቆጣጠሩ?"</string>
+    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ለውጫዊ መሳሪያዎችዎ መቆጣጠሪያዎችን ወደ ማያ ገፅ ቆልፍ ማከል ይችላሉ።\n\nየእርስዎ መሣሪያ መተግበሪያ የእርስዎን ስልክ ወይም ጡባዊ ሳይከፍቱ አንዳንድ መሣሪያዎችን እንዲቆጣጠሩ ሊፈቅድልዎ ይችላል።\n\nበቅንብሮች ውስጥ በማንኛውም ጊዜ ለውጦችን ማድረግ ይችላሉ።"</string>
+    <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"መሳሪያዎች ከማያ ገፅ ቆልፍ ይቆጣጠሩ?"</string>
     <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"የእርስዎን ስልክ ወይም ጡባዊ ሳይከፍቱ አንዳንድ መሣሪያዎችን መቆጣጠር ይችላሉ። የእርስዎ መሣሪያ መተግበሪያ የትኞቹን መሣሪያዎች በዚህ መንገድ መቆጣጠር እንደሚቻል ይወስናል።"</string>
     <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"አይ፣ አመሰግናለሁ"</string>
     <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"አዎ"</string>
@@ -1075,7 +1103,7 @@
     <string name="clipboard_edit" msgid="4500155216174011640">"አርትዕ"</string>
     <string name="add" msgid="81036585205287996">"አክል"</string>
     <string name="manage_users" msgid="1823875311934643849">"ተጠቃሚዎችን ያስተዳድሩ"</string>
-    <string name="drag_split_not_supported" msgid="7173481676120546121">"ይህ ማሳወቂያ ወደ የተከፈለ ማያ ገጽ መጎተትን አይደግፍም"</string>
+    <string name="drag_split_not_supported" msgid="7173481676120546121">"ይህ ማሳወቂያ ወደ የተከፈለ ማያ ገፅ መጎተትን አይደግፍም"</string>
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi አይገኝም"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"የቅድሚያ ሁነታ"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ማንቂያ ተቀናብሯል"</string>
@@ -1123,15 +1151,13 @@
     <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>
-    <string name="lock_screen_settings" msgid="6152703934761402399">"ማያ ገጽ ቁልፍን አብጅ"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="6152703934761402399">"ማያ ገፅ ቁልፍን አብጅ"</string>
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"የማያ ገጽ ቁልፍን ለማበጀት ይክፈቱ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi አይገኝም"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ካሜራ ታግዷል"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ካሜራ እና ማይክሮፎን ታግደዋል"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ማይክሮፎን ታግዷል"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"የቅድሚያ ሁነታ በርቷል"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"የረዳት ትኩረት በርቷል"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"በቅንብሮች ውስጥ ነባሪ የማስታወሻዎች መተግበሪያን ያቀናብሩ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml
index a89d79be..d3d1433 100644
--- a/packages/SystemUI/res/values-am/strings_tv.xml
+++ b/packages/SystemUI/res/values-am/strings_tv.xml
@@ -30,6 +30,6 @@
     <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ማይክሮፎን መቅዳት አቁሟል"</string>
     <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ካሜራ መቅረጽ አቁሟል"</string>
     <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ካሜራ መቅረጽ እና ማይክሮፎን መቅዳት አቁመዋል"</string>
-    <string name="screen_recording_announcement" msgid="2996750593472241520">"የማያ ገጽ ቀረጻ ተጀምሯል"</string>
-    <string name="screen_stopped_recording_announcement" msgid="979749439036681416">"የማያ ገጽ ቀረጻ ቆሟል"</string>
+    <string name="screen_recording_announcement" msgid="2996750593472241520">"የማያ ገፅ ቀረጻ ተጀምሯል"</string>
+    <string name="screen_stopped_recording_announcement" msgid="979749439036681416">"የማያ ገፅ ቀረጻ ቆሟል"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 29a7c50..22e3c49 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"عند إدخال نقش غير صحيح في المحاولة التالية، سيتم حذف ملفك الشخصي للعمل وبياناته."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"عند إدخال رقم تعريف شخصي غير صحيح في المحاولة التالية، سيتم حذف ملفك الشخصي للعمل وبياناته."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"عند إدخال كلمة مرور غير صحيحة في المحاولة التالية، سيتم حذف ملفك الشخصي للعمل وبياناته."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"المس أداة استشعار بصمة الإصبع"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"يتعذّر التعرّف على الوجه. استخدِم بصمة الإصبع بدلاً من ذلك."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"التبديل إلى الملف الشخصي للعمل"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"إغلاق"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"تخصيص شاشة القفل"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"الفتح لتخصيص شاشة القفل"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏لا يتوفّر اتصال Wi-Fi."</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"استخدام الكاميرا محظور."</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"استخدام الكاميرا والميكروفون محظور."</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"استخدام الميكروفون محظور."</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"وضع الأولوية مفعّل."</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"‏ميزة لفت انتباه \"مساعد Google\" مفعّلة."</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"يمكنك ضبط تطبيق تدوين الملاحظات التلقائي في \"الإعدادات\"."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 775c8d4..6df58a3 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -24,7 +24,7 @@
     <string name="battery_low_description" msgid="3282977755476423966">"আপোনাৰ <xliff:g id="PERCENTAGE">%s</xliff:g> বেটাৰী বাকী আছে। বেটাৰী সঞ্চয়কাৰীয়ে গাঢ় ৰঙৰ থীম অন কৰে, নেপথ্যৰ কাৰ্যকলাপ সীমাবদ্ধ কৰে আৰু জাননী পলম কৰে।"</string>
     <string name="battery_low_intro" msgid="5148725009653088790">"বেটাৰী সঞ্চয়কাৰীয়ে গাঢ় ৰঙৰ থীম অন কৰে, নেপথ্যৰ কাৰ্যকলাপ সীমাবদ্ধ কৰে আৰু জাননী পলম কৰে।"</string>
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> বাকী আছে"</string>
-    <string name="invalid_charger_title" msgid="938685362320735167">"ইউএছবি জৰিয়তে চ্চাৰ্জ কৰিব নোৱাৰি"</string>
+    <string name="invalid_charger_title" msgid="938685362320735167">"ইউএছবি জৰিয়তে চাৰ্জ কৰিব নোৱাৰি"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"আপোনাৰ ডিভাইচৰ লগত পোৱা চ্চাৰ্জাৰটো ব্যৱহাৰ কৰক।"</string>
     <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"বেটাৰী সঞ্চয়কাৰী অন কৰিবনে?"</string>
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"বেটাৰী সঞ্চয়কাৰীৰ বিষয়ে"</string>
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"আপুনি পৰৱৰ্তী প্ৰয়াসত এটা ভুল আৰ্হি দিলে, আপোনাৰ কৰ্মস্থানৰ প্ৰ’ফাইল আৰু ইয়াৰ ডেটা মচি পেলোৱা হ’ব।"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"আপুনি পৰৱৰ্তী প্ৰয়াসত এটা ভুল পিন দিলে, আপোনাৰ কৰ্মস্থানৰ প্ৰ’ফাইল আৰু ইয়াৰ ডেটা মচি পেলোৱা হ’ব।"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"আপুনি পৰৱৰ্তী প্ৰয়াসত এটা ভুল পাছৱৰ্ড দিলে, আপোনাৰ কৰ্মস্থানৰ প্ৰ’ফাইল আৰু ইয়াৰ ডেটা মচি পেলোৱা হ’ব।"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো স্পৰ্শ কৰক"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"মুখাৱয়ব চিনিব নোৱাৰি। ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক।"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -712,7 +740,7 @@
   </string-array>
   <string-array name="battery_options">
     <item msgid="7714004721411852551">"সদায় শতাংশত দেখুৱাব"</item>
-    <item msgid="3805744470661798712">"চ্চাৰ্জ কৰি থকাৰ সময়ত শতাংশ দেখুৱাওক (ডিফ\'ল্ট)"</item>
+    <item msgid="3805744470661798712">"চাৰ্জ কৰি থকাৰ সময়ত শতাংশ দেখুৱাওক (ডিফ\'ল্ট)"</item>
     <item msgid="8619482474544321778">"এই আইকনটো নেদেখুৱাব"</item>
   </string-array>
     <string name="tuner_low_priority" msgid="8412666814123009820">"কম গুৰুত্বপূৰ্ণ জাননীৰ আইকনসমূহ দেখুৱাওক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index c30b283..d9ecaee 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Növbəti cəhddə yanlış model daxil etsəniz, iş profili və datası silinəcək."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Növbəti cəhddə yanlış PIN daxil etsəniz, iş profili və datası silinəcək."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Növbəti cəhddə yanlış parol daxil etsəniz, iş profili və datası silinəcək."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Barmaq izi sensoruna klikləyin"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Tanımaq olmur. Barmaq izini işlədin."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profilinə keçin"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bağlayın"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Kilid ekranını fərdiləşdirin"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Kilid ekranını fərdiləşdirmək üçün kiliddən çıxarın"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi əlçatan deyil"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera bloklanıb"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera və mikrofon bloklanıb"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon bloklanıb"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritet rejimi aktivdir"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent aktivdir"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ayarlarda defolt qeydlər tətbiqi ayarlayın"</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 81e2eff..fca07c8 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ako unesete netačan šablon pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ako unesete netačan PIN pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ako unesete netačnu lozinku pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dodirnite senzor za otisak prsta"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Lice nije prepoznato. Koristite otisak prsta."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da biste videli još"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavaju se preporuke"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Želite li da sakrijete ovu kontrolu za medije za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Želite da sakrijete ovu kontrolu za medije za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuelna sesija medija ne može da bude sakrivena."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređi na poslovni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključani ekran"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da biste prilagodili zaključani ekran"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi nije dostupan"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera i mikrofon su blokirani"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon je blokiran"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritetni režim je uključen"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Pomoćnik je u aktivnom stanju"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Podesite podrazumevanu aplikaciju za beleške u Podešavanjima"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index e742c01..196e030 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Калі вы ўведзяце няправільны ўзор разблакіроўкі яшчэ раз, ваш працоўны профіль і звязаныя з ім даныя будуць выдалены."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Калі вы ўведзяце няправільны PIN-код яшчэ раз, ваш працоўны профіль і звязаныя з ім даныя будуць выдалены."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Калі вы ўведзяце няправільны пароль яшчэ раз, ваш працоўны профіль і звязаныя з ім даныя будуць выдалены."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Дакраніцеся да сканера адбіткаў пальцаў"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Твар не распазнаны. Скарыстайце адбітак пальца."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пераключыцца на працоўны профіль"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыць"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Наладзіць экран блакіроўкі"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Разблакіруйце, каб наладзіць экран блакіроўкі"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Сетка Wi-Fi недаступная"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камера заблакіравана"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камера і мікрафон заблакіраваны"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Мікрафон заблакіраваны"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Прыярытэтны рэжым уключаны"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Памочнік гатовы выконваць каманды"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайце ў Наладах стандартную праграму для нататак"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 910ecfc..8cd1efd 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ако въведете неправилна фигура при следващия опит, служебният ви потребителски профил и данните в него ще бъдат изтрити."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ако въведете неправилен ПИН код при следващия опит, служебният ви потребителски профил и данните в него ще бъдат изтрити."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ако въведете неправилна парола при следващия опит, служебният ви потребителски профил и данните в него ще бъдат изтрити."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Докоснете сензора за отпечатъци"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Лицето не е разпознато. Използвайте отпечатък."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Прекарайте пръст, за да видите повече"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Препоръките се зареждат"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Мултимедия"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Скриване за <xliff:g id="APP_NAME">%1$s</xliff:g> на контролата за мултимедия?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Скриване на мултимед. контрола за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Текущата сесия за мултимедия не бе скрита."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриване"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Превключване към служебния потребителски профил"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затваряне"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Персонализ. на заключения екран"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Отключете, за да персонализирате заключения екран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi не е налице"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Достъпът до камерата е блокиран"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Достъпът до камерата и микрофона е блокиран"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Достъпът до микрофона е блокиран"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Приоритетният режим е включен"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Функцията за активиране на Асистент е включена"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайте стандартно приложение за бележки от настройките"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 9e029dc..692a2dc 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -168,6 +168,20 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"আপনি পরের বারও ভুল প্যাটার্ন দিলে আপনার অফিস প্রোফাইল এবং তার ডেটা মুছে দেওয়া হবে।"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"আপনি পরের বারও ভুল পিন দিলে আপনার অফিস প্রোফাইল এবং তার ডেটা মুছে দেওয়া হবে।"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"আপনি পরের বারও ভুল পাসওয়ার্ড দিলে আপনার অফিস প্রোফাইল এবং তার ডেটা মুছে দেওয়া হবে।"</string>
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"সেট-আপ করুন"</string>
+    <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"এখন নয়"</string>
+    <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"সুরক্ষা ও পারফর্ম্যান্স উন্নত করতে এটি প্রয়োজন"</string>
+    <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"\'ফিঙ্গারপ্রিন্ট আনলক\' আবার সেট-আপ করুন"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"ফিঙ্গারপ্রিন্ট আনলক"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"\'ফিঙ্গারপ্রিন্ট আনলক\' সেট-আপ করুন"</string>
+    <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"\'ফিঙ্গারপ্রিন্ট আনলক\' আবার সেট-আপ করতে, আপনার বর্তমানে থাকা ফিঙ্গারপ্রিন্ট ইমেজ ও মডেল মুছে ফেলা হবে।\n\nমুছে ফেলা হয়ে গেলে, আপনার ফোন আনলক করতে অথবা নিজের পরিচয় যাচাই করার জন্য ফিঙ্গারপ্রিন্ট ব্যবহার করতে হলে আপনাকে আবার \'ফিঙ্গারপ্রিন্ট আনলক\' সেট-আপ করতে হবে।"</string>
+    <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"\'ফিঙ্গারপ্রিন্ট আনলক\' আবার সেট-আপ করতে, আপনার বর্তমানে থাকা ফিঙ্গারপ্রিন্ট ইমেজ ও মডেল মুছে ফেলা হবে।\n\nমুছে ফেলা হয়ে গেলে, আপনার ফোন আনলক করতে অথবা নিজের পরিচয় যাচাই করার জন্য ফিঙ্গারপ্রিন্ট ব্যবহার করতে হলে আপনাকে আবার \'ফিঙ্গারপ্রিন্ট আনলক\' সেট-আপ করতে হবে।"</string>
+    <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"\'ফিঙ্গারপ্রিন্ট আনলক\' সেট-আপ করা যায়নি। আবার চেষ্টা করতে সেটিংসে যান।"</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"\'ফেস আনলক\' আবার সেট আপ করুন"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"ফেস আনলক"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"\'ফেস আনলক\' সেট-আপ করুন"</string>
+    <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"\'ফেস আনলক\' আবার সেট-আপ করতে, বর্তমানে থাকা আপনার ফেস মডেলটি মুছে ফেলা হবে।\n\nফেস ব্যবহার করে আপনার ফোন আনলক করার জন্য আপনাকে আবার এই ফিচার সেট-আপ করতে হবে।"</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"\'ফেস আনলক\' সেট-আপ করা যায়নি। আবার চেষ্টা করতে সেটিংসে যান।"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"আঙ্গুলের ছাপের সেন্সর স্পর্শ করুন"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"মুখ শনাক্ত করতে পারছি না। পরিবর্তে আঙ্গুলের ছাপ ব্যবহার করুন।"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -885,8 +899,7 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"পছন্দসই থেকে সরান"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> অবস্থানে সরান"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"নিয়ন্ত্রণ"</string>
-    <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
-    <skip />
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"ঝটপট অ্যাক্সেস করতে, ডিভাইস সংক্রান্ত কন্ট্রোল বেছে নিন"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"কন্ট্রোলগুলিকে আবার সাজানোর জন্য ধরে রেখে টেনে আনুন"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"সমস্ত কন্ট্রোল সরানো হয়েছে"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"পরিবর্তন সেভ করা হয়নি"</string>
@@ -1124,14 +1137,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"অফিস প্রোফাইলে পাল্টে নিন"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ করুন"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"লক স্ক্রিন কাস্টমাইজ করুন"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"লক স্ক্রিন কাস্টমাইজ করতে আনলক করুন"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ওয়াই-ফাই উপলভ্য নয়"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ক্যামেরার অ্যাক্সেস ব্লক করা আছে"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ক্যামেরা এবং মাইক্রোফোনের অ্যাক্সেস ব্লক করা আছে"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"মাইক্রোফোনের অ্যাক্সেস ব্লক করা আছে"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"\'প্রায়োরিটি\' মোড চালু করা আছে"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"অ্যাসিস্ট্যান্ট আপনার কথা শোনার জন্য চালু করা আছে"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"\'সেটিংস\' থেকে ডিফল্ট নোট নেওয়ার অ্যাপ সেট করুন"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 34dc7f5..82d59df 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -168,6 +168,20 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ako u sljedećem pokušaju unesete neispravan uzorak, vaš radni profil i njegovi podaci će se izbrisati."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ako u sljedećem pokušaju unesete neispravan PIN, vaš radni profil i njegovi podaci će se izbrisati."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ako u sljedećem pokušaju unesete neispravnu lozinku, vaš radni profil i njegovi podaci će se izbrisati."</string>
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"Postavi"</string>
+    <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"Ne sada"</string>
+    <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"Ovo je potrebno radi poboljšanja sigurnosti i performansi"</string>
+    <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Ponovo postavite otključavanje otiskom prsta"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Otključavanje otiskom prsta"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Postavite otključavanje otiskom prsta"</string>
+    <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Da ponovo postavite otključavanje otiskom prsta, trenutne slike i modeli otiska prsta će se izbrisati.\n\nNakon što se izbrišu, morat ćete ponovo postaviti otključavanje otiskom prsta da koristite otisak prsta za otključavanje telefona ili potvrdu identiteta."</string>
+    <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Da ponovo postavite otključavanje otiskom prsta, trenutne slike i model otiska prsta će se izbrisati.\n\nNakon što se izbrišu, morat ćete ponovo postaviti otključavanje otiskom prsta da koristite otisak prsta za otključavanje telefona ili potvrdu identiteta."</string>
+    <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Postavljanje otključavanja otiskom prsta nije uspjelo. Idite u Postavke da pokušate ponovo."</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Ponovo postavite otključavanje licem"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Otključavanje licem"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Postavite otključavanje licem"</string>
+    <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Da ponovo postavite otključavanje licem, trenutni model lica će se izbrisati.\n\nMorat ćete ponovo postaviti ovu funkciju da koristite lice za otključavanje telefona."</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Postavljanje otključavanja licem nije uspjelo. Idite u Postavke da pokušate ponovo."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dodirnite senzor za otisak prsta"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nije moguće prepoznati lice. Koristite otisak prsta."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -885,8 +899,7 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"uklonite iz omiljenog"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"Premjesti na poziciju <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrole"</string>
-    <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
-    <skip />
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Odaberite kontrole uređaja da pristupite brzo"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Držite i prevucite da preuredite kontrole"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"Sve kontrole su uklonjene"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Promjene nisu sačuvane"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 1a8239b..b34a0a1 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si tornes a introduir un patró incorrecte, se suprimirà el perfil de treball i les dades que contingui."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si tornes a introduir un PIN incorrecte, se suprimirà el perfil de treball i les dades que contingui."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si tornes a introduir una contrasenya incorrecta, se suprimirà el perfil de treball i les dades que contingui."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toca el sensor d\'empremtes digitals"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"No podem detectar la cara. Usa l\'empremta digital."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Llisca per veure\'n més"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregant les recomanacions"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Multimèdia"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Vols amagar aquest control multimèdia per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Amagar aquest control multimèdia per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"La sessió multimèdia actual no es pot amagar."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Amaga"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Reprèn"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Canvia al perfil de treball"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tanca"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalitza pantalla de bloqueig"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloqueja per personalitzar la pantalla de bloqueig"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"No hi ha cap Wi‑Fi disponible"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"La càmera està bloquejada"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"La càmera i el micròfon estan bloquejats"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"El micròfon està bloquejat"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"El mode Prioritat està activat"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"L\'Assistent està activat"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defineix l\'aplicació de notes predeterminada a Configuració"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index c26bd88..380635d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Pokud při příštím pokusu zadáte nesprávné gesto, váš pracovní profil a přidružená data budou smazána."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Pokud při příštím pokusu zadáte nesprávný PIN, váš pracovní profil a přidružená data budou smazána."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Pokud při příštím pokusu zadáte nesprávné heslo, váš pracovní profil a přidružená data budou smazána."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotkněte se snímače otisků prstů"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Obličej se nepodařilo rozpoznat. Použijte místo něj otisk prstu."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Přepnout na pracovní profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavřít"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Přizpůsobit zámek obrazovky"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Pokud chcete upravit obrazovku uzamčení, odemkněte zařízení"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Síť Wi-Fi není dostupná"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokována"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera a mikrofon jsou blokovány"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon je blokován"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Režim priority je zapnutý"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Pozornost Asistenta je zapnutá"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Výchozí aplikaci pro poznámky nastavíte v Nastavení"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index bb3841d..f3409a3 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -168,6 +168,20 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Hvis du angiver et forkert mønster i næste forsøg, slettes din arbejdsprofil og de tilhørende data."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Hvis du angiver en forkert pinkode i næste forsøg, slettes din arbejdsprofil og de tilhørende data."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Hvis du angiver en forkert adgangskode i næste forsøg, slettes din arbejdsprofil og de tilhørende data."</string>
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"Konfigurer"</string>
+    <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"Ikke nu"</string>
+    <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"Dette er påkrævet for at forbedre sikkerheden og ydeevnen"</string>
+    <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Konfigurer oplåsning med fingeraftryk igen"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Oplåsning med fingeraftryk"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Konfigurer oplåsning med fingeraftryk"</string>
+    <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Hvis du vil konfigurere oplåsning med fingeraftryk igen, bliver dine nuværende fingeraftryksbilleder og -modeller slettet.\n\nNår de er slettet, skal du konfigurere oplåsning med fingeraftryk igen for at bruge dit fingeraftryk til at låse din telefon op eller verificere din identitet."</string>
+    <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Hvis du vil konfigurere oplåsning med fingeraftryk igen, bliver dine nuværende fingeraftryksbilleder og -modeller slettet.\n\nNår de er slettet, skal du konfigurere oplåsning med fingeraftryk igen for at bruge dit fingeraftryk til at låse din telefon op eller verificere din identitet."</string>
+    <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Oplåsning med fingeraftryk kunne ikke konfigureres. Gå til Indstillinger for at prøve igen."</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Konfigurer ansigtslås igen"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Ansigtslås"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Konfigurer ansigtslås"</string>
+    <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Hvis du vil konfigurere ansigtslås igen, bliver din nuværende ansigtsmodel slettet.\n\nDu skal konfigurere funktionen igen for at bruge ansigtsgenkendelse til at låse din telefon op."</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Ansigtslås kunne ikke konfigureres. Gå til Indstillinger for at prøve igen."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sæt fingeren på fingeraftrykssensoren"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ansigtet kan ikke genkendes. Brug fingeraftryk i stedet."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -885,8 +899,7 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"fjern fra favoritter"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"Flyt til position <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"Betjeningselementer"</string>
-    <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
-    <skip />
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Vælg, hvilke enhedsindstillinger du vil have hurtig adgang til"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Flyt et felt ved at holde det nede og trække"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"Alle styringselementerne blev fjernet"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Ændringerne blev ikke gemt"</string>
@@ -1124,14 +1137,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skift til arbejdsprofil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Luk"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Tilpas låseskærm"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Lås op for at tilpasse låseskærmen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi er ikke tilgængeligt"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kameraet er blokeret"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Der er blokeret for kameraet og mikrofonen"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofonen er blokeret"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritetstilstand er aktiveret"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent lytter"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Angiv standardapp til noter i Indstillinger"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 23ba2fe..415a430 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Wenn du beim nächsten Versuch ein falsches Muster eingibst, werden dein Arbeitsprofil und die zugehörigen Daten gelöscht."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Wenn du beim nächsten Versuch eine falsche PIN eingibst, werden dein Arbeitsprofil und die zugehörigen Daten gelöscht."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Wenn du beim nächsten Versuch ein falsches Passwort eingibst, werden dein Arbeitsprofil und die zugehörigen Daten gelöscht."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Berühre den Fingerabdrucksensor"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Gesicht wurde nicht erkannt. Verwende stattdessen den Fingerabdruck."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -643,10 +671,10 @@
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Sperrbildschirm"</string>
     <string name="group_system_quick_memo" msgid="2914234890158583919">"Notizen-App für schnelles Memo aufrufen"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System-Multitasking"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Geteilten Bildschirm aktivieren, aktuelle App rechts"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Geteilten Bildschirm aktivieren, aktuelle App links"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Vom geteilten Bildschirm zum Vollbild wechseln"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Im geteilten Bildschirm: eine App durch eine andere ersetzen"</string>
+    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Splitscreen aktivieren, aktuelle App rechts"</string>
+    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Splitscreen aktivieren, aktuelle App links"</string>
+    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Vom Splitscreen zum Vollbild wechseln"</string>
+    <string name="system_multitasking_replace" msgid="844285282472557186">"Im Splitscreen: eine App durch eine andere ersetzen"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Eingabe"</string>
     <string name="input_switch_input_language_next" msgid="3394291576873633793">"Eingabesprache ändern (nächste Sprache)"</string>
     <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Eingabesprache ändern (vorherige Sprache)"</string>
@@ -891,12 +919,9 @@
     <string name="controls_favorite_removed" msgid="5276978408529217272">"Alle Steuerelemente entfernt"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Änderungen nicht gespeichert"</string>
     <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Andere Apps ansehen"</string>
-    <!-- no translation found for controls_favorite_rearrange_button (2942788904364641185) -->
-    <skip />
-    <!-- no translation found for controls_favorite_add_controls (1221420435546694004) -->
-    <skip />
-    <!-- no translation found for controls_favorite_back_to_editing (184125114090062713) -->
-    <skip />
+    <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Neu anordnen"</string>
+    <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Steuerelemente hinzufügen"</string>
+    <string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Zurück zum Bearbeiten"</string>
     <string name="controls_favorite_load_error" msgid="5126216176144877419">"Steuerelemente konnten nicht geladen werden. Prüfe in der <xliff:g id="APP">%s</xliff:g> App, ob die Einstellungen möglicherweise geändert wurden."</string>
     <string name="controls_favorite_load_none" msgid="7687593026725357775">"Kompatible Steuerelemente nicht verfügbar"</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Andere"</string>
@@ -920,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Wischen, um weitere zu sehen"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Empfehlungen werden geladen"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Medien"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Dieses Mediensteuerelement für <xliff:g id="APP_NAME">%1$s</xliff:g> ausblenden?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Mediensteuerung für <xliff:g id="APP_NAME">%1$s</xliff:g> ausblenden?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Die Mediensitzung kann nicht ausgeblendet werden."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ausblenden"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string>
@@ -1078,7 +1103,7 @@
     <string name="clipboard_edit" msgid="4500155216174011640">"bearbeiten"</string>
     <string name="add" msgid="81036585205287996">"Hinzufügen"</string>
     <string name="manage_users" msgid="1823875311934643849">"Nutzer verwalten"</string>
-    <string name="drag_split_not_supported" msgid="7173481676120546121">"Diese Benachrichtigung lässt sich nicht auf einen geteilten Bildschirm ziehen"</string>
+    <string name="drag_split_not_supported" msgid="7173481676120546121">"Diese Benachrichtigung lässt sich nicht auf einen Splitscreen ziehen"</string>
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN nicht verfügbar"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritätsmodus"</string>
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wecker gestellt"</string>
@@ -1127,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Zum Arbeitsprofil wechseln"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Schließen"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Sperrbildschirm personalisieren"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Zum Anpassen des Sperrbildschirms entsperren"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Kein WLAN verfügbar"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera blockiert"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera und Mikrofon blockiert"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon blockiert"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritätsmodus an"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant-Aktivierung an"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standard-Notizen-App in den Einstellungen einrichten"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index b7ad7b9..c3d3477 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Εάν εισαγάγετε εσφαλμένο μοτίβο στην επόμενη προσπάθεια, το προφίλ εργασίας σας και τα δεδομένα του θα διαγραφούν."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Εάν εισαγάγετε εσφαλμένο PIN στην επόμενη προσπάθεια, το προφίλ εργασίας σας και τα δεδομένα του θα διαγραφούν."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Εάν εισαγάγετε εσφαλμένο κωδικό πρόσβασης στην επόμενη προσπάθεια, το προφίλ εργασίας σας και τα δεδομένα του θα διαγραφούν."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Αγγίξτε τον αισθητήρα δακτυλικού αποτυπώματος"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Το πρόσωπο δεν αναγνωρίζεται. Χρησιμ. δακτ. αποτ."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Σύρετε για να δείτε περισσότερα."</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Φόρτωση προτάσεων"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Μέσα"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Απόκρυψη στοιχείων ελέγχου μέσων για την εφαρμ. <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Απόκρυψη στοιχ. ελέγχου μέσων για <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Αδυναμία απόκρ. τρέχουσας περιόδ. λειτουργ. μέσου."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Απόκρυψη"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Συνέχιση"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Εναλλαγή σε προφίλ εργασίας"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Κλείσιμο"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Προσαρμογή οθόνης κλειδώματος"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ξεκλειδώστε για προσαρμογή της οθόνης κλειδώματος"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Δεν υπάρχει διαθέσιμο δίκτυο Wi-Fi"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Η κάμερα έχει αποκλειστεί"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Η κάμερα και το μικρόφωνο έχουν αποκλειστεί"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Το μικρόφωνο έχει αποκλειστεί"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Η λειτουργία προτεραιότητας είναι ενεργοποιημένη"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Ο Βοηθός βρίσκεται σε αναμονή"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ορίστε την προεπιλεγμένη εφαρμογή σημειώσεων στις Ρυθμίσεις"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index bed2089..7c47b52 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognise face. Use fingerprint instead."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 01cccac..f1a1e66 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -168,6 +168,20 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"Set up"</string>
+    <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"Not now"</string>
+    <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"This is required to improve security and performance"</string>
+    <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Set up Fingerprint Unlock again"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Fingerprint Unlock"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Set up Fingerprint Unlock"</string>
+    <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"To set up Fingerprint Unlock again, your current fingerprint images and models will be deleted.\n\nAfter theyre deleted, youll need to set up Fingerprint Unlock again to use your fingerprint to unlock your phone or verify its you."</string>
+    <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"To set up Fingerprint Unlock again, your current fingerprint images and model will be deleted.\n\nAfter theyre deleted, youll need to set up Fingerprint Unlock again to use your fingerprint to unlock your phone or verify its you."</string>
+    <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Couldn’t set up fingerprint unlock. Go to Settings to try again."</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Set up Face Unlock again"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Face Unlock"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Set up Face Unlock"</string>
+    <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"To set up Face Unlock again, your current face model will be deleted.\n\nYoull need to set up this feature again to use your face to unlock your phone."</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Couldn’t set up face unlock. Go to Settings to try again."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognize face. Use fingerprint instead."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -465,15 +479,15 @@
     <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Lowered to safer volume"</string>
     <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"The volume has been high for longer than recommended"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"App is pinned"</string>
-    <string name="screen_pinning_description" msgid="8699395373875667743">"This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin."</string>
-    <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin."</string>
+    <string name="screen_pinning_description" msgid="8699395373875667743">"This keeps it in view until you unpin. Touch and hold Back and Overview to unpin."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"This keeps it in view until you unpin. Touch and hold Back and Home to unpin."</string>
     <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"This keeps it in view until you unpin. Swipe up &amp; hold to unpin."</string>
-    <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
-    <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
+    <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"This keeps it in view until you unpin. Touch and hold Overview to unpin."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"This keeps it in view until you unpin. Touch and hold Home to unpin."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Personal data may be accessible (such as contacts and email content)."</string>
     <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Pinned app may open other apps."</string>
-    <string name="screen_pinning_toast" msgid="8177286912533744328">"To unpin this app, touch &amp; hold Back and Overview buttons"</string>
-    <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"To unpin this app, touch &amp; hold Back and Home buttons"</string>
+    <string name="screen_pinning_toast" msgid="8177286912533744328">"To unpin this app, touch and hold the Back and Overview buttons"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"To unpin this app, touch and hold the Back and Home buttons"</string>
     <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"To unpin this app, swipe up &amp; hold"</string>
     <string name="screen_pinning_positive" msgid="3285785989665266984">"Got it"</string>
     <string name="screen_pinning_negative" msgid="6882816864569211666">"No thanks"</string>
@@ -885,8 +899,7 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"unfavorite"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"Move to position <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"Controls"</string>
-    <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
-    <skip />
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Choose device controls to access quickly"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold &amp; drag to rearrange controls"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"All controls removed"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Changes not saved"</string>
@@ -1106,7 +1119,7 @@
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Install a camera app"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch &amp; hold shortcut"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch and hold shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index bed2089..7c47b52 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognise face. Use fingerprint instead."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index bed2089..7c47b52 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognise face. Use fingerprint instead."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 885acd1..b91ee56 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -168,6 +168,20 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted.‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted.‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎If you enter an incorrect password on the next attempt, your work profile and its data will be deleted.‎‏‎‎‏‎"</string>
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎Set up‎‏‎‎‏‎"</string>
+    <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎Not now‎‏‎‎‏‎"</string>
+    <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‎‎‎This is required to improve security and performance‎‏‎‎‏‎"</string>
+    <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎Set up Fingerprint Unlock again‎‏‎‎‏‎"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎Fingerprint Unlock‎‏‎‎‏‎"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎Set up Fingerprint Unlock‎‏‎‎‏‎"</string>
+    <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‏‏‎To set up Fingerprint Unlock again, your current fingerprint images and models will be deleted.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎After theyre deleted, youll need to set up Fingerprint Unlock again to use your fingerprint to unlock your phone or verify its you.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎To set up Fingerprint Unlock again, your current fingerprint images and model will be deleted.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎After theyre deleted, youll need to set up Fingerprint Unlock again to use your fingerprint to unlock your phone or verify its you.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎Couldn’t set up fingerprint unlock. Go to Settings to try again.‎‏‎‎‏‎"</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎Set up Face Unlock again‎‏‎‎‏‎"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎Face Unlock‎‏‎‎‏‎"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‎‎Set up Face Unlock‎‏‎‎‏‎"</string>
+    <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎To set up Face Unlock again, your current face model will be deleted.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Youll need to set up this feature again to use your face to unlock your phone.‎‏‎‎‏‎"</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‎Couldn’t set up face unlock. Go to Settings to try again.‎‏‎‎‏‎"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎Touch the fingerprint sensor‎‏‎‎‏‎"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎Can’t recognize face. Use fingerprint instead.‎‏‎‎‏‎"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -885,8 +899,7 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎unfavorite‎‏‎‎‏‎"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎Move to position ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎Controls‎‏‎‎‏‎"</string>
-    <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
-    <skip />
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎Choose device controls to access quickly‎‏‎‎‏‎"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎Hold &amp; drag to rearrange controls‎‏‎‎‏‎"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎All controls removed‎‏‎‎‏‎"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎Changes not saved‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index f63abf2..9445bc4 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si ingresas un patrón incorrecto en el próximo intento, se borrarán tu perfil de trabajo y sus datos."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si ingresas un PIN incorrecto en el próximo intento, se borrarán tu perfil de trabajo y sus datos."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si ingresas una contraseña incorrecta en el próximo intento, se borrarán tu perfil de trabajo y sus datos."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toca el sensor de huellas dactilares"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"No se reconoce el rostro. Usa la huella dactilar."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar pantalla de bloqueo"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloquea para personalizar la pantalla de bloqueo"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi no disponible"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"La cámara está bloqueada"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"La cámara y el micrófono están bloqueados"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"El micrófono está bloqueado"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"El modo de prioridad está activado"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistente está prestando atención"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Configura la app de notas predeterminada en Configuración"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 3714253..61f50e3 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si vuelves a introducir un patrón incorrecto, tu perfil de trabajo y sus datos se eliminarán."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si vuelves a introducir un PIN incorrecto, tu perfil de trabajo y sus datos se eliminarán."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si vuelves a introducir una contraseña incorrecta, tu perfil de trabajo y sus datos se eliminarán."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toca el sensor de huellas digitales"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"No se reconoce la cara. Usa la huella digital."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar pantalla de bloqueo"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloquea para personalizar la pantalla de bloqueo"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Red Wi-Fi no disponible"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Cámara bloqueada"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Cámara y micrófono bloqueados"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Micrófono bloqueado"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Modo Prioridad activado"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"El Asistente está activado"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Configura la aplicación de notas predeterminada en Ajustes"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index bb9b4fc..09efa50 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Kui sisestate järgmisel katsel vale mustri, kustutatakse teie tööprofiil ja selle andmed."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Kui sisestate järgmisel katsel vale PIN-koodi, kustutatakse teie tööprofiil ja selle andmed."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Kui sisestate järgmisel katsel vale parooli, kustutatakse teie tööprofiil ja selle andmed."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Puudutage sõrmejäljeandurit"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nägu ei õnnestu tuvastada. Kasutage sõrmejälge."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -871,7 +899,7 @@
     <string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Teisalda servast eemale ja kuva"</string>
     <string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Eemalda"</string>
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"lülita"</string>
-    <string name="quick_controls_title" msgid="6839108006171302273">"Seadmete juhikud"</string>
+    <string name="quick_controls_title" msgid="6839108006171302273">"Seadmete juhtimisvidinad"</string>
     <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>
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Pühkige sõrmega, et näha rohkem"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Soovituste laadimine"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Meedia"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Kas peita rakenduses <xliff:g id="APP_NAME">%1$s</xliff:g> see meediajuhik?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Kas peita see rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> meediajuhik?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Praegust meediaseanssi ei saa peita."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Peida"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 7a6b8f8..aded22c 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Hurrengo saiakeran eredua oker marrazten baduzu, laneko profila eta bertako datuak ezabatuko dira."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Hurrengo saiakeran PINa oker idazten baduzu, laneko profila eta bertako datuak ezabatuko dira."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Hurrengo saiakeran pasahitza oker idazten baduzu, laneko profila eta bertako datuak ezabatuko dira."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sakatu hatz-marken sentsorea"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ezin da hauteman aurpegia. Erabili hatz-marka."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -824,7 +852,7 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"pantaila-grabaketa"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ez du izenik"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Egonean"</string>
-    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Letraren tamaina"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Letra-tamaina"</string>
     <string name="font_scaling_smaller" msgid="1012032217622008232">"Txikitu"</string>
     <string name="font_scaling_larger" msgid="5476242157436806760">"Handitu"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Lupa-leihoa"</string>
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasatu hatza aukera gehiago ikusteko"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Gomendioak kargatzen"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Multimedia-edukia"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren multimedia kontr. aukerak ezkutatu?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Multimedia kontrolatzeko aukerak (<xliff:g id="APP_NAME">%1$s</xliff:g>) ezkutatu?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Ezin da ezkutatu multimedia-saioa."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ezkutatu"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Aldatu laneko profilera"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Itxi"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Pertsonalizatu pantaila blokeatua"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desblokeatu eta pertsonalizatu pantaila blokeatua"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi-konexioa ez dago erabilgarri"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera blokeatuta dago"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera eta mikrofonoa blokeatuta daude"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofonoa blokeatuta dago"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Lehentasun modua aktibatuta dago"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Laguntzailea zerbitzuak arreta jarrita dauka"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ezarri oharren aplikazio lehenetsia ezarpenetan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index f12ca75..ce08dd6 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"اگر در تلاش بعدی الگوی نادرستی وارد کنید، داده‌های نمایه کاری شما و داده‌های آن حذف خواهد شد."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"اگر در تلاش بعدی‌ پین نادرستی وارد کنید، نمایه کاری شما و داده‌های آن حذف خواهند شد."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"اگر در تلاش بعدی‌ گذرواژه نادرستی وارد کنید، نمایه کاری شما و داده‌های آن حذف خواهند شد."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"حسگر اثر انگشت را لمس کنید"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"چهره شناسایی نشد. درعوض از اثر انگشت استفاده کنید."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -796,7 +824,7 @@
     <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"وضعیت داده تلفن همراه به‌طور خودکار براساس دردسترس بودن تغییر نخواهد کرد"</string>
     <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"نه متشکرم"</string>
     <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"بله، عوض شود"</string>
-    <string name="touch_filtered_warning" msgid="8119511393338714836">"چون برنامه‌ای درحال ایجاد تداخل در درخواست مجوز است، «تنظیمات» نمی‌تواند پاسخ شما را تأیید کند."</string>
+    <string name="touch_filtered_warning" msgid="8119511393338714836">"چون برنامه‌ای درحال ایجاد تداخل در درخواست اجازه است، «تنظیمات» نمی‌تواند پاسخ شما را تأیید کند."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"به <xliff:g id="APP_0">%1$s</xliff:g> اجازه داده شود تکه‌های <xliff:g id="APP_2">%2$s</xliff:g> را نشان دهد؟"</string>
     <string name="slice_permission_text_1" msgid="6675965177075443714">"- می‌تواند اطلاعات <xliff:g id="APP">%1$s</xliff:g> را بخواند"</string>
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- می‌تواند در <xliff:g id="APP">%1$s</xliff:g> اقدام انجام دهد"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"رفتن به نمایه کاری"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"بستن"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"سفارشی‌سازی صفحه قفل"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"برای سفارشی‌سازی صفحه قفل، قفل را باز کنید"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏Wi-Fi دردسترس نیست"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"دوربین مسدود شده است"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"دوربین و میکروفون مسدود شده‌اند"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"میکروفون مسدود شده است"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"حالت اولویت روشن است"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"توجه «دستیار» روشن است"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"برنامه پیش‌فرض یادداشت را در «تنظیمات» تنظیم کنید"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 435cfc9..f989a48 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jos annat väärän kuvion seuraavalla yrityskerralla, työprofiilisi ja sen data poistetaan."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jos annat väärän PIN-koodin seuraavalla yrityskerralla, työprofiilisi ja sen data poistetaan."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jos annat väärän salasanan seuraavalla yrityskerralla, työprofiilisi ja sen data poistetaan."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Kosketa sormenjälkitunnistinta"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Kasvoja ei voi tunnistaa. Käytä sormenjälkeä."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Vaihda työprofiiliin"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sulje"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Customize lukitusnäyttöä"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Avaa lukitus muokataksesi lukitusnäyttöä"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi-yhteys ei ole käytettävissä"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera estetty"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera ja mikrofoni estetty"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofoni estetty"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Tärkeät-tila on päällä"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant on aktiivinen"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Aseta oletusmuistiinpanosovellus Asetuksista"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 71b6ad8..190eaa8 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -95,7 +95,7 @@
     <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="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à une note"</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>
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si vous entrez un schéma incorrect à la prochaine tentative suivante, votre profil professionnel et ses données seront supprimés."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si vous entrez un NIP incorrect à la prochaine tentative, votre profil professionnel et ses données seront supprimés."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si vous entrez un mot de passe incorrect à la prochaine tentative suivante, votre profil professionnel et ses données seront supprimés."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touchez le capteur d\'empreintes digitales"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Visage non reconnu. Utilisez plutôt l\'empreinte digitale."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -701,7 +729,7 @@
     <string name="right_icon" msgid="1103955040645237425">"Icône droite"</string>
     <string name="drag_to_add_tiles" msgid="8933270127508303672">"Sélectionnez et faites glisser les tuiles pour les ajouter"</string>
     <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Faites glisser les tuiles pour les réorganiser"</string>
-    <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Faites glisser les tuiles ici pour les supprimer"</string>
+    <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Faites glisser les tuiles ici pour les retirer"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Vous avez besoin d\'au moins <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tuiles"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Modifier"</string>
     <string name="tuner_time" msgid="2450785840990529997">"Heure"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 8f96d2c..9bbe15e 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si vous dessinez un schéma incorrect lors de la prochaine tentative, votre profil professionnel et les données associées seront supprimés."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si vous saisissez un code incorrect lors de la prochaine tentative, votre profil professionnel et les données associées seront supprimés."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si vous saisissez un mot de passe incorrect lors de la prochaine tentative, votre profil professionnel et les données associées seront supprimés."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Appuyez sur le lecteur d\'empreinte digitale"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Visage non reconnu. Utilisez votre empreinte."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personnaliser écran verrouillage"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Déverrouiller pour personnaliser l\'écran de verrouillage"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi non disponible"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Caméra bloquée"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Caméra et micro bloqués"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Micro bloqué"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Mode Prioritaire activé"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant à l\'écoute"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir une appli de notes par défaut dans les paramètres"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index 12fa44d..0a38851 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -43,7 +43,7 @@
   </string-array>
   <string-array name="tile_states_cell">
     <item msgid="1235899788959500719">"Indisponibles"</item>
-    <item msgid="2074416252859094119">"Désactivées"</item>
+    <item msgid="2074416252859094119">"Désactivé"</item>
     <item msgid="287997784730044767">"Activées"</item>
   </string-array>
   <string-array name="tile_states_battery">
@@ -148,7 +148,7 @@
   </string-array>
   <string-array name="tile_states_controls">
     <item msgid="8199009425335668294">"Indisponibles"</item>
-    <item msgid="4544919905196727508">"Désactivées"</item>
+    <item msgid="4544919905196727508">"Désactivé"</item>
     <item msgid="3422023746567004609">"Activées"</item>
   </string-array>
   <string-array name="tile_states_wallet">
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index e2f625d..f97bebf 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se indicas un padrón incorrecto no seguinte intento, eliminaranse o teu perfil de traballo e os datos asociados."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se indicas un PIN incorrecto no seguinte intento, eliminaranse o teu perfil de traballo e os datos asociados."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se indicas un contrasinal incorrecto no seguinte intento, eliminaranse o teu perfil de traballo e os datos asociados."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toca o sensor de impresión dixital"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Non se recoñeceu a cara. Usa a impresión dixital."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <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="6152703934761402399">"Personalizar pantalla de bloqueo"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Para personalizar a pantalla de bloqueo, primeiro desbloquea o dispositivo"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi non dispoñible"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"A cámara está bloqueada"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"A cámara e o micrófono están bloqueados"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"O micrófono está bloqueado"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"O modo de prioridade está activado"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"A atención do Asistente está activada"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Establece a aplicación de notas predeterminada en Configuración"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index b78d852..910c7e5 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"જો તમે આગલા પ્રયત્નમાં ખોટી પૅટર્ન દાખલ કરશો, તો તમારી કાર્યાલયની પ્રોફાઇલ અને તેનો ડેટા ડિલીટ કરવામાં આવશે."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"જો તમે આગલા પ્રયત્નમાં ખોટો પિન દાખલ કરશો, તો તમારી કાર્યાલયની પ્રોફાઇલ અને તેનો ડેટા ડિલીટ કરવામાં આવશે."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"જો તમે આગલા પ્રયત્નમાં ખોટો પાસવર્ડ દાખલ કરશો, તો તમારી કાર્યાલયની પ્રોફાઇલ અને તેનો ડેટા ડિલીટ કરવામાં આવશે."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ફિંગરપ્રિન્ટના સેન્સરને સ્પર્શ કરો"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ચહેરો ઓળખી શકતા નથી. તેને બદલે ફિંગરપ્રિન્ટ વાપરો."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -819,7 +847,7 @@
     <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
     <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
     <string name="privacy_type_camera" msgid="7974051382167078332">"કૅમેરા"</string>
-    <string name="privacy_type_location" msgid="7991481648444066703">"સ્થાન"</string>
+    <string name="privacy_type_location" msgid="7991481648444066703">"લોકેશન"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"માઇક્રોફોન"</string>
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"સ્ક્રીન રેકોર્ડિંગ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"કોઈ શીર્ષક નથી"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ઑફિસની પ્રોફાઇલ પર સ્વિચ કરો"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"બંધ કરો"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"લૉક સ્ક્રીન કસ્ટમાઇઝ કરો"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"લૉક સ્ક્રીનને કસ્ટમાઇઝ કરવા માટે અનલૉક કરો"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"વાઇ-ફાઇ ઉપલબ્ધ નથી"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"કૅમેરા બ્લૉક કરેલો છે"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"કૅમેરા અને માઇક્રોફોન બ્લૉક કરેલા છે"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"માઇક્રોફોન બ્લૉક કરેલો છે"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"પ્રાધાન્યતા મોડ ચાલુ છે"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant સક્રિય છે"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"સેટિંગમાં નોંધની ડિફૉલ્ટ ઍપ સેટ કરો"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 946b193..9ef9503 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"अगर आप फिर से गलत पैटर्न डालते हैं, तो आपकी वर्क प्रोफ़ाइल और उसका डेटा मिटा दिया जाएगा."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"अगर आप फिर से गलत पिन डालते हैं, तो आपकी वर्क प्रोफ़ाइल और उसका डेटा मिटा दिया जाएगा."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"अगर आप फिर से गलत पासवर्ड डालते हैं, तो आपकी वर्क प्रोफ़ाइल और उसका डेटा मिटा दिया जाएगा."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"फ़िंगरप्रिंट सेंसर को छुएं"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"चेहरे की पहचान नहीं हुई. फ़िंगरप्रिंट इस्तेमाल करें."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -545,7 +573,7 @@
     <string name="notification_silence_title" msgid="8608090968400832335">"बिना आवाज़ के सूचनाएं दिखाएं"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"डिफ़ॉल्ट"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"अपने-आप"</string>
-    <string name="notification_channel_summary_low" msgid="4860617986908931158">"किसी तरह की आवाज़ या वाइब्रेशन न हो"</string>
+    <string name="notification_channel_summary_low" msgid="4860617986908931158">"आवाज़ या वाइब्रेशन न हो"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"इससे किसी तरह की आवाज़ या वाइब्रेशन नहीं होता और बातचीत, सेक्शन में सबसे नीचे दिखती है"</string>
     <string name="notification_channel_summary_default" msgid="777294388712200605">"डिवाइस की सेटिंग के आधार पर, सूचना आने पर घंटी बज सकती है या वाइब्रेशन हो सकता है"</string>
     <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"डिवाइस की सेटिंग के आधार पर, सूचना आने पर घंटी बज सकती है या वाइब्रेशन हो सकता है. <xliff:g id="APP_NAME">%1$s</xliff:g> पर होने वाली बातचीत, डिफ़ॉल्ट रूप से बबल के तौर पर दिखती है."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 8a13b54..522394e 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ako pri sljedećem pokušaju unesete netočan uzorak, izbrisat će se vaš poslovni profil i njegovi podaci."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ako pri sljedećem pokušaju unesete netočan PIN, izbrisat će se vaš poslovni profil i njegovi podaci."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ako pri sljedećem pokušaju unesete netočnu zaporku, izbrisat će se vaš poslovni profil i njegovi podaci."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dodirnite senzor otiska prsta"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Prepoznavanje lica nije uspjelo. Upotrijebite otisak prsta."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prijeđite na poslovni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključavanje zaslona"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da biste prilagodili zaključan zaslon"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nije dostupan"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Blokirani su kamera i mikrofon"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon je blokiran"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Uključen je prioritetni način rada"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Pažnja Asistenta je aktivirana"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Postavite zadanu aplikaciju za bilješke u postavkama"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 4163cb9..f63b116 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Amennyiben helytelen mintát ad meg a következő kísérletnél, a rendszer törli munkaprofilját és a kapcsolódó adatokat."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Amennyiben helytelen PIN-kódot ad meg a következő kísérletnél, a rendszer törli munkaprofilját és a kapcsolódó adatokat."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Amennyiben helytelen jelszót ad meg a következő kísérletnél, a rendszer törli munkaprofilját és a kapcsolódó adatokat."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Érintse meg az ujjlenyomat-érzékelőt"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Az arc nem felismerhető. Használjon ujjlenyomatot."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Váltás munkaprofilra"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bezárás"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Lezárási képernyő testreszabása"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Oldja fel a zárolást a lezárási képernyő testreszabásához"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Nem áll rendelkezésre Wi-Fi"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera letiltva"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera és mikrofon letiltva"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon letiltva"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritás mód bekapcsolva"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"A Segéd figyel"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Állítson be alapértelmezett jegyzetkészítő alkalmazást a Beállításokban"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index bdfb8b0..caefabe 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Հաջորդ փորձի ժամանակ սխալ նախշ մուտքագրելու դեպքում ձեր աշխատանքային պրոֆիլը և դրա տվյալները կջնջվեն։"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Հաջորդ փորձի ժամանակ սխալ PIN կոդ մուտքագրելու դեպքում աշխատանքային պրոֆիլը և դրա տվյալները կջնջվեն։"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Հաջորդ փորձի ժամանակ սխալ գաղտնաբառ մուտքագրելու դեպքում աշխատանքային պրոֆիլը և դրա տվյալները կջնջվեն։"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Հպեք մատնահետքի սկաներին"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Դեմքը չի հաջողվում ճանաչել։ Օգտագործեք մատնահետքը։"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -918,7 +946,7 @@
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Բեռնման խորհուրդներ"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Մեդիա"</string>
     <string name="controls_media_close_session" msgid="4780485355795635052">"Թաքցնե՞լ <xliff:g id="APP_NAME">%1$s</xliff:g>-ի մեդիա աշխատաշրջանի կառավարման տարրը։"</string>
-    <string name="controls_media_active_session" msgid="3146882316024153337">"Չհաջողվեց թաքցնել մեդիայի ընթացիկ աշխատաշրջանը։"</string>
+    <string name="controls_media_active_session" msgid="3146882316024153337">"Չհաջողվեց թաքցնել ընթացիկ մուլտիմեդիա աշխատաշրջանը։"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Թաքցնել"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Շարունակել"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Կարգավորումներ"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Անցնել աշխատանքային պրոֆիլ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Փակել"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Անհատականացնել կողպէկրանը"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ապակողպեք սարքը՝ կողպէկրանը կարգավորելու համար"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ցանց հասանելի չէ"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Տեսախցիկն արգելափակված է"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Տեսախցիկն ու խոսափողը արգելափակված են"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Խոսափողն արգելափակված է"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Առաջնահերթության ռեժիմը միացված է"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Օգնականը լսում է"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Կարգավորեք նշումների կանխադրված հավելված Կարգավորումներում"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index ce3e7e3..1e16aa3 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jika Anda memasukkan pola yang salah saat mencoba lagi, profil kerja dan datanya akan dihapus."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jika Anda memasukkan PIN yang salah saat mencoba lagi, profil kerja dan datanya akan dihapus."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jika Anda memasukkan sandi yang salah saat mencoba lagi, profil kerja dan datanya akan dihapus."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sentuh sensor sidik jari"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Tidak dapat mengenali wajah. Gunakan sidik jari."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -455,7 +483,7 @@
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Tetap terbuka kuncinya oleh TrustAgent"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Setelan suara"</string>
-    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Otomatis beri teks ke media"</string>
+    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Otomatis beri teks di media"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Tutup tooltip teks"</string>
     <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Overlay teks"</string>
     <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"aktifkan"</string>
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Geser untuk melihat selengkapnya"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuat rekomendasi"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Sembunyikan kontrol media ini untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Sembunyikan kontrol media untuk <xliff:g id="APP_NAME">%1$s</xliff:g> ini?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Sesi media aktif tidak dapat disembunyikan."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Lanjutkan"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Beralih ke profil kerja"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Sesuaikan layar kunci"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Buka kunci untuk menyesuaikan layar kunci"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi tidak tersedia"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera diblokir"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera dan mikrofon diblokir"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon diblokir"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Mode prioritas diaktifkan"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asisten sedang memerhatikan"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setel aplikasi catatan default di Setelan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 0f29c29..73047a2 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ef þú slærð inn rangt mynstur í næstu tilraun verður vinnusniðinu þínu og gögnum þess eytt."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ef þú slærð inn rangt PIN-númer í næstu tilraun verður vinnusniðinu þínu og gögnum þess eytt."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ef þú slærð inn rangt aðgangsorð í næstu tilraun verður vinnusniðinu þínu og gögnum þess eytt."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Snertu fingrafaralesarann"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Andlit þekkist ekki. Notaðu fingrafar í staðinn."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skipta yfir í vinnusnið"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Loka"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Sérsníða lásskjá"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Taktu úr lás til að sérsníða lásskjá"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi er ekki til staðar"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Lokað fyrir myndavél"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Lokað fyrir myndavél og hljóðnema"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Lokað fyrir hljóðnema"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Kveikt er á forgangsstillingu"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Hjálparinn er að hlusta"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Stilltu sjálfgefið glósuforrit í stillingunum"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 908a42d..4da1c50 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se al prossimo tentativo inserirai una sequenza sbagliata, il tuo profilo di lavoro e i relativi dati verranno eliminati."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se al prossimo tentativo inserirai un PIN sbagliato, il tuo profilo di lavoro e i relativi dati verranno eliminati."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se al prossimo tentativo inserirai una password sbagliata, il tuo profilo di lavoro e i relativi dati verranno eliminati."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Tocca il sensore di impronte"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Impossibile riconoscere il volto. Usa l\'impronta."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b632953..4c01b6b 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"הזנת קו ביטול נעילה שגוי בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"הזנה של קוד אימות שגוי בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"הזנת סיסמה שגויה בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"יש לגעת בחיישן טביעות האצבע"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"לא ניתן לזהות את הפנים. יש להשתמש בטביעת אצבע במקום."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"מעבר לפרופיל עבודה"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"סגירה"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"התאמה אישית של מסך הנעילה"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"כדי להתאים אישית את מסך הנעילה, יש לבטל את הנעילה"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏ה-Wi-Fi לא זמין"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"המצלמה חסומה"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"המצלמה והמיקרופון חסומים"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"המיקרופון חסום"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"מצב \'עדיפות\' מופעל"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"‏Assistant מאזינה"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"צריך להגדיר את אפליקציית ברירת המחדל לפתקים ב\'הגדרות\'"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 54b989a1..99a2edd 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"パターンをあと 1 回間違えると、仕事用プロファイルと関連データが削除されます。"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"PIN をあと 1 回間違えると、仕事用プロファイルと関連データが削除されます。"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"パスワードをあと 1 回間違えると、仕事用プロファイルと関連データが削除されます。"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"指紋認証センサーをタッチ"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"顔を認識できません。指紋認証を使用してください。"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 9d46a75..33e08de 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -168,6 +168,20 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"შემდეგი მცდელობისას განმბლოკავი ნიმუშის არასწორად შეყვანის შემთხვევაში, თქვენი სამსახურის პროფილი და მისი მონაცემები წაიშლება."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"შემდეგი მცდელობისას PIN-კოდის არასწორად შეყვანის შემთხვევაში, თქვენი სამსახურის პროფილი და მისი მონაცემები წაიშლება."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"შემდეგი მცდელობისას პაროლის არასწორად შეყვანის შემთხვევაში, თქვენი სამსახურის პროფილი და მისი მონაცემები წაიშლება."</string>
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"დაყენება"</string>
+    <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"ახლა არა"</string>
+    <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"საჭიროა უსაფრთხოებისა და ეფექტურობის გასაუმჯობესებლად"</string>
+    <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"ანაბეჭდით განბლოკვის ხელახლა დაყენება"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"ანაბეჭდით განბლოკვა"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"თითის ანაბეჭდით განბლოკვის დაყენება"</string>
+    <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"ანაბეჭდით განბლოკვის ხელახლა დასაყენებლად ამჟამინდელი ანაბეჭდის ფოტოები და მოდელები წაიშლება.\n\nმათი წაშლის შემდეგ მოგიწევთ ანაბეჭდით განბლოკვის ხელახლა დაყენება, ტელეფონის ანაბეჭდით განსაბლოკად ან ვინაობის დასადასტურებლად."</string>
+    <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"ანაბეჭდით განბლოკვის ხელახლა დასაყენებლად ამჟამინდელი ანაბეჭდის ფოტოები და მოდელები წაიშლება.\n\nმათი წაშლის შემდეგ მოგიწევთ ანაბეჭდით განბლოკვის ხელახლა დაყენება, ტელეფონის ანაბეჭდით განსაბლოკად ან ვინაობის დასადასტურებლად."</string>
+    <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"ანაბეჭდით განბლოკვის დაყენება ვერ მოხერხდა. გადადით პარამეტრებზე და ცადეთ ხელახლა."</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"დააყენეთ სახით განბლოკვა ხელახლა"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"განბლოკვა სახით"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"სახით განბლოკვის პარამეტრების დაყენება"</string>
+    <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"სახით განბლოკვის ისევ დასაყენებლად თქვენი ამჟამინდელი სახის მოდელი წაიშლება.\n\nთქვენ მოგიწევთ ამ ფუნქციის ხელახლა დაყენება სახის მეშვეობით ტელეფონის განსაბლოკად."</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"სახით განბლოკვის დაყენება ვერ მოხერხდა. გადადით პარამეტრებზე და ცადეთ ხელახლა."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"შეეხეთ თითის ანაბეჭდის სენსორს"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"სახის ამოცნობა ვერ ხერხდება. სანაცვლოდ თითის ანაბეჭდი გამოიყენეთ."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -885,8 +899,7 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"რჩეულებიდან ამოღება"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"გადატანა პოზიციაზე <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"მართვის საშუალებები"</string>
-    <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
-    <skip />
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"სწრაფად წვდომისთვის აირჩიეთ მოწყობილობების მართვის საშუალებები"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"მართვის საშუალებების გადაწყობა შეგიძლიათ მათი ჩავლებით გადატანით"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"მართვის ყველა საშუალება ამოიშალა"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"ცვლილებები არ შენახულა"</string>
@@ -1124,14 +1137,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"სამსახურის პროფილზე გადართვა"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"დახურვა"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ჩაკეთილი ეკრანის მორგება"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ჩაკეტილი ეკრანის მოსარგებად გაბლოკეთ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi მიუწვდომელია"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"კამერა დაბლოკილია"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"კამერა და მიკროფონი დაბლოკილია"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"მიკროფონი დაბლოკილია"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"პრიორიტეტული რეჟიმი ჩართულია"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"ასისტენტის ყურადღების ფუნქცია ჩართულია"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"დააყენეთ ნაგულისხმევი შენიშვნების აპი პარამეტრებში"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 7eb7a93..c4a161b 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Келесі әрекет кезінде қате өрнек енгізсеңіз, жұмыс профиліңіз бен оның деректері жойылады."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Келесі әрекет кезінде қате PIN кодын енгізсеңіз, жұмыс профиліңіз бен оның деректері жойылады."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Келесі әрекет кезінде қате құпия сөз енгізсеңіз, жұмыс профиліңіз бен оның деректері жойылады."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Саусақ ізін оқу сканерін түртіңіз"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Бет танылмады. Орнына саусақ ізін пайдаланыңыз."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -364,12 +392,12 @@
     <string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"Тек\nдабылдар"</string>
     <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Сымсыз зарядталуда • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string>
     <string name="keyguard_indication_charging_time" msgid="6492711711891071502">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарядталуда • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string>
-    <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Жылдам зарядталуда • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string>
+    <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Жылдам зарядтау • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Баяу зарядталуда • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string>
     <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарядталып жатыр. • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ашылмалы мәзір"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданбалар мен деректер жойылады."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданба мен дерек жойылады."</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Қош келдіңіз, қонақ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансты жалғастыру керек пе?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Қайта бастау"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жұмыс профиліне ауысу"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабу"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Құлып экранын бейімдеу"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Құлып экранын бейімдеу үшін құлыпты ашыңыз"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi қолжетімсіз."</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камера бөгелген."</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камера мен микрофон бөгелген."</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофон бөгелген."</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"\"Маңызды\" режимі қосулы."</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant қосулы."</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Параметрлерден әдепкі жазба қолданбасын орнатыңыз."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 4eafd98..97f4b85 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ប្រសិនបើអ្នក​បញ្ចូលលំនាំមិនត្រឹមត្រូវ នៅពេលព្យាយាមបញ្ចូល​លើកក្រោយ កម្រងព័ត៌មាន​ការងាររបស់អ្នក និងទិន្នន័យរបស់កម្រងព័ត៌មាននេះនឹងត្រូវ​បានលុប។"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ប្រសិនបើអ្នក​បញ្ចូលកូដ PIN មិនត្រឹមត្រូវ នៅពេលព្យាយាមបញ្ចូល​លើកក្រោយ កម្រងព័ត៌មានការងាររបស់អ្នក និងទិន្នន័យរបស់កម្រងព័ត៌មាននេះ​នឹងត្រូវបានលុប។"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ប្រសិនបើអ្នក​បញ្ចូលពាក្យសម្ងាត់មិន​ត្រឹមត្រូវ នៅពេលព្យាយាមបញ្ចូល​លើកក្រោយ កម្រងព័ត៌មាន​ការងាររបស់អ្នក និងទិន្នន័យ​របស់កម្រងព័ត៌មាននេះនឹងត្រូវបានលុប។"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ប៉ះ​ឧបករណ៍​ចាប់ស្នាម​ម្រាមដៃ"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"មិនអាចសម្គាល់មុខបានទេ។ សូមប្រើស្នាមម្រាមដៃជំនួសវិញ។"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index b0193f0..854ae9f 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ಮುಂದಿನ ಪ್ರಯತ್ನದಲ್ಲಿ ನೀವು ತಪ್ಪಾದ ಪ್ಯಾಟರ್ನ್ ನಮೂದಿಸಿದರೆ, ನಿಮ್ಮ ಉದ್ಯೋಗದ ಪ್ರೊಫೈಲ್ ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ಮುಂದಿನ ಪ್ರಯತ್ನದಲ್ಲಿ ನೀವು ತಪ್ಪಾದ ಪಿನ್ ನಮೂದಿಸಿದರೆ, ನಿಮ್ಮ ಉದ್ಯೋಗದ ಪ್ರೊಫೈಲ್ ಮತ್ತು ಅದರ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ಮುಂದಿನ ಪ್ರಯತ್ನದಲ್ಲಿ ನೀವು ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್ ನಮೂದಿಸಿದರೆ, ನಿಮ್ಮ ಉದ್ಯೋಗದ ಪ್ರೊಫೈಲ್ ಮತ್ತು ಅದರ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ಮುಖ ಗುರುತಿಸಲಾಗುತ್ತಿಲ್ಲ ಬದಲಿಗೆ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಬಳಸಿ."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -382,7 +410,7 @@
     <string name="user_remove_user_title" msgid="9124124694835811874">"ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ಈ ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುವುದು."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"ತೆಗೆದುಹಾಕಿ"</string>
-    <string name="media_projection_dialog_text" msgid="1755705274910034772">"ರೆಕಾರ್ಡ್ ಮಾಡುವಾಗ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸ್ಕ್ರೀನ್‌ ಮೇಲೆ ಕಾಣಿಸುವ ಸಕಲ ಮಾಹಿತಿಗೂ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಪ್ರವೇಶ ಹೊಂದಿರುತ್ತದೆ. ಇದು ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೋ ಪ್ಲೇಬ್ಯಾಕ್‌ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಕೂಡ ಒಳಗೊಂಡಿರುತ್ತದೆ."</string>
+    <string name="media_projection_dialog_text" msgid="1755705274910034772">"ರೆಕಾರ್ಡ್ ಮಾಡುವಾಗ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸ್ಕ್ರೀನ್‌ ಮೇಲೆ ಕಾಣಿಸುವ ಸಕಲ ಮಾಹಿತಿಗೂ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಆ್ಯಕ್ಸೆಸ್ ಹೊಂದಿರುತ್ತದೆ. ಇದು ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೋ ಪ್ಲೇಬ್ಯಾಕ್‌ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಕೂಡ ಒಳಗೊಂಡಿರುತ್ತದೆ."</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"ಈ ವೈಶಿಷ್ಟ್ಯವು ಒದಗಿಸುವ ಸೇವೆಗಳು, ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಗೋಚರಿಸುವ ಅಥವಾ ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಾಗ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಆಗುವ ಎಲ್ಲಾ ಮಾಹಿತಿಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೋ ಪ್ಲೇಬ್ಯಾಕ್‌ನಂತಹ ಮಾಹಿತಿಯನ್ನು ಇದು ಒಳಗೊಂಡಿದೆ."</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ರೆಕಾರ್ಡಿಂಗ್ ಅಥವಾ ಬಿತ್ತರಿಸುವಿಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಬೇಕೆ?"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಮೂಲಕ ರೆಕಾರ್ಡಿಂಗ್, ಬಿತ್ತರಿಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸುವುದೇ?"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ಗೆ ಬದಲಿಸಿ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ಮುಚ್ಚಿರಿ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ಕ್ಯಾಮರಾವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೊಫೋನ್‌ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ಆದ್ಯತೆಯ ಮೋಡ್‌ ಆನ್‌ ಆಗಿದೆ"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant ನಿಮ್ಮ ಮಾತನ್ನು ಆಲಿಸುತ್ತಿದೆ"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಡೀಫಾಲ್ಟ್ ಟಿಪ್ಪಣಿಗಳ ಆ್ಯಪ್ ಅನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 32e27ee..c4abe60 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"다음번 시도에서 잘못된 패턴을 입력하면 직장 프로필 및 관련 데이터가 삭제됩니다."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"다음번 시도에서 잘못된 PIN을 입력하면 직장 프로필 및 관련 데이터가 삭제됩니다."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"다음번 시도에서 잘못된 비밀번호를 입력하면 직장 프로필 및 관련 데이터가 삭제됩니다."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"지문 센서를 터치하세요."</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"얼굴을 인식할 수 없습니다. 대신 지문을 사용하세요."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"자세히 보려면 스와이프하세요."</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"추천 제어 기능 로드 중"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"미디어"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>에 대한 미디어 컨트롤을 숨길까요?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>의 미디어 컨트롤을 숨길까요?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"현재 미디어 세션은 숨길 수 없습니다."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"숨기기"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"직장 프로필로 전환"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"닫기"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"잠금 화면 맞춤 설정"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"잠금 화면 맞춤설정을 위해 잠금 해제"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi를 사용할 수 없음"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"카메라 차단됨"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"카메라 및 마이크 차단됨"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"마이크 차단됨"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"우선순위 모드 설정됨"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"어시스턴트가 대기 중임"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"설정에서 기본 메모 앱 설정"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 6b78db8..8ea9fb2 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Эгер графикалык ачкычты дагы бир жолу туура эмес киргизсеңиз, жумуш профилиңиз жана андагы маалыматтын баары өчөт."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Эгер PIN кодду дагы бир жолу туура эмес киргизсеңиз, жумуш профилиңиз жана андагы маалыматтын баары өчөт."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Эгер сырсөздү дагы бир жолу туура эмес киргизсеңиз, жумуш профилиңиз жана андагы маалыматтын баары өчөт."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Манжа изинин сенсорун басыңыз"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Жүз таанылбай жатат. Манжа изин колдонуңуз."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -436,9 +464,9 @@
     <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"Тастыктоочу борбордун тастыктамасы"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Саясаттарды карап көрүү"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Башкаруу элементтерин көрүү"</string>
-    <string name="monitoring_description_named_management" msgid="505833016545056036">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык.\n\nАдминистраторуңуз бул түзмөктөгү жөндөөлөрдү, корпоративдик ресурстарды пайдалануу мүмкүнчүлүгүн берген параметрлерди жана колдонмолорду, түзмөгүңүзгө байланыштуу маалыматтарды (мисалы, түзмөгүңүздүн жайгашкан жери сыяктуу) көзөмөлдөп башкара алат.\n\nТолугураак маалымат алуу үчүн IT администраторуңузга кайрылыңыз."</string>
+    <string name="monitoring_description_named_management" msgid="505833016545056036">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык.\n\nАдминистраторуңуз бул түзмөктөгү параметрлерди, корпоративдик ресурстарды пайдалануу мүмкүнчүлүгүн берген параметрлерди жана колдонмолорду, түзмөгүңүзгө байланыштуу маалыматтарды (мисалы, түзмөгүңүздүн жайгашкан жери сыяктуу) көзөмөлдөп башкара алат.\n\nТолугураак маалымат алуу үчүн IT администраторуңузга кайрылыңыз."</string>
     <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> бул түзмөк менен байланышкан маалыматты көрүп, колдонмолорду башкарып, анын параметрлерин өзгөртө алат.\n\nЭгер суроолоруңуз болсо, <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g> уюмуна кайрылыңыз."</string>
-    <string name="monitoring_description_management" msgid="4308879039175729014">"Бул түзмөк уюмуңузга таандык.\n\nАдминистраторуңуз бул түзмөктөгү жөндөөлөрдү, корпоративдик ресурстарды пайдалануу мүмкүнчүлүгүн берген параметрлерди жана колдонмолорду, түзмөгүңүзгө байланыштуу маалыматтарды (мисалы, түзмөгүңүздүн жайгашкан жери сыяктуу) көзөмөлдөп башкара алат.\n\nТолугураак маалымат алуу үчүн IT администраторуңузга кайрылыңыз."</string>
+    <string name="monitoring_description_management" msgid="4308879039175729014">"Бул түзмөк уюмуңузга таандык.\n\nАдминистраторуңуз бул түзмөктөгү параметрлерди, корпоративдик ресурстарды пайдалануу мүмкүнчүлүгүн берген параметрлерди жана колдонмолорду, түзмөгүңүзгө байланыштуу маалыматтарды (мисалы, түзмөгүңүздүн жайгашкан жери сыяктуу) көзөмөлдөп башкара алат.\n\nТолугураак маалымат алуу үчүн IT администраторуңузга кайрылыңыз."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Ишканаңыз бул түзмөккө тастыктоочу борборду орнотту. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Ишканаңыз жумуш профилиңизге тастыктоочу борборду орнотту. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Бул түзмөктө тастыктоочу борбор орнотулган. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
@@ -666,7 +694,7 @@
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Үндү көзөмөлдөөчү баскычтардын кыска жолдору"</string>
     <string name="battery" msgid="769686279459897127">"Батарея"</string>
     <string name="headset" msgid="4485892374984466437">"Гарнитура"</string>
-    <string name="accessibility_long_click_tile" msgid="210472753156768705">"Жөндөөлөрдү ачуу"</string>
+    <string name="accessibility_long_click_tile" msgid="210472753156768705">"Параметрлерди ачуу"</string>
     <string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"Гарнитуралар туташкан"</string>
     <string name="accessibility_status_bar_headset" msgid="2699275863720926104">"Гарнитура туташты"</string>
     <string name="data_saver" msgid="3484013368530820763">"Трафикти үнөмдөө"</string>
@@ -728,9 +756,9 @@
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Карта өчүрүлдү"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ыкчам параметрлер түзөткүчү."</string>
     <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> эскертмеси: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
-    <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Жөндөөлөрдү ачуу."</string>
-    <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ыкчам жөндөөлөрдү ачуу."</string>
-    <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Ыкчам жөндөөлөрдү жабуу."</string>
+    <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Параметрлерди ачуу."</string>
+    <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ыкчам параметрлерди ачуу."</string>
+    <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Ыкчам параметрлерди жабуу."</string>
     <string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> аккаунту менен кирди"</string>
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"колдонуучуну тандоо"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Интернет жок"</string>
@@ -858,7 +886,7 @@
     <string name="accessibility_magnification_done" msgid="263349129937348512">"Бүттү"</string>
     <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"Түзөтүү"</string>
     <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"Чоңойткуч терезесинин параметрлери"</string>
-    <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Атайын мүмкүнчүлүктөрдү ачуу үчүн басыңыз. Бул баскычты Жөндөөлөрдөн өзгөртүңүз.\n\n"<annotation id="link">"Жөндөөлөрдү көрүү"</annotation></string>
+    <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"Атайын мүмкүнчүлүктөрдү ачуу үчүн басыңыз. Бул баскычты Жөндөөлөрдөн өзгөртүңүз.\n\n"<annotation id="link">"Параметрлерди көрүү"</annotation></string>
     <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"Баскычты убактылуу жашыра туруу үчүн экрандын четине жылдырыңыз"</string>
     <string name="accessibility_floating_button_undo" msgid="511112888715708241">"Кайтаруу"</string>
     <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"<xliff:g id="FEATURE_NAME">%s</xliff:g> ыкчам баскычы өчүрүлдү"</string>
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Дагы көрүү үчүн экранды сүрүп коюңуз"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Сунуштар жүктөлүүдө"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда ушул нерсени жашырасызбы?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> \'да ушул медиа башкарууну жашырасызбы?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Учурдагы медиа сеансын жашыруу мүмкүн эмес."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жашыруу"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Улантуу"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жумуш профилине которулуу"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабуу"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Кулпу экранын тууралоо"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Кулпуланган экранды тууралоо үчүн кулпусун ачыңыз"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi жеткиликтүү эмес"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камера бөгөттөлдү"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камера менен микрофон бөгөттөлдү"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофон бөгөттөлдү"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Маанилүү сүйлөшүүлөр режими күйүк"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Жардамчы иштетилди"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Параметрлерден демейки кыска жазуулар колдонмосун тууралаңыз"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 5b01705..46fb2c2 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ຫາກທ່ານໃສ່ຣູບແບບຜິດໃນຄວາມພະຍາຍາມເທື່ອຕໍ່ໄປ, ໂປຣໄຟລ໌ບ່ອນເຣັດວຽກຂອງທ່ານ ແລະ ຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ຫາກທ່ານໃສ່ລະຫັດ PIN ຜິດໃນຄວາມພະຍາຍາມເທື່ອຕໍ່ໄປ, ໂປຣໄຟລ໌ບ່ອນເຣັດວຽກຂອງທ່ານ ແລະ ຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ຫາກທ່ານໃສ່ລະຫັດຜິດໃນຄວາມພະຍາຍາມເທື່ອຕໍ່ໄປ, ໂປຣໄຟລ໌ບ່ອນເຣັດວຽກຂອງທ່ານ ແລະ ຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ແຕະໃສ່ເຊັນເຊີລາຍນິ້ວມື"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ບໍ່ສາມາດຈຳແນກໜ້າໄດ້. ກະລຸນາໃຊ້ລາຍນິ້ວມືແທນ."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ສະຫຼັບໄປໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ປິດ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ປັບແຕ່ງໜ້າຈໍລັອກ"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ປົດລັອກເພື່ອປັບແຕ່ງໜ້າຈໍລັອກ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ບໍ່ພ້ອມໃຫ້ນຳໃຊ້"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ກ້ອງຖ່າຍຮູບຖືກບລັອກຢູ່"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ກ້ອງຖ່າຍຮູບ ແລະ ໄມໂຄຣໂຟນຖືກບລັອກຢູ່"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ໄມໂຄຣໂຟນຖືກບລັອກຢູ່"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ໂໝດຄວາມສຳຄັນເປີດຢູ່"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"ການເອີ້ນໃຊ້ຜູ້ຊ່ວຍເປີດຢູ່"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ຕັ້ງຄ່າແອັບຈົດບັນທຶກເລີ່ມຕົ້ນໃນການຕັ້ງຄ່າ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index c0de813..eeb8101 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jei kitu bandymu nupiešite netinkamą atrakinimo piešinį, darbo profilis ir jo duomenys bus ištrinti."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jei kitu bandymu įvesite netinkamą PIN kodą, darbo profilis ir jo duomenys bus ištrinti."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jei kitu bandymu įvesite netinkamą slaptažodį, darbo profilis ir jo duomenys bus ištrinti."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Palieskite piršto antspaudo jutiklį"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Veidas neatpažintas. Naudokite kontrolinį kodą."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Perjungti į darbo profilį"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Uždaryti"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Užrakinimo ekrano tinkinimas"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Atrakinę tinkinkite užrakinimo ekraną"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"„Wi-Fi“ ryšys nepasiekiamas"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Fotoaparatas užblokuotas"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Fotoaparatas ir mikrofonas užblokuoti"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofonas užblokuotas"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioriteto režimas įjungtas"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Padėjėjas klauso"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nustatykite numatytąją užrašų programą Nustatymuose"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 3ec0e20..2ae34bb 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ja nākamajā mēģinājumā ievadīsiet nepareizu kombināciju, jūsu darba profils un ar to saistītie dati tiks dzēsti."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ja nākamajā mēģinājumā ievadīsiet nepareizu PIN, jūsu darba profils un ar to saistītie dati tiks dzēsti."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ja nākamajā mēģinājumā ievadīsiet nepareizu paroli, jūsu darba profils un ar to saistītie dati tiks dzēsti."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Pieskarieties pirksta nospieduma sensoram"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nevar atpazīt seju. Lietojiet pirksta nospiedumu."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pārslēgties uz darba profilu"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Aizvērt"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Pielāgot bloķēšanas ekrānu"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Bloķēšanas ekrāna pielāgošana pēc atbloķēšanas"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nav pieejams"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera ir bloķēta"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kameras un mikrofona lietošana ir bloķēta"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofons ir bloķēts"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritātes režīms ir ieslēgts"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistents klausās"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Iestatījumos iestatiet noklusējuma piezīmju lietotni."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 09cd589..eb2f70c 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ако внесете погрешна шема при следниот обид, работниот профил и неговите податоци ќе се избришат."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ако внесете погрешен PIN при следниот обид, работниот профил и неговите податоци ќе се избришат."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ако внесете погрешна лозинка при следниот обид, работниот профил и неговите податоци ќе се избришат."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Допрете го сензорот за отпечатоци"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Не се препознава ликот. Користете отпечаток."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -223,7 +251,7 @@
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Екранот е заклучен во ориентација на пејзаж."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Екранот е заклучен во ориентација на портрет."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
-    <string name="start_dreams" msgid="9131802557946276718">"Заштитник на екран"</string>
+    <string name="start_dreams" msgid="9131802557946276718">"Штедач на екран"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Етернет"</string>
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не вознемирувај"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
@@ -237,7 +265,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматско ротирање"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматско ротирање на екранот"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
-    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Заштитник на екран"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Штедач на екран"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Пристап до камерата"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Пристап до микрофонот"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Дозволен"</string>
@@ -538,7 +566,7 @@
     <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"Вклучи"</string>
     <string name="tuner_full_importance_settings" msgid="1388025816553459059">"Контроли за известувањата за напојување"</string>
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Вклучено - според лице"</string>
-    <string name="power_notification_controls_description" msgid="1334963837572708952">"Со контролите за известувањата за напојување, може да поставите ниво на важност од 0 до 5 за известувањата на која било апликација. \n\n"<b>"Ниво 5"</b>" \n- Прикажувај на врвот на списокот со известувања \n- Дозволи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 4"</b>" \n- Спречи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 3"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n\n"<b>"Ниво 2"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n\n"<b>"Ниво 1"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n- Сокриј од заклучен екран и статусна лента \n- Прикажувај на дното на списокот со известувања \n\n"<b>"Ниво 0"</b>" \n- Блокирај ги сите известувања од апликацијата"</string>
+    <string name="power_notification_controls_description" msgid="1334963837572708952">"Со контролите за известувањата за напојување, може да поставите ниво на важност од 0 до 5 за известувањата на која било апликација. \n\n"<b>"Ниво 5"</b>" \n- Прикажувај на врвот на списокот со известувања \n- Дозволи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 4"</b>" \n- Спречи прекин во цел екран \n- Секогаш користи појавување \n\n"<b>"Ниво 3"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n\n"<b>"Ниво 2"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n\n"<b>"Ниво 1"</b>" \n- Спречи прекин во цел екран \n- Без појавување \n- Без звук и вибрации \n- Скриј од заклучен екран и статусна лента \n- Прикажувај на дното на списокот со известувања \n\n"<b>"Ниво 0"</b>" \n- Блокирај ги сите известувања од апликацијата"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Примени"</string>
     <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Исклучи известувања"</string>
@@ -637,7 +665,7 @@
     <string name="group_system_cycle_forward" msgid="9202444850838205990">"Прелистувајте ги неодамнешните апликации (напред)"</string>
     <string name="group_system_cycle_back" msgid="5163464503638229131">"Прелистувајте ги неодамнешните апликации (назад)"</string>
     <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Отв. список со сите аплик. и пребарувајте (т.е. Пребарување/Стартер)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Сокриј и (повторно) прикажи ја лентата со задачи"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Скриј и (повторно) прикажи ја лентата со задачи"</string>
     <string name="group_system_access_system_settings" msgid="7961639365383008053">"Пристапете до поставките на системот"</string>
     <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Пристапете до „Помошник на Google“"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Заклучен екран"</string>
@@ -917,9 +945,9 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Повлечете за да видите повеќе"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Се вчитуваат препораки"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Аудиовизуелни содржини"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Да се сокријат контролите за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <string name="controls_media_active_session" msgid="3146882316024153337">"Аудиовизуелнава сесија не може да се сокрие."</string>
-    <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сокриј"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Да се скријат контролите за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="controls_media_active_session" msgid="3146882316024153337">"Аудиовизуелнава сесија не може да се скрие."</string>
+    <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриј"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Продолжи"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Поставки"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> од <xliff:g id="ARTIST_NAME">%2$s</xliff:g> е пуштено на <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Префрли се на работен профил"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Приспособете го заклучениот екран"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Отклучување за приспособување на заклучениот екран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi не е достапно"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камерата е блокирана"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камерата и микрофонот се блокирани"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофонот е блокиран"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Приоритетниот режим е вклучен"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Вниманието на „Помошникот“ е вклучено"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Поставете стандардна апликација за белешки во „Поставки“"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index aa61976..407e80a 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -168,6 +168,20 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"അടുത്ത തവണയും നിങ്ങൾ തെറ്റായ പാറ്റേൺ നൽകിയാൽ, നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലും അതിന്റെ ഡാറ്റയും ഇല്ലാതാക്കപ്പെടും."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"അടുത്ത തവണയും നിങ്ങൾ തെറ്റായ പിൻ നൽകിയാൽ, നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലും അതിന്റെ ഡാറ്റയും ഇല്ലാതാക്കപ്പെടും."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"അടുത്ത തവണയും നിങ്ങൾ തെറ്റായ പാസ്‌വേഡ് നൽകിയാൽ, നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലും അതിന്റെ ഡാറ്റയും ഇല്ലാതാക്കപ്പെടും."</string>
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"സജ്ജീകരിക്കുക"</string>
+    <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"ഇപ്പോൾ വേണ്ട"</string>
+    <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"സുരക്ഷയും പ്രകടനവും മെച്ചപ്പെടുത്താൻ ഇത് ആവശ്യമാണ്"</string>
+    <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"ഫിംഗർപ്രിന്റ് അൺലോക്ക്"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് സജ്ജീകരിക്കുക"</string>
+    <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കാൻ, നിങ്ങളുടെ നിലവിലുള്ള ഫിംഗർപ്രിന്റ് ചിത്രങ്ങളും മോഡലുകളും ഇല്ലാതാക്കും.\n\nഅവ ഇല്ലാതാക്കിയ ശേഷം, ഫോൺ അൺലോക്ക് ചെയ്യാനോ ഇത് നിങ്ങൾ തന്നെയാണെന്ന് പരിശോധിച്ചുറപ്പിക്കാനോ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുന്നതിന്, ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കേണ്ടതുണ്ട്."</string>
+    <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കാൻ, നിങ്ങളുടെ നിലവിലുള്ള ഫിംഗർപ്രിന്റ് ചിത്രങ്ങളും മോഡലും ഇല്ലാതാക്കും.\n\nഅവ ഇല്ലാതാക്കിയ ശേഷം, ഫോൺ അൺലോക്ക് ചെയ്യാനോ ഇത് നിങ്ങൾ തന്നെയാണെന്ന് പരിശോധിച്ചുറപ്പിക്കാനോ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുന്നതിന്, ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കേണ്ടതുണ്ട്."</string>
+    <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് സജ്ജീകരിക്കാനായില്ല. വീണ്ടും ശ്രമിക്കാൻ ക്രമീകരണത്തിലേക്ക് പോകുക."</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"ഫെയ്‌സ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"ഫെയ്‌സ് അൺലോക്ക്"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"ഫെയ്‌സ് അൺലോക്ക് സജ്ജീകരിക്കുക"</string>
+    <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"ഫെയ്‌സ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കാൻ, നിങ്ങളുടെ നിലവിലുള്ള മുഖ മോഡൽ ഇല്ലാതാക്കും.\n\nഫോൺ അൺലോക്ക് ചെയ്യാൻ നിങ്ങളുടെ മുഖം ഉപയോഗിക്കുന്നതിന് ഈ ഫീച്ചർ വീണ്ടും സജ്ജീകരിക്കേണ്ടതുണ്ട്."</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"ഫെയ്‌സ് അൺലോക്ക് സജ്ജീകരിക്കാനായില്ല. വീണ്ടും ശ്രമിക്കാൻ ക്രമീകരണത്തിലേക്ക് പോകുക."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ഫിംഗർപ്രിന്റ് സെൻസർ സ്‌പർശിക്കുക"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"മുഖം തിരിച്ചറിയാനായില്ല. പകരം ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കൂ."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -885,8 +899,7 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"പ്രിയപ്പെട്ടതല്ലാതാക്കുക"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g>-ാം സ്ഥാനത്തേയ്ക്ക് നീക്കുക"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"നിയന്ത്രണങ്ങൾ"</string>
-    <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
-    <skip />
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"വേഗത്തിൽ ആക്സസ് ചെയ്യാൻ ഉപകരണ നിയന്ത്രണങ്ങൾ തിരഞ്ഞെടുക്കുക"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"നിയന്ത്രണങ്ങൾ പുനഃക്രമീകരിക്കാൻ അമർത്തിപ്പിടിച്ച് വലിച്ചിടുക"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"എല്ലാ നിയന്ത്രണങ്ങളും നീക്കം ചെയ്തു"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"മാറ്റങ്ങൾ സംരക്ഷിച്ചിട്ടില്ല"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 7d0d8a2..37a9e96 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Та дараагийн оролдлогоор буруу хээ оруулбал таны ажлын профайлыг өгөгдөлтэй нь цуг устгах болно."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Та дараагийн оролдлогоор буруу ПИН оруулбал таны ажлын профайлыг өгөгдөлтэй нь цуг устгах болно."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Та дараагийн оролдлогоор буруу нууц үг оруулбал таны ажлын профайлыг өгөгдөлтэй нь цуг устгах болно."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Хурууны хээ мэдрэгчид хүрэх"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Царай таних боломжгүй. Оронд нь хурууны хээ ашигла"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -892,7 +920,7 @@
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Өөрчлөлтийг хадгалаагүй"</string>
     <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Бусад аппыг харах"</string>
     <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Дахин эмхлэх"</string>
-    <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Тохиргоо нэмэх"</string>
+    <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Хяналт нэмэх"</string>
     <string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Засах руу буцах"</string>
     <string name="controls_favorite_load_error" msgid="5126216176144877419">"Хяналтыг ачаалж чадсангүй. Аппын тохиргоог өөрчлөөгүй эсэхийг нягтлахын тулд <xliff:g id="APP">%s</xliff:g> аппыг шалгана уу."</string>
     <string name="controls_favorite_load_none" msgid="7687593026725357775">"Тохирох хяналт байхгүй"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ажлын профайл руу сэлгэх"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Хаах"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Түгжигдсэн дэлгэцийг өөрчлөх"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Түгжээтэй дэлгэцийг өөрчлөхийн тулд түгжээг тайлна уу"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi боломжгүй байна"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камерыг блоклосон"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камер болон микрофоныг блоклосон"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофоныг блоклосон"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Чухал горим асаалттай байна"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Туслах анхаарлаа хандуулж байна"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Тохиргоонд тэмдэглэлийн өгөгдмөл апп тохируулна уу"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 4135188..7e1f445 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"तुम्‍ही पुढील प्रयत्‍नात चुकीचा पॅटर्न एंटर केल्यास, तुमची कार्य प्रोफाइल आणि तिचा डेटा हटवला जाईल."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"तुम्‍ही पुढील प्रयत्‍नात चुकीचा पिन एंटर केल्यास, तुमची कार्य प्रोफाइल आणि तिचा डेटा हटवला जाईल."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"तुम्‍ही पुढील प्रयत्‍नात चुकीचा पासवर्ड एंटर केल्यास, तुमची कार्य प्रोफाइल आणि तिचा डेटा हटवला जाईल."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"फिंगरप्रिंट सेन्सरला स्पर्श करा"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"चेहरा ओळखू शकत नाही. त्याऐवजी फिंगरप्रिंट वापरा."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइलवर स्विच करा"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करा"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"कस्टमाइझ लॉक स्‍क्रीन"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"लॉक स्‍क्रीन कस्टमाइझ करण्यासाठी अनलॉक करा"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"वाय-फाय उपलब्ध नाही"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"कॅमेरा ब्लॉक केला"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"कॅमेरा आणि मायक्रोफोन ब्लॉक केले आहेत"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"मायक्रोफोन ब्लॉक केला"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"प्राधान्य मोड सुरू आहे"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant चे लक्ष हे आता अ‍ॅक्टिव्ह आहे"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिंग्ज मध्ये डीफॉल्ट टिपा अ‍ॅप सेट करा"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index dd0a896..8a16efc 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jika anda memasukkan corak yang salah pada percubaan seterusnya, profil kerja anda dan data profil itu akan dipadamkan."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jika anda memasukkan PIN yang salah pada percubaan seterusnya, profil kerja anda dan data profil itu akan dipadamkan."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jika anda memasukkan kata laluan yang salah pada percubaan seterusnya, profil kerja anda dan data profil itu akan dipadamkan."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sentuh penderia cap jari"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Tidak mengenali wajah. Gunakan cap jari."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tukar kepada profil kerja"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Sesuaikan skrin kunci"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Buka kunci untuk menyesuaikan skrin kunci"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi tidak tersedia"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera disekat"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera dan mikrofon disekat"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon disekat"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Mod keutamaan dihidupkan"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Perhatian pembantu dihidupkan"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Tetapkan apl nota lalai dalam Tetapan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 925fb98..a050102 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"မှားယွင်းသည့် ပုံစံကို နောက်တစ်ကြိမ်ထည့်သွင်းပါက သင်၏အလုပ်ပရိုဖိုင်နှင့် ၎င်း၏ ဒေတာများကို ဖျက်လိုက်ပါမည်။"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"မှားယွင်းသည့် ပင်နံပါတ်ကို နောက်တစ်ကြိမ်ထည့်သွင်းပါက သင်၏အလုပ်ပရိုဖိုင်နှင့် ၎င်း၏ဒေတာများကို ဖျက်လိုက်ပါမည်။"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"မှားယွင်းသည့် စကားဝှက်ကို နောက်တစ်ကြိမ်ထည့်သွင်းပါက သင်၏အလုပ်ပရိုဖိုင်နှင့် ၎င်း၏ ဒေတာများကို ဖျက်လိုက်ပါမည်။"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"လက်ဗွေအာရုံခံကိရိယာကို တို့ပါ"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"မျက်နှာကို မမှတ်မိပါ။ လက်ဗွေကို အစားထိုးသုံးပါ။"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -223,7 +251,7 @@
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ဖန်သားပြင် အနေအထားက အလျားလိုက်အဖြစ် ပုံသေ လုပ်ထားပါသည်"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ဖန်သားပြင် အနေအထားက ဒေါင်လိုက်အဖြစ် ပုံသေ လုပ်ထားပါသည်"</string>
     <string name="dessert_case" msgid="9104973640704357717">"မုန့်ထည့်သော ပုံး"</string>
-    <string name="start_dreams" msgid="9131802557946276718">"စခရင်နားချိန်"</string>
+    <string name="start_dreams" msgid="9131802557946276718">"စခရင်နားချိန်ပုံ"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"အီသာနက်"</string>
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"မနှောင့်ယှက်ရ"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ဘလူးတုသ်"</string>
@@ -237,7 +265,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"အော်တို-လည်"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"မျက်နှာပြင်အား အလိုအလျောက်လှည့်ခြင်း"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"တည်နေရာ"</string>
-    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"စကရင်နားချိန်"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"စခရင်နားချိန်ပုံ"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"ကင်မရာသုံးခွင့်"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"မိုက်သုံးခွင့်"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ရနိုင်သည်"</string>
@@ -295,7 +323,7 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ကို ပိတ်ထားသည်"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ကို ဖွင့်ထားသည်"</string>
-    <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"စကရင် ရိုက်ကူးရန်"</string>
+    <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"စခရင် ရိုက်ကူးရန်"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"စတင်ရန်"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ရပ်ရန်"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"လက်တစ်ဖက်သုံးမုဒ်"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"အလုပ်ပရိုဖိုင်သို့ ပြောင်းရန်"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ပိတ်ရန်"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"လော့ခ်မျက်နှာပြင်စိတ်ကြိုက်လုပ်ရန်"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"လော့ခ်မျက်နှာပြင် စိတ်ကြိုက်လုပ်ရန် ဖွင့်ပါ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi မရနိုင်ပါ"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ကင်မရာကို ပိတ်ထားသည်"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ကင်မရာနှင့် မိုက်ခရိုဖုန်းကို ပိတ်ထားသည်"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"မိုက်ခရိုဖုန်းကို ပိတ်ထားသည်"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ဦးစားပေးမုဒ် ဖွင့်ထားသည်"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant နားထောင်နေသည်"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ဆက်တင်များတွင် မူရင်းမှတ်စုများအက်ပ် သတ်မှတ်ပါ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 72bb06a..a1d6c44 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Hvis du oppgir feil mønster på neste forsøk, slettes jobbprofilen din og tilknyttede data."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Hvis du skriver inn feil PIN-kode på neste forsøk, slettes jobbprofilen din og tilknyttede data."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Hvis du skriver inn feil passord på neste forsøk, slettes jobbprofilen din og tilknyttede data."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Trykk på fingeravtrykkssensoren"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ansiktet gjenkjennes ikke. Bruk fingeravtrykk."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Bytt til jobbprofilen"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Lukk"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Tilpass låseskjermen"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Du må låse opp enheten for å tilpasse låseskjermen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi er ikke tilgjengelig"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kameraet er blokkert"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kameraet og mikrofonen er blokkert"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofonen er blokkert"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioriteringsmodus er på"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistentoppmerksomhet er på"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Du kan velge en standardapp for notater i Innstillinger"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index eb5d3db..9f022ef 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -95,7 +95,7 @@
     <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="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>
@@ -168,6 +168,20 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"तपाईंले अर्को पटक पनि गलत ढाँचा प्रविष्टि गर्नुभयो भने यो कार्य प्रोफाइल र त्यहाँको डेटा मेटाइने छ।"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"तपाईंले अर्को पटक पनि गलत PIN प्रविष्टि गर्नुभयो भने तपाईंको कार्य प्रोफाइल र त्यहाँको डेटा मेटाइने छ।"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"तपाईंले अर्को पटक पनि गलत पासवर्ड प्रविष्टि गर्नुभयो भने तपाईंको कार्य प्रोफाइल र त्यहाँको डेटा मेटाइने छ।"</string>
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"सेटअप गर्नुहोस्"</string>
+    <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"अहिले होइन"</string>
+    <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"सुरक्षाको गुणस्तर तथा पर्फर्मेन्स सुधार गर्न यो अनुमति दिनु पर्ने हुन्छ"</string>
+    <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"फिंगरप्रिन्ट अनलक"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"फिंगरप्रिन्ट अनलक सेटअप गर्नुहोस्"</string>
+    <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"फिंगरप्रिन्ट अनलक फेरि सेटअप गर्न तपाईंका हालका फिंगरप्रिन्टका फोटो तथा मोडेलहरू मेटाइने छन्।\n\nती फोटो तथा मोडेलहरू मेटाइएपछि तपाईंले आफ्नो फिंगरप्रिन्ट प्रयोग गरेर फोन अनलक गर्न वा आफ्नो पहिचान पुष्टि गर्न फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नु पर्ने हुन्छ।"</string>
+    <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"फिंगरप्रिन्ट अनलक फेरि सेटअप गर्न तपाईंका हालका फिंगरप्रिन्टका फोटो तथा मोडेल मेटाइने छन्।\n\nती फोटो तथा मोडेलहरू मेटाइएपछि तपाईंले आफ्नो फिंगरप्रिन्ट प्रयोग गरेर फोन अनलक गर्न वा आफ्नो पहिचान पुष्टि गर्न फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नु पर्ने हुन्छ।"</string>
+    <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"फिंगरप्रिन्ट अनलक सेटअप गर्न सकिएन। फेरि प्रयास गर्न सेटिङमा जानुहोस्।"</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"फेस अनलक फेरि सेटअप गर्नुहोस्"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"फेस अनलक"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"फेस अनलक सेटअप गर्नुहोस्"</string>
+    <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"फेस अनलक फेरि सेटअप गर्न तपाईंको हालको फेस मोडेल मेटाइने छ।\n\nतपाईं आफ्नो अनुहार प्रयोग गरेर फोन अनलक गर्न चाहनुहुन्छ भने तपाईंले यो सुविधा फेरि सेटअप गर्नु पर्ने हुन्छ।"</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"फेस अनलक सेटअप गर्न सकिएन। फेरि प्रयास गर्न सेटिङमा जानुहोस्।"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"फिंगरप्रिन्ट सेन्सरमा छुनुहोस्‌"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"अनुहार पहिचान गर्न सकिएन। बरु फिंगरप्रिन्ट प्रयोग गर्नुहोस्।"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -885,8 +899,7 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"मन पर्ने कुराहरूको सूचीमा नराख्नुहोस्"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g>ले निर्देश गर्ने ठाउँमा सार्नुहोस्"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"नियन्त्रणहरू"</string>
-    <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
-    <skip />
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"द्रुत रूपमा एक्सेस गर्न डिभाइस नियन्त्रण गर्ने विजेटहरू छनौट गर्नुहोस्"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"कन्ट्रोललाई होल्ड एण्ड ड्र्याग गरी कन्ट्रोलको क्रम मिलाउनुहोस्"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"सबै कन्ट्रोल हटाइए"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"परिवर्तनहरू सुरक्षित गरिएका छैनन्"</string>
@@ -933,7 +946,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="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>
@@ -1124,14 +1137,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइल प्रयोग गर्नुहोस्"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"बन्द गर्नुहोस्"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"लक स्क्रिन कस्टमाइज गर्नुहोस्"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"लक स्क्रिन कस्टमाइज गर्न अनलक गर्नुहोस्"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi उपलब्ध छैन"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"क्यामेरा ब्लक गरिएको छ"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"क्यामेरा र माइक्रोफोन ब्लक गरिएको छ"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"माइक्रोफोन ब्लक गरिएको छ"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"प्राथमिकता मोड अन छ"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"सहायकले सुनिरहेको छ"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिङमा गई नोट बनाउने डिफल्ट एप तोक्नुहोस्"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 9589804..e152c110 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Als je bij de volgende poging een onjuist patroon opgeeft, worden je werkprofiel en de bijbehorende gegevens verwijderd."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Als je bij de volgende poging een onjuiste pincode opgeeft, worden je werkprofiel en de bijbehorende gegevens verwijderd."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Als je bij de volgende poging een onjuist wachtwoord opgeeft, worden je werkprofiel en de bijbehorende gegevens verwijderd."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Raak de vingerafdruksensor aan"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Gezicht niet herkend. Gebruik je vingerafdruk."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Overschakelen naar werkprofiel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sluiten"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Vergrendelscherm aanpassen"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ontgrendelen om het vergrendelscherm aan te passen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi niet beschikbaar"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Camera geblokkeerd"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Camera en microfoon geblokkeerd"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microfoon geblokkeerd"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioriteitsmodus aan"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent-aandacht aan"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standaard notitie-app instellen in Instellingen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index f298fd3..04f07f6 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -127,7 +127,7 @@
     <string name="accessibility_accessibility_button" msgid="4089042473497107709">"ଆକ୍ସେସିବିଲିଟୀ"</string>
     <string name="accessibility_rotate_button" msgid="1238584767612362586">"ସ୍କ୍ରୀନ୍‌କୁ ଘୁରାନ୍ତୁ"</string>
     <string name="accessibility_recent" msgid="901641734769533575">"ଓଭରଭିଉ"</string>
-    <string name="accessibility_camera_button" msgid="2938898391716647247">"କ୍ୟାମେରା"</string>
+    <string name="accessibility_camera_button" msgid="2938898391716647247">"କେମେରା"</string>
     <string name="accessibility_phone_button" msgid="4256353121703100427">"ଫୋନ"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ଭଏସ୍‌ ସହାୟକ"</string>
     <string name="accessibility_wallet_button" msgid="1458258783460555507">"ୱାଲେଟ୍"</string>
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ଆପଣ ପରବର୍ତ୍ତୀ ପ୍ରଚେଷ୍ଟାରେ ଏକ ଭୁଲ ପାଟର୍ନ ପ୍ରବେଶ କଲେ, ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଏବଂ ଏହାର ଡାଟାକୁ ଡିଲିଟ୍ କରିଦିଆଯିବ।"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ଆପଣ ପରବର୍ତ୍ତୀ ପ୍ରଚେଷ୍ଟାରେ ଏକ ଭୁଲ PIN ଲେଖିଲେ, ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଏବଂ ଏହାର ଡାଟାକୁ ଡିଲିଟ୍ କରିଦିଆଯିବ।"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ଆପଣ ପରବର୍ତ୍ତୀ ପ୍ରଚେଷ୍ଟାରେ ଏକ ଭୁଲ ପାସୱାର୍ଡ ଲେଖିଲେ, ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଓ ଏହାର ଡାଟାକୁ ଡିଲିଟ୍ କରିଦିଆଯିବ।"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ଟିପଚିହ୍ନ ସେନସର୍‌କୁ ଛୁଅଁନ୍ତୁ"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ଫେସ୍ ଚିହ୍ନଟ କରିହେବ ନାହିଁ। ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -182,7 +210,7 @@
     <string name="accessibility_not_connected" msgid="4061305616351042142">"କନେକ୍ଟ ହୋଇନାହିଁ।"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"ରୋମିଙ୍ଗ"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ବନ୍ଦ ଅଛି"</string>
-    <string name="accessibility_airplane_mode" msgid="1899529214045998505">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍‌।"</string>
+    <string name="accessibility_airplane_mode" msgid="1899529214045998505">"ଏରୋପ୍ଲେନ ମୋଡ।"</string>
     <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN ଅନ୍‍।"</string>
     <string name="accessibility_battery_level" msgid="5143715405241138822">"ବ୍ୟାଟେରୀ <xliff:g id="NUMBER">%d</xliff:g> ଶତକଡ଼ା।"</string>
     <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"ବେଟେରୀ <xliff:g id="PERCENTAGE">%1$d</xliff:g> ଶତକଡ଼ା, <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -520,7 +548,7 @@
     <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR କୋଡ ସ୍କାନର"</string>
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"ଅପଡେଟ ହେଉଛି"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌"</string>
-    <string name="status_bar_airplane" msgid="4848702508684541009">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍"</string>
+    <string name="status_bar_airplane" msgid="4848702508684541009">"ଏରୋପ୍ଲେନ ମୋଡ"</string>
     <string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>ବେଳେ ଆପଣ ନିଜର ପରବର୍ତ୍ତୀ ଆଲାର୍ମ ଶୁଣିପାରିବେ ନାହିଁ"</string>
     <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> ହେଲେ"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> ବେଳେ"</string>
@@ -818,7 +846,7 @@
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(<xliff:g id="APPLICATION_NAME_S_">%s</xliff:g> ମାଧ୍ୟମରେ)"</string>
     <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
     <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
-    <string name="privacy_type_camera" msgid="7974051382167078332">"କ୍ୟାମେରା"</string>
+    <string name="privacy_type_camera" msgid="7974051382167078332">"Camera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"ଲୋକେସନ"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"ମାଇକ୍ରୋଫୋନ"</string>
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ସ୍କ୍ରିନ ରେକର୍ଡିଂ"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ୱାର୍କ ପ୍ରୋଫାଇଲକୁ ସ୍ୱିଚ କରନ୍ତୁ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ଲକ ସ୍କ୍ରିନକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ଲକ ସ୍କ୍ରିନକୁ କଷ୍ଟମାଇଜ କରିବା ପାଇଁ ଅନଲକ କରନ୍ତୁ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"କେମେରାକୁ ବ୍ଲକ କରାଯାଇଛି"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"କେମେରା ଏବଂ ମାଇକ୍ରୋଫୋନକୁ ବ୍ଲକ କରାଯାଇଛି"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ମାଇକ୍ରୋଫୋନକୁ ବ୍ଲକ କରାଯାଇଛି"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ପ୍ରାୟୋରିଟି ମୋଡ ଚାଲୁ ଅଛି"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant ଆଟେନସନ ଚାଲୁ ଅଛି"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ସେଟିଂସରେ ଡିଫଲ୍ଟ ନୋଟ୍ସ ଆପ ସେଟ କରନ୍ତୁ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 50e829f..dbeda18 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ਜੇ ਤੁਸੀਂ ਅਗਲੀ ਕੋਸ਼ਿਸ਼ ਵਿੱਚ ਕੋਈ ਗਲਤ ਪੈਟਰਨ ਦਾਖਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਇਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ਜੇ ਤੁਸੀਂ ਅਗਲੀ ਕੋਸ਼ਿਸ਼ ਵਿੱਚ ਕੋਈ ਗਲਤ ਪਿੰਨ ਦਾਖਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਇਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ਜੇ ਤੁਸੀਂ ਅਗਲੀ ਕੋਸ਼ਿਸ਼ ਵਿੱਚ ਕੋਈ ਗਲਤ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਇਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ਚਿਹਰਾ ਨਹੀਂ ਪਛਾਣ ਸਕਦੇ। ਇਸਦੀ ਬਜਾਏ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ।"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਜਾਓ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ਬੰਦ ਕਰੋ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ਲਾਕ ਸਕ੍ਰੀਨ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ਲਾਕ ਸਕ੍ਰੀਨ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ਵਾਈ-ਫਾਈ ਉਪਲਬਧ ਨਹੀਂ"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ਕੈਮਰਾ ਬਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਬਲਾਕ ਕੀਤੇ ਗਏ"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਬਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ਤਰਜੀਹ ਮੋਡ ਚਾਲੂ ਹੈ"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant ਧਿਆਨ ਸੁਵਿਧਾ ਨੂੰ ਚਾਲੂ ਹੈ"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਨੋਟ ਐਪ ਨੂੰ ਸੈੱਟ ਕਰੋ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 499925a..6dda47d 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jeśli następnym razem podasz nieprawidłowy wzór, profil służbowy oraz powiązane z nim dane zostaną usunięte."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jeśli następnym razem podasz nieprawidłowy kod PIN, profil służbowy oraz powiązane z nim dane zostaną usunięte."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jeśli następnym razem podasz nieprawidłowe hasło, profil służbowy oraz powiązane z nim dane zostaną usunięte."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotknij czytnika linii papilarnych"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nie rozpoznaję twarzy. Użyj odcisku palca."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Przełącz na profil służbowy"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zamknij"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Dostosuj ekran blokady"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Odblokuj, aby dostosować ekran blokady"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Sieć Wi-Fi jest niedostępna"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera jest zablokowana"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera i mikrofon są zablokowane"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon jest zablokowany"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Tryb priorytetowy jest włączony"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asystent jest aktywny"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ustaw domyślną aplikację do obsługi notatek w Ustawieniach"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 2469f2e..486c666 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -95,7 +95,7 @@
     <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="app_clips_save_add_to_note" msgid="3460200751278069445">"Incluir anotação"</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>
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se você informar um padrão incorreto na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se você informar um PIN incorreto na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se você informar uma senha incorreta na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toque no sensor de impressão digital"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Não foi possível reconhecer o rosto Use a impressão digital."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 07378b9..ca7756f 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se introduzir um padrão incorreto na tentativa seguinte, o seu perfil de trabalho e os respetivos dados serão eliminados."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se introduzir um PIN incorreto na tentativa seguinte, o seu perfil de trabalho e os respetivos dados serão eliminados."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se introduzir uma palavra-passe incorreta na tentativa seguinte, o seu perfil de trabalho e os respetivos dados serão eliminados."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toque no sensor de impressões digitais."</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Impos. reconh. rosto. Utilize a impressão digital."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Mudar para perfil de trabalho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar o ecrã de bloqueio"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloqueie para personalizar o ecrã de bloqueio"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi indisponível"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Câmara bloqueada"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Câmara e microfone bloqueados"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microfone bloqueado"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Modo Prioridade ativado"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Atenção do Assistente ativada"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Predefina a app de notas nas Definições"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 2469f2e..486c666 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -95,7 +95,7 @@
     <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="app_clips_save_add_to_note" msgid="3460200751278069445">"Incluir anotação"</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>
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se você informar um padrão incorreto na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se você informar um PIN incorreto na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se você informar uma senha incorreta na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toque no sensor de impressão digital"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Não foi possível reconhecer o rosto Use a impressão digital."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 6d73152..159475a 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Dacă la următoarea încercare introduci un model incorect, profilul de serviciu și datele sale vor fi șterse."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Dacă la următoarea încercare introduci un cod PIN incorect, profilul de serviciu și datele sale vor fi șterse."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Dacă la următoarea încercare introduci o parolă incorectă, profilul de serviciu și datele sale vor fi șterse."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Atinge senzorul de amprente"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Chipul nu a fost recunoscut. Folosește amprenta."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -223,7 +251,7 @@
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ecranul este blocat în orientarea de tip peisaj."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ecranul este blocat în orientarea de tip portret."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina cu dulciuri"</string>
-    <string name="start_dreams" msgid="9131802557946276718">"Economizor de ecran"</string>
+    <string name="start_dreams" msgid="9131802557946276718">"Screensaver"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nu deranja"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Comută la profilul de serviciu"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Închide"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizează ecranul de blocare"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Deblochează pentru a personaliza ecranul de blocare"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Conexiune Wi-Fi indisponibilă"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Camera foto a fost blocată"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Camera foto și microfonul sunt blocate"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microfonul a fost blocat"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Modul Cu prioritate este activat"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistentul este atent"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setează aplicația prestabilită de note din Setări"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 25807f2..1c5b662 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Если вы неправильно введете графический ключ ещё раз, ваш рабочий профиль и его данные будут удалены."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Если вы неправильно введете PIN-код ещё раз, ваш рабочий профиль и его данные будут удалены."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Если вы неправильно введете пароль ещё раз, ваш рабочий профиль и его данные будут удалены."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Прикоснитесь к сканеру отпечатков пальцев."</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Не удалось распознать лицо. Используйте отпечаток."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в рабочий профиль"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыть"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Настройки заблок. экрана"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Разблокируйте устройство, чтобы настроить заблокированный экран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Функция Wi-Fi недоступна"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камера заблокирована"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камера и микрофон заблокированы"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофон заблокирован"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Режим \"Только важные\" включен"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Ассистент готов слушать"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайте стандартное приложение для заметок в настройках."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index a4e340c..bf66434 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ඔබ ඊළඟ උත්සාහයේදී වැරදි රටාවක් ඇතුළු කළහොත්, ඔබේ කාර්යාල පැතිකඩ සහ එහි දත්ත මකනු ඇත."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ඔබ ඊළඟ උත්සාහයේදී වැරදි PIN එකක් ඇතුළු කළහොත්, ඔබේ කාර්යාල පැතිකඩ සහ එහි දත්ත මකනු ඇත."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ඔබ ඊළඟ උත්සාහයේදී වැරදි මුරපදයක් ඇතුළු කළහොත්, ඔබේ කාර්යාල පැතිකඩ සහ එහි දත්ත මකනු ඇත."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"මුහුණ හැඳිනිය නොහැක. ඒ වෙනුවට ඇඟිලි සලකුණ භාවිත ක."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"කාර්යාල පැතිකඩ වෙත මාරු වන්න"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"වසන්න"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"අගුළු තිරය අභිරුචිකරණය කරන්න"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"අගුළු තිරය අභිරුචිකරණය කිරීමට අගුළු හරින්න"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ලද නොහැක"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"කැමරාව අවහිරයි"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"කැමරාව සහ මයික්‍රොෆෝනය අවහිරයි"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"මයික්‍රොෆෝනය අවහිරයි"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ප්‍රමුඛතා මාදිලිය සක්‍රීයයි"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"සහයක අවධානය යොමු කරයි"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"සැකසීම් තුළ පෙරනිමි සටහන් යෙදුම සකසන්න"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index d59c6ae..4c44724 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ak pri ďalšom pokuse zadáte nesprávny vzor, váš pracovný profil a jeho dáta budú odstránené."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ak pri ďalšom pokuse zadáte nesprávny PIN, váš pracovný profil a jeho dáta budú odstránené."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ak pri ďalšom pokuse zadáte nesprávne heslo, váš pracovný profil a jeho dáta budú odstránené."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotknite sa senzora odtlačkov prstov"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Tvár sa nedá rozpoznať. Použite odtlačok prsta."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Potiahnutím zobrazíte ďalšie položky"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítavajú sa odporúčania"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Médiá"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Chcete tento ovládač médií pre aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> skryť?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Chcete tento ovládač médií pre <xliff:g id="APP_NAME">%1$s</xliff:g> skryť?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuálna relácia média sa nedá skryť."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skryť"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Pokračovať"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b600337ce..78016c2 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Če pri naslednjem poskusu vnesete napačen vzorec, bodo delovni profil in podatki v njem izbrisani."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Če pri naslednjem poskusu vnesete napačno kodo PIN, bodo delovni profil in podatki v njem izbrisani."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Če pri naslednjem poskusu vnesete napačno geslo, bodo delovni profil in podatki v njem izbrisani."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotaknite se tipala prstnih odtisov"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Obraza ni mogoče prepoznati. Uporabite prstni odtis."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index ea380a0..cdeaa89 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Nëse fut një motiv të pasaktë në tentativën tjetër, profili yt i punës dhe të dhënat e tij do të fshihen."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Nëse fut një kod PIN të pasaktë në tentativën tjetër, profili yt i punës dhe të dhënat e tij do të fshihen."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Nëse fut një fjalëkalim të pasaktë në tentativën tjetër, profili yt i punës dhe të dhënat e tij do të fshihen."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Prek sensorin e gjurmës së gishtit"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nuk mund ta dallojë fytyrën. Përdor më mirë gjurmën e gishtit."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Kalo te profili i punës"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Mbyll"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizo ekranin e kyçjes"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Shkyçe për të personalizuar ekranin e kyçjes"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nuk ofrohet"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera u bllokua"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera dhe mikrofoni u bllokuan"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofoni u bllokua"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Modaliteti i përparësisë aktiv"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Vëmendja e \"Asistentit\" aktive"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Cakto aplikacionin e parazgjedhur të shënimeve te \"Cilësimet\""</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 14dddd68..1791a7f 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ако унесете нетачан шаблон при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ако унесете нетачан PIN при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ако унесете нетачну лозинку при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Додирните сензор за отисак прста"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Лице није препознато. Користите отисак прста."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Превуците да бисте видели још"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Учитавају се препоруке"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Медији"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Желите ли да сакријете ову контролу за медије за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Желите да сакријете ову контролу за медије за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Актуелна сесија медија не може да буде сакривена."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сакриј"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пређи на пословни профил"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Прилагоди закључани екран"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Откључајте да бисте прилагодили закључани екран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi није доступан"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камера је блокирана"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камера и микрофон су блокирани"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофон је блокиран"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Приоритетни режим је укључен"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Помоћник је у активном стању"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Подесите подразумевану апликацију за белешке у Подешавањима"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 5149bbf..191d9b6 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jobbprofilen och dess data raderas om du ritar fel mönster vid nästa försök."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jobbprofilen och dess data raderas om du anger fel pinkod vid nästa försök."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Din jobbprofil och dess data raderas om du anger fel lösenord vid nästa försök."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Tryck på fingeravtryckssensorn"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ansiktet kändes inte igen. Använd fingeravtryck."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Svep om du vill se mer"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Rekommendationer läses in"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Vill du dölja detta uppspelningsreglage för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Vill du dölja denna mediastyrning för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Den aktuella mediesessionen kan inte döljas."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Dölj"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Återuppta"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Byt till jobbprofilen"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Stäng"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Anpassa låsskärmen"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Lås upp för att anpassa låsskärmen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi är inte tillgängligt"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kameran är blockerad"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kameran och mikrofonen är blockerade"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofonen är blockerad"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritetsläge är aktiverat"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistenten är aktiverad"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ställ in en standardapp för anteckningar i inställningarna"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index eb32d9b..15f4e52 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ukiweka mchoro usio sahihi utakapojaribu tena, wasifu wako wa kazini utafutwa pamoja na data yake."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ukiweka PIN isiyo sahihi utakapojaribu tena, wasifu wako wa kazini utafutwa pamoja na data yake."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ukiweka nenosiri lisilo sahihi utakapojaribu tena, wasifu wako wa kazini utafutwa pamoja na data yake."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Gusa kitambua alama ya kidole"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Imeshindwa kutambua uso. Tumia alama ya kidole."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Telezesha kidole ili uone zaidi"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Inapakia mapendekezo"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Maudhui"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Ungependa kuficha kidhibiti hiki kwa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Ungependa kuficha kidhibiti hiki kwenye <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Kipindi cha sasa cha maudhui hakiwezi kufichwa."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ficha"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tumia wasifu wa kazini"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Funga"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Wekea mapendeleo skrini iliyofungwa"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Fungua ili uweke mapendeleo ya skrini iliyofungwa"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi haipatikani"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera imezuiwa"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera na maikrofoni zimezuiwa"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Maikrofoni imezuiwa"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Hali ya kipaumbele imewashwa"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Programu ya Mratibu imewashwa"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Teua programu chaguomsingi ya madokezo katika Mipangilio"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 2086459..f40615e 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -17,7 +17,7 @@
 -->
 <resources>
     <!-- gap on either side of status bar notification icons -->
-    <dimen name="status_bar_icon_padding">1dp</dimen>
+    <dimen name="status_bar_icon_padding">1sp</dimen>
 
     <dimen name="controls_header_horizontal_padding">28dp</dimen>
     <dimen name="controls_content_margin_horizontal">40dp</dimen>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 583ec25..14777e4 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"அடுத்த முறை தவறான பேட்டர்னை வரைந்தால் உங்கள் பணிக் கணக்கும் அதன் தரவும் நீக்கப்படும்."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"அடுத்த முறை தவறான பின்னை உள்ளிட்டால் உங்கள் பணிக் கணக்கும் அதன் தரவும் நீக்கப்படும்."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"அடுத்த முறை தவறான கடவுச்சொல்லை உள்ளிட்டால் உங்கள் பணிக் கணக்கும் அதன் தரவும் நீக்கப்படும்."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"கைரேகை சென்சாரைத் தொடவும்"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"முகத்தை அடையாளம் காண முடியவில்லை. கைரேகையைப் பயன்படுத்தவும்."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"பணிக் கணக்கிற்கு மாறு"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"மூடுக"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"பூட்டுத் திரையை பிரத்தியேகமாக்கு"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"பூட்டுத் திரையைப் பிரத்தியேகப்படுத்த அன்லாக் செய்யுங்கள்"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"வைஃபை கிடைக்கவில்லை"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"கேமரா தடுக்கப்பட்டுள்ளது"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"கேமராவும் மைக்ரோஃபோனும் தடுக்கப்பட்டுள்ளன"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"மைக்ரோஃபோன் தடுக்கப்பட்டுள்ளது"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"முன்னுரிமைப் பயன்முறை இயக்கத்தில் உள்ளது"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"அசிஸ்டண்ட்டின் கவனம் இயக்கத்தில் உள்ளது"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"குறிப்பு எடுப்பதற்கான இயல்புநிலை ஆப்ஸை அமைப்புகளில் அமையுங்கள்"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 8ada2ee..0a0e7fd 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"మీరు ఒకవేళ తర్వాతి ప్రయత్నంలో తప్పు ఆకృతిని ఎంటర్ చేస్తే, మీ కార్యాలయ ప్రొఫైల్, అలాగే దాని డేటా తొలగించబడతాయి."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"మీరు ఒకవేళ తర్వాతి ప్రయత్నంలో తప్పు పిన్‌ను ఎంటర్ చేస్తే, మీ కార్యాలయ ప్రొఫైల్, అలాగే దాని డేటా తొలగించబడతాయి."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"మీరు ఒకవేళ తర్వాతి ప్రయత్నంలో తప్పు పాస్‌వర్డ్‌ను ఎంటర్ చేస్తే, మీ కార్యాలయ ప్రొఫైల్, అలాగే దాని డేటా తొలగించబడతాయి."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"వేలిముద్ర సెన్సార్‌ను తాకండి"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ముఖం గుర్తించలేము. బదులుగా వేలిముద్ర ఉపయోగించండి."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -545,7 +573,7 @@
     <string name="notification_silence_title" msgid="8608090968400832335">"నిశ్శబ్దం"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ఆటోమేటిక్ సెట్టింగ్"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ఆటోమేటిక్"</string>
-    <string name="notification_channel_summary_low" msgid="4860617986908931158">"శబ్దం లేదా వైబ్రేషన్‌లు ఏవీ లేవు"</string>
+    <string name="notification_channel_summary_low" msgid="4860617986908931158">"సౌండ్ లేదా వైబ్రేషన్‌లు ఏవీ ఉండవు"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"శబ్దం లేదా వైబ్రేషన్ లేదు, సంభాషణ విభాగం దిగువన కనిపిస్తుంది"</string>
     <string name="notification_channel_summary_default" msgid="777294388712200605">"పరికర సెట్టింగ్‌ల ఆధారంగా రింగ్ లేదా వైబ్రేట్ కావచ్చు"</string>
     <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"పరికర సెట్టింగ్‌ల ఆధారంగా రింగ్ లేదా వైబ్రేట్ కావచ్చు. <xliff:g id="APP_NAME">%1$s</xliff:g> నుండి సంభాషణలు ఆటోమేటిక్‌గా బబుల్‌లో కనిపిస్తాయి."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index ce35c40..76d9981 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"หากคุณป้อนรูปแบบไม่ถูกต้องในความพยายามครั้งถัดไป ระบบจะลบโปรไฟล์งานและข้อมูลในโปรไฟล์"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"หากคุณป้อน PIN ไม่ถูกต้องในความพยายามครั้งถัดไป ระบบจะลบโปรไฟล์งานและข้อมูลในโปรไฟล์"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"หากคุณป้อนรหัสผ่านไม่ถูกต้องในความพยายามครั้งถัดไป ระบบจะลบโปรไฟล์งานและข้อมูลในโปรไฟล์"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"แตะเซ็นเซอร์ลายนิ้วมือ"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ไม่รู้จักใบหน้า ใช้ลายนิ้วมือแทน"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"สลับไปใช้โปรไฟล์งาน"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ปิด"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ปรับแต่งหน้าจอล็อก"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ปลดล็อกเพื่อปรับแต่งหน้าจอล็อก"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ไม่พร้อมใช้งาน"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"กล้องถูกบล็อกอยู่"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"กล้องและไมโครโฟนถูกบล็อกอยู่"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ไมโครโฟนถูกบล็อกอยู่"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"โหมดลำดับความสำคัญเปิดอยู่"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"การเรียกใช้งาน Assistant เปิดอยู่"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"กำหนดแอปการจดบันทึกเริ่มต้นในการตั้งค่า"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 527a2f6..653ed5c 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Kung maling pattern ang mailalagay mo sa susunod na pagsubok, made-delete ang iyong profile sa trabaho at ang data nito."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Kung maling PIN ang mailalagay mo sa susunod na pagsubok, made-delete ang iyong profile sa trabaho at ang data nito."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Kung maling password ang mailalagay mo sa susunod na pagsubok, made-delete ang iyong profile sa trabaho at ang data nito."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Pindutin ang fingerprint sensor"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Hindi makilala ang mukha. Gumamit ng fingerprint."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Lumipat sa profile sa trabaho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Isara"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"I-customize ang lock screen"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"I-unlock para i-customize ang lock screen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Hindi available ang Wi-Fi"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Naka-block ang camera"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Naka-block ang camera at mikropono"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Naka-block ang mikropono"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Naka-on ang Priority mode"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Naka-on ang atensyon ng Assistant"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Magtakda ng default na app sa pagtatala sa Mga Setting"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index cb50462..82c89d9 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Bir sonraki denemenizde yanlış desen girerseniz iş profiliniz ve verileri silinir."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Bir sonraki denemenizde yanlış PIN girerseniz iş profiliniz ve verileri silinir."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Bir sonraki denemenizde yanlış şifre girerseniz iş profiliniz ve verileri silinir."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Parmak izi sensörüne dokunun"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Yüz tanınamadı. Bunun yerine parmak izi kullanın."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profiline geç"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Kapat"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Kilit ekranını özelleştir"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Kilit ekranını özelleştirmek için kilidi açın"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Kablosuz bağlantı kullanılamıyor"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera engellendi"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera ve mikrofon engellendi"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon engellendi"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Öncelik modu etkin"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistan dinliyor"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ayarlar\'ı kullanarak varsayılan notlar ayarlayın"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index d236f50..767d319 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Якщо наступного разу ви введете неправильний ключ, ваш робочий профіль і його дані буде видалено."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Якщо наступного разу ви введете неправильний PIN-код, ваш робочий профіль і його дані буде видалено."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Якщо наступного разу ви введете неправильний пароль, ваш робочий профіль і його дані буде видалено."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Торкніться сканера відбитків пальців"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Обличчя не розпізнано. Скористайтеся відбитком пальця."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в робочий профіль"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрити"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Налаштувати заблокований екран"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Розблокуйте, щоб налаштувати заблокований екран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Мережа Wi-Fi недоступна"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камеру заблоковано"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камеру й мікрофон заблоковано"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Мікрофон заблоковано"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Режим пріоритету ввімкнено"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Асистента активовано"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Призначте стандартний додаток для нотаток у налаштуваннях"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 92a7652..b4d1ebc 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"اگر آپ نے اگلی کوشش میں غلط پیٹرن درج کیا تو آپ کی دفتری پروفائل اور اس کا ڈیٹا حذف کر دیا جائے گا۔"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"‏اگر آپ نے اگلی کوشش میں غلط PIN درج کیا تو آپ کی دفتری پروفائل اور اس کا ڈیٹا حذف کر دیا جائے گا۔"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"اگر آپ نے اگلی کوشش میں غلط پاس ورڈ درج کیا تو آپ کی دفتری پروفائل اور اس کا ڈیٹا حذف کر دیا جائے گا۔"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"فنگر پرنٹ سینسر پر ٹچ کریں"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"چہرے کی شناخت نہیں ہو سکی۔ اس کے بجائے فنگر پرنٹ استعمال کریں۔"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"دفتری پروفائل پر سوئچ کریں"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"بند کریں"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"مقفل اسکرین کو حسب ضرورت بنائیں"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"مقفل اسکرین کو حسب ضرورت بنانے کے لیے غیر مقفل کریں"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏Wi-Fi دستیاب نہیں ہے"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"کیمرا مسدود ہے"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"کیمرا اور مائیکروفون مسدود ہے"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"مائیکروفون مسدود ہے"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ترجیحی موڈ آن ہے"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"اسسٹنٹ کی توجہ آن ہے"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ترتیبات میں ڈیفالٹ نوٹس ایپ سیٹ کریں"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 3d148e4..0154c53 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Agar grafik kalitni xato kiritsangiz, ish profili va undagi maʼlumotlar oʻchirib tashlanadi."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Agar PIN kodni xato kiritsangiz, ish profili va undagi maʼlumotlar oʻchirib tashlanadi."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Agar parolni xato kiritsangiz, ish profili va undagi maʼlumotlar oʻchirib tashlanadi."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Barmoq izi skaneriga tegining"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Bu yuz notanish. Barmoq izi orqali urining."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ish profiliga almashish"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Yopish"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Ekran qulfini moslash"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ekran qulfini sozlash uchun qulfni oching"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi mavjud emas"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera bloklangan"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera va mikrofon bloklangan"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon bloklangan"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Imtiyozli rejim yoniq"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent diqqati yoniq"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standart qaydlar ilovasini Sozlamalar orqali tanlang"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index f9a23ed..1dca015 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Nếu bạn nhập hình mở khóa không chính xác vào lần thử tiếp theo, thì hồ sơ công việc của bạn và dữ liệu của hồ sơ công việc sẽ bị xóa."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Nếu bạn nhập mã PIN không chính xác vào lần thử tiếp theo, thì hồ sơ công việc của bạn và dữ liệu của hồ sơ công việc sẽ bị xóa."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Nếu bạn nhập mật khẩu không chính xác vào lần thử tiếp theo, thì hồ sơ công việc của bạn và dữ liệu của hồ sơ công việc sẽ bị xóa."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Chạm vào cảm biến vân tay"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Không thể nhận dạng khuôn mặt. Hãy dùng vân tay."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -917,7 +945,7 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Vuốt để xem thêm"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Đang tải các đề xuất"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"Nội dung nghe nhìn"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"Ẩn chế độ điều khiển nội dung nghe nhìn này cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"Ẩn tính năng điều khiển này cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Không thể ẩn phiên phát nội dung nghe nhìn hiện tại."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ẩn"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"Tiếp tục"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Chuyển sang hồ sơ công việc"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Đóng"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Tuỳ chỉnh màn hình khoá"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Mở khoá để tuỳ chỉnh màn hình khoá"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Không có Wi-Fi"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Máy ảnh bị chặn"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Máy ảnh và micrô bị chặn"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Micrô bị chặn"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Chế độ ưu tiên đang bật"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Trợ lý đang bật"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Đặt ứng dụng ghi chú mặc định trong phần Cài đặt"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 5110027..e7294c3 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"如果您下次绘制的解锁图案仍然有误,您的工作资料及其相关数据将会被删除。"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"如果您下次输入的 PIN 码仍然有误,您的工作资料及其相关数据将会被删除。"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"如果您下次输入的密码仍然有误,您的工作资料及其相关数据将会被删除。"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"请触摸指纹传感器"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"无法识别人脸。请改用指纹。"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -982,8 +1010,8 @@
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"无法保存。"</string>
     <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"必须至少 4 个字符"</string>
     <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"必须少于 16 个字符"</string>
-    <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string>
-    <string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string>
+    <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>
     <string name="select_conversation_title" msgid="6716364118095089519">"对话微件"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"点按对话即可将其添加到主屏幕"</string>
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切换到工作资料"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"关闭"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"自定义锁屏状态"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"解锁以自定义锁定屏幕"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"没有 WLAN 连接"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"已禁用摄像头"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"已禁用摄像头和麦克风"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"已禁用麦克风"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"已开启优先模式"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"已开启 Google 助理感知功能"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在设置中设置默认记事应用"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 82f81f6..5609ac9 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -36,8 +36,8 @@
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?\n此應用程式尚未獲授予錄音權限,但可透過此 USB 裝置記錄音訊。"</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」處理「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"此應用程式尚未獲授予錄音權限,但可透過此 USB 裝置記錄音訊。如將「<xliff:g id="APPLICATION">%1$s</xliff:g>」與此裝置配合使用,您可能無法聽見來電、通知及鬧鐘的音效。"</string>
-    <string name="usb_audio_device_prompt" msgid="7944987408206252949">"如將「<xliff:g id="APPLICATION">%1$s</xliff:g>」與此裝置配合使用,您可能無法聽見來電、通知及鬧鐘的音效。"</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"此應用程式尚未獲授予錄音權限,但可透過此 USB 裝置記錄音訊。如將「<xliff:g id="APPLICATION">%1$s</xliff:g>」與此裝置配合使用,你可能無法聽見來電、通知及鬧鐘的音效。"</string>
+    <string name="usb_audio_device_prompt" msgid="7944987408206252949">"如將「<xliff:g id="APPLICATION">%1$s</xliff:g>」與此裝置配合使用,你可能無法聽見來電、通知及鬧鐘的音效。"</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>」嗎?"</string>
     <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」處理「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
     <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」應用程式來控制「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?\n此應用程式尚未獲授予錄音權限,但可透過此 USB 裝置記錄音訊。"</string>
@@ -64,7 +64,7 @@
     <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"不允許無線偵錯功能"</string>
     <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"目前登入此裝置的使用者無法啟用無線偵錯功能。如要使用此功能,請切換至管理員使用者。"</string>
     <string name="usb_contaminant_title" msgid="894052515034594113">"已停用 USB 連接埠"</string>
-    <string name="usb_contaminant_message" msgid="7730476585174719805">"為了保護您的裝置免受液體或碎片損害,USB 連接埠已停用,因此不會偵測到任何配件。\n\nUSB 連接埠可安全使用時,您會收到通知。"</string>
+    <string name="usb_contaminant_message" msgid="7730476585174719805">"為了保護你的裝置免受液體或碎片損害,USB 連接埠已停用,因此不會偵測到任何配件。\n\nUSB 連接埠可安全使用時,你會收到通知。"</string>
     <string name="usb_port_enabled" msgid="531823867664717018">"已啟用 USB 連接埠以偵測充電器和配件"</string>
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"啟用 USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"瞭解詳情"</string>
@@ -78,8 +78,8 @@
     <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"必須先解鎖裝置,才能儲存螢幕截圖"</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"請再嘗試拍攝螢幕擷取畫面"</string>
     <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"無法儲存螢幕截圖"</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"應用程式或您的機構不允許擷取螢幕畫面"</string>
-    <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"您的 IT 管理員已禁止擷取螢幕截圖"</string>
+    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"應用程式或你的機構不允許擷取螢幕畫面"</string>
+    <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"你的 IT 管理員已禁止擷取螢幕截圖"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"編輯"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"編輯螢幕截圖"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"分享螢幕截圖"</string>
@@ -141,7 +141,7 @@
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"請再試一次"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"輕按即可取消驗證"</string>
     <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"請再試一次"</string>
-    <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"正在尋找您的面孔"</string>
+    <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"正在尋找你的面孔"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"面孔已經驗證"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已確認"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕按 [確定] 以完成"</string>
@@ -157,17 +157,45 @@
     <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"圖案錯誤"</string>
     <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"密碼錯誤"</string>
     <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"輸入錯誤的次數太多,\n請於 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試。"</string>
-    <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"請再試一次。您已嘗試 <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> 次,最多可試 <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> 次。"</string>
-    <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"您的資料將會刪除"</string>
-    <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"如果您下次畫出錯誤的上鎖圖案,系統將會刪除此裝置上的資料。"</string>
-    <string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"如果您下次輸入錯誤的 PIN,系統將會刪除此裝置上的資料。"</string>
-    <string name="biometric_dialog_last_password_attempt_before_wipe_device" msgid="2363778585575998317">"如果您下次輸入錯誤的密碼,系統將會刪除此裝置上的資料。"</string>
-    <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"如果您下次畫出錯誤的上鎖圖案,系統將會刪除此使用者。"</string>
-    <string name="biometric_dialog_last_pin_attempt_before_wipe_user" msgid="4159878829962411168">"如果您下次輸入錯誤的 PIN,系統將會刪除此使用者。"</string>
-    <string name="biometric_dialog_last_password_attempt_before_wipe_user" msgid="4695682515465063885">"如果您下次輸入錯誤的密碼,系統將會刪除此使用者。"</string>
-    <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"如果您下次畫出錯誤的上鎖圖案,系統將會刪除工作設定檔和相關資料。"</string>
-    <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"如果您下次輸入錯誤的 PIN,系統將會刪除工作設定檔和相關資料。"</string>
-    <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"如果您下次輸入錯誤的密碼,系統將會刪除工作設定檔和相關資料。"</string>
+    <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"請再試一次。你已嘗試 <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> 次,最多可試 <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> 次。"</string>
+    <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"你的資料將會刪除"</string>
+    <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"如果你下次畫出錯誤的上鎖圖案,系統將會刪除此裝置上的資料。"</string>
+    <string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"如果你下次輸入錯誤的 PIN,系統將會刪除此裝置上的資料。"</string>
+    <string name="biometric_dialog_last_password_attempt_before_wipe_device" msgid="2363778585575998317">"如果你下次輸入錯誤的密碼,系統將會刪除此裝置上的資料。"</string>
+    <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"如果你下次畫出錯誤的上鎖圖案,系統將會刪除此使用者。"</string>
+    <string name="biometric_dialog_last_pin_attempt_before_wipe_user" msgid="4159878829962411168">"如果你下次輸入錯誤的 PIN,系統將會刪除此使用者。"</string>
+    <string name="biometric_dialog_last_password_attempt_before_wipe_user" msgid="4695682515465063885">"如果你下次輸入錯誤的密碼,系統將會刪除此使用者。"</string>
+    <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"如果你下次畫出錯誤的上鎖圖案,系統將會刪除工作設定檔和相關資料。"</string>
+    <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"如果你下次輸入錯誤的 PIN,系統將會刪除工作設定檔和相關資料。"</string>
+    <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"如果你下次輸入錯誤的密碼,系統將會刪除工作設定檔和相關資料。"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"請輕觸指紋感應器"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"無法辨識面孔,請改用指紋完成驗證。"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -213,7 +241,7 @@
     <string name="accessibility_brightness" msgid="5391187016177823721">"顯示光暗度"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"已暫停使用流動數據"</string>
     <string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"已暫停使用數據"</string>
-    <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"您的數據用量已達到所設定的上限,因此系統已停用流動數據連線。\n\n如果您恢復使用流動數據連線,可能需要支付數據用量費用。"</string>
+    <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"你的數據用量已達到所設定的上限,因此系統已停用流動數據連線。\n\n如果你恢復使用流動數據連線,可能需要支付數據用量費用。"</string>
     <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"恢復"</string>
     <string name="accessibility_location_active" msgid="2845747916764660369">"位置要求啟動中"</string>
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"已啟用「感應器關閉」"</string>
@@ -306,9 +334,9 @@
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解除封鎖裝置相機嗎?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要解除封鎖裝置相機和麥克風嗎?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"解除封鎖後,凡有存取權的應用程式和服務都可使用您的麥克風。"</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"解除封鎖後,凡有存取權的應用程式和服務都可使用您的相機。"</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"解除封鎖後,凡有存取權的應用程式和服務都可使用您的相機或麥克風。"</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"解除封鎖後,凡有存取權的應用程式和服務都可使用你的麥克風。"</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"解除封鎖後,凡有存取權的應用程式和服務都可使用你的相機。"</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"解除封鎖後,凡有存取權的應用程式和服務都可使用你的相機或麥克風。"</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"已封鎖麥克風"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"已封鎖相機"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"已封鎖麥克風和相機"</string>
@@ -321,8 +349,8 @@
     <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"麥克風已開啟"</string>
     <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"麥克風已關閉"</string>
     <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"已為所有應用程式和服務啟用麥克風。"</string>
-    <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"已停用所有應用程式和服務的麥克風存取權。您可以在 [設定] &gt; [私隱] &gt; [麥克風] 啟用麥克風存取權。"</string>
-    <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"已停用所有應用程式和服務的麥克風存取權。您可以在 [設定] &gt; [私隱] &gt; [麥克風] 更改設定。"</string>
+    <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"已停用所有應用程式和服務的麥克風存取權。你可以在 [設定] &gt; [私隱] &gt; [麥克風] 啟用麥克風存取權。"</string>
+    <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"已停用所有應用程式和服務的麥克風存取權。你可以在 [設定] &gt; [私隱] &gt; [麥克風] 更改設定。"</string>
     <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"相機已開啟"</string>
     <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"相機已關閉"</string>
     <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"已為所有應用程式和服務啟用相機。"</string>
@@ -331,10 +359,10 @@
     <string name="sensor_privacy_dialog_open_settings" msgid="5635865896053011859">"開啟「設定」"</string>
     <string name="media_seamless_other_device" msgid="4654849800789196737">"其他裝置"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"切換概覽"</string>
-    <string name="zen_priority_introduction" msgid="3159291973383796646">"您不會受到聲音和震動騷擾 (鬧鐘、提醒、活動和您指定的來電者鈴聲除外)。當您選擇播放音樂、影片和遊戲等,仍可以聽到該內容的聲音。"</string>
-    <string name="zen_alarms_introduction" msgid="3987266042682300470">"您不會受到聲音和震動騷擾 (鬧鐘除外)。當您選擇播放音樂、影片和遊戲等,仍可以聽到該內容的聲音。"</string>
+    <string name="zen_priority_introduction" msgid="3159291973383796646">"你不會受到聲音和震動騷擾 (鬧鐘、提醒、活動和你指定的來電者鈴聲除外)。當你選擇播放音樂、影片和遊戲等,仍可以聽到該內容的聲音。"</string>
+    <string name="zen_alarms_introduction" msgid="3987266042682300470">"你不會受到聲音和震動騷擾 (鬧鐘除外)。當你選擇播放音樂、影片和遊戲等,仍可以聽到該內容的聲音。"</string>
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"自訂"</string>
-    <string name="zen_silence_introduction_voice" msgid="853573681302712348">"這會封鎖所有聲音和震動 (包括鬧鐘、音樂、影片及遊戲),但您仍可以撥打電話。"</string>
+    <string name="zen_silence_introduction_voice" msgid="853573681302712348">"這會封鎖所有聲音和震動 (包括鬧鐘、音樂、影片及遊戲),但你仍可以撥打電話。"</string>
     <string name="zen_silence_introduction" msgid="6117517737057344014">"這會封鎖所有聲音和震動,包括鬧鐘、音樂、影片和遊戲。"</string>
     <string name="notification_tap_again" msgid="4477318164947497249">"再次輕按即可開啟"</string>
     <string name="tap_again" msgid="1315420114387908655">"再次輕按"</string>
@@ -349,7 +377,7 @@
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"已識別面孔"</string>
     <string name="keyguard_retry" msgid="886802522584053523">"請向上滑動以再試一次"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖方可使用 NFC"</string>
-    <string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於您的機構"</string>
+    <string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於你的機構"</string>
     <string name="do_disclosure_with_name" msgid="2091641464065004091">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」"</string>
     <string name="do_financed_disclosure_with_name" msgid="6723004643314467864">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
     <string name="phone_hint" msgid="6682125338461375925">"從圖示滑動即可使用手機功能"</string>
@@ -370,15 +398,15 @@
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
-    <string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客您好,歡迎回來!"</string>
-    <string name="guest_wipe_session_message" msgid="3393823610257065457">"您要繼續您的工作階段嗎?"</string>
+    <string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客你好,歡迎回來!"</string>
+    <string name="guest_wipe_session_message" msgid="3393823610257065457">"你要繼續你的工作階段嗎?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是的,請繼續"</string>
     <string name="guest_notification_app_name" msgid="2110425506754205509">"訪客模式"</string>
-    <string name="guest_notification_session_active" msgid="5567273684713471450">"您正在使用訪客模式"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"你正在使用訪客模式"</string>
     <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"新增使用者後,系統就會結束訪客模式,並刪除目前訪客工作階段中的所有應用程式和資料。"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已達到使用者上限"</string>
-    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{只可建立一位使用者。}other{您可以加入多達 # 位使用者。}}"</string>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{只可建立一位使用者。}other{你可以加入多達 # 位使用者。}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"移除使用者?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"系統將會刪除這個使用者的所有應用程式和資料。"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"移除"</string>
@@ -389,14 +417,14 @@
     <string name="media_projection_permission_dialog_title" msgid="7130975432309482596">"允許 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 分享或錄製嗎?"</string>
     <string name="media_projection_permission_dialog_option_entire_screen" msgid="392086473225692983">"整個螢幕畫面"</string>
     <string name="media_projection_permission_dialog_option_single_app" msgid="1591110238124910521">"一個應用程式"</string>
-    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"當您分享、錄製或投放應用程式時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可存取在螢幕畫面上顯示或在裝置上播放的所有內容。因此請小心保管密碼、付款資料、訊息或其他敏感資料。"</string>
+    <string name="media_projection_permission_dialog_warning_entire_screen" msgid="3989078820637452717">"當你分享、錄製或投放應用程式時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可存取在螢幕畫面上顯示或在裝置上播放的所有內容。因此請小心保管密碼、付款資料、訊息或其他敏感資料。"</string>
     <string name="media_projection_permission_dialog_warning_single_app" msgid="1659532781536753059">"進行分享、錄製或投放時,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 可存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
     <string name="media_projection_permission_dialog_continue" msgid="1827799658916736006">"繼續"</string>
     <string name="media_projection_permission_app_selector_title" msgid="894251621057480704">"分享或錄製應用程式"</string>
     <string name="media_projection_permission_dialog_system_service_title" msgid="6827129613741303726">"要允許此應用程式分享或錄製內容嗎?"</string>
     <string name="media_projection_permission_dialog_system_service_warning_entire_screen" msgid="8801616203805837575">"進行分享、錄製或投放時,此應用程式可存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
     <string name="media_projection_permission_dialog_system_service_warning_single_app" msgid="543310680568419338">"進行分享、錄製或投放時,此應用程式可存取顯示在螢幕畫面上或在該應用程式上播放的所有內容。因此請謹慎處理密碼、付款資料、訊息或其他敏感資料。"</string>
-    <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"已被您的 IT 管理員封鎖"</string>
+    <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"已被你的 IT 管理員封鎖"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"螢幕截圖功能因裝置政策而停用"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
@@ -411,23 +439,23 @@
     <string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
-    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此裝置由您的家長管理"</string>
-    <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"您的機構擁有此裝置,並可能會監察網絡流量"</string>
+    <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此裝置由你的家長管理"</string>
+    <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"你的機構擁有此裝置,並可能會監察網絡流量"</string>
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」擁有此裝置,並可能會監察網絡流量"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
-    <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"此裝置屬於您的機構,並已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
+    <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"此裝置屬於你的機構,並已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
     <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"此裝置由「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」所有,並透過「<xliff:g id="VPN_APP">%2$s</xliff:g>」連接至互聯網"</string>
-    <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"此裝置屬於您的機構"</string>
+    <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"此裝置屬於你的機構"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」"</string>
-    <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"此裝置屬於您的機構,並已透過 VPN 連接至互聯網"</string>
+    <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"此裝置屬於你的機構,並已透過 VPN 連接至互聯網"</string>
     <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並已透過 VPN 連接至互聯網"</string>
-    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"您的機構可能監控您工作設定檔上的網絡流量"</string>
-    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>可能會監控您工作設定檔上的網絡流量"</string>
+    <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"你的機構可能監控你工作設定檔上的網絡流量"</string>
+    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>可能會監控你工作設定檔上的網絡流量"</string>
     <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IT 管理員可以查看工作設定檔的網絡活動"</string>
     <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"網絡可能會受到監控"</string>
     <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"此裝置已透過 VPN 連接至互聯網"</string>
-    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"您的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
-    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"您的個人應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"你的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
+    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"你的個人應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"此裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
     <string name="monitoring_title_financed_device" msgid="3659962357973919387">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"裝置管理"</string>
@@ -436,21 +464,21 @@
     <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"CA 憑證"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"查看政策"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"查看控制項"</string>
-    <string name="monitoring_description_named_management" msgid="505833016545056036">"此裝置屬於 <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>。\n\n您的 IT 管理員可監察及管理與裝置相關聯的設定、公司存取權、應用程式和資料,以及裝置的位置資料。\n\n如要瞭解詳情,請與您的 IT 管理員聯絡。"</string>
+    <string name="monitoring_description_named_management" msgid="505833016545056036">"此裝置屬於 <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>。\n\n你的 IT 管理員可監察及管理與裝置相關聯的設定、公司存取權、應用程式和資料,以及裝置的位置資料。\n\n如要瞭解詳情,請與你的 IT 管理員聯絡。"</string>
     <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> 或可存取此裝置的相關資料、管理應用程式並變更裝置設定。\n\n如有疑問,請聯絡 <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>。"</string>
-    <string name="monitoring_description_management" msgid="4308879039175729014">"此裝置屬於您的機構。\n\n您的 IT 管理員可監察及管理與裝置相關聯的設定、公司存取權、應用程式和資料,以及裝置的位置資料。\n\n如要瞭解詳情,請與您的 IT 管理員聯絡。"</string>
-    <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"您的機構已在此裝置中安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
-    <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"您的機構已在您的工作設定檔中安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
-    <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"此裝置已安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
-    <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"您的管理員已開啟網絡記錄功能,以監控您裝置上的流量。"</string>
-    <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"您的管理員已開啟網絡記錄功能,可監控您工作設定檔 (而非個人設定檔) 的流量。"</string>
-    <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"此裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。IT 管理員可以看到您的網絡活動,包括電郵和瀏覽資料。"</string>
-    <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"此裝置已透過「<xliff:g id="VPN_APP_0">%1$s</xliff:g>」和「<xliff:g id="VPN_APP_1">%2$s</xliff:g>」連接至互聯網。IT 管理員可以看到您的網絡活動,包括電郵和瀏覽資料。"</string>
-    <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"您的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。IT 管理員和 VPN 供應商可以看到您在工作應用程式的網絡活動,包括電郵和瀏覽資料。"</string>
-    <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"您的個人應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。您的 VPN 供應商可以看到您的網絡活動,包括電郵和瀏覽資料。"</string>
+    <string name="monitoring_description_management" msgid="4308879039175729014">"此裝置屬於你的機構。\n\n你的 IT 管理員可監察及管理與裝置相關聯的設定、公司存取權、應用程式和資料,以及裝置的位置資料。\n\n如要瞭解詳情,請與你的 IT 管理員聯絡。"</string>
+    <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"你的機構已在此裝置中安裝憑證授權單位。你的安全網絡流量可能會受監控或修改。"</string>
+    <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"你的機構已在你的工作設定檔中安裝憑證授權單位。你的安全網絡流量可能會受監控或修改。"</string>
+    <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"此裝置已安裝憑證授權單位。你的安全網絡流量可能會受監控或修改。"</string>
+    <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"你的管理員已開啟網絡記錄功能,以監控你裝置上的流量。"</string>
+    <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"你的管理員已開啟網絡記錄功能,可監控你工作設定檔 (而非個人設定檔) 的流量。"</string>
+    <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"此裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。IT 管理員可以看到你的網絡活動,包括電郵和瀏覽資料。"</string>
+    <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"此裝置已透過「<xliff:g id="VPN_APP_0">%1$s</xliff:g>」和「<xliff:g id="VPN_APP_1">%2$s</xliff:g>」連接至互聯網。IT 管理員可以看到你的網絡活動,包括電郵和瀏覽資料。"</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"你的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。IT 管理員和 VPN 供應商可以看到你在工作應用程式的網絡活動,包括電郵和瀏覽資料。"</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"你的個人應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。你的 VPN 供應商可以看到你的網絡活動,包括電郵和瀏覽資料。"</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"開啟 VPN 設定"</string>
-    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"此裝置由您的家長管理。家長可以查看及管理裝置上的資料,例如您使用的應用程式、位置和裝置使用時間。"</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"此裝置由你的家長管理。家長可以查看及管理裝置上的資料,例如你使用的應用程式、位置和裝置使用時間。"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"由信任的代理保持解鎖狀態"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
@@ -465,11 +493,11 @@
     <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"已調低至較安全的音量"</string>
     <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"使用高音量已超過建議的時間"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"已固定應用程式"</string>
-    <string name="screen_pinning_description" msgid="8699395373875667743">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。按住「返回」和「概覽」按鈕即可取消固定。"</string>
-    <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。按住「返回」按鈕和主按鈕即可取消固定。"</string>
-    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。向上滑動後按住即可取消固定。"</string>
-    <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。按住「概覽」按鈕即可取消固定。"</string>
-    <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"應用程式將會固定在螢幕上顯示,直至您取消固定為止。按住主按鈕即可取消固定。"</string>
+    <string name="screen_pinning_description" msgid="8699395373875667743">"應用程式將會固定在螢幕上顯示,直至你取消固定為止。按住「返回」和「概覽」按鈕即可取消固定。"</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"應用程式將會固定在螢幕上顯示,直至你取消固定為止。按住「返回」按鈕和主按鈕即可取消固定。"</string>
+    <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"應用程式將會固定在螢幕上顯示,直至你取消固定為止。向上滑動後按住即可取消固定。"</string>
+    <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"應用程式將會固定在螢幕上顯示,直至你取消固定為止。按住「概覽」按鈕即可取消固定。"</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"應用程式將會固定在螢幕上顯示,直至你取消固定為止。按住主按鈕即可取消固定。"</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"應用程式可能會存取個人資料 (例如通訊錄和電郵內容)。"</string>
     <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"固定的應用程式可開啟其他應用程式。"</string>
     <string name="screen_pinning_toast" msgid="8177286912533744328">"如要取消固定此應用程式,請按住「返回」按鈕和「概覽」按鈕"</string>
@@ -521,16 +549,16 @@
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"正在更新"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"工作設定檔"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"飛行模式"</string>
-    <string name="zen_alarm_warning" msgid="7844303238486849503">"您不會<xliff:g id="WHEN">%1$s</xliff:g>聽到鬧鐘"</string>
+    <string name="zen_alarm_warning" msgid="7844303238486849503">"你不會<xliff:g id="WHEN">%1$s</xliff:g>聽到鬧鐘"</string>
     <string name="alarm_template" msgid="2234991538018805736">"在 <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"在<xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"熱點"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作設定檔"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"這只是測試版本,並不包含完整功能"</string>
-    <string name="tuner_warning" msgid="1861736288458481650">"使用者介面調諧器讓您以更多方法修改和自訂 Android 使用者介面。但請小心,這些實驗功能可能會在日後發佈時更改、分拆或消失。"</string>
+    <string name="tuner_warning" msgid="1861736288458481650">"使用者介面調諧器讓你以更多方法修改和自訂 Android 使用者介面。但請小心,這些實驗功能可能會在日後發佈時更改、分拆或消失。"</string>
     <string name="tuner_persistent_warning" msgid="230466285569307806">"請小心,這些實驗功能可能會在日後發佈時更改、分拆或消失。"</string>
     <string name="got_it" msgid="477119182261892069">"知道了"</string>
-    <string name="tuner_toast" msgid="3812684836514766951">"恭喜您!系統使用者介面調諧器已新增至「設定」中"</string>
+    <string name="tuner_toast" msgid="3812684836514766951">"恭喜你!系統使用者介面調諧器已新增至「設定」中"</string>
     <string name="remove_from_settings" msgid="633775561782209994">"從「設定」移除"</string>
     <string name="remove_from_settings_prompt" msgid="551565437265615426">"要從「設定」移除系統使用者介面調諧器,並停止其所有功能嗎?"</string>
     <string name="enable_bluetooth_title" msgid="866883307336662596">"要開啟藍牙嗎?"</string>
@@ -538,7 +566,7 @@
     <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"開啟"</string>
     <string name="tuner_full_importance_settings" msgid="1388025816553459059">"通知控制項"</string>
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"已開啟 - 根據面孔偵測"</string>
-    <string name="power_notification_controls_description" msgid="1334963837572708952">"通知控制項讓您設定應用程式通知的重要性 (0 至 5 級)。\n\n"<b>"第 5 級"</b>" \n- 在通知清單頂部顯示 \n- 允許全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 4 級"</b>" \n- 阻止全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 3 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n\n"<b>"第 2 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n\n"<b>"第 1 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n- 從上鎖畫面和狀態列中隱藏 \n- 在通知清單底部顯示 \n\n"<b>"第 0 級"</b>" \n- 封鎖所有應用程式通知"</string>
+    <string name="power_notification_controls_description" msgid="1334963837572708952">"通知控制項讓你設定應用程式通知的重要性 (0 至 5 級)。\n\n"<b>"第 5 級"</b>" \n- 在通知清單頂部顯示 \n- 允許全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 4 級"</b>" \n- 阻止全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 3 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n\n"<b>"第 2 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n\n"<b>"第 1 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n- 從上鎖畫面和狀態列中隱藏 \n- 在通知清單底部顯示 \n\n"<b>"第 0 級"</b>" \n- 封鎖所有應用程式通知"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"完成"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"套用"</string>
     <string name="inline_turn_off_notifications" msgid="8543989584403106071">"關閉通知"</string>
@@ -570,7 +598,7 @@
     <string name="feedback_silenced" msgid="9116540317466126457">"系統已自動將此通知的重要性&lt;b&gt;降低為靜音&lt;/b&gt;。"</string>
     <string name="feedback_promoted" msgid="2125562787759780807">"系統已自動&lt;b&gt;提高&lt;/b&gt;此通知在通知欄中的次序。"</string>
     <string name="feedback_demoted" msgid="951884763467110604">"系統已自動&lt;b&gt;調低&lt;/b&gt;此通知在通知欄中的次序。"</string>
-    <string name="feedback_prompt" msgid="3656728972307896379">"與開發人員分享您的意見。是否正確?"</string>
+    <string name="feedback_prompt" msgid="3656728972307896379">"與開發人員分享你的意見。是否正確?"</string>
     <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"開咗「<xliff:g id="APP_NAME">%1$s</xliff:g>」嘅通知控制項"</string>
     <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"閂咗「<xliff:g id="APP_NAME">%1$s</xliff:g>」嘅通知控制項"</string>
     <string name="notification_more_settings" msgid="4936228656989201793">"更多設定"</string>
@@ -702,7 +730,7 @@
     <string name="drag_to_add_tiles" msgid="8933270127508303672">"按住並拖曳即可新增圖塊"</string>
     <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"按住並拖曳即可重新排列圖塊"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"拖曳這裡即可移除"</string>
-    <string name="drag_to_remove_disabled" msgid="933046987838658850">"您需要有至少 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個資訊方塊"</string>
+    <string name="drag_to_remove_disabled" msgid="933046987838658850">"你需要有至少 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個資訊方塊"</string>
     <string name="qs_edit" msgid="5583565172803472437">"編輯"</string>
     <string name="tuner_time" msgid="2450785840990529997">"時間"</string>
   <string-array name="clock_options">
@@ -740,12 +768,12 @@
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁 (共 <xliff:g id="ID_2">%2$d</xliff:g> 頁)"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"螢幕鎖定"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"手機因過熱而關上"</string>
-    <string name="thermal_shutdown_message" msgid="6142269839066172984">"您的手機現已正常運作。\n輕按即可瞭解詳情"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"您的手機之前因過熱而關上降溫。手機現已正常運作。\n\n以下情況可能會導致手機過熱:\n	• 使用耗用大量資源的應用程式 (例如遊戲、影片或導航應用程式)\n	• 下載或上載大型檔案\n	• 在高溫環境下使用手機"</string>
+    <string name="thermal_shutdown_message" msgid="6142269839066172984">"你的手機現已正常運作。\n輕按即可瞭解詳情"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"你的手機之前因過熱而關上降溫。手機現已正常運作。\n\n以下情況可能會導致手機過熱:\n	• 使用耗用大量資源的應用程式 (例如遊戲、影片或導航應用程式)\n	• 下載或上載大型檔案\n	• 在高溫環境下使用手機"</string>
     <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"查看保養步驟"</string>
     <string name="high_temp_title" msgid="2218333576838496100">"手機溫度正在上升"</string>
     <string name="high_temp_notif_message" msgid="1277346543068257549">"手機降溫時,部分功能會受限制。\n輕按即可瞭解詳情"</string>
-    <string name="high_temp_dialog_message" msgid="3793606072661253968">"手機會自動嘗試降溫。您仍可以使用手機,但手機的運作速度可能較慢。\n\n手機降溫後便會恢復正常。"</string>
+    <string name="high_temp_dialog_message" msgid="3793606072661253968">"手機會自動嘗試降溫。你仍可以使用手機,但手機的運作速度可能較慢。\n\n手機降溫後便會恢復正常。"</string>
     <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"查看保養步驟"</string>
     <string name="high_temp_alarm_title" msgid="8654754369605452169">"拔除裝置"</string>
     <string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"充電埠附近的裝置溫度正在上升。如裝置正連接充電器或 USB 配件,請拔除裝置並小心安全,因為電線的溫度可能也偏高。"</string>
@@ -790,13 +818,13 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"正在背景中執行的應用程式"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"輕按即可查看電池和數據用量詳情"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"要關閉流動數據嗎?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"您無法透過「<xliff:g id="CARRIER">%s</xliff:g>」使用流動數據或互聯網。如要使用互聯網,您必須連接 Wi-Fi。"</string>
-    <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"您的流動網絡供應商"</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"你無法透過「<xliff:g id="CARRIER">%s</xliff:g>」使用流動數據或互聯網。如要使用互聯網,你必須連接 Wi-Fi。"</string>
+    <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"你的流動網絡供應商"</string>
     <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"要切換回「<xliff:g id="CARRIER">%s</xliff:g>」嗎?"</string>
     <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"流動數據不會根據可用性自動切換"</string>
     <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"不用了,謝謝"</string>
     <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"是,請切換"</string>
-    <string name="touch_filtered_warning" msgid="8119511393338714836">"由於某個應用程式已阻擋權限要求畫面,因此「設定」應用程式無法驗證您的回應。"</string>
+    <string name="touch_filtered_warning" msgid="8119511393338714836">"由於某個應用程式已阻擋權限要求畫面,因此「設定」應用程式無法驗證你的回應。"</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"要允許「<xliff:g id="APP_0">%1$s</xliff:g>」顯示「<xliff:g id="APP_2">%2$s</xliff:g>」的快訊嗎?"</string>
     <string name="slice_permission_text_1" msgid="6675965177075443714">"- 可以讀取「<xliff:g id="APP">%1$s</xliff:g>」中的資料"</string>
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- 可以在「<xliff:g id="APP">%1$s</xliff:g>」內執行操作"</string>
@@ -903,9 +931,9 @@
     <string name="controls_dialog_message" msgid="342066938390663844">"由「<xliff:g id="APP">%s</xliff:g>」提供的建議"</string>
     <string name="controls_tile_locked" msgid="731547768182831938">"裝置已上鎖"</string>
     <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"要從上鎖畫面查看及控制裝置嗎?"</string>
-    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"您可以在上鎖畫面新增外部裝置的控制項。\n\n裝置應用程式可能會讓您在不解鎖手機或平板電腦的情況下控制部分裝置。\n\n您可隨時在「設定」中作出變更。"</string>
+    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"你可以在上鎖畫面新增外部裝置的控制項。\n\n裝置應用程式可能會讓你在不解鎖手機或平板電腦的情況下控制部分裝置。\n\n你可隨時在「設定」中作出變更。"</string>
     <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"要在上鎖畫面控制裝置嗎?"</string>
-    <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"您可以在不解鎖手機或平板電腦的情況下控制部分裝置。裝置應用程式決定哪些裝置可透過此方式控制。"</string>
+    <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"你可以在不解鎖手機或平板電腦的情況下控制部分裝置。裝置應用程式決定哪些裝置可透過此方式控制。"</string>
     <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"不用了,謝謝"</string>
     <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"是"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 含有字母或符號"</string>
@@ -933,7 +961,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="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>
@@ -971,8 +999,8 @@
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播運作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string>
-    <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近有兼容藍牙裝置的人可收聽您正在廣播的媒體內容"</string>
-    <string name="media_output_broadcasting_message" msgid="4150299923404886073">"如附近有兼容藍牙裝置的人,只要掃瞄您的 QR 碼或使用您的廣播名稱和密碼,便可收聽您的廣播內容"</string>
+    <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近有兼容藍牙裝置的人可收聽你正在廣播的媒體內容"</string>
+    <string name="media_output_broadcasting_message" msgid="4150299923404886073">"如附近有兼容藍牙裝置的人,只要掃瞄你的 QR 碼或使用你的廣播名稱和密碼,便可收聽你的廣播內容"</string>
     <string name="media_output_broadcast_name" msgid="8786127091542624618">"廣播名稱"</string>
     <string name="media_output_broadcast_code" msgid="870795639644728542">"密碼"</string>
     <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"儲存"</string>
@@ -987,7 +1015,7 @@
     <string name="basic_status" msgid="2315371112182658176">"開啟對話"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"對話小工具"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"輕按對話即可新增至主畫面"</string>
-    <string name="no_conversations_text" msgid="5354115541282395015">"您最近的對話會在這裡顯示"</string>
+    <string name="no_conversations_text" msgid="5354115541282395015">"你最近的對話會在這裡顯示"</string>
     <string name="priority_conversations" msgid="3967482288896653039">"優先對話"</string>
     <string name="recent_conversations" msgid="8531874684782574622">"最近的對話"</string>
     <string name="days_timestamp" msgid="5821854736213214331">"<xliff:g id="DURATION">%1$s</xliff:g> 天前"</string>
@@ -1046,7 +1074,7 @@
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"目前系統不會自動連線至 Wi-Fi"</string>
     <string name="see_all_networks" msgid="3773666844913168122">"顯示全部"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"如要切換網絡,請中斷以太網連線"</string>
-    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"為改善裝置的使用體驗,應用程式和服務仍可隨時掃瞄 Wi-Fi 網絡 (即使 Wi-Fi 已關閉)。您可在 Wi-Fi 掃瞄設定中變更此設定。"<annotation id="link">"變更"</annotation></string>
+    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"為改善裝置的使用體驗,應用程式和服務仍可隨時掃瞄 Wi-Fi 網絡 (即使 Wi-Fi 已關閉)。你可在 Wi-Fi 掃瞄設定中變更此設定。"<annotation id="link">"變更"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"關閉飛行模式"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"「<xliff:g id="APPNAME">%1$s</xliff:g>」想在「快速設定」選單新增以下圖塊"</string>
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"新增圖塊"</string>
@@ -1055,7 +1083,7 @@
     <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{已啟用 # 個應用程式}other{已啟用 # 個應用程式}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"新資料"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</string>
-    <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"這些應用程式已啟用並執行 (即使您沒有使用)。這會提升應用程式的功能,但也可影響電池壽命。"</string>
+    <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"這些應用程式已啟用並執行 (即使你沒有使用)。這會提升應用程式的功能,但也可影響電池壽命。"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"停止"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"已停止"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"完成"</string>
@@ -1120,16 +1148,16 @@
     <string name="stylus_battery_low" msgid="7134370101603167096">"觸控筆電量不足"</string>
     <string name="video_camera" msgid="7654002575156149298">"攝影機"</string>
     <string name="call_from_work_profile_title" msgid="6991157106804289643">"無法透過此設定檔撥打電話"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"您的公司政策只允許透過工作設定檔撥打電話"</string>
+    <string name="call_from_work_profile_text" msgid="3458704745640229638">"你的公司政策只允許透過工作設定檔撥打電話"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作設定檔"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"自訂上鎖畫面"</string>
-    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"解鎖後即可自訂螢幕鎖定畫面"</string>
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"解鎖後即可自訂上鎖畫面"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"無法連線至 Wi-Fi"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"已封鎖相機"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"已封鎖相機和麥克風"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"已封鎖麥克風"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"優先模式已開啟"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"「Google 助理」感應功能已開啟"</string>
-    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在「設定」中指定預設記事應用程式"</string>
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在「設定」中指定預設筆記應用程式"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 1652a1c..abb2535 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -95,7 +95,7 @@
     <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="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>
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"如果下次輸入的解鎖圖案仍不正確,系統將刪除你的工作資料夾和相關資料。"</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"如果下次輸入的 PIN 碼仍不正確,系統將刪除你的工作資料夾和相關資料。"</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"如果下次輸入的密碼仍不正確,系統將刪除你的工作資料夾和相關資料。"</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"請輕觸指紋感應器"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"無法辨識臉孔,請改用指紋完成驗證。"</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -663,7 +691,7 @@
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"計算機"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"地圖"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"零打擾"</string>
-    <string name="volume_dnd_silent" msgid="4154597281458298093">"音量按鈕快速鍵"</string>
+    <string name="volume_dnd_silent" msgid="4154597281458298093">"音量鍵快速鍵"</string>
     <string name="battery" msgid="769686279459897127">"電池"</string>
     <string name="headset" msgid="4485892374984466437">"耳機"</string>
     <string name="accessibility_long_click_tile" msgid="210472753156768705">"開啟設定"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index aa6f168..ea21f9a 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -168,6 +168,34 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Uma ufaka iphethini engalungile kumzamo olandelayo, iphrofayela yakho yomsebenzi nedatha yayo izosuswa."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Uma ufaka iphinikhodi engalungile kumzamo olandelayo, iphrofayela yakho yomsebenzi nedatha yayo izosuswa."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Uma ufake iphasiwedi engalungile kumzamo olandelayo, iphrofayela yakho yomsebenzi nedatha yayo izosuswa."</string>
+    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
+    <skip />
+    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
+    <skip />
+    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
+    <skip />
+    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
+    <skip />
+    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
+    <skip />
+    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
+    <skip />
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Thinta inzwa yesigxivizo zeminwe"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ayibazi ubuso. Sebenzisa izigxivizo zeminwe kunalokho."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -1124,14 +1152,12 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Shintshela kuphrofayela yomsebenzi"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Vala"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Yenza ngokwezifiso ukukhiya isikrini"</string>
-    <!-- no translation found for keyguard_unlock_to_customize_ls (2068542308086253819) -->
-    <skip />
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Vula ukuze wenze ukuvala isikrini ngendlela oyifisayo"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"I-Wi-Fi ayitholakali"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Ikhamera ivinjiwe"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Ikhamera nemakrofoni zivinjiwe"</string>
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Imakrofoni ivinjiwe"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Imodi ebalulekile ivuliwe"</string>
     <string name="assistant_attention_content_description" msgid="6830215897604642875">"Ukunaka kwe-Assistant kuvuliwe"</string>
-    <!-- no translation found for set_default_notes_app_toast_content (2812374329662610753) -->
-    <skip />
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setha i-app yamanothi azenzakalelayo Kumsethingi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 9cb8aa0..f5c4a4e 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -122,26 +122,26 @@
     <dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
 
     <!-- Default horizontal drawable padding for status bar icons. -->
-    <dimen name="status_bar_horizontal_padding">2.5dp</dimen>
+    <dimen name="status_bar_horizontal_padding">2.5sp</dimen>
 
     <!-- Height of the battery icon in the status bar. -->
-    <dimen name="status_bar_battery_icon_height">13.0dp</dimen>
+    <dimen name="status_bar_battery_icon_height">13.0sp</dimen>
 
     <!-- Width of the battery icon in the status bar. The battery drawable assumes a 12x20 canvas,
-    so the width of the icon should be 13.0dp * (12.0 / 20.0) -->
-    <dimen name="status_bar_battery_icon_width">7.8dp</dimen>
+    so the width of the icon should be 13.0sp * (12.0 / 20.0) -->
+    <dimen name="status_bar_battery_icon_width">7.8sp</dimen>
 
-    <!-- The battery icon is 13dp tall, but the other system icons are 15dp tall (see
+    <!-- The battery icon is 13sp tall, but the other system icons are 15sp tall (see
          @*android:dimen/status_bar_system_icon_size) with some top and bottom padding embedded in
-         the drawables themselves. So, the battery icon may need an extra 1dp of spacing so that its
+         the drawables themselves. So, the battery icon may need an extra 1sp of spacing so that its
          bottom still aligns with the bottom of all the other system icons. See b/258672854. -->
-    <dimen name="status_bar_battery_extra_vertical_spacing">1dp</dimen>
+    <dimen name="status_bar_battery_extra_vertical_spacing">1sp</dimen>
 
     <!-- The font size for the clock in the status bar. -->
     <dimen name="status_bar_clock_size">14sp</dimen>
 
     <!-- The starting padding for the clock in the status bar. -->
-    <dimen name="status_bar_clock_starting_padding">7dp</dimen>
+    <dimen name="status_bar_clock_starting_padding">7sp</dimen>
 
     <!-- The end padding for the clock in the status bar. -->
     <dimen name="status_bar_clock_end_padding">0dp</dimen>
@@ -153,16 +153,19 @@
     <dimen name="status_bar_left_clock_end_padding">2dp</dimen>
 
     <!-- Spacing after the wifi signals that is present if there are any icons following it. -->
-    <dimen name="status_bar_wifi_signal_spacer_width">2.5dp</dimen>
+    <dimen name="status_bar_wifi_signal_spacer_width">2.5sp</dimen>
 
     <!-- Size of the view displaying the wifi signal icon in the status bar. -->
-    <dimen name="status_bar_wifi_signal_size">@*android:dimen/status_bar_system_icon_size</dimen>
+    <dimen name="status_bar_wifi_signal_size">13sp</dimen>
+
+    <!-- Size of the view displaying the mobile signal icon in the status bar. -->
+    <dimen name="status_bar_mobile_signal_size">13sp</dimen>
 
     <!-- Spacing before the airplane mode icon if there are any icons preceding it. -->
-    <dimen name="status_bar_airplane_spacer_width">4dp</dimen>
+    <dimen name="status_bar_airplane_spacer_width">4sp</dimen>
 
     <!-- Spacing between system icons. -->
-    <dimen name="status_bar_system_icon_spacing">0dp</dimen>
+    <dimen name="status_bar_system_icon_spacing">2sp</dimen>
 
     <!-- The amount to scale each of the status bar icons by. A value of 1 means no scaling. -->
     <item name="status_bar_icon_scale_factor" format="float" type="dimen">1.0</item>
@@ -310,7 +313,7 @@
     <dimen name="snooze_snackbar_min_height">56dp</dimen>
 
     <!-- size at which Notification icons will be drawn in the status bar -->
-    <dimen name="status_bar_icon_drawing_size">15dp</dimen>
+    <dimen name="status_bar_icon_drawing_size">15sp</dimen>
 
     <!-- size at which Notification icons will be drawn on Ambient Display -->
     <dimen name="status_bar_icon_drawing_size_dark">
@@ -321,22 +324,22 @@
     <item type="dimen" name="status_bar_icon_drawing_alpha">90%</item>
 
     <!-- gap on either side of status bar notification icons -->
-    <dimen name="status_bar_icon_padding">0dp</dimen>
+    <dimen name="status_bar_icon_padding">0sp</dimen>
 
     <!-- the padding on the start of the statusbar -->
-    <dimen name="status_bar_padding_start">8dp</dimen>
+    <dimen name="status_bar_padding_start">8sp</dimen>
 
     <!-- the padding on the end of the statusbar -->
-    <dimen name="status_bar_padding_end">8dp</dimen>
+    <dimen name="status_bar_padding_end">8sp</dimen>
 
     <!-- the padding on the top of the statusbar (usually 0) -->
-    <dimen name="status_bar_padding_top">0dp</dimen>
+    <dimen name="status_bar_padding_top">0sp</dimen>
 
     <!-- the radius of the overflow dot in the status bar -->
-    <dimen name="overflow_dot_radius">2dp</dimen>
+    <dimen name="overflow_dot_radius">2sp</dimen>
 
     <!-- the padding between dots in the icon overflow -->
-    <dimen name="overflow_icon_dot_padding">3dp</dimen>
+    <dimen name="overflow_icon_dot_padding">3sp</dimen>
 
     <!-- Dimensions related to screenshots -->
 
@@ -389,7 +392,7 @@
     <dimen name="navigation_key_width">70dp</dimen>
 
     <!-- The width/height of the icon of a navigation button -->
-    <dimen name="navigation_icon_size">32dp</dimen>
+    <dimen name="navigation_icon_size">24dp</dimen>
 
     <!-- The padding on the side of the navigation bar. Must be greater than or equal to
          navigation_extra_key_width -->
@@ -617,8 +620,8 @@
     <dimen name="qs_footer_icon_size">20dp</dimen>
     <dimen name="qs_header_row_min_height">48dp</dimen>
 
-    <dimen name="qs_header_non_clickable_element_height">24dp</dimen>
-    <dimen name="new_qs_header_non_clickable_element_height">24dp</dimen>
+    <dimen name="qs_header_non_clickable_element_height">24sp</dimen>
+    <dimen name="new_qs_header_non_clickable_element_height">24sp</dimen>
 
     <dimen name="qs_footer_padding">20dp</dimen>
     <dimen name="qs_security_footer_height">88dp</dimen>
@@ -808,6 +811,8 @@
     <dimen name="keyguard_lock_height">42dp</dimen>
     <dimen name="keyguard_lock_padding">20dp</dimen>
 
+    <dimen name="keyguard_security_container_padding_top">20dp</dimen>
+
     <dimen name="keyguard_indication_margin_bottom">32dp</dimen>
     <dimen name="lock_icon_margin_bottom">74dp</dimen>
     <dimen name="ambient_indication_margin_bottom">71dp</dimen>
@@ -820,7 +825,7 @@
 
     <!-- Padding between the mobile signal indicator and the start icon when the roaming icon
          is displayed in the upper left corner. -->
-    <dimen name="roaming_icon_start_padding">2dp</dimen>
+    <dimen name="roaming_icon_start_padding">2sp</dimen>
 
     <!-- Extra padding between the mobile data type icon and the strength indicator when the data
          type icon is wide for the tile in quick settings. -->
@@ -1040,13 +1045,13 @@
     <dimen name="display_cutout_margin_consumption">0px</dimen>
 
     <!-- Height of the Ongoing App Ops chip -->
-    <dimen name="ongoing_appops_chip_height">24dp</dimen>
+    <dimen name="ongoing_appops_chip_height">24sp</dimen>
     <!-- Side padding between background of Ongoing App Ops chip and content -->
     <dimen name="ongoing_appops_chip_side_padding">8dp</dimen>
     <!-- Margin between icons of Ongoing App Ops chip -->
     <dimen name="ongoing_appops_chip_icon_margin">4dp</dimen>
     <!-- Icon size of Ongoing App Ops chip -->
-    <dimen name="ongoing_appops_chip_icon_size">16dp</dimen>
+    <dimen name="ongoing_appops_chip_icon_size">16sp</dimen>
     <!-- Radius of Ongoing App Ops chip corners -->
     <dimen name="ongoing_appops_chip_bg_corner_radius">28dp</dimen>
     <!--  One or two privacy items  -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 4e68efe..c57fef1 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -251,25 +251,22 @@
     <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>
+    <string name="screenrecord_title">Screen Recorder</string>
     <!-- Processing screen recoding video in the background [CHAR LIMIT=30]-->
     <string name="screenrecord_background_processing_label">Processing screen recording</string>
     <!-- Description of the screen recording notification channel [CHAR LIMIT=NONE]-->
     <string name="screenrecord_channel_description">Ongoing notification for a screen record session</string>
+
+    <!-- For updated Screen Recording permission dialog (i.e. with PSS)-->
     <!-- Title for the screen prompting the user to begin recording their screen [CHAR LIMIT=NONE]-->
-    <string name="screenrecord_start_label">Start Recording?</string>
-    <!-- Message reminding the user that sensitive information may be captured during a screen recording [CHAR_LIMIT=NONE]-->
-    <string name="screenrecord_description">While recording, Android System can capture any sensitive information that\u2019s visible on your screen or played on your device. This includes passwords, payment info, photos, messages, and audio.</string>
-    <!-- Dropdown option to record the entire screen [CHAR_LIMIT=30]-->
-    <string name="screenrecord_option_entire_screen">Record entire screen</string>
-    <!-- Dropdown option to record a single app [CHAR_LIMIT=30]-->
-    <string name="screenrecord_option_single_app">Record a single app</string>
+    <string name="screenrecord_permission_dialog_title">Start Recording?</string>
     <!-- Message reminding the user that sensitive information may be captured during a full screen recording for the updated dialog that includes partial screen sharing option [CHAR_LIMIT=350]-->
-    <string name="screenrecord_warning_entire_screen">While you\'re recording, Android has access to anything visible on your screen or played on your device. So be careful with passwords, payment details, messages, or other sensitive information.</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen">While you’re recording, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
     <!-- Message reminding the user that sensitive information may be captured during a single app screen recording for the updated dialog that includes partial screen sharing option [CHAR_LIMIT=350]-->
-    <string name="screenrecord_warning_single_app">While you\'re recording an app, Android has access to anything shown or played on that app. So be careful with passwords, payment details, messages, or other sensitive information.</string>
+    <string name="screenrecord_permission_dialog_warning_single_app">While you’re recording an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
     <!-- Button to start a screen recording in the updated screen record dialog that allows to select an app to record [CHAR LIMIT=50]-->
-    <string name="screenrecord_start_recording">Start recording</string>
+    <string name="screenrecord_permission_dialog_continue">Start recording</string>
+
     <!-- Label for a switch to enable recording audio [CHAR LIMIT=NONE]-->
     <string name="screenrecord_audio_label">Record audio</string>
     <!-- Label for the option to record audio from the device [CHAR LIMIT=NONE]-->
@@ -281,7 +278,7 @@
     <!-- Label for an option to record audio from both device and microphone [CHAR LIMIT=NONE]-->
     <string name="screenrecord_device_audio_and_mic_label">Device audio and microphone</string>
     <!-- Button to start a screen recording [CHAR LIMIT=50]-->
-    <string name="screenrecord_start">Start</string>
+    <string name="screenrecord_continue">Start</string>
     <!-- Notification text displayed when we are recording the screen [CHAR LIMIT=100]-->
     <string name="screenrecord_ongoing_screen_only">Recording screen</string>
     <!-- Notification text displayed when we are recording both the screen and audio [CHAR LIMIT=100]-->
@@ -1064,47 +1061,52 @@
     <!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
     <string name="user_remove_user_remove">Remove</string>
 
-    <!-- Media projection permission dialog warning text. [CHAR LIMIT=NONE] -->
-    <string name="media_projection_dialog_text"><xliff:g id="app_seeking_permission" example="Hangouts">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages, and audio that you play.</string>
-
-    <!-- Media projection permission dialog warning text for system services. [CHAR LIMIT=NONE] -->
-    <string name="media_projection_dialog_service_text">The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages, and audio that you play.</string>
-
-    <!-- Media projection permission dialog warning title for system services. [CHAR LIMIT=NONE] -->
-    <string name="media_projection_dialog_service_title">Start recording or casting?</string>
-
+    <!-- Media projection without Partial Screenshare -->
     <!-- Media projection permission dialog warning title. [CHAR LIMIT=NONE] -->
     <string name="media_projection_dialog_title">Start recording or casting with <xliff:g id="app_seeking_permission" example="Hangouts">%s</xliff:g>?</string>
+    <!-- Media projection permission dialog warning text. [CHAR LIMIT=NONE] -->
+    <string name="media_projection_dialog_warning"><xliff:g id="app_seeking_permission" example="Hangouts">%s</xliff:g> will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages, and audio that you play.</string>
+    <!-- Media projection permission dialog warning title for system services. [CHAR LIMIT=NONE] -->
+    <string name="media_projection_sys_service_dialog_title">Start recording or casting?</string>
+    <!-- Media projection permission dialog warning text for system services. [CHAR LIMIT=NONE] -->
+    <string name="media_projection_sys_service_dialog_warning">The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages, and audio that you play.</string>
 
-    <!-- Media projection permission dialog title. [CHAR LIMIT=NONE] -->
-    <string name="media_projection_permission_dialog_title">Allow <xliff:g id="app_seeking_permission" example="Meet">%s</xliff:g> to share or record?</string>
-
-    <!-- Media projection permission dropdown option for capturing the whole screen. [CHAR LIMIT=30] -->
-    <string name="media_projection_permission_dialog_option_entire_screen">Entire screen</string>
-
-    <!-- Media projection permission dropdown option for capturing single app. [CHAR LIMIT=30] -->
-    <string name="media_projection_permission_dialog_option_single_app">A single app</string>
-
-    <!-- Media projection permission warning for capturing the whole screen. [CHAR LIMIT=350] -->
-    <string name="media_projection_permission_dialog_warning_entire_screen">When you\'re sharing, recording, or casting, <xliff:g id="app_seeking_permission" example="Meet">%s</xliff:g> has access to anything visible on your screen or played on your device. So be careful with passwords, payment details, messages, or other sensitive information.</string>
-
-    <!-- Media projection permission warning for capturing an app. [CHAR LIMIT=350] -->
-    <string name="media_projection_permission_dialog_warning_single_app">When you\'re sharing, recording, or casting an app, <xliff:g id="app_seeking_permission" example="Meet">%s</xliff:g> has access to anything shown or played on that app. So be careful with passwords, payment details, messages, or other sensitive information.</string>
-
-    <!-- Media projection permission button to continue with app selection or recording [CHAR LIMIT=60] -->
-    <string name="media_projection_permission_dialog_continue">Continue</string>
-
+    <!-- Permission dropdown option for sharing or recording the whole screen. [CHAR LIMIT=30] -->
+    <string name="screen_share_permission_dialog_option_entire_screen">Entire screen</string>
+    <!-- Permission dropdown option for sharing or recording single app. [CHAR LIMIT=30] -->
+    <string name="screen_share_permission_dialog_option_single_app">A single app</string>
     <!-- Title of the dialog that allows to select an app to share or record [CHAR LIMIT=NONE] -->
-    <string name="media_projection_permission_app_selector_title">Share or record an app</string>
+    <string name="screen_share_permission_app_selector_title">Share or record an app</string>
 
-    <!-- Media projection permission dialog title when there is no app name (e.g. it could be a system service when casting). [CHAR LIMIT=100] -->
-    <string name="media_projection_permission_dialog_system_service_title">Allow this app to share or record?</string>
+    <!-- Media projection that launched from 1P/3P apps -->
+    <!-- 1P/3P app media projection permission dialog title. [CHAR LIMIT=NONE] -->
+    <string name="media_projection_entry_app_permission_dialog_title">Start recording or casting with <xliff:g id="app_seeking_permission" example="Meet">%s</xliff:g>?</string>
+    <!-- 1P/3P app media projection permission warning for capturing the whole screen. [CHAR LIMIT=350] -->
+    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen">When you’re sharing, recording, or casting, <xliff:g id="app_seeking_permission" example="Meet">%s</xliff:g> has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
+    <!-- 1P/3P app media projection permission warning for capturing an app. [CHAR LIMIT=350] -->
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app">When you’re sharing, recording, or casting an app, <xliff:g id="app_seeking_permission" example="Meet">%s</xliff:g> has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
+    <!-- 1P/3P apps media projection permission button to continue with app selection or recording [CHAR LIMIT=60] -->
+    <string name="media_projection_entry_app_permission_dialog_continue">Start</string>
 
-    <!-- Media projection permission warning for capturing the whole screen when a system service requests it (e.g. when casting). [CHAR LIMIT=350] -->
-    <string name="media_projection_permission_dialog_system_service_warning_entire_screen">When you\'re sharing, recording, or casting, this app has access to anything visible on your screen or played on your device. So be careful with passwords, payment details, messages, or other sensitive information.</string>
+    <!-- Casting that launched by SysUI (i.e. when there is no app name) -->
+    <!-- System casting media projection permission dialog title. [CHAR LIMIT=100] -->
+    <string name="media_projection_entry_cast_permission_dialog_title">Start casting?</string>
+    <!-- System casting media projection permission warning for capturing the whole screen when SysUI casting requests it. [CHAR LIMIT=350] -->
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen">When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
+    <!-- System casting media projection permission warning for capturing a single app when SysUI casting requests it. [CHAR LIMIT=350] -->
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app">When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
+    <!-- System casting media projection permission button to continue for SysUI casting. [CHAR LIMIT=60] -->
+    <string name="media_projection_entry_cast_permission_dialog_continue">Start casting</string>
 
-    <!-- Media projection permission warning for capturing a single app when a system service requests it (e.g. when casting). [CHAR LIMIT=350] -->
-    <string name="media_projection_permission_dialog_system_service_warning_single_app">When you\'re sharing, recording, or casting an app, this app has access to anything shown or played on that app. So be careful with passwords, payment details, messages, or other sensitive information.</string>
+    <!-- Other sharing (not recording nor casting) that launched by SysUI (currently not in use) -->
+    <!-- System sharing media projection permission dialog title. [CHAR LIMIT=100] -->
+    <string name="media_projection_entry_generic_permission_dialog_title">Start sharing?</string>
+    <!-- System sharing media projection permission warning for capturing the whole screen. [CHAR LIMIT=350] -->
+    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen">When you’re sharing, recording, or casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
+    <!-- System sharing media projection permission warning for capturing a single app. [CHAR LIMIT=350] -->
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app">When you’re sharing, recording, or casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
+    <!-- System sharing media projection permission button to continue. [CHAR LIMIT=60] -->
+    <string name="media_projection_entry_generic_permission_dialog_continue">Start</string>
 
     <!-- Title for the dialog that is shown when screen capturing is disabled by enterprise policy. [CHAR LIMIT=100] -->
     <string name="screen_capturing_disabled_by_policy_dialog_title">Blocked by your IT admin</string>
@@ -1255,7 +1257,10 @@
     <string name="monitoring_description_managed_profile_network_logging">Your admin has turned on network logging, which monitors traffic in your work profile but not in your personal profile.</string>
 
     <!-- Monitoring dialog: Description of an active VPN. [CHAR LIMIT=NONE]-->
-    <string name="monitoring_description_named_vpn">This device is connected to the internet through <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin.</string>
+    <string name="monitoring_description_named_vpn">This device is connected to the internet through <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to the VPN provider.</string>
+
+    <!-- Monitoring dialog: Description of an active VPN on a managed device. [CHAR LIMIT=NONE]-->
+    <string name="monitoring_description_managed_device_named_vpn">This device is connected to the internet through <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin.</string>
 
     <!-- Monitoring dialog: Description of two active VPNs. [CHAR LIMIT=NONE]-->
     <string name="monitoring_description_two_named_vpns">This device is connected to the internet through <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g> and <xliff:g id="vpn_app" example="Bar VPN App">%2$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin.</string>
@@ -3033,6 +3038,19 @@
     -->
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2">&#8226; At least one device is available</string>
 
+    <!---
+    Requirement for the notes app to be available for the user to use. This is shown as part of a
+    bulleted list of requirements. When all requirements are met, the app can be accessed through a
+    shortcut button on the lock screen. [CHAR LIMIT=NONE] -->
+    <string name="keyguard_affordance_enablement_dialog_notes_app_instruction">Select a default notes app to use the notetaking shortcut</string>
+
+    <!---
+    The action to make the lock screen shortcut for the notes app to be available for the user to
+    use. This is shown as the action button in the dialog listing the requirements. When all
+    requirements are met, the app can be accessed through a shortcut button on the lock screen.
+    [CHAR LIMIT=NONE] -->
+    <string name="keyguard_affordance_enablement_dialog_notes_app_action">Select app</string>
+
     <!--
     Error message shown when a shortcut must be pressed and held to activate it, usually shown when
     the user tried to tap the shortcut or held it for too short a time. [CHAR LIMIT=32].
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 209d5e8..43df08d 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
@@ -32,8 +32,10 @@
 import javax.inject.Inject;
 
 /**
- * {@link Monitor} takes in a set of conditions, monitors whether all of them have
- * been fulfilled, and informs any registered listeners.
+ * {@link Monitor} allows {@link Subscription}s to a set of conditions and monitors whether all of
+ * them have been fulfilled.
+ * <p>
+ * This class should be used as a singleton, to prevent duplicate monitoring of the same conditions.
  */
 public class Monitor {
     private final String mTag = getClass().getSimpleName();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java
index 3d05542..4f73fc4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java
@@ -109,7 +109,7 @@
     /** Load all plugins matching this instance's action. */
     public void loadAll() {
         if (DEBUG) Log.d(TAG, "startListening");
-        mBgExecutor.execute(this::queryAll);
+        mBgExecutor.execute(() -> queryAll());
     }
 
     /** Unload all plugins managed by this instance. */
@@ -255,17 +255,18 @@
             intent.setPackage(pkgName);
         }
         List<ResolveInfo> result = mPm.queryIntentServices(intent, 0);
-        if (DEBUG) Log.d(TAG, "Found " + result.size() + " plugins");
+        if (DEBUG) {
+            Log.d(TAG, "Found " + result.size() + " plugins");
+            for (ResolveInfo info : result) {
+                ComponentName name = new ComponentName(info.serviceInfo.packageName,
+                        info.serviceInfo.name);
+                Log.d(TAG, "  " + name);
+            }
+        }
+
         if (result.size() > 1 && !mAllowMultiple) {
             // TODO: Show warning.
             Log.w(TAG, "Multiple plugins found for " + mAction);
-            if (DEBUG) {
-                for (ResolveInfo info : result) {
-                    ComponentName name = new ComponentName(info.serviceInfo.packageName,
-                            info.serviceInfo.name);
-                    Log.w(TAG, "  " + name);
-                }
-            }
             return;
         }
         for (ResolveInfo info : result) {
@@ -307,7 +308,7 @@
             // TODO: Only create the plugin before version check if we need it for
             // legacy version check.
             if (DEBUG) {
-                Log.d(TAG, "createPlugin");
+                Log.d(TAG, "createPlugin: " + component);
             }
             try {
                 return mPluginInstanceFactory.create(
@@ -317,7 +318,7 @@
                 reportInvalidVersion(component, component.getClassName(), e);
             }
         } catch (Throwable e) {
-            Log.w(TAG, "Couldn't load plugin: " + packageName, e);
+            Log.w(TAG, "Couldn't load plugin: " + component, e);
             return null;
         }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
index 016d573..4a66562 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
@@ -230,7 +230,7 @@
 
         private ClassLoader getParentClassLoader(ClassLoader baseClassLoader) {
             return new PluginManagerImpl.ClassLoaderFilter(
-                    baseClassLoader, "com.android.systemui.plugin");
+                    baseClassLoader, "com.android.systemui.log", "com.android.systemui.plugin");
         }
 
         /** Returns class loader specific for the given plugin. */
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
index 2f9f5b2..1e668b8 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
@@ -248,19 +248,23 @@
     // This allows plugins to include any libraries or copied code they want by only including
     // classes from the plugin library.
     static class ClassLoaderFilter extends ClassLoader {
-        private final String mPackage;
+        private final String[] mPackages;
         private final ClassLoader mBase;
 
-        public ClassLoaderFilter(ClassLoader base, String pkg) {
+        ClassLoaderFilter(ClassLoader base, String... pkgs) {
             super(ClassLoader.getSystemClassLoader());
             mBase = base;
-            mPackage = pkg;
+            mPackages = pkgs;
         }
 
         @Override
         protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-            if (!name.startsWith(mPackage)) super.loadClass(name, resolve);
-            return mBase.loadClass(name);
+            for (String pkg : mPackages) {
+                if (name.startsWith(pkg)) {
+                    return mBase.loadClass(name);
+                }
+            }
+            return super.loadClass(name, resolve);
         }
     }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java
index 1b0dacc..8dcd2aa 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java
@@ -206,7 +206,7 @@
                 t.close();
                 info.releaseAllSurfaces();
                 if (finishRunnable == null) return;
-                onAnimationCancelled(false /* isKeyguardOccluded */);
+                onAnimationCancelled();
                 finishRunnable.run();
             }
         };
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index 362d7a9..7cf3121 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -68,7 +68,7 @@
         onActivityLaunchOnSecondaryDisplayRerouted();
     }
 
-    default void onTaskProfileLocked(RunningTaskInfo taskInfo) { }
+    default void onTaskProfileLocked(RunningTaskInfo taskInfo, int userId) { }
     default void onTaskCreated(int taskId, ComponentName componentName) { }
     default void onTaskRemoved(int taskId) { }
     default void onTaskMovedToFront(int taskId) { }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index dd52cfb..c613afb 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -262,8 +262,8 @@
         }
 
         @Override
-        public void onTaskProfileLocked(RunningTaskInfo taskInfo) {
-            mHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, taskInfo).sendToTarget();
+        public void onTaskProfileLocked(RunningTaskInfo taskInfo, int userId) {
+            mHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, userId, 0, taskInfo).sendToTarget();
         }
 
         @Override
@@ -418,8 +418,9 @@
                     }
                     case ON_TASK_PROFILE_LOCKED: {
                         final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
+                        final int userId = msg.arg1;
                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                            mTaskStackListeners.get(i).onTaskProfileLocked(info);
+                            mTaskStackListeners.get(i).onTaskProfileLocked(info, userId);
                         }
                         break;
                     }
diff --git a/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
new file mode 100644
index 0000000..af29b05
--- /dev/null
+++ b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
@@ -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.systemui.log
+
+import android.os.Build
+import android.util.Log
+import android.util.Log.LOG_ID_MAIN
+
+/**
+ * A simplified debug logger built as a wrapper around Android's [Log]. Internal for development.
+ *
+ * The main advantages are:
+ * - Sensible defaults, automatically retrieving the class name from the call-site (i.e., tag);
+ * - The messages are purged from source on release builds (keep in mind they are visible on AOSP);
+ * - Lazily evaluate Strings for zero impact in production builds or when disabled;
+ *
+ * Usage example:
+ * ```kotlin
+ * // Logging a message:
+ * debugLog { "message" }
+ *
+ * // Logging an error:
+ * debugLog(error = exception) { "message" }
+ *
+ * // Logging the current stack trace, for debugging:
+ * debugLog(error = Throwable()) { "message" }
+ * ```
+ */
+object DebugLogger {
+
+    /**
+     * Log a debug message, with sensible defaults.
+     *
+     * For example:
+     * ```kotlin
+     * val one = 1
+     * debugLog { "message#$one" }
+     * ```
+     *
+     * The output will be: `D/NoteTaskController: message#1`
+     *
+     * Beware, the [debugLog] content is **REMOVED FROM SOURCE AND BINARY** in Release builds.
+     *
+     * @param enabled: whether or not the message should be logged. By default, it is
+     *   [Build.IS_DEBUGGABLE].
+     * @param priority: type of this log. By default, it is [Log.DEBUG].
+     * @param tag: identifies the source of a log. By default, it is the receiver's simple name.
+     * @param error: a [Throwable] to log.
+     * @param message: a lazily evaluated message you wish to log.
+     */
+    inline fun Any.debugLog(
+        enabled: Boolean = Build.IS_DEBUGGABLE,
+        priority: Int = Log.DEBUG,
+        tag: String = this::class.simpleName.orEmpty(),
+        error: Throwable? = null,
+        message: () -> String,
+    ) {
+        if (enabled) {
+            if (error == null) {
+                Log.println(priority, tag, message())
+            } else {
+                Log.printlns(LOG_ID_MAIN, priority, tag, message(), error)
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
new file mode 100644
index 0000000..2764a1f
--- /dev/null
+++ b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log
+
+import android.os.Build
+import android.util.Log
+
+/** An empty logger for release builds. */
+object DebugLogger {
+
+    @JvmName("logcatMessage")
+    inline fun Any.debugLog(
+        enabled: Boolean = Build.IS_DEBUGGABLE,
+        priority: Int = Log.DEBUG,
+        tag: String = this::class.simpleName.orEmpty(),
+        error: Throwable? = null,
+        message: () -> String,
+    ) {
+        // no-op.
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
index f59bf8e..62f4f22 100644
--- a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
+++ b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
@@ -28,6 +28,7 @@
 import android.view.View
 import com.android.settingslib.Utils
 import com.android.systemui.animation.Interpolators
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.TITLE
 
 /** Displays security messages for the keyguard bouncer. */
 open class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) :
@@ -56,8 +57,7 @@
     }
 
     override fun onThemeChanged() {
-        val array: TypedArray =
-            mContext.obtainStyledAttributes(intArrayOf(android.R.attr.textColorPrimary))
+        val array: TypedArray = mContext.obtainStyledAttributes(intArrayOf(TITLE))
         val newTextColors: ColorStateList = ColorStateList.valueOf(array.getColor(0, Color.RED))
         array.recycle()
         mDefaultColorState = newTextColors
@@ -65,7 +65,7 @@
     }
 
     override fun reloadColor() {
-        mDefaultColorState = Utils.getColorAttr(context, android.R.attr.textColorPrimary)
+        mDefaultColorState = Utils.getColorAttr(context, TITLE)
         super.reloadColor()
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardBouncerMessages.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardBouncerMessages.kt
new file mode 100644
index 0000000..f4145db
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardBouncerMessages.kt
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.annotation.IntDef
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEFAULT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FACE_LOCKED_OUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FINGERPRINT_LOCKED_OUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FACE_INPUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NONE
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST
+import com.android.systemui.R.string.bouncer_face_not_recognized
+import com.android.systemui.R.string.keyguard_enter_password
+import com.android.systemui.R.string.keyguard_enter_pattern
+import com.android.systemui.R.string.keyguard_enter_pin
+import com.android.systemui.R.string.kg_bio_too_many_attempts_password
+import com.android.systemui.R.string.kg_bio_too_many_attempts_pattern
+import com.android.systemui.R.string.kg_bio_too_many_attempts_pin
+import com.android.systemui.R.string.kg_bio_try_again_or_password
+import com.android.systemui.R.string.kg_bio_try_again_or_pattern
+import com.android.systemui.R.string.kg_bio_try_again_or_pin
+import com.android.systemui.R.string.kg_face_locked_out
+import com.android.systemui.R.string.kg_fp_locked_out
+import com.android.systemui.R.string.kg_fp_not_recognized
+import com.android.systemui.R.string.kg_primary_auth_locked_out_password
+import com.android.systemui.R.string.kg_primary_auth_locked_out_pattern
+import com.android.systemui.R.string.kg_primary_auth_locked_out_pin
+import com.android.systemui.R.string.kg_prompt_after_dpm_lock
+import com.android.systemui.R.string.kg_prompt_after_user_lockdown_password
+import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pattern
+import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pin
+import com.android.systemui.R.string.kg_prompt_auth_timeout
+import com.android.systemui.R.string.kg_prompt_password_auth_timeout
+import com.android.systemui.R.string.kg_prompt_pattern_auth_timeout
+import com.android.systemui.R.string.kg_prompt_pin_auth_timeout
+import com.android.systemui.R.string.kg_prompt_reason_restart_password
+import com.android.systemui.R.string.kg_prompt_reason_restart_pattern
+import com.android.systemui.R.string.kg_prompt_reason_restart_pin
+import com.android.systemui.R.string.kg_prompt_unattended_update
+import com.android.systemui.R.string.kg_too_many_failed_attempts_countdown
+import com.android.systemui.R.string.kg_trust_agent_disabled
+import com.android.systemui.R.string.kg_unlock_with_password_or_fp
+import com.android.systemui.R.string.kg_unlock_with_pattern_or_fp
+import com.android.systemui.R.string.kg_unlock_with_pin_or_fp
+import com.android.systemui.R.string.kg_wrong_input_try_fp_suggestion
+import com.android.systemui.R.string.kg_wrong_password_try_again
+import com.android.systemui.R.string.kg_wrong_pattern_try_again
+import com.android.systemui.R.string.kg_wrong_pin_try_again
+
+typealias BouncerMessage = Pair<Int, Int>
+
+fun emptyBouncerMessage(): BouncerMessage = Pair(0, 0)
+
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+    PROMPT_REASON_TIMEOUT,
+    PROMPT_REASON_DEVICE_ADMIN,
+    PROMPT_REASON_USER_REQUEST,
+    PROMPT_REASON_AFTER_LOCKOUT,
+    PROMPT_REASON_PREPARE_FOR_UPDATE,
+    PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT,
+    PROMPT_REASON_TRUSTAGENT_EXPIRED,
+    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
+    PROMPT_REASON_INCORRECT_FACE_INPUT,
+    PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT,
+    PROMPT_REASON_FACE_LOCKED_OUT,
+    PROMPT_REASON_FINGERPRINT_LOCKED_OUT,
+    PROMPT_REASON_DEFAULT,
+    PROMPT_REASON_NONE,
+    PROMPT_REASON_RESTART,
+    PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT,
+)
+annotation class BouncerPromptReason
+
+/**
+ * Helper method that provides the relevant bouncer message that should be shown for different
+ * scenarios indicated by [reason]. [securityMode] & [fpAllowedInBouncer] parameters are used to
+ * provide a more specific message.
+ */
+@JvmOverloads
+fun getBouncerMessage(
+    @BouncerPromptReason reason: Int,
+    securityMode: SecurityMode,
+    fpAllowedInBouncer: Boolean = false
+): BouncerMessage {
+    return when (reason) {
+        PROMPT_REASON_RESTART -> authRequiredAfterReboot(securityMode)
+        PROMPT_REASON_TIMEOUT -> authRequiredAfterPrimaryAuthTimeout(securityMode)
+        PROMPT_REASON_DEVICE_ADMIN -> authRequiredAfterAdminLockdown(securityMode)
+        PROMPT_REASON_USER_REQUEST -> authRequiredAfterUserLockdown(securityMode)
+        PROMPT_REASON_AFTER_LOCKOUT -> biometricLockout(securityMode)
+        PROMPT_REASON_PREPARE_FOR_UPDATE -> authRequiredForUnattendedUpdate(securityMode)
+        PROMPT_REASON_FINGERPRINT_LOCKED_OUT -> fingerprintUnlockUnavailable(securityMode)
+        PROMPT_REASON_FACE_LOCKED_OUT -> faceUnlockUnavailable(securityMode)
+        PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT ->
+            if (fpAllowedInBouncer) incorrectSecurityInputWithFingerprint(securityMode)
+            else incorrectSecurityInput(securityMode)
+        PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT ->
+            if (fpAllowedInBouncer) nonStrongAuthTimeoutWithFingerprintAllowed(securityMode)
+            else nonStrongAuthTimeout(securityMode)
+        PROMPT_REASON_TRUSTAGENT_EXPIRED ->
+            if (fpAllowedInBouncer) trustAgentDisabledWithFingerprintAllowed(securityMode)
+            else trustAgentDisabled(securityMode)
+        PROMPT_REASON_INCORRECT_FACE_INPUT ->
+            if (fpAllowedInBouncer) incorrectFaceInputWithFingerprintAllowed(securityMode)
+            else incorrectFaceInput(securityMode)
+        PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT -> incorrectFingerprintInput(securityMode)
+        PROMPT_REASON_DEFAULT ->
+            if (fpAllowedInBouncer) defaultMessageWithFingerprint(securityMode)
+            else defaultMessage(securityMode)
+        PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT -> primaryAuthLockedOut(securityMode)
+        else -> emptyBouncerMessage()
+    }
+}
+
+fun defaultMessage(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, 0)
+        SecurityMode.Password -> Pair(keyguard_enter_password, 0)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, 0)
+        else -> Pair(0, 0)
+    }
+}
+
+fun defaultMessageWithFingerprint(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, 0)
+        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, 0)
+        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, 0)
+        else -> Pair(0, 0)
+    }
+}
+
+fun incorrectSecurityInput(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, 0)
+        SecurityMode.Password -> Pair(kg_wrong_password_try_again, 0)
+        SecurityMode.PIN -> Pair(kg_wrong_pin_try_again, 0)
+        else -> Pair(0, 0)
+    }
+}
+
+fun incorrectSecurityInputWithFingerprint(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, kg_wrong_input_try_fp_suggestion)
+        SecurityMode.Password -> Pair(kg_wrong_password_try_again, kg_wrong_input_try_fp_suggestion)
+        SecurityMode.PIN -> Pair(kg_wrong_pin_try_again, kg_wrong_input_try_fp_suggestion)
+        else -> Pair(0, 0)
+    }
+}
+
+fun incorrectFingerprintInput(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_pattern)
+        SecurityMode.Password -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_password)
+        SecurityMode.PIN -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_pin)
+        else -> Pair(0, 0)
+    }
+}
+
+fun incorrectFaceInput(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_pattern)
+        SecurityMode.Password -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_password)
+        SecurityMode.PIN -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_pin)
+        else -> Pair(0, 0)
+    }
+}
+
+fun incorrectFaceInputWithFingerprintAllowed(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, bouncer_face_not_recognized)
+        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, bouncer_face_not_recognized)
+        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, bouncer_face_not_recognized)
+        else -> Pair(0, 0)
+    }
+}
+
+fun biometricLockout(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_bio_too_many_attempts_pattern)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_bio_too_many_attempts_password)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_bio_too_many_attempts_pin)
+        else -> Pair(0, 0)
+    }
+}
+
+fun authRequiredAfterReboot(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_reason_restart_pattern)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_reason_restart_password)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin)
+        else -> Pair(0, 0)
+    }
+}
+
+fun authRequiredAfterAdminLockdown(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_dpm_lock)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_after_dpm_lock)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock)
+        else -> Pair(0, 0)
+    }
+}
+
+fun authRequiredAfterUserLockdown(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_user_lockdown_pattern)
+        SecurityMode.Password ->
+            Pair(keyguard_enter_password, kg_prompt_after_user_lockdown_password)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin)
+        else -> Pair(0, 0)
+    }
+}
+
+fun authRequiredForUnattendedUpdate(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_unattended_update)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_unattended_update)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_unattended_update)
+        else -> Pair(0, 0)
+    }
+}
+
+fun authRequiredAfterPrimaryAuthTimeout(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_pattern_auth_timeout)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_password_auth_timeout)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout)
+        else -> Pair(0, 0)
+    }
+}
+
+fun nonStrongAuthTimeout(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_auth_timeout)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_auth_timeout)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_prompt_auth_timeout)
+        else -> Pair(0, 0)
+    }
+}
+
+fun nonStrongAuthTimeoutWithFingerprintAllowed(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_prompt_auth_timeout)
+        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_prompt_auth_timeout)
+        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_prompt_auth_timeout)
+        else -> Pair(0, 0)
+    }
+}
+
+fun faceUnlockUnavailable(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_face_locked_out)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_face_locked_out)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_face_locked_out)
+        else -> Pair(0, 0)
+    }
+}
+
+fun fingerprintUnlockUnavailable(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_fp_locked_out)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_fp_locked_out)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_fp_locked_out)
+        else -> Pair(0, 0)
+    }
+}
+
+fun trustAgentDisabled(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_trust_agent_disabled)
+        SecurityMode.Password -> Pair(keyguard_enter_password, kg_trust_agent_disabled)
+        SecurityMode.PIN -> Pair(keyguard_enter_pin, kg_trust_agent_disabled)
+        else -> Pair(0, 0)
+    }
+}
+
+fun trustAgentDisabledWithFingerprintAllowed(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_trust_agent_disabled)
+        SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_trust_agent_disabled)
+        SecurityMode.PIN -> Pair(kg_unlock_with_pin_or_fp, kg_trust_agent_disabled)
+        else -> Pair(0, 0)
+    }
+}
+
+fun primaryAuthLockedOut(securityMode: SecurityMode): BouncerMessage {
+    return when (securityMode) {
+        SecurityMode.Pattern ->
+            Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_pattern)
+        SecurityMode.Password ->
+            Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_password)
+        SecurityMode.PIN ->
+            Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_pin)
+        else -> Pair(0, 0)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index ba5a8c9..b88d85c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -54,6 +54,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.graphics.drawable.LayerDrawable;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -333,6 +334,11 @@
         mSpringAnimation = new SpringAnimation(this, DynamicAnimation.TRANSLATION_Y);
         mViewConfiguration = ViewConfiguration.get(context);
         mDoubleTapDetector = new GestureDetector(context, new DoubleTapListener());
+
+        // Add additional top padding.
+        setPadding(getPaddingLeft(), getPaddingTop() + getResources().getDimensionPixelSize(
+                        R.dimen.keyguard_security_container_padding_top), getPaddingRight(),
+                getPaddingBottom());
     }
 
     void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
@@ -780,6 +786,8 @@
 
     void reloadColors() {
         mViewMode.reloadColors();
+        setBackgroundColor(Utils.getColorAttrDefaultColor(getContext(),
+                com.android.internal.R.attr.materialColorSurface));
     }
 
     /** Handles density or font scale changes. */
@@ -1022,11 +1030,15 @@
             mUserSwitcherController.removeUserSwitchCallback(mUserSwitchCallback);
         }
 
-        private Drawable findUserIcon(int userId) {
+        private Drawable findLargeUserIcon(int userId) {
             Bitmap userIcon = UserManager.get(mView.getContext()).getUserIcon(userId);
             if (userIcon != null) {
-                return CircleFramedDrawable.getInstance(mView.getContext(),
-                        userIcon);
+                int iconSize =
+                        mResources.getDimensionPixelSize(R.dimen.bouncer_user_switcher_icon_size);
+                return CircleFramedDrawable.getInstance(
+                    mView.getContext(),
+                    Icon.scaleDownIfNecessary(userIcon, iconSize, iconSize)
+                );
             }
 
             return UserIcons.getDefaultUserIcon(mResources, userId, false);
@@ -1085,7 +1097,7 @@
                 return;
             }
             final String currentUserName = mUserSwitcherController.getCurrentUserName();
-            Drawable userIcon = findUserIcon(currentUser.info.id);
+            Drawable userIcon = findLargeUserIcon(currentUser.info.id);
             ((ImageView) mView.findViewById(R.id.user_icon)).setImageDrawable(userIcon);
             mUserSwitcher.setText(currentUserName);
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
index 22ad725..419303d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
@@ -67,6 +67,42 @@
     int PROMPT_REASON_TRUSTAGENT_EXPIRED = 8;
 
     /**
+     * Prompt that is shown when there is an incorrect primary authentication input.
+     */
+    int PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT = 9;
+
+    /**
+     * Prompt that is shown when there is an incorrect face biometric input.
+     */
+    int PROMPT_REASON_INCORRECT_FACE_INPUT = 10;
+
+    /**
+     * Prompt that is shown when there is an incorrect fingerprint biometric input.
+     */
+    int PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT = 11;
+
+    /**
+     * Prompt that is shown when face authentication is in locked out state.
+     */
+    int PROMPT_REASON_FACE_LOCKED_OUT = 12;
+
+    /**
+     * Prompt that is shown when fingerprint authentication is in locked out state.
+     */
+    int PROMPT_REASON_FINGERPRINT_LOCKED_OUT = 13;
+
+    /**
+     * Default prompt that is shown on the bouncer.
+     */
+    int PROMPT_REASON_DEFAULT = 14;
+
+    /**
+     * Prompt that is shown when primary authentication is in locked out state after too many
+     * attempts
+     */
+    int PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT = 15;
+
+    /**
      * Reset the view and prepare to take input. This should do things like clearing the
      * password or pattern and clear error messages.
      */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
index b4bfca1..3fc39af 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
@@ -20,7 +20,9 @@
 import android.util.AttributeSet
 import android.widget.ImageView
 import androidx.core.graphics.drawable.DrawableCompat
+import com.android.settingslib.Utils
 import com.android.systemui.R
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.EMERGENCY_BUTTON
 
 abstract class KeyguardSimInputView(context: Context, attrs: AttributeSet) :
     KeyguardPinBasedInputView(context, attrs) {
@@ -42,10 +44,7 @@
 
     override fun reloadColors() {
         super.reloadColors()
-        val customAttrs = intArrayOf(android.R.attr.textColorSecondary)
-        val a = context.obtainStyledAttributes(customAttrs)
-        val imageColor = a.getColor(0, 0)
-        a.recycle()
+        val imageColor = Utils.getColorAttrDefaultColor(context, EMERGENCY_BUTTON)
         simImageView?.let {
             val wrappedDrawable = DrawableCompat.wrap(it.drawable)
             DrawableCompat.setTint(wrappedDrawable, imageColor)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index edfcb8d..0826f8a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -363,8 +363,6 @@
             } else {
                 View clockView = clockContainerView.getChildAt(0);
 
-                transition.excludeTarget(clockView, /* exclude= */ true);
-
                 TransitionSet set = new TransitionSet();
                 set.addTransition(transition);
 
@@ -389,8 +387,9 @@
 
     @VisibleForTesting
     static class SplitShadeTransitionAdapter extends Transition {
-        private static final String PROP_BOUNDS = "splitShadeTransitionAdapter:bounds";
-        private static final String[] TRANSITION_PROPERTIES = { PROP_BOUNDS };
+        private static final String PROP_BOUNDS_LEFT = "splitShadeTransitionAdapter:boundsLeft";
+        private static final String PROP_X_IN_WINDOW = "splitShadeTransitionAdapter:xInWindow";
+        private static final String[] TRANSITION_PROPERTIES = { PROP_BOUNDS_LEFT, PROP_X_IN_WINDOW};
 
         private final KeyguardClockSwitchController mController;
 
@@ -400,12 +399,10 @@
         }
 
         private void captureValues(TransitionValues transitionValues) {
-            Rect boundsRect = new Rect();
-            boundsRect.left = transitionValues.view.getLeft();
-            boundsRect.top = transitionValues.view.getTop();
-            boundsRect.right = transitionValues.view.getRight();
-            boundsRect.bottom = transitionValues.view.getBottom();
-            transitionValues.values.put(PROP_BOUNDS, boundsRect);
+            transitionValues.values.put(PROP_BOUNDS_LEFT, transitionValues.view.getLeft());
+            int[] locationInWindowTmp = new int[2];
+            transitionValues.view.getLocationInWindow(locationInWindowTmp);
+            transitionValues.values.put(PROP_X_IN_WINDOW, locationInWindowTmp[0]);
         }
 
         @Override
@@ -427,8 +424,12 @@
             }
             ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
 
-            Rect from = (Rect) startValues.values.get(PROP_BOUNDS);
-            Rect to = (Rect) endValues.values.get(PROP_BOUNDS);
+            int fromLeft = (int) startValues.values.get(PROP_BOUNDS_LEFT);
+            int fromWindowX = (int) startValues.values.get(PROP_X_IN_WINDOW);
+            int toWindowX = (int) endValues.values.get(PROP_X_IN_WINDOW);
+            // Using windowX, to determine direction, instead of left, as in RTL the difference of
+            // toLeft - fromLeft is always positive, even when moving left.
+            int direction = toWindowX - fromWindowX > 0 ? 1 : -1;
 
             anim.addUpdateListener(animation -> {
                 ClockController clock = mController.getClock();
@@ -437,7 +438,7 @@
                 }
 
                 clock.getLargeClock().getAnimations()
-                        .onPositionUpdated(from, to, animation.getAnimatedFraction());
+                        .onPositionUpdated(fromLeft, direction, animation.getAnimatedFraction());
             });
 
             return anim;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 9573913..7d7b276 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -522,6 +522,14 @@
                     FACE_AUTH_TRIGGERED_TRUST_DISABLED);
         }
 
+        mLogger.logTrustChanged(wasTrusted, enabled, userId);
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onTrustChanged(userId);
+            }
+        }
+
         if (enabled) {
             String message = null;
             if (KeyguardUpdateMonitor.getCurrentUser() == userId
@@ -560,14 +568,6 @@
                 }
             }
         }
-
-        mLogger.logTrustChanged(wasTrusted, enabled, userId);
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onTrustChanged(userId);
-            }
-        }
     }
 
     /**
@@ -4379,9 +4379,11 @@
      */
     public void startBiometricWatchdog() {
         if (mFaceManager != null && !isFaceAuthInteractorEnabled()) {
+            mLogger.scheduleWatchdog("face");
             mFaceManager.scheduleWatchdog();
         }
         if (mFpm != null) {
+            mLogger.scheduleWatchdog("fingerprint");
             mFpm.scheduleWatchdog();
         }
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 5f2afe8..7cedecc 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -56,6 +56,7 @@
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.AuthRippleController;
 import com.android.systemui.biometrics.UdfpsController;
+import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
@@ -66,7 +67,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.ViewController;
@@ -84,7 +84,7 @@
  * For devices with UDFPS, the lock icon will show at the sensor location. Else, the lock
  * icon will show a set distance from the bottom of the device.
  */
-@CentralSurfacesComponent.CentralSurfacesScope
+@SysUISingleton
 public class LockIconViewController extends ViewController<LockIconView> implements Dumpable {
     private static final String TAG = "LockIconViewController";
     private static final float sDefaultDensity =
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index ad66909..c6c7113 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -15,12 +15,19 @@
  */
 package com.android.keyguard;
 
+import static com.android.settingslib.Utils.getColorAttrDefaultColor;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BACKGROUND;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BACKGROUND_PRESSED;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BUTTON;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_PRESSED;
 import static com.android.systemui.util.ColorUtilKt.getPrivateAttrColorIfUnset;
 
 import android.animation.AnimatorSet;
 import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -112,20 +119,18 @@
 
         int[] customAttrs = {android.R.attr.colorControlNormal};
         ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle);
-        TypedArray a = ctw.obtainStyledAttributes(customAttrs);
+        @SuppressLint("ResourceType") TypedArray a = ctw.obtainStyledAttributes(customAttrs);
         mNormalBackgroundColor = getPrivateAttrColorIfUnset(ctw, a, 0, 0,
-                com.android.internal.R.attr.colorSurface);
+                       NUM_PAD_BACKGROUND);
         a.recycle();
-        mBackground.setColor(mNormalBackgroundColor);
 
-        mPressedBackgroundColor = context.getColor(android.R.color.system_accent1_200);
+        mPressedBackgroundColor = getColorAttrDefaultColor(context, NUM_PAD_BACKGROUND_PRESSED);
+        mTextColorPressed = getColorAttrDefaultColor(context, NUM_PAD_PRESSED);
+
+        mBackground.setColor(mNormalBackgroundColor);
         mTextColorPrimary = isNumPadKey
-                ? com.android.settingslib.Utils
-                .getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
-                : com.android.settingslib.Utils
-                        .getColorAttrDefaultColor(context, android.R.attr.textColorPrimaryInverse);
-        mTextColorPressed = com.android.settingslib.Utils
-                .getColorAttrDefaultColor(context, com.android.internal.R.attr.textColorOnAccent);
+                ? getColorAttrDefaultColor(context, NUM_PAD_KEY)
+                : getColorAttrDefaultColor(context, NUM_PAD_BUTTON);
         createAnimators();
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index 11c329e..6ae80a6 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -15,10 +15,12 @@
  */
 package com.android.keyguard;
 
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BUTTON;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
+
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
-import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.VectorDrawable;
@@ -27,6 +29,7 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.settingslib.Utils;
 import com.android.systemui.R;
 
 /**
@@ -95,12 +98,8 @@
     public void reloadColors() {
         if (mAnimator != null) mAnimator.reloadColors(getContext());
 
-        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();
+        int textColorResId = mIsTransparentMode ? NUM_PAD_KEY : NUM_PAD_BUTTON;
+        int imageColor = Utils.getColorAttrDefaultColor(getContext(), textColorResId);
         ((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(imageColor));
     }
 
@@ -119,7 +118,7 @@
     public void setTransparentMode(boolean isTransparentMode) {
         mIsTransparentMode = isTransparentMode;
         if (isTransparentMode) {
-            setBackgroundColor(android.R.color.transparent);
+            setBackgroundColor(getResources().getColor(android.R.color.transparent));
         } else {
             setBackground(getContext().getDrawable(R.drawable.num_pad_key_background));
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 7c7680a..e22fc30 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -15,6 +15,8 @@
  */
 package com.android.keyguard;
 
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
+
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
@@ -150,7 +152,7 @@
      * Reload colors from resources.
      **/
     public void reloadColors() {
-        int textColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
+        int textColor = Utils.getColorAttr(getContext(), NUM_PAD_KEY)
                 .getDefaultColor();
         int klondikeColor = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary)
                 .getDefaultColor();
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
index fc5c254..32f06dc 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
@@ -16,6 +16,8 @@
 
 package com.android.keyguard;
 
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.PIN_SHAPES;
+
 import android.content.Context;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
@@ -37,7 +39,7 @@
 
     private int mPinLength;
     private int mDotDiameter;
-    private int mColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
+    private int mColor = Utils.getColorAttr(getContext(), PIN_SHAPES)
             .getDefaultColor();
     private int mPosition = 0;
     private static final int DEFAULT_PIN_LENGTH = 6;
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
index 14810d9..4aeab97 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
@@ -16,6 +16,8 @@
 
 package com.android.keyguard;
 
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.PIN_SHAPES;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
@@ -45,8 +47,7 @@
  */
 public class PinShapeNonHintingView extends LinearLayout implements PinShapeInput {
 
-    private int mColor = Utils.getColorAttr(getContext(),
-            android.R.attr.textColorPrimary).getDefaultColor();
+    private int mColor = Utils.getColorAttr(getContext(), PIN_SHAPES).getDefaultColor();
     private int mPosition = 0;
     private final PinShapeAdapter mPinShapeAdapter;
     private ValueAnimator mValueAnimator = ValueAnimator.ofFloat(1f, 0f);
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index 1661806..4974f79 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -67,8 +67,10 @@
             "ActiveUnlock",
             DEBUG,
             { int1 = wakeReason },
-            { "Skip requesting active unlock from wake reason that doesn't trigger face auth" +
-                    " reason=${PowerManager.wakeReasonToString(int1)}" }
+            {
+                "Skip requesting active unlock from wake reason that doesn't trigger face auth" +
+                    " reason=${PowerManager.wakeReasonToString(int1)}"
+            }
         )
     }
 
@@ -207,17 +209,27 @@
     }
 
     fun logFaceDetected(userId: Int, isStrongBiometric: Boolean) {
-        logBuffer.log(TAG, DEBUG, {
-            int1 = userId
-            bool1 = isStrongBiometric
-        }, {"Face detected: userId: $int1, isStrongBiometric: $bool1"})
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            {
+                int1 = userId
+                bool1 = isStrongBiometric
+            },
+            { "Face detected: userId: $int1, isStrongBiometric: $bool1" }
+        )
     }
 
     fun logFingerprintDetected(userId: Int, isStrongBiometric: Boolean) {
-        logBuffer.log(TAG, DEBUG, {
-            int1 = userId
-            bool1 = isStrongBiometric
-        }, {"Fingerprint detected: userId: $int1, isStrongBiometric: $bool1"})
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            {
+                int1 = userId
+                bool1 = isStrongBiometric
+            },
+            { "Fingerprint detected: userId: $int1, isStrongBiometric: $bool1" }
+        )
     }
 
     fun logFingerprintError(msgId: Int, originalErrMsg: String) {
@@ -669,13 +681,10 @@
     }
 
     fun logHandleBatteryUpdate(isInteresting: Boolean) {
-        logBuffer.log(
-            TAG,
-            DEBUG,
-            {
-                bool1 = isInteresting
-            },
-            { "handleBatteryUpdate: $bool1" }
-        )
+        logBuffer.log(TAG, DEBUG, { bool1 = isInteresting }, { "handleBatteryUpdate: $bool1" })
+    }
+
+    fun scheduleWatchdog(@CompileTimeConstant watchdogType: String) {
+        logBuffer.log(TAG, DEBUG, "Scheduling biometric watchdog for $watchdogType")
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
index 401f6c9..bf84f8a 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
@@ -35,6 +35,8 @@
 /**
  * Single common instance of ActivityStarter that can be gotten and referenced from anywhere, but
  * delegates to an actual implementation (CentralSurfaces).
+ *
+ * @deprecated Migrating to ActivityStarterImpl
  */
 @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
 @SysUISingleton
@@ -92,6 +94,14 @@
     }
 
     @Override
+    public void startActivity(Intent intent,
+            boolean dismissShade,
+            @Nullable ActivityLaunchAnimator.Controller animationController) {
+        mActualStarterOptionalLazy.get().ifPresent(
+                starter -> starter.startActivity(intent, dismissShade, animationController));
+    }
+
+    @Override
     public void startActivity(Intent intent, boolean dismissShade,
             @Nullable ActivityLaunchAnimator.Controller animationController,
             boolean showOverLockscreenWhenLocked) {
@@ -177,4 +187,35 @@
                 starter -> starter.dismissKeyguardThenExecute(action, cancel, afterKeyguardGone,
                         customMessage));
     }
+
+    @Override
+    public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
+            boolean dismissShade, boolean disallowEnterPictureInPictureWhileLaunching,
+            Callback callback, int flags,
+            @Nullable ActivityLaunchAnimator.Controller animationController,
+            UserHandle userHandle) {
+        mActualStarterOptionalLazy.get().ifPresent(
+                starter -> starter.startActivityDismissingKeyguard(intent, onlyProvisioned,
+                        dismissShade, disallowEnterPictureInPictureWhileLaunching, callback,
+                        flags, animationController, userHandle));
+    }
+
+    @Override
+    public void executeRunnableDismissingKeyguard(Runnable runnable,
+            Runnable cancelAction, boolean dismissShade,
+            boolean afterKeyguardGone, boolean deferred) {
+        mActualStarterOptionalLazy.get().ifPresent(
+                starter -> starter.executeRunnableDismissingKeyguard(runnable, cancelAction,
+                        dismissShade, afterKeyguardGone, deferred));
+    }
+
+    @Override
+    public void executeRunnableDismissingKeyguard(Runnable runnable, Runnable cancelAction,
+            boolean dismissShade, boolean afterKeyguardGone, boolean deferred,
+            boolean willAnimateOnKeyguard, @Nullable String customMessage) {
+        mActualStarterOptionalLazy.get().ifPresent(
+                starter -> starter.executeRunnableDismissingKeyguard(runnable, cancelAction,
+                        dismissShade, afterKeyguardGone, deferred, willAnimateOnKeyguard,
+                        customMessage));
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
index 12dd8f0..4c16d41c 100644
--- a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java
@@ -16,6 +16,7 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
@@ -23,21 +24,29 @@
 import android.view.View;
 import android.widget.FrameLayout;
 
-import com.android.systemui.statusbar.policy.ConfigurationController;
-
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Custom {@link FrameLayout} that re-inflates when changes to {@link Configuration} happen.
  * Currently supports changes to density, asset path, and locale.
  */
-public class AutoReinflateContainer extends FrameLayout implements
-        ConfigurationController.ConfigurationListener {
+public class AutoReinflateContainer extends FrameLayout {
+
+    private static final Set<Integer> SUPPORTED_CHANGES = Set.of(
+            ActivityInfo.CONFIG_LOCALE,
+            ActivityInfo.CONFIG_UI_MODE,
+            ActivityInfo.CONFIG_ASSETS_PATHS,
+            ActivityInfo.CONFIG_DENSITY,
+            ActivityInfo.CONFIG_FONT_SCALE
+    );
 
     private final List<InflateListener> mInflateListeners = new ArrayList<>();
     private final int mLayout;
 
+    private final Configuration mLastConfig = new Configuration();
+
     public AutoReinflateContainer(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
 
@@ -51,15 +60,14 @@
     }
 
     @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        Dependency.get(ConfigurationController.class).addCallback(this);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        Dependency.get(ConfigurationController.class).removeCallback(this);
+    protected void onConfigurationChanged(Configuration newConfig) {
+        int diff = mLastConfig.updateFrom(newConfig);
+        for (int change: SUPPORTED_CHANGES) {
+            if ((diff & change) != 0) {
+                inflateLayout();
+                return;
+            }
+        }
     }
 
     protected void inflateLayoutImpl() {
@@ -80,26 +88,6 @@
         listener.onInflated(getChildAt(0));
     }
 
-    @Override
-    public void onDensityOrFontScaleChanged() {
-        inflateLayout();
-    }
-
-    @Override
-    public void onThemeChanged() {
-        inflateLayout();
-    }
-
-    @Override
-    public void onUiModeChanged() {
-        inflateLayout();
-    }
-
-    @Override
-    public void onLocaleListChanged() {
-        inflateLayout();
-    }
-
     public interface InflateListener {
         /**
          * Called whenever a new view is inflated.
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index ef16a3a..aade71a 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -106,7 +106,6 @@
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DataSaverController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.ExtensionController;
@@ -134,14 +133,14 @@
 import com.android.systemui.util.leak.LeakReporter;
 import com.android.systemui.util.sensors.AsyncSensorManager;
 
+import dagger.Lazy;
+
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 import javax.inject.Inject;
 import javax.inject.Named;
 
-import dagger.Lazy;
-
 /**
  * Class to handle ugly dependencies throughout sysui until we determine the
  * long-term dependency injection solution.
@@ -270,7 +269,6 @@
     @Inject Lazy<NotificationShadeWindowController> mNotificationShadeWindowController;
     @Inject Lazy<StatusBarWindowController> mTempStatusBarWindowController;
     @Inject Lazy<DarkIconDispatcher> mDarkIconDispatcher;
-    @Inject Lazy<ConfigurationController> mConfigurationController;
     @Inject Lazy<StatusBarIconController> mStatusBarIconController;
     @Inject Lazy<ScreenLifecycle> mScreenLifecycle;
     @Inject Lazy<WakefulnessLifecycle> mWakefulnessLifecycle;
@@ -441,8 +439,6 @@
 
         mProviders.put(DarkIconDispatcher.class, mDarkIconDispatcher::get);
 
-        mProviders.put(ConfigurationController.class, mConfigurationController::get);
-
         mProviders.put(StatusBarIconController.class, mStatusBarIconController::get);
 
         mProviders.put(ScreenLifecycle.class, mScreenLifecycle::get);
diff --git a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
index a3e7d71..48805be 100644
--- a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
@@ -110,6 +110,10 @@
         if (showScanningAnimNow == showScanningAnim) {
             return
         }
+        logger.cameraProtectionShownOrHidden(keyguardUpdateMonitor.isFaceDetectionRunning,
+                authController.isShowing,
+                show,
+                showScanningAnim)
         showScanningAnim = showScanningAnimNow
         updateProtectionBoundingPath()
         // Delay the relayout until the end of the animation when hiding,
@@ -352,6 +356,7 @@
             if (biometricSourceType == BiometricSourceType.FACE) {
                 post {
                     faceAuthSucceeded = true
+                    logger.biometricEvent("biometricAuthenticated")
                     enableShowProtection(true)
                 }
             }
@@ -372,6 +377,7 @@
             if (biometricSourceType == BiometricSourceType.FACE) {
                 post {
                     faceAuthSucceeded = false
+                    logger.biometricEvent("biometricFailed")
                     enableShowProtection(false)
                 }
             }
@@ -385,6 +391,7 @@
             if (biometricSourceType == BiometricSourceType.FACE) {
                 post {
                     faceAuthSucceeded = false
+                    logger.biometricEvent("biometricError")
                     enableShowProtection(false)
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index adc0412..ea0f343 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -90,6 +90,8 @@
 import com.android.systemui.util.concurrency.ThreadFactory;
 import com.android.systemui.util.settings.SecureSettings;
 
+import kotlin.Pair;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
@@ -98,8 +100,6 @@
 
 import javax.inject.Inject;
 
-import kotlin.Pair;
-
 /**
  * An overlay that draws screen decorations in software (e.g for rounded corners or display cutout)
  * for antialiasing and emulation purposes.
@@ -254,11 +254,13 @@
             new CameraAvailabilityListener.CameraTransitionCallback() {
         @Override
         public void onApplyCameraProtection(@NonNull Path protectionPath, @NonNull Rect bounds) {
+            mLogger.cameraProtectionEvent("onApplyCameraProtection");
             showCameraProtection(protectionPath, bounds);
         }
 
         @Override
         public void onHideCameraProtection() {
+            mLogger.cameraProtectionEvent("onHideCameraProtection");
             hideCameraProtection();
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 2503520..aa94ad9 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -374,11 +374,10 @@
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
                 final boolean captured = (mIsSwiping || mLongPressSent || mMenuRowIntercepting);
-                mIsSwiping = false;
-                mTouchedView = null;
                 mLongPressSent = false;
                 mCallback.onLongPressSent(null);
                 mMenuRowIntercepting = false;
+                resetSwipeState();
                 cancelLongPress();
                 if (captured) return true;
                 break;
@@ -491,7 +490,7 @@
                 }
                 if (!mCancelled || wasRemoved) {
                     mCallback.onChildDismissed(animView);
-                    resetSwipeState();
+                    resetSwipeOfView(animView);
                 }
                 if (endAction != null) {
                     endAction.accept(mCancelled);
@@ -546,7 +545,7 @@
 
             if (!cancelled) {
                 updateSwipeProgressFromOffset(animView, canBeDismissed);
-                resetSwipeState();
+                resetSwipeOfView(animView);
             }
             onChildSnappedBack(animView, targetLeft);
         });
@@ -806,9 +805,20 @@
         return mIsSwiping ? mTouchedView : null;
     }
 
+    protected void resetSwipeOfView(View view) {
+        if (getSwipedView() == view) {
+            resetSwipeState();
+        }
+    }
+
     public void resetSwipeState() {
+        View swipedView = getSwipedView();
         mTouchedView = null;
         mIsSwiping = false;
+        if (swipedView != null) {
+            snapChildIfNeeded(swipedView, false, 0);
+            onChildSnappedBack(swipedView, 0);
+        }
     }
 
     private float getTouchSlop(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
new file mode 100644
index 0000000..1f66c91
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 44215
+
+include /core/java/android/view/accessibility/OWNERS
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index f3c71da..4158390 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -45,6 +45,8 @@
 
 import com.android.internal.R;
 import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
+import com.android.internal.accessibility.util.AccessibilityUtils;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ScreenshotHelper;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.dagger.SysUISingleton;
@@ -520,8 +522,11 @@
                 SCREENSHOT_ACCESSIBILITY_ACTIONS, new Handler(Looper.getMainLooper()), null);
     }
 
-    private void handleHeadsetHook() {
-        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK);
+    @VisibleForTesting
+    void handleHeadsetHook() {
+        if (!AccessibilityUtils.interceptHeadsetHookForActiveCall(mContext)) {
+            sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK);
+        }
     }
 
     private void handleAccessibilityButton() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index 7bfd84e..155c26d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -463,13 +463,17 @@
         if ((configDiff & ActivityInfo.CONFIG_UI_MODE) != 0
                 || (configDiff & ActivityInfo.CONFIG_ASSETS_PATHS) != 0
                 || (configDiff & ActivityInfo.CONFIG_FONT_SCALE) != 0
+                || (configDiff & ActivityInfo.CONFIG_LOCALE) != 0
                 || (configDiff & ActivityInfo.CONFIG_DENSITY) != 0) {
             // We listen to following config changes to trigger layout inflation:
             // CONFIG_UI_MODE: theme change
             // CONFIG_ASSETS_PATHS: wallpaper change
             // CONFIG_FONT_SCALE: font size change
+            // CONFIG_LOCALE: language change
             // CONFIG_DENSITY: display size change
 
+            mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
+
             boolean showSettingPanelAfterThemeChange = mIsVisible;
             hideSettingPanel(/* resetPosition= */ false);
             inflateView();
@@ -490,11 +494,6 @@
                     + mDraggableWindowBounds.top;
             return;
         }
-
-        if ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0) {
-            updateAccessibilityWindowTitle();
-            return;
-        }
     }
 
     private void onWindowInsetChanged() {
@@ -515,13 +514,6 @@
         }
     }
 
-    private void updateAccessibilityWindowTitle() {
-        mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
-        if (mIsVisible) {
-            mWindowManager.updateViewLayout(mSettingView, mParams);
-        }
-    }
-
     public void editMagnifierSizeMode(boolean enable) {
         setEditMagnifierSizeMode(enable);
         updateSelectedButton(MagnificationSize.NONE);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index 4b5c50f..5499d2c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -19,7 +19,6 @@
 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
 import android.view.Surface
@@ -35,21 +34,18 @@
 import com.android.systemui.biometrics.AuthBiometricView.STATE_HELP
 import com.android.systemui.biometrics.AuthBiometricView.STATE_IDLE
 import com.android.systemui.biometrics.AuthBiometricView.STATE_PENDING_CONFIRMATION
-import com.android.systemui.unfold.compat.ScreenSizeFoldProvider
-import com.android.systemui.unfold.updates.FoldProvider
 
 /** Fingerprint only icon animator for BiometricPrompt.  */
 open class AuthBiometricFingerprintIconController(
         context: Context,
         iconView: LottieAnimationView,
         protected val iconViewOverlay: LottieAnimationView
-) : AuthIconController(context, iconView), FoldProvider.FoldCallback {
+) : AuthIconController(context, iconView) {
 
-    private var isDeviceFolded: Boolean = false
     private val isSideFps: Boolean
     private val isReverseDefaultRotation =
             context.resources.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)
-    private val screenSizeFoldProvider: ScreenSizeFoldProvider = ScreenSizeFoldProvider(context)
+
     var iconLayoutParamSize: Pair<Int, Int> = Pair(1, 1)
         set(value) {
             if (field == value) {
@@ -77,20 +73,16 @@
         if (isSideFps && getRotationFromDefault(displayInfo.rotation) == Surface.ROTATION_180) {
             iconView.rotation = 180f
         }
-        screenSizeFoldProvider.registerCallback(this, context.mainExecutor)
-        screenSizeFoldProvider.onConfigurationChange(context.resources.configuration)
     }
 
     private fun updateIconSideFps(@BiometricState lastState: Int, @BiometricState newState: Int) {
         val displayInfo = DisplayInfo()
         context.display?.getDisplayInfo(displayInfo)
         val rotation = getRotationFromDefault(displayInfo.rotation)
-        val iconAnimation = getSideFpsAnimationForTransition(rotation)
         val iconViewOverlayAnimation =
                 getSideFpsOverlayAnimationForTransition(lastState, newState, rotation) ?: return
 
         if (!(lastState == STATE_AUTHENTICATING_ANIMATING_IN && newState == STATE_AUTHENTICATING)) {
-            iconView.setAnimation(iconAnimation)
             iconViewOverlay.setAnimation(iconViewOverlayAnimation)
         }
 
@@ -132,10 +124,6 @@
         LottieColorUtils.applyDynamicColors(context, iconView)
     }
 
-    override fun onConfigurationChanged(newConfig: Configuration) {
-        screenSizeFoldProvider.onConfigurationChange(newConfig)
-    }
-
     override fun updateIcon(@BiometricState lastState: Int, @BiometricState newState: Int) {
         if (isSideFps) {
             updateIconSideFps(lastState, newState)
@@ -230,25 +218,6 @@
             if (isReverseDefaultRotation) (rotation + 1) % 4 else rotation
 
     @RawRes
-    private fun getSideFpsAnimationForTransition(rotation: Int): Int = when (rotation) {
-        Surface.ROTATION_90 -> if (isDeviceFolded) {
-            R.raw.biometricprompt_folded_base_topleft
-        } else {
-            R.raw.biometricprompt_portrait_base_topleft
-        }
-        Surface.ROTATION_270 -> if (isDeviceFolded) {
-            R.raw.biometricprompt_folded_base_bottomright
-        } else {
-            R.raw.biometricprompt_portrait_base_bottomright
-        }
-        else -> if (isDeviceFolded) {
-            R.raw.biometricprompt_folded_base_default
-        } else {
-            R.raw.biometricprompt_landscape_base
-        }
-    }
-
-    @RawRes
     private fun getSideFpsOverlayAnimationForTransition(
             @BiometricState oldState: Int,
             @BiometricState newState: Int,
@@ -357,8 +326,4 @@
             )
         }
     }
-
-    override fun onFoldUpdated(isFolded: Boolean) {
-        isDeviceFolded = isFolded
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index e04dd06..f330c34 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -124,6 +124,7 @@
     protected final int mTextColorHint;
 
     private AuthPanelController mPanelController;
+
     private PromptInfo mPromptInfo;
     private boolean mRequireConfirmation;
     private int mUserId;
@@ -266,11 +267,9 @@
     /** Create the controller for managing the icons transitions during the prompt.*/
     @NonNull
     protected abstract AuthIconController createIconController();
-
     void setPanelController(AuthPanelController panelController) {
         mPanelController = panelController;
     }
-
     void setPromptInfo(PromptInfo promptInfo) {
         mPromptInfo = promptInfo;
     }
@@ -463,9 +462,16 @@
         return false;
     }
 
+    /**
+     * Updates mIconView animation on updates to fold state, device rotation, or rear display mode
+     * @param animation new asset to use for iconw
+     */
+    public void updateIconViewAnimation(int animation) {
+        mIconView.setAnimation(animation);
+    }
+
     public void updateState(@BiometricState int newState) {
         Log.v(TAG, "newState: " + newState);
-
         mIconController.updateState(mState, newState);
 
         switch (newState) {
@@ -625,7 +631,6 @@
     public void restoreState(@Nullable Bundle savedState) {
         mSavedState = savedState;
     }
-
     private void setTextOrHide(TextView view, CharSequence charSequence) {
         if (TextUtils.isEmpty(charSequence)) {
             view.setVisibility(View.GONE);
@@ -658,7 +663,6 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        mIconController.onConfigurationChanged(newConfig);
         if (mSavedState != null) {
             updateState(mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_STATE));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index aeebb01..b386bc9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -67,6 +67,8 @@
 import com.android.systemui.biometrics.AuthController.ScaleFactorProvider;
 import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor;
 import com.android.systemui.biometrics.ui.CredentialView;
+import com.android.systemui.biometrics.ui.binder.AuthBiometricFingerprintViewBinder;
+import com.android.systemui.biometrics.ui.viewmodel.AuthBiometricFingerprintViewModel;
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -126,6 +128,8 @@
 
     // TODO: these should be migrated out once ready
     private final Provider<BiometricPromptCredentialInteractor> mBiometricPromptInteractor;
+    private final Provider<AuthBiometricFingerprintViewModel>
+            mAuthBiometricFingerprintViewModelProvider;
     private final Provider<CredentialViewModel> mCredentialViewModelProvider;
 
     @VisibleForTesting final BiometricCallback mBiometricCallback;
@@ -241,12 +245,14 @@
                 @NonNull LockPatternUtils lockPatternUtils,
                 @NonNull InteractionJankMonitor jankMonitor,
                 @NonNull Provider<BiometricPromptCredentialInteractor> biometricPromptInteractor,
+                @NonNull Provider<AuthBiometricFingerprintViewModel>
+                        authBiometricFingerprintViewModelProvider,
                 @NonNull Provider<CredentialViewModel> credentialViewModelProvider) {
             mConfig.mSensorIds = sensorIds;
             return new AuthContainerView(mConfig, fpProps, faceProps, wakefulnessLifecycle,
                     panelInteractionDetector, userManager, lockPatternUtils, jankMonitor,
-                    biometricPromptInteractor, credentialViewModelProvider,
-                    new Handler(Looper.getMainLooper()), bgExecutor);
+                    biometricPromptInteractor, authBiometricFingerprintViewModelProvider,
+                    credentialViewModelProvider, new Handler(Looper.getMainLooper()), bgExecutor);
         }
     }
 
@@ -339,6 +345,8 @@
             @NonNull LockPatternUtils lockPatternUtils,
             @NonNull InteractionJankMonitor jankMonitor,
             @NonNull Provider<BiometricPromptCredentialInteractor> biometricPromptInteractor,
+            @NonNull Provider<AuthBiometricFingerprintViewModel>
+                    authBiometricFingerprintViewModelProvider,
             @NonNull Provider<CredentialViewModel> credentialViewModelProvider,
             @NonNull Handler mainHandler,
             @NonNull @Background DelayableExecutor bgExecutor) {
@@ -368,6 +376,7 @@
         mBackgroundExecutor = bgExecutor;
         mInteractionJankMonitor = jankMonitor;
         mBiometricPromptInteractor = biometricPromptInteractor;
+        mAuthBiometricFingerprintViewModelProvider = authBiometricFingerprintViewModelProvider;
         mCredentialViewModelProvider = credentialViewModelProvider;
 
         // Inflate biometric view only if necessary.
@@ -386,6 +395,9 @@
                 fingerprintAndFaceView.updateOverrideIconLayoutParamsSize();
                 fingerprintAndFaceView.setFaceClass3(
                         faceProperties.sensorStrength == STRENGTH_STRONG);
+                final AuthBiometricFingerprintViewModel fpAndFaceViewModel =
+                        mAuthBiometricFingerprintViewModelProvider.get();
+                AuthBiometricFingerprintViewBinder.bind(fingerprintAndFaceView, fpAndFaceViewModel);
                 mBiometricView = fingerprintAndFaceView;
             } else if (fpProperties != null) {
                 final AuthBiometricFingerprintView fpView =
@@ -394,6 +406,9 @@
                 fpView.setSensorProperties(fpProperties);
                 fpView.setScaleFactorProvider(config.mScaleProvider);
                 fpView.updateOverrideIconLayoutParamsSize();
+                final AuthBiometricFingerprintViewModel fpViewModel =
+                        mAuthBiometricFingerprintViewModelProvider.get();
+                AuthBiometricFingerprintViewBinder.bind(fpView, fpViewModel);
                 mBiometricView = fpView;
             } else if (faceProperties != null) {
                 mBiometricView = (AuthBiometricFaceView) layoutInflater.inflate(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 6eb3c70..3579e8c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -73,6 +73,7 @@
 import com.android.systemui.CoreStartable;
 import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor;
 import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
+import com.android.systemui.biometrics.ui.viewmodel.AuthBiometricFingerprintViewModel;
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -127,6 +128,9 @@
 
     // TODO: these should be migrated out once ready
     @NonNull private final Provider<BiometricPromptCredentialInteractor> mBiometricPromptInteractor;
+
+    @NonNull private final Provider<AuthBiometricFingerprintViewModel>
+            mAuthBiometricFingerprintViewModelProvider;
     @NonNull private final Provider<CredentialViewModel> mCredentialViewModelProvider;
     @NonNull private final LogContextInteractor mLogContextInteractor;
 
@@ -722,7 +726,6 @@
         }
         onDialogDismissed(reason);
     }
-
     @Inject
     public AuthController(Context context,
             Execution execution,
@@ -741,6 +744,8 @@
             @NonNull UdfpsLogger udfpsLogger,
             @NonNull LogContextInteractor logContextInteractor,
             @NonNull Provider<BiometricPromptCredentialInteractor> biometricPromptInteractor,
+            @NonNull Provider<AuthBiometricFingerprintViewModel>
+                    authBiometricFingerprintViewModelProvider,
             @NonNull Provider<CredentialViewModel> credentialViewModelProvider,
             @NonNull InteractionJankMonitor jankMonitor,
             @Main Handler handler,
@@ -771,6 +776,7 @@
 
         mLogContextInteractor = logContextInteractor;
         mBiometricPromptInteractor = biometricPromptInteractor;
+        mAuthBiometricFingerprintViewModelProvider = authBiometricFingerprintViewModelProvider;
         mCredentialViewModelProvider = credentialViewModelProvider;
 
         mOrientationListener = new BiometricDisplayListener(
@@ -1299,7 +1305,7 @@
                 .build(bgExecutor, sensorIds, mFpProps, mFaceProps, wakefulnessLifecycle,
                         panelInteractionDetector, userManager, lockPatternUtils,
                         mInteractionJankMonitor, mBiometricPromptInteractor,
-                        mCredentialViewModelProvider);
+                        mAuthBiometricFingerprintViewModelProvider, mCredentialViewModelProvider);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
index d6ad4da..f5f4640 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
@@ -18,7 +18,6 @@
 
 import android.annotation.DrawableRes
 import android.content.Context
-import android.content.res.Configuration
 import android.graphics.drawable.Animatable2
 import android.graphics.drawable.AnimatedVectorDrawable
 import android.graphics.drawable.Drawable
@@ -94,8 +93,6 @@
     /** Called during [onAnimationEnd] if the controller is not [deactivated]. */
     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) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index 4319f01..962140f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -55,6 +55,7 @@
 import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.Dumpable
 import com.android.systemui.R
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
@@ -84,6 +85,7 @@
     private val activityTaskManager: ActivityTaskManager,
     overviewProxyService: OverviewProxyService,
     displayManager: DisplayManager,
+    private val displayStateInteractor: DisplayStateInteractor,
     @Main private val mainExecutor: DelayableExecutor,
     @Main private val handler: Handler,
     private val alternateBouncerInteractor: AlternateBouncerInteractor,
@@ -203,14 +205,16 @@
         request: SideFpsUiRequestSource,
         @BiometricOverlayConstants.ShowReason reason: Int = BiometricOverlayConstants.REASON_UNKNOWN
     ) {
-        requests.add(request)
-        mainExecutor.execute {
-            if (overlayView == null) {
-                traceSection("SideFpsController#show(request=${request.name}, reason=$reason") {
-                    createOverlayForDisplay(reason)
+        if (!displayStateInteractor.isInRearDisplayMode.value) {
+            requests.add(request)
+            mainExecutor.execute {
+                if (overlayView == null) {
+                    traceSection("SideFpsController#show(request=${request.name}, reason=$reason") {
+                        createOverlayForDisplay(reason)
+                    }
+                } else {
+                    Log.v(TAG, "overlay already shown")
                 }
-            } else {
-                Log.v(TAG, "overlay already shown")
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
index 3b50bbc..935de02 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
@@ -464,7 +464,12 @@
             // Fade out the icon if we are animating an activity launch over the lockscreen and the
             // activity didn't request the UDFPS.
             if (isLaunchingActivity && !udfpsRequested) {
-                alpha = (alpha * (1.0f - activityLaunchProgress)).toInt()
+                val udfpsActivityLaunchAlphaMultiplier =
+                    1f -
+                        (activityLaunchProgress *
+                                (ActivityLaunchAnimator.TIMINGS.totalDuration / 83))
+                            .coerceIn(0f, 1f)
+                alpha = (alpha * udfpsActivityLaunchAlphaMultiplier).toInt()
             }
 
             // Fade out alpha when a dialog is shown
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 67d2f30..c831663 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
@@ -17,10 +17,16 @@
 package com.android.systemui.biometrics.dagger
 
 import com.android.settingslib.udfps.UdfpsUtils
+import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
+import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepositoryImpl
 import com.android.systemui.biometrics.data.repository.PromptRepository
 import com.android.systemui.biometrics.data.repository.PromptRepositoryImpl
+import com.android.systemui.biometrics.data.repository.RearDisplayStateRepository
+import com.android.systemui.biometrics.data.repository.RearDisplayStateRepositoryImpl
 import com.android.systemui.biometrics.domain.interactor.CredentialInteractor
 import com.android.systemui.biometrics.domain.interactor.CredentialInteractorImpl
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
 import com.android.systemui.biometrics.domain.interactor.LogContextInteractor
 import com.android.systemui.biometrics.domain.interactor.LogContextInteractorImpl
 import com.android.systemui.dagger.SysUISingleton
@@ -41,10 +47,22 @@
 
     @Binds
     @SysUISingleton
+    fun fingerprintRepository(impl: FingerprintPropertyRepositoryImpl):
+            FingerprintPropertyRepository
+    @Binds
+    @SysUISingleton
+    fun rearDisplayStateRepository(impl: RearDisplayStateRepositoryImpl): RearDisplayStateRepository
+
+    @Binds
+    @SysUISingleton
     fun providesCredentialInteractor(impl: CredentialInteractorImpl): CredentialInteractor
 
     @Binds
     @SysUISingleton
+    fun providesDisplayStateInteractor(impl: DisplayStateInteractorImpl): DisplayStateInteractor
+
+    @Binds
+    @SysUISingleton
     fun bindsLogContextInteractor(impl: LogContextInteractorImpl): LogContextInteractor
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
new file mode 100644
index 0000000..33fb36c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.data.repository
+
+import android.hardware.biometrics.SensorLocationInternal
+import android.hardware.fingerprint.FingerprintManager
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
+import com.android.systemui.biometrics.shared.model.FingerprintSensorType
+import com.android.systemui.biometrics.shared.model.SensorStrength
+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 javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.shareIn
+
+/**
+ * A repository for the global state of FingerprintProperty.
+ *
+ * There is never more than one instance of the FingerprintProperty at any given time.
+ */
+interface FingerprintPropertyRepository {
+
+    /**
+     * If the repository is initialized or not. Other properties are defaults until this is true.
+     */
+    val isInitialized: Flow<Boolean>
+
+    /** The id of fingerprint sensor. */
+    val sensorId: StateFlow<Int>
+
+    /** The security strength of sensor (convenience, weak, strong). */
+    val strength: StateFlow<SensorStrength>
+
+    /** The types of fingerprint sensor (rear, ultrasonic, optical, etc.). */
+    val sensorType: StateFlow<FingerprintSensorType>
+
+    /** The primary sensor location relative to the default display. */
+    val sensorLocation: StateFlow<SensorLocationInternal>
+
+    // TODO(b/251476085): don't implement until we need it, but expose alternative locations as
+    // a map of display id -> location or similar.
+    /** The sensor location relative to each physical display. */
+    // val sensorLocations<Map<String, SensorLocationInternal>>
+}
+
+@SysUISingleton
+class FingerprintPropertyRepositoryImpl
+@Inject
+constructor(
+    @Application private val applicationScope: CoroutineScope,
+    private val fingerprintManager: FingerprintManager
+) : FingerprintPropertyRepository {
+
+    override val isInitialized: Flow<Boolean> =
+        conflatedCallbackFlow {
+                val callback =
+                    object : IFingerprintAuthenticatorsRegisteredCallback.Stub() {
+                        override fun onAllAuthenticatorsRegistered(
+                            sensors: List<FingerprintSensorPropertiesInternal>
+                        ) {
+                            if (sensors.isNotEmpty()) {
+                                setProperties(sensors[0])
+                                trySendWithFailureLogging(true, TAG, "initialize properties")
+                            }
+                        }
+                    }
+                fingerprintManager.addAuthenticatorsRegisteredCallback(callback)
+                trySendWithFailureLogging(false, TAG, "initial value defaulting to false")
+                awaitClose {}
+            }
+            .shareIn(scope = applicationScope, started = SharingStarted.Eagerly, replay = 1)
+
+    private val _sensorId: MutableStateFlow<Int> = MutableStateFlow(-1)
+    override val sensorId: StateFlow<Int> = _sensorId.asStateFlow()
+
+    private val _strength: MutableStateFlow<SensorStrength> =
+        MutableStateFlow(SensorStrength.CONVENIENCE)
+    override val strength = _strength.asStateFlow()
+
+    private val _sensorType: MutableStateFlow<FingerprintSensorType> =
+        MutableStateFlow(FingerprintSensorType.UNKNOWN)
+    override val sensorType = _sensorType.asStateFlow()
+
+    private val _sensorLocation: MutableStateFlow<SensorLocationInternal> =
+        MutableStateFlow(SensorLocationInternal.DEFAULT)
+    override val sensorLocation = _sensorLocation.asStateFlow()
+
+    private fun setProperties(prop: FingerprintSensorPropertiesInternal) {
+        _sensorId.value = prop.sensorId
+        _strength.value = sensorStrengthIntToObject(prop.sensorStrength)
+        _sensorType.value = sensorTypeIntToObject(prop.sensorType)
+        _sensorLocation.value = prop.location
+    }
+
+    companion object {
+        private const val TAG = "FingerprintPropertyRepositoryImpl"
+    }
+}
+
+private fun sensorStrengthIntToObject(value: Int): SensorStrength {
+    return when (value) {
+        0 -> SensorStrength.CONVENIENCE
+        1 -> SensorStrength.WEAK
+        2 -> SensorStrength.STRONG
+        else -> throw IllegalArgumentException("Invalid SensorStrength value: $value")
+    }
+}
+
+private fun sensorTypeIntToObject(value: Int): FingerprintSensorType {
+    return when (value) {
+        0 -> FingerprintSensorType.UNKNOWN
+        1 -> FingerprintSensorType.REAR
+        2 -> FingerprintSensorType.UDFPS_ULTRASONIC
+        3 -> FingerprintSensorType.UDFPS_OPTICAL
+        4 -> FingerprintSensorType.POWER_BUTTON
+        5 -> FingerprintSensorType.HOME_BUTTON
+        else -> throw IllegalArgumentException("Invalid SensorType value: $value")
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepository.kt
new file mode 100644
index 0000000..d17d961
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepository.kt
@@ -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.systemui.biometrics.data.repository
+
+import android.content.Context
+import android.hardware.devicestate.DeviceStateManager
+import com.android.internal.util.ArrayUtils
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.stateIn
+
+/** Provide current rear display state. */
+interface RearDisplayStateRepository {
+    /** Provides the current rear display state. */
+    val isInRearDisplayMode: StateFlow<Boolean>
+}
+
+@SysUISingleton
+class RearDisplayStateRepositoryImpl
+@Inject
+constructor(
+    @Application applicationScope: CoroutineScope,
+    @Application context: Context,
+    deviceStateManager: DeviceStateManager,
+    @Main mainExecutor: Executor
+) : RearDisplayStateRepository {
+    override val isInRearDisplayMode: StateFlow<Boolean> =
+        conflatedCallbackFlow {
+                val sendRearDisplayStateUpdate = { state: Boolean ->
+                    trySendWithFailureLogging(
+                        state,
+                        TAG,
+                        "Error sending rear display state update to $state"
+                    )
+                }
+
+                val callback =
+                    DeviceStateManager.DeviceStateCallback { state ->
+                        val isInRearDisplayMode =
+                            ArrayUtils.contains(
+                                context.resources.getIntArray(
+                                    com.android.internal.R.array.config_rearDisplayDeviceStates
+                                ),
+                                state
+                            )
+                        sendRearDisplayStateUpdate(isInRearDisplayMode)
+                    }
+
+                sendRearDisplayStateUpdate(false)
+                deviceStateManager.registerCallback(mainExecutor, callback)
+                awaitClose { deviceStateManager.unregisterCallback(callback) }
+            }
+            .stateIn(
+                applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = false,
+            )
+
+    companion object {
+        const val TAG = "RearDisplayStateRepositoryImpl"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt
new file mode 100644
index 0000000..c935aa2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.domain.interactor
+
+import android.content.Context
+import android.content.res.Configuration
+import com.android.systemui.biometrics.data.repository.RearDisplayStateRepository
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.unfold.compat.ScreenSizeFoldProvider
+import com.android.systemui.unfold.updates.FoldProvider
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.stateIn
+
+/** Aggregates display state information. */
+interface DisplayStateInteractor {
+
+    /** Whether the device is currently in rear display mode. */
+    val isInRearDisplayMode: StateFlow<Boolean>
+
+    /** Whether the device is currently folded. */
+    val isFolded: Flow<Boolean>
+
+    /** Called on configuration changes, used to keep the display state in sync */
+    fun onConfigurationChanged(newConfig: Configuration)
+}
+
+/** Encapsulates logic for interacting with the display state. */
+class DisplayStateInteractorImpl
+@Inject
+constructor(
+    @Application applicationScope: CoroutineScope,
+    @Application context: Context,
+    @Main mainExecutor: Executor,
+    rearDisplayStateRepository: RearDisplayStateRepository,
+) : DisplayStateInteractor {
+    private var screenSizeFoldProvider: ScreenSizeFoldProvider = ScreenSizeFoldProvider(context)
+
+    fun setScreenSizeFoldProvider(foldProvider: ScreenSizeFoldProvider) {
+        screenSizeFoldProvider = foldProvider
+    }
+
+    override val isFolded: Flow<Boolean> =
+        conflatedCallbackFlow {
+                val sendFoldStateUpdate = { state: Boolean ->
+                    trySendWithFailureLogging(
+                        state,
+                        TAG,
+                        "Error sending fold state update to $state"
+                    )
+                }
+
+                val callback =
+                    object : FoldProvider.FoldCallback {
+                        override fun onFoldUpdated(isFolded: Boolean) {
+                            sendFoldStateUpdate(isFolded)
+                        }
+                    }
+                sendFoldStateUpdate(false)
+                screenSizeFoldProvider.registerCallback(callback, mainExecutor)
+                awaitClose { screenSizeFoldProvider.unregisterCallback(callback) }
+            }
+            .stateIn(
+                applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = false,
+            )
+
+    override val isInRearDisplayMode: StateFlow<Boolean> =
+        rearDisplayStateRepository.isInRearDisplayMode
+
+    override fun onConfigurationChanged(newConfig: Configuration) {
+        screenSizeFoldProvider.onConfigurationChange(newConfig)
+    }
+
+    companion object {
+        private const val TAG = "DisplayStateInteractor"
+    }
+}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/FingerprintSensorType.kt
similarity index 61%
copy from services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java
copy to packages/SystemUI/src/com/android/systemui/biometrics/shared/model/FingerprintSensorType.kt
index 7c339d2..df5cefd 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/FingerprintSensorType.kt
@@ -14,14 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.server.companion.datatransfer.contextsync;
+package com.android.systemui.biometrics.shared.model
 
-/** Callback for call metadata syncing. */
-public abstract class CallMetadataSyncCallback {
+import android.hardware.fingerprint.FingerprintSensorProperties
 
-    abstract void processCallControlAction(int crossDeviceCallId, int callControlAction);
-
-    abstract void requestCrossDeviceSync(int userId);
-
-    abstract void updateStatus(int userId, boolean shouldSyncCallMetadata);
+/** Fingerprint sensor types. Represents [FingerprintSensorProperties.SensorType]. */
+enum class FingerprintSensorType {
+    UNKNOWN,
+    REAR,
+    UDFPS_ULTRASONIC,
+    UDFPS_OPTICAL,
+    POWER_BUTTON,
+    HOME_BUTTON,
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/SensorStrength.kt
similarity index 63%
copy from packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
copy to packages/SystemUI/src/com/android/systemui/biometrics/shared/model/SensorStrength.kt
index 7ded90f..2982d0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/SensorStrength.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,15 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone.dagger;
+package com.android.systemui.biometrics.shared.model
 
-import dagger.Module;
-import dagger.multibindings.Multibinds;
+import android.hardware.biometrics.SensorProperties
 
-import java.util.Set;
-
-@Module
-interface CentralSurfacesStartableModule {
-    @Multibinds
-    Set<CentralSurfacesComponent.Startable> multibindStartables();
+/** Fingerprint sensor security strength. Represents [SensorProperties.Strength]. */
+enum class SensorStrength {
+    CONVENIENCE,
+    WEAK,
+    STRONG,
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt
index 9847c10..baf8d74 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt
@@ -22,9 +22,7 @@
 import com.android.systemui.biometrics.EllipseOverlapDetectorParams
 import com.android.systemui.dagger.SysUISingleton
 import kotlin.math.cos
-import kotlin.math.pow
 import kotlin.math.sin
-import kotlin.math.sqrt
 
 private enum class SensorPixelPosition {
     OUTSIDE, // Pixel that falls outside of sensor circle
@@ -42,8 +40,8 @@
 @SysUISingleton
 class EllipseOverlapDetector(private val params: EllipseOverlapDetectorParams) : OverlapDetector {
     override fun isGoodOverlap(touchData: NormalizedTouchData, nativeSensorBounds: Rect): Boolean {
-        // First, check if entire ellipse is within the sensor
-        if (isEllipseWithinSensor(touchData, nativeSensorBounds)) {
+        // First, check if touch is within bounding box,
+        if (nativeSensorBounds.contains(touchData.x.toInt(), touchData.y.toInt())) {
             return true
         }
 
@@ -119,28 +117,4 @@
 
         return result <= 1
     }
-
-    /** Returns whether the entire ellipse is contained within the sensor area */
-    private fun isEllipseWithinSensor(
-        touchData: NormalizedTouchData,
-        nativeSensorBounds: Rect
-    ): Boolean {
-        val a2 = (touchData.minor / 2.0).pow(2.0)
-        val b2 = (touchData.major / 2.0).pow(2.0)
-
-        val sin2a = sin(touchData.orientation.toDouble()).pow(2.0)
-        val cos2a = cos(touchData.orientation.toDouble()).pow(2.0)
-
-        val cx = sqrt(a2 * cos2a + b2 * sin2a)
-        val cy = sqrt(a2 * sin2a + b2 * cos2a)
-
-        val ellipseRect =
-            Rect(
-                (-cx + touchData.x).toInt(),
-                (-cy + touchData.y).toInt(),
-                (cx + touchData.x).toInt(),
-                (cy + touchData.y).toInt()
-            )
-        return nativeSensorBounds.contains(ellipseRect)
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
index bcc0575..ede62ac 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
@@ -65,7 +65,7 @@
         super.onLayout(changed, left, top, right, bottom)
 
         val inputLeftBound: Int
-        val inputTopBound: Int
+        var inputTopBound: Int
         var headerRightBound = right
         var headerTopBounds = top
         val subTitleBottom: Int = if (subtitleView.isGone) titleView.bottom else subtitleView.bottom
@@ -75,14 +75,23 @@
             inputLeftBound = (right - left) / 2
             headerRightBound = inputLeftBound
             headerTopBounds -= iconView.bottom.coerceAtMost(bottomInset)
+
+            if (descriptionView.bottom > bottomInset) {
+                credentialHeader.layout(left, headerTopBounds, headerRightBound, bottom)
+            }
         } else {
             inputTopBound = descBottom + (bottom - descBottom - credentialInput.height) / 2
             inputLeftBound = (right - left - credentialInput.width) / 2
+
+            if (bottom - inputTopBound < credentialInput.height) {
+                inputTopBound = bottom - credentialInput.height
+            }
+
+            if (descriptionView.bottom > inputTopBound) {
+                credentialHeader.layout(left, headerTopBounds, headerRightBound, inputTopBound)
+            }
         }
 
-        if (descriptionView.bottom > bottomInset) {
-            credentialHeader.layout(left, headerTopBounds, headerRightBound, bottom)
-        }
         credentialInput.layout(inputLeftBound, inputTopBound, right, bottom)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/AuthBiometricFingerprintViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/AuthBiometricFingerprintViewBinder.kt
new file mode 100644
index 0000000..e776ab4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/AuthBiometricFingerprintViewBinder.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.biometrics.ui.binder
+
+import android.view.Surface
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.biometrics.AuthBiometricFingerprintView
+import com.android.systemui.biometrics.ui.viewmodel.AuthBiometricFingerprintViewModel
+import com.android.systemui.lifecycle.repeatWhenAttached
+import kotlinx.coroutines.launch
+
+object AuthBiometricFingerprintViewBinder {
+
+    /** Binds a [AuthBiometricFingerprintView] to a [AuthBiometricFingerprintViewModel]. */
+    @JvmStatic
+    fun bind(view: AuthBiometricFingerprintView, viewModel: AuthBiometricFingerprintViewModel) {
+        view.repeatWhenAttached {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                viewModel.onConfigurationChanged(view.context.resources.configuration)
+                viewModel.setRotation(view.context.display?.orientation ?: Surface.ROTATION_0)
+                launch {
+                    viewModel.iconAsset.collect { iconAsset ->
+                        view.updateIconViewAnimation(iconAsset)
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/AuthBiometricFingerprintViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/AuthBiometricFingerprintViewModel.kt
new file mode 100644
index 0000000..617d80c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/AuthBiometricFingerprintViewModel.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+import android.annotation.RawRes
+import android.content.res.Configuration
+import android.view.Surface
+import com.android.systemui.R
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+
+/** Models UI of AuthBiometricFingerprintView to support rear display state changes. */
+class AuthBiometricFingerprintViewModel
+@Inject
+constructor(private val interactor: DisplayStateInteractor) {
+    /** Current device rotation. */
+    private var rotation: Int = Surface.ROTATION_0
+
+    /** Current AuthBiometricFingerprintView asset. */
+    val iconAsset: Flow<Int> =
+        combine(interactor.isFolded, interactor.isInRearDisplayMode) {
+            isFolded: Boolean,
+            isInRearDisplayMode: Boolean ->
+            getSideFpsAnimationAsset(isFolded, isInRearDisplayMode)
+        }
+
+    @RawRes
+    private fun getSideFpsAnimationAsset(
+        isDeviceFolded: Boolean,
+        isInRearDisplayMode: Boolean,
+    ): Int =
+        when (rotation) {
+            Surface.ROTATION_90 ->
+                if (isInRearDisplayMode) {
+                    R.raw.biometricprompt_rear_portrait_reverse_base
+                } else if (isDeviceFolded) {
+                    R.raw.biometricprompt_folded_base_topleft
+                } else {
+                    R.raw.biometricprompt_portrait_base_topleft
+                }
+            Surface.ROTATION_270 ->
+                if (isInRearDisplayMode) {
+                    R.raw.biometricprompt_rear_portrait_base
+                } else if (isDeviceFolded) {
+                    R.raw.biometricprompt_folded_base_bottomright
+                } else {
+                    R.raw.biometricprompt_portrait_base_bottomright
+                }
+            else ->
+                if (isInRearDisplayMode) {
+                    R.raw.biometricprompt_rear_landscape_base
+                } else if (isDeviceFolded) {
+                    R.raw.biometricprompt_folded_base_default
+                } else {
+                    R.raw.biometricprompt_landscape_base
+                }
+        }
+
+    /** Called on configuration changes */
+    fun onConfigurationChanged(newConfig: Configuration) {
+        interactor.onConfigurationChanged(newConfig)
+    }
+
+    fun setRotation(newRotation: Int) {
+        rotation = newRotation
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt
new file mode 100644
index 0000000..0542e13
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.clipboardoverlay
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.net.Uri
+import android.util.Log
+import android.util.Size
+import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import java.io.IOException
+import java.util.function.Consumer
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import kotlinx.coroutines.withTimeoutOrNull
+
+class ClipboardImageLoader
+@Inject
+constructor(
+    private val context: Context,
+    @Background private val bgDispatcher: CoroutineDispatcher,
+    @Application private val mainScope: CoroutineScope
+) {
+    private val TAG: String = "ClipboardImageLoader"
+
+    suspend fun load(uri: Uri, timeoutMs: Long = 300) =
+        withTimeoutOrNull(timeoutMs) {
+            withContext(bgDispatcher) {
+                try {
+                    val size = context.resources.getDimensionPixelSize(R.dimen.overlay_x_scale)
+                    context.contentResolver.loadThumbnail(uri, Size(size, size * 4), null)
+                } catch (e: IOException) {
+                    Log.e(TAG, "Thumbnail loading failed!", e)
+                    null
+                }
+            }
+        }
+
+    fun loadAsync(uri: Uri, callback: Consumer<Bitmap?>) {
+        mainScope.launch { callback.accept(load(uri)) }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index 0aeab10..757ebf4 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -32,6 +32,7 @@
 import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SWIPE_DISMISSED;
 import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_TAP_OUTSIDE;
 import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_TIMED_OUT;
+import static com.android.systemui.flags.Flags.CLIPBOARD_IMAGE_TIMEOUT;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -90,6 +91,7 @@
     private final ClipboardOverlayUtils mClipboardUtils;
     private final FeatureFlags mFeatureFlags;
     private final Executor mBgExecutor;
+    private final ClipboardImageLoader mClipboardImageLoader;
 
     private final ClipboardOverlayView mView;
 
@@ -109,6 +111,7 @@
 
     private Runnable mOnUiUpdate;
 
+    private boolean mShowingUi;
     private boolean mIsMinimized;
     private ClipboardModel mClipboardModel;
 
@@ -175,9 +178,11 @@
             FeatureFlags featureFlags,
             ClipboardOverlayUtils clipboardUtils,
             @Background Executor bgExecutor,
+            ClipboardImageLoader clipboardImageLoader,
             UiEventLogger uiEventLogger) {
         mContext = context;
         mBroadcastDispatcher = broadcastDispatcher;
+        mClipboardImageLoader = clipboardImageLoader;
 
         mClipboardLogger = new ClipboardLogger(uiEventLogger);
 
@@ -260,21 +265,42 @@
         boolean shouldAnimate = !model.dataMatches(mClipboardModel) || wasExiting;
         mClipboardModel = model;
         mClipboardLogger.setClipSource(mClipboardModel.getSource());
-        if (shouldAnimate) {
-            reset();
-            mClipboardLogger.setClipSource(mClipboardModel.getSource());
-            if (shouldShowMinimized(mWindow.getWindowInsets())) {
-                mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_SHOWN_MINIMIZED);
-                mIsMinimized = true;
-                mView.setMinimized(true);
-            } else {
-                mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_SHOWN_EXPANDED);
+        if (mFeatureFlags.isEnabled(CLIPBOARD_IMAGE_TIMEOUT)) {
+            if (shouldAnimate) {
+                reset();
+                mClipboardLogger.setClipSource(mClipboardModel.getSource());
+                if (shouldShowMinimized(mWindow.getWindowInsets())) {
+                    mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_SHOWN_MINIMIZED);
+                    mIsMinimized = true;
+                    mView.setMinimized(true);
+                } else {
+                    mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_SHOWN_EXPANDED);
+                    setExpandedView(this::animateIn);
+                }
+                mView.announceForAccessibility(
+                        getAccessibilityAnnouncement(mClipboardModel.getType()));
+            } else if (!mIsMinimized) {
+                setExpandedView(() -> {
+                });
+            }
+        } else {
+            if (shouldAnimate) {
+                reset();
+                mClipboardLogger.setClipSource(mClipboardModel.getSource());
+                if (shouldShowMinimized(mWindow.getWindowInsets())) {
+                    mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_SHOWN_MINIMIZED);
+                    mIsMinimized = true;
+                    mView.setMinimized(true);
+                } else {
+                    mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_SHOWN_EXPANDED);
+                    setExpandedView();
+                    animateIn();
+                }
+                mView.announceForAccessibility(
+                        getAccessibilityAnnouncement(mClipboardModel.getType()));
+            } else if (!mIsMinimized) {
                 setExpandedView();
             }
-            animateIn();
-            mView.announceForAccessibility(getAccessibilityAnnouncement(mClipboardModel.getType()));
-        } else if (!mIsMinimized) {
-            setExpandedView();
         }
         if (mClipboardModel.isRemote()) {
             mTimeoutHandler.cancelTimeout();
@@ -285,6 +311,58 @@
         }
     }
 
+    private void setExpandedView(Runnable onViewReady) {
+        final ClipboardModel model = mClipboardModel;
+        mView.setMinimized(false);
+        switch (model.getType()) {
+            case TEXT:
+                if (model.isRemote() || DeviceConfig.getBoolean(
+                        DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_SHOW_ACTIONS, false)) {
+                    if (model.getTextLinks() != null) {
+                        classifyText(model);
+                    }
+                }
+                if (model.isSensitive()) {
+                    mView.showTextPreview(mContext.getString(R.string.clipboard_asterisks), true);
+                } else {
+                    mView.showTextPreview(model.getText().toString(), false);
+                }
+                mView.setEditAccessibilityAction(true);
+                mOnPreviewTapped = this::editText;
+                onViewReady.run();
+                break;
+            case IMAGE:
+                mView.setEditAccessibilityAction(true);
+                mOnPreviewTapped = () -> editImage(model.getUri());
+                if (model.isSensitive()) {
+                    mView.showImagePreview(null);
+                    onViewReady.run();
+                } else {
+                    mClipboardImageLoader.loadAsync(model.getUri(), (bitmap) -> mView.post(() -> {
+                        if (bitmap == null) {
+                            mView.showDefaultTextPreview();
+                        } else {
+                            mView.showImagePreview(bitmap);
+                        }
+                        onViewReady.run();
+                    }));
+                }
+                break;
+            case URI:
+            case OTHER:
+                mView.showDefaultTextPreview();
+                onViewReady.run();
+                break;
+        }
+        if (!model.isRemote()) {
+            maybeShowRemoteCopy(model.getClipData());
+        }
+        if (model.getType() != ClipboardModel.Type.OTHER) {
+            mOnShareTapped = () -> shareContent(model.getClipData());
+            mView.showShareChip();
+        }
+    }
+
     private void setExpandedView() {
         final ClipboardModel model = mClipboardModel;
         mView.setMinimized(false);
@@ -350,8 +428,12 @@
                     mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_EXPANDED_FROM_MINIMIZED);
                     mIsMinimized = false;
                 }
-                setExpandedView();
-                animateIn();
+                if (mFeatureFlags.isEnabled(CLIPBOARD_IMAGE_TIMEOUT)) {
+                    setExpandedView(() -> animateIn());
+                } else {
+                    setExpandedView();
+                    animateIn();
+                }
             }
         });
         mEnterAnimator.start();
@@ -412,7 +494,8 @@
                 mInputMonitor.getInputChannel(), Looper.getMainLooper()) {
             @Override
             public void onInputEvent(InputEvent event) {
-                if (event instanceof MotionEvent) {
+                if ((!mFeatureFlags.isEnabled(CLIPBOARD_IMAGE_TIMEOUT) || mShowingUi)
+                        && event instanceof MotionEvent) {
                     MotionEvent motionEvent = (MotionEvent) event;
                     if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
                         if (!mView.isInTouchRegion(
@@ -452,6 +535,12 @@
         mEnterAnimator = mView.getEnterAnimation();
         mEnterAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
+            public void onAnimationStart(Animator animation) {
+                super.onAnimationStart(animation);
+                mShowingUi = true;
+            }
+
+            @Override
             public void onAnimationEnd(Animator animation) {
                 super.onAnimationEnd(animation);
                 if (mOnUiUpdate != null) {
@@ -518,6 +607,7 @@
         mOnRemoteCopyTapped = null;
         mOnShareTapped = null;
         mOnPreviewTapped = null;
+        mShowingUi = false;
         mView.reset();
         mTimeoutHandler.cancelTimeout();
         mClipboardLogger.reset();
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
index 1fa9ac5..1ffbe32 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
@@ -72,7 +72,7 @@
         } catch (PackageManager.NameNotFoundException e) {
             Log.w(TAG, "Package not found: " + mClipboardManager.getPrimaryClipSource(), e);
         }
-        mEditText.setText(clip.getItemAt(0).getText());
+        mEditText.setText(clip.getItemAt(0).getText().toString());
         mEditText.requestFocus();
         mEditText.setSelection(0);
         mSensitive = clip.getDescription().getExtras() != null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java b/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/CommonRepositoryModule.kt
similarity index 64%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
rename to packages/SystemUI/src/com/android/systemui/common/ui/data/repository/CommonRepositoryModule.kt
index 7ded90f..9b0c3fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/CommonRepositoryModule.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,15 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone.dagger;
+package com.android.systemui.common.ui.data.repository
 
-import dagger.Module;
-import dagger.multibindings.Multibinds;
-
-import java.util.Set;
+import dagger.Binds
+import dagger.Module
 
 @Module
-interface CentralSurfacesStartableModule {
-    @Multibinds
-    Set<CentralSurfacesComponent.Startable> multibindStartables();
+interface CommonRepositoryModule {
+    @Binds fun bindRepository(impl: ConfigurationRepositoryImpl): ConfigurationRepository
 }
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt b/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt
new file mode 100644
index 0000000..3e6ac86
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.common.ui.data.repository
+
+import android.content.Context
+import android.content.res.Configuration
+import android.view.DisplayInfo
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.wrapper.DisplayUtilsWrapper
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.stateIn
+
+interface ConfigurationRepository {
+    /** Called whenever ui mode, theme or configuration has changed. */
+    val onAnyConfigurationChange: Flow<Unit>
+    val scaleForResolution: Flow<Float>
+
+    fun getResolutionScale(): Float
+}
+
+@ExperimentalCoroutinesApi
+@SysUISingleton
+class ConfigurationRepositoryImpl
+@Inject
+constructor(
+    private val configurationController: ConfigurationController,
+    private val context: Context,
+    @Application private val scope: CoroutineScope,
+    private val displayUtils: DisplayUtilsWrapper,
+) : ConfigurationRepository {
+    private val displayInfo = MutableStateFlow(DisplayInfo())
+
+    override val onAnyConfigurationChange: Flow<Unit> =
+        ConflatedCallbackFlow.conflatedCallbackFlow {
+            val callback =
+                object : ConfigurationController.ConfigurationListener {
+                    override fun onUiModeChanged() {
+                        sendUpdate("ConfigurationRepository#onUiModeChanged")
+                    }
+
+                    override fun onThemeChanged() {
+                        sendUpdate("ConfigurationRepository#onThemeChanged")
+                    }
+
+                    override fun onConfigChanged(newConfig: Configuration) {
+                        sendUpdate("ConfigurationRepository#onConfigChanged")
+                    }
+
+                    fun sendUpdate(reason: String) {
+                        trySendWithFailureLogging(Unit, reason)
+                    }
+                }
+            configurationController.addCallback(callback)
+            awaitClose { configurationController.removeCallback(callback) }
+        }
+
+    private val configurationChange: Flow<Unit> =
+        ConflatedCallbackFlow.conflatedCallbackFlow {
+            val callback =
+                object : ConfigurationController.ConfigurationListener {
+                    override fun onConfigChanged(newConfig: Configuration) {
+                        trySendWithFailureLogging(Unit, "ConfigurationRepository#onConfigChanged")
+                    }
+                }
+            configurationController.addCallback(callback)
+            awaitClose { configurationController.removeCallback(callback) }
+        }
+
+    override val scaleForResolution: StateFlow<Float> =
+        configurationChange
+            .mapLatest { getResolutionScale() }
+            .distinctUntilChanged()
+            .stateIn(scope, SharingStarted.WhileSubscribed(), getResolutionScale())
+
+    override fun getResolutionScale(): Float {
+        context.display.getDisplayInfo(displayInfo.value)
+        val maxDisplayMode =
+            displayUtils.getMaximumResolutionDisplayMode(displayInfo.value.supportedModes)
+        maxDisplayMode?.let {
+            val scaleFactor =
+                displayUtils.getPhysicalPixelDisplaySizeRatio(
+                    maxDisplayMode.physicalWidth,
+                    maxDisplayMode.physicalHeight,
+                    displayInfo.value.naturalWidth,
+                    displayInfo.value.naturalHeight
+                )
+            return if (scaleFactor == Float.POSITIVE_INFINITY) 1f else scaleFactor
+        }
+        return 1f
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java b/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java
index 016891d..a334c1e 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.complication;
 
-import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
-
 import android.database.ContentObserver;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -25,6 +23,7 @@
 import com.android.settingslib.dream.DreamBackend;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dagger.qualifiers.SystemUser;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.shared.condition.Monitor;
 import com.android.systemui.util.condition.ConditionalCoreStartable;
@@ -33,7 +32,6 @@
 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
@@ -53,7 +51,7 @@
             @Main Executor executor,
             SecureSettings secureSettings,
             DreamOverlayStateController dreamOverlayStateController,
-            @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+            @SystemUser Monitor monitor) {
         super(monitor);
         mDreamBackend = dreamBackend;
         mExecutor = executor;
diff --git a/packages/SystemUI/src/com/android/systemui/complication/DreamClockTimeComplication.java b/packages/SystemUI/src/com/android/systemui/complication/DreamClockTimeComplication.java
index 5020480..9c3448b 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/DreamClockTimeComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/DreamClockTimeComplication.java
@@ -18,11 +18,11 @@
 
 import static com.android.systemui.complication.dagger.DreamClockTimeComplicationModule.DREAM_CLOCK_TIME_COMPLICATION_VIEW;
 import static com.android.systemui.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.dagger.qualifiers.SystemUser;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.shared.condition.Monitor;
 import com.android.systemui.util.condition.ConditionalCoreStartable;
@@ -74,7 +74,7 @@
         public Registrant(
                 DreamOverlayStateController dreamOverlayStateController,
                 DreamClockTimeComplication dreamClockTimeComplication,
-                @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+                @SystemUser Monitor monitor) {
             super(monitor);
             mDreamOverlayStateController = dreamOverlayStateController;
             mComplication = dreamClockTimeComplication;
diff --git a/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java b/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
index 8f192de..f973aee 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
@@ -21,7 +21,6 @@
 import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
 import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK;
 import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.UNAVAILABLE;
-import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
 
 import android.content.Context;
 import android.content.Intent;
@@ -40,6 +39,7 @@
 import com.android.systemui.controls.management.ControlsListingController;
 import com.android.systemui.controls.ui.ControlsActivity;
 import com.android.systemui.controls.ui.ControlsUiController;
+import com.android.systemui.dagger.qualifiers.SystemUser;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.shared.condition.Monitor;
@@ -108,7 +108,7 @@
         public Registrant(DreamHomeControlsComplication complication,
                 DreamOverlayStateController dreamOverlayStateController,
                 ControlsComponent controlsComponent,
-                @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+                @SystemUser Monitor monitor) {
             super(monitor);
             mComplication = complication;
             mControlsComponent = controlsComponent;
diff --git a/packages/SystemUI/src/com/android/systemui/complication/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/complication/SmartSpaceComplication.java
index 2f5ef6d..b98794e 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/SmartSpaceComplication.java
@@ -17,7 +17,6 @@
 package com.android.systemui.complication;
 
 import static com.android.systemui.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;
@@ -26,6 +25,7 @@
 import android.widget.FrameLayout;
 
 import com.android.systemui.CoreStartable;
+import com.android.systemui.dagger.qualifiers.SystemUser;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
 import com.android.systemui.flags.FeatureFlags;
@@ -88,7 +88,7 @@
                 DreamOverlayStateController dreamOverlayStateController,
                 SmartSpaceComplication smartSpaceComplication,
                 DreamSmartspaceController smartSpaceController,
-                @Named(DREAM_PRETEXT_MONITOR) Monitor monitor,
+                @SystemUser Monitor monitor,
                 FeatureFlags featureFlags) {
             super(monitor);
             mDreamOverlayStateController = dreamOverlayStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
index 3d6d335..18bd467 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
@@ -41,7 +41,8 @@
     private val context: Context,
     @Background private val backgroundExecutor: DelayableExecutor,
     private val lazyController: Lazy<ControlsController>,
-    userTracker: UserTracker
+    private val packageUpdateMonitorFactory: PackageUpdateMonitor.Factory,
+    userTracker: UserTracker,
 ) : ControlsBindingController {
 
     companion object {
@@ -93,7 +94,8 @@
                 backgroundExecutor,
                 actionCallbackService,
                 currentUser,
-                component
+                component,
+                packageUpdateMonitorFactory
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
index 217f4d8..cb2476c 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.controls.controller
 
+import android.annotation.WorkerThread
 import android.content.ComponentName
 import android.content.Context
 import android.content.Intent
@@ -23,7 +24,6 @@
 import android.os.Binder
 import android.os.Bundle
 import android.os.IBinder
-import android.os.RemoteException
 import android.os.UserHandle
 import android.service.controls.ControlsProviderService
 import android.service.controls.ControlsProviderService.CALLBACK_BUNDLE
@@ -38,6 +38,7 @@
 import com.android.internal.annotations.GuardedBy
 import com.android.systemui.util.concurrency.DelayableExecutor
 import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicBoolean
 
 /**
  * Manager for the lifecycle of the connection to a given [ControlsProviderService].
@@ -45,6 +46,9 @@
  * This class handles binding and unbinding and requests to the service. The class will queue
  * requests until the service is connected and dispatch them then.
  *
+ * If the provider app is updated, and we are currently bound to it, it will try to rebind after
+ * update is completed.
+ *
  * @property context A SystemUI context for binding to the services
  * @property executor A delayable executor for posting timeouts
  * @property actionCallbackService a callback interface to hand the remote service for sending
@@ -59,22 +63,22 @@
     private val executor: DelayableExecutor,
     private val actionCallbackService: IControlsActionCallback.Stub,
     val user: UserHandle,
-    val componentName: ComponentName
-) : IBinder.DeathRecipient {
+    val componentName: ComponentName,
+    packageUpdateMonitorFactory: PackageUpdateMonitor.Factory,
+) {
 
     val token: IBinder = Binder()
     private var requiresBound = false
     @GuardedBy("queuedServiceMethods")
     private val queuedServiceMethods: MutableSet<ServiceMethod> = ArraySet()
     private var wrapper: ServiceWrapper? = null
-    private var bindTryCount = 0
     private val TAG = javaClass.simpleName
     private var onLoadCanceller: Runnable? = null
 
+    private var lastForPanel = false
+
     companion object {
-        private const val BIND_RETRY_DELAY = 1000L // ms
         private const val LOAD_TIMEOUT_SECONDS = 20L // seconds
-        private const val MAX_BIND_RETRIES = 5
         private const val DEBUG = true
         private val BIND_FLAGS = Context.BIND_AUTO_CREATE or Context.BIND_FOREGROUND_SERVICE or
             Context.BIND_NOT_PERCEPTIBLE
@@ -91,60 +95,56 @@
         })
     }
 
-    private fun bindService(bind: Boolean, forPanel: Boolean = false) {
-        executor.execute {
-            requiresBound = bind
-            if (bind) {
-                if (bindTryCount != MAX_BIND_RETRIES && wrapper == null) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Binding service $intent")
-                    }
-                    bindTryCount++
-                    try {
-                        val flags = if (forPanel) BIND_FLAGS_PANEL else BIND_FLAGS
-                        val bound = context
-                                .bindServiceAsUser(intent, serviceConnection, flags, user)
-                        if (!bound) {
-                            context.unbindService(serviceConnection)
-                        }
-                    } catch (e: SecurityException) {
-                        Log.e(TAG, "Failed to bind to service", e)
-                    }
-                }
-            } else {
-                if (DEBUG) {
-                    Log.d(TAG, "Unbinding service $intent")
-                }
-                bindTryCount = 0
-                wrapper?.run {
-                    context.unbindService(serviceConnection)
-                }
-                wrapper = null
+    private val packageUpdateMonitor = packageUpdateMonitorFactory.create(
+        user,
+        componentName.packageName,
+    ) {
+        if (requiresBound) {
+            // Let's unbind just in case. onBindingDied should have been called and unbound before.
+            executor.execute {
+                unbindAndCleanup("package updated")
+                bindService(true, lastForPanel)
             }
         }
     }
 
+    private fun bindService(bind: Boolean, forPanel: Boolean = false) {
+        executor.execute {
+            bindServiceBackground(bind, forPanel)
+        }
+    }
+
     private val serviceConnection = object : ServiceConnection {
+
+        val connected = AtomicBoolean(false)
+
         override fun onServiceConnected(name: ComponentName, service: IBinder) {
             if (DEBUG) Log.d(TAG, "onServiceConnected $name")
-            bindTryCount = 0
             wrapper = ServiceWrapper(IControlsProvider.Stub.asInterface(service))
-            try {
-                service.linkToDeath(this@ControlsProviderLifecycleManager, 0)
-            } catch (_: RemoteException) {}
+            packageUpdateMonitor.startMonitoring()
             handlePendingServiceMethods()
         }
 
         override fun onServiceDisconnected(name: ComponentName?) {
             if (DEBUG) Log.d(TAG, "onServiceDisconnected $name")
             wrapper = null
-            bindService(false)
+            // No need to call unbind. We may get a new `onServiceConnected`
         }
 
         override fun onNullBinding(name: ComponentName?) {
             if (DEBUG) Log.d(TAG, "onNullBinding $name")
             wrapper = null
-            context.unbindService(this)
+            executor.execute {
+                unbindAndCleanup("null binding")
+            }
+        }
+
+        override fun onBindingDied(name: ComponentName?) {
+            super.onBindingDied(name)
+            if (DEBUG) Log.d(TAG, "onBindingDied $name")
+            executor.execute {
+                unbindAndCleanup("binder died")
+            }
         }
     }
 
@@ -159,14 +159,55 @@
         }
     }
 
-    override fun binderDied() {
-        if (wrapper == null) return
-        wrapper = null
-        if (requiresBound) {
-            if (DEBUG) {
-                Log.d(TAG, "binderDied")
+    @WorkerThread
+    private fun bindServiceBackground(bind: Boolean, forPanel: Boolean = true) {
+        requiresBound = bind
+        if (bind) {
+            if (wrapper == null) {
+                if (DEBUG) {
+                    Log.d(TAG, "Binding service $intent")
+                }
+                try {
+                    lastForPanel = forPanel
+                    val flags = if (forPanel) BIND_FLAGS_PANEL else BIND_FLAGS
+                    var bound = false
+                    if (serviceConnection.connected.compareAndSet(false, true)) {
+                        bound = context
+                            .bindServiceAsUser(intent, serviceConnection, flags, user)
+                    }
+                    if (!bound) {
+                        Log.d(TAG, "Couldn't bind to $intent")
+                        doUnbind()
+                    }
+                } catch (e: SecurityException) {
+                    Log.e(TAG, "Failed to bind to service", e)
+                    // Couldn't even bind. Let's reset the connected value
+                    serviceConnection.connected.set(false)
+                }
             }
-            // Try rebinding some time later
+        } else {
+            unbindAndCleanup("unbind requested")
+            packageUpdateMonitor.stopMonitoring()
+        }
+    }
+
+    @WorkerThread
+    private fun unbindAndCleanup(reason: String) {
+        if (DEBUG) {
+            Log.d(TAG, "Unbinding service $intent. Reason: $reason")
+        }
+        wrapper = null
+        try {
+            doUnbind()
+        } catch (e: IllegalArgumentException) {
+            Log.e(TAG, "Failed to unbind service", e)
+        }
+    }
+
+    @WorkerThread
+    private fun doUnbind() {
+        if (serviceConnection.connected.compareAndSet(true, false)) {
+            context.unbindService(serviceConnection)
         }
     }
 
@@ -313,7 +354,7 @@
         fun run() {
             if (!callWrapper()) {
                 queueServiceMethod(this)
-                binderDied()
+                executor.execute { unbindAndCleanup("couldn't call through binder") }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/PackageUpdateMonitor.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/PackageUpdateMonitor.kt
new file mode 100644
index 0000000..1973b62
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/PackageUpdateMonitor.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.controls.controller
+
+import android.content.Context
+import android.os.Handler
+import android.os.UserHandle
+import com.android.internal.content.PackageMonitor
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.util.concurrent.atomic.AtomicBoolean
+
+/** [PackageMonitor] that tracks when [packageName] has finished updating for user [user]. */
+class PackageUpdateMonitor
+@AssistedInject
+constructor(
+    @Assisted private val user: UserHandle,
+    @Assisted private val packageName: String,
+    @Assisted private val callback: Runnable,
+    @Background private val bgHandler: Handler,
+    @Application private val context: Context,
+) : PackageMonitor() {
+
+    private val monitoring = AtomicBoolean(false)
+
+    @AssistedFactory
+    fun interface Factory {
+        /**
+         * Create a [PackageUpdateMonitor] for a given [user] and [packageName]. It will run
+         * [callback] every time the package finishes updating.
+         */
+        fun create(user: UserHandle, packageName: String, callback: Runnable): PackageUpdateMonitor
+    }
+
+    /** Start monitoring for package updates. No-op if already monitoring. */
+    fun startMonitoring() {
+        if (monitoring.compareAndSet(/* expected */ false, /* new */ true)) {
+            register(context, user, false, bgHandler)
+        }
+    }
+
+    /** Stop monitoring for package updates. No-op if not monitoring. */
+    fun stopMonitoring() {
+        if (monitoring.compareAndSet(/* expected */ true, /* new */ false)) {
+            unregister()
+        }
+    }
+
+    /**
+     * If the package and the user match the ones for this [PackageUpdateMonitor], it will run
+     * [callback].
+     */
+    override fun onPackageUpdateFinished(packageName: String?, uid: Int) {
+        super.onPackageUpdateFinished(packageName, uid)
+        if (packageName == this.packageName && UserHandle.getUserHandleForUid(uid) == user) {
+            callback.run()
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt
index 2c717f5..45cb13b 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt
@@ -16,11 +16,11 @@
 
 package com.android.systemui.controls.controller
 
-import android.service.controls.actions.ControlAction
 import android.service.controls.IControlsActionCallback
 import android.service.controls.IControlsProvider
 import android.service.controls.IControlsSubscriber
 import android.service.controls.IControlsSubscription
+import android.service.controls.actions.ControlAction
 import android.service.controls.actions.ControlActionWrapper
 import android.util.Log
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index 5d608c3..7cbd1f5 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -16,9 +16,11 @@
 
 package com.android.systemui.controls.ui
 
+import android.app.Activity
 import android.app.ActivityOptions
 import android.app.ActivityTaskManager
 import android.app.ActivityTaskManager.INVALID_TASK_ID
+import android.app.ComponentOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
 import android.app.Dialog
 import android.app.PendingIntent
 import android.content.ComponentName
@@ -96,7 +98,9 @@
                 activityContext,
                 0 /* enterResId */,
                 0 /* exitResId */
-            )
+            ).setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+            options.isPendingIntentBackgroundActivityLaunchAllowedByPermission = true
+
             taskView.startActivity(
                 pendingIntent,
                 fillInIntent,
@@ -214,6 +218,12 @@
         if (!isShowing()) return
         taskView.release()
 
+        val isActivityFinishing =
+            (activityContext as? Activity)?.let { it.isFinishing || it.isDestroyed }
+        if (isActivityFinishing == true) {
+            // Don't dismiss the dialog if the activity is finishing, it will get removed
+            return
+        }
         super.dismiss()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
index 9a23181..025d7e4 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
@@ -41,6 +41,10 @@
     private val hide: () -> Unit = {}
 ) {
 
+    init {
+        taskView.alpha = 0f
+    }
+
     private var detailTaskId = INVALID_TASK_ID
 
     private val fillInIntent =
@@ -96,6 +100,7 @@
 
             override fun onTaskCreated(taskId: Int, name: ComponentName?) {
                 detailTaskId = taskId
+                taskView.alpha = 1f
             }
 
             override fun onReleased() {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java b/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
index 67ad3db..8764297 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
@@ -18,6 +18,8 @@
 
 import com.android.systemui.ActivityStarterDelegate;
 import com.android.systemui.classifier.FalsingManagerProxy;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.globalactions.GlobalActionsComponent;
 import com.android.systemui.globalactions.GlobalActionsImpl;
 import com.android.systemui.plugins.ActivityStarter;
@@ -28,6 +30,7 @@
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarStateControllerImpl;
+import com.android.systemui.statusbar.phone.ActivityStarterImpl;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
 import com.android.systemui.volume.VolumeDialogControllerImpl;
 
@@ -46,7 +49,11 @@
     /** */
     @Provides
     static ActivityStarter provideActivityStarter(ActivityStarterDelegate delegate,
-            PluginDependencyProvider dependencyProvider) {
+            PluginDependencyProvider dependencyProvider, ActivityStarterImpl activityStarterImpl,
+            FeatureFlags featureFlags) {
+        if (featureFlags.isEnabled(Flags.USE_NEW_ACTIVITY_STARTER)) {
+            return activityStarterImpl;
+        }
         dependencyProvider.allowPluginDependency(ActivityStarter.class, delegate);
         return delegate;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index dff2c0e..89c45d7 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -39,9 +39,11 @@
 import com.android.systemui.biometrics.dagger.UdfpsModule;
 import com.android.systemui.classifier.FalsingModule;
 import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule;
+import com.android.systemui.common.ui.data.repository.CommonRepositoryModule;
 import com.android.systemui.complication.dagger.ComplicationComponent;
 import com.android.systemui.controls.dagger.ControlsModule;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dagger.qualifiers.SystemUser;
 import com.android.systemui.demomode.dagger.DemoModeModule;
 import com.android.systemui.doze.dagger.DozeComponent;
 import com.android.systemui.dreams.dagger.DreamModule;
@@ -60,6 +62,7 @@
 import com.android.systemui.plugins.BcSmartspaceConfigPlugin;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 import com.android.systemui.privacy.PrivacyModule;
+import com.android.systemui.process.condition.SystemProcessCondition;
 import com.android.systemui.qrcodescanner.dagger.QRCodeScannerModule;
 import com.android.systemui.qs.FgsManagerController;
 import com.android.systemui.qs.FgsManagerControllerImpl;
@@ -74,6 +77,7 @@
 import com.android.systemui.shade.ShadeModule;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolatorImpl;
+import com.android.systemui.shared.condition.Monitor;
 import com.android.systemui.smartspace.dagger.SmartspaceModule;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -126,6 +130,7 @@
 import dagger.Module;
 import dagger.Provides;
 
+import java.util.Collections;
 import java.util.Optional;
 import java.util.concurrent.Executor;
 
@@ -151,6 +156,7 @@
             ClipboardOverlayModule.class,
             ClockInfoModule.class,
             ClockRegistryModule.class,
+            CommonRepositoryModule.class,
             ConnectivityModule.class,
             CoroutinesModule.class,
             DreamModule.class,
@@ -232,6 +238,17 @@
         return state;
     }
 
+    /**
+     * Provides the monitor for SystemUI that requires the process running as the system user.
+     */
+    @SysUISingleton
+    @Provides
+    @SystemUser
+    static Monitor provideSystemUserMonitor(@Main Executor executor,
+            SystemProcessCondition systemProcessCondition) {
+        return new Monitor(executor, Collections.singleton(systemProcessCondition));
+    }
+
     @BindsOptionalOf
     abstract CommandQueue optionalCommandQueue();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/SystemUser.kt
similarity index 62%
copy from packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
copy to packages/SystemUI/src/com/android/systemui/dagger/qualifiers/SystemUser.kt
index 7ded90f..6878a52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/SystemUser.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.
@@ -13,16 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.systemui.dagger.qualifiers
 
-package com.android.systemui.statusbar.phone.dagger;
+import javax.inject.Qualifier
 
-import dagger.Module;
-import dagger.multibindings.Multibinds;
-
-import java.util.Set;
-
-@Module
-interface CentralSurfacesStartableModule {
-    @Multibinds
-    Set<CentralSurfacesComponent.Startable> multibindStartables();
-}
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class SystemUser
diff --git a/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelperWrapper.kt b/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelperWrapper.kt
index d853e04..1057852 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelperWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelperWrapper.kt
@@ -24,4 +24,8 @@
     fun burnInOffset(amplitude: Int, xAxis: Boolean): Int {
         return getBurnInOffset(amplitude, xAxis)
     }
+
+    fun burnInProgressOffset(): Float {
+        return getBurnInProgressOffset()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/AssistantAttentionMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/AssistantAttentionMonitor.java
index 49d7f78..822cfb8 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/AssistantAttentionMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/AssistantAttentionMonitor.java
@@ -19,6 +19,7 @@
 import android.util.Log;
 
 import com.android.systemui.CoreStartable;
+import com.android.systemui.dagger.qualifiers.SystemUser;
 import com.android.systemui.dreams.callbacks.AssistantAttentionCallback;
 import com.android.systemui.dreams.conditions.AssistantAttentionCondition;
 import com.android.systemui.shared.condition.Monitor;
@@ -38,7 +39,7 @@
 
     @Inject
     public AssistantAttentionMonitor(
-            Monitor monitor,
+            @SystemUser Monitor monitor,
             AssistantAttentionCondition assistantAttentionCondition,
             AssistantAttentionCallback callback) {
         mConditionMonitor = monitor;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamLogger.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamLogger.kt
new file mode 100644
index 0000000..eb79290
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamLogger.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.dreams
+
+import com.android.systemui.log.dagger.DreamLog
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import javax.inject.Inject
+
+/** Logs dream-related stuff to a {@link LogBuffer}. */
+class DreamLogger @Inject constructor(@DreamLog private val buffer: LogBuffer) {
+    /** Logs a debug message to the buffer. */
+    fun d(tag: String, message: String) {
+        buffer.log(tag, LogLevel.DEBUG, { str1 = message }, { message })
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java
index 7f567aa..e9ebd3b 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java
@@ -16,11 +16,10 @@
 
 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.dagger.qualifiers.SystemUser;
 import com.android.systemui.dreams.callbacks.DreamStatusBarStateCallback;
 import com.android.systemui.dreams.conditions.DreamCondition;
 import com.android.systemui.flags.RestartDozeListener;
@@ -28,7 +27,6 @@
 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.
@@ -42,13 +40,11 @@
     private final DreamStatusBarStateCallback mCallback;
     private RestartDozeListener mRestartDozeListener;
 
-
     @Inject
-    public DreamMonitor(Monitor monitor, DreamCondition dreamCondition,
-            @Named(DREAM_PRETEXT_MONITOR) Monitor pretextMonitor,
+    public DreamMonitor(@SystemUser Monitor monitor, DreamCondition dreamCondition,
             DreamStatusBarStateCallback callback,
             RestartDozeListener restartDozeListener) {
-        super(pretextMonitor);
+        super(monitor);
         mConditionMonitor = monitor;
         mDreamCondition = dreamCondition;
         mCallback = callback;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
index 5b56c04..df46e07 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
@@ -21,6 +21,7 @@
 import android.animation.ValueAnimator
 import android.view.View
 import android.view.animation.Interpolator
+import androidx.core.animation.doOnCancel
 import androidx.core.animation.doOnEnd
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
@@ -65,7 +66,11 @@
     private val mDreamInTranslationYDistance: Int,
     @Named(DreamOverlayModule.DREAM_IN_TRANSLATION_Y_DURATION)
     private val mDreamInTranslationYDurationMs: Long,
+    private val mLogger: DreamLogger,
 ) {
+    companion object {
+        private const val TAG = "DreamOverlayAnimationsController"
+    }
 
     private var mAnimator: Animator? = null
     private lateinit var view: View
@@ -169,8 +174,11 @@
                 doOnEnd {
                     mAnimator = null
                     mOverlayStateController.setEntryAnimationsFinished(true)
+                    mLogger.d(TAG, "Dream overlay entry animations finished.")
                 }
+                doOnCancel { mLogger.d(TAG, "Dream overlay entry animations canceled.") }
                 start()
+                mLogger.d(TAG, "Dream overlay entry animations started.")
             }
     }
 
@@ -232,8 +240,11 @@
                 doOnEnd {
                     mAnimator = null
                     mOverlayStateController.setExitAnimationsRunning(false)
+                    mLogger.d(TAG, "Dream overlay exit animations finished.")
                 }
+                doOnCancel { mLogger.d(TAG, "Dream overlay exit animations canceled.") }
                 start()
+                mLogger.d(TAG, "Dream overlay exit animations started.")
             }
         mOverlayStateController.setExitAnimationsRunning(true)
         return mAnimator as AnimatorSet
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
index a2dcdf5..80e68cf 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
@@ -17,7 +17,6 @@
 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;
@@ -35,6 +34,7 @@
 import android.util.Log;
 
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dagger.qualifiers.SystemUser;
 import com.android.systemui.shared.condition.Monitor;
 import com.android.systemui.util.condition.ConditionalCoreStartable;
 
@@ -105,7 +105,7 @@
     @Inject
     public DreamOverlayRegistrant(Context context, @Main Resources resources,
             @Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent,
-            @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+            @SystemUser Monitor monitor) {
         super(monitor);
         mContext = context;
         mResources = resources;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
index 0f370ac..b141db1 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
@@ -199,7 +199,8 @@
                     if (mShouldShowComplications) {
                         return (requiredTypes & getAvailableComplicationTypes()) == requiredTypes;
                     }
-                    return (requiredTypes & mSupportedTypes) == requiredTypes;
+                    final int typesToAlwaysShow = mSupportedTypes & getAvailableComplicationTypes();
+                    return (requiredTypes & typesToAlwaysShow) == requiredTypes;
                 })
                 .collect(Collectors.toCollection(HashSet::new))
                 : mComplications);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
index 5bbfbda..3ef19b7 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
@@ -16,12 +16,9 @@
 package com.android.systemui.dreams.conditions;
 
 import android.app.DreamManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.text.TextUtils;
 
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.shared.condition.Condition;
 
 import javax.inject.Inject;
@@ -30,48 +27,33 @@
  * {@link DreamCondition} provides a signal when a dream begins and ends.
  */
 public class DreamCondition extends Condition {
-    private final Context mContext;
     private final DreamManager mDreamManager;
 
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            processIntent(intent);
-        }
-    };
+    private final KeyguardUpdateMonitor mUpdateMonitor;
+
+
+    private final KeyguardUpdateMonitorCallback mUpdateCallback =
+            new KeyguardUpdateMonitorCallback() {
+                @Override
+                public void onDreamingStateChanged(boolean dreaming) {
+                    updateCondition(dreaming);
+                }
+            };
 
     @Inject
-    public DreamCondition(Context context,
-            DreamManager dreamManager) {
-        mContext = context;
+    public DreamCondition(DreamManager dreamManager, KeyguardUpdateMonitor monitor) {
         mDreamManager = dreamManager;
-    }
-
-    private void processIntent(Intent intent) {
-        // In the case of a non-existent sticky broadcast, ignore when there is no intent.
-        if (intent == null) {
-            return;
-        }
-        if (TextUtils.equals(intent.getAction(), Intent.ACTION_DREAMING_STARTED)) {
-            updateCondition(true);
-        } else if (TextUtils.equals(intent.getAction(), Intent.ACTION_DREAMING_STOPPED)) {
-            updateCondition(false);
-        } else {
-            throw new IllegalStateException("unexpected intent:" + intent);
-        }
+        mUpdateMonitor = monitor;
     }
 
     @Override
     protected void start() {
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_DREAMING_STARTED);
-        filter.addAction(Intent.ACTION_DREAMING_STOPPED);
-        mContext.registerReceiver(mReceiver, filter);
+        mUpdateMonitor.registerCallback(mUpdateCallback);
         updateCondition(mDreamManager.isDreaming());
     }
 
     @Override
     protected void stop() {
-        mContext.unregisterReceiver(mReceiver);
+        mUpdateMonitor.removeCallback(mUpdateCallback);
     }
 }
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 1271645d..c61b4775 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -31,22 +31,14 @@
 import com.android.systemui.dreams.DreamOverlayService;
 import com.android.systemui.dreams.complication.dagger.ComplicationComponent;
 import com.android.systemui.dreams.touch.scrim.dagger.ScrimModule;
-import com.android.systemui.process.condition.SystemProcessCondition;
-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;
 
-
 /**
  * Dagger Module providing Dream-related functionality.
  */
@@ -65,11 +57,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";
     String DREAM_OVERLAY_WINDOW_TITLE = "dream_overlay_window_title";
 
-
     /**
      * Provides the dream component
      */
@@ -129,21 +118,6 @@
     }
 
     /** */
-    @Binds
-    @IntoSet
-    @Named(DREAM_PRETEXT_CONDITIONS)
-    Condition bindSystemProcessCondition(SystemProcessCondition condition);
-
-    /** */
-    @Provides
-    @Named(DREAM_PRETEXT_MONITOR)
-    static Monitor providesDockerPretextMonitor(
-            @Main Executor executor,
-            @Named(DREAM_PRETEXT_CONDITIONS) Set<Condition> pretextConditions) {
-        return new Monitor(executor, pretextConditions);
-    }
-
-    /** */
     @Provides
     @Named(DREAM_OVERLAY_WINDOW_TITLE)
     static String providesDreamOverlayWindowTitle(@Main Resources resources) {
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 05153b6..6ca409f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -61,6 +61,9 @@
     // TODO(b/254512538): Tracking Bug
     val INSTANT_VOICE_REPLY = unreleasedFlag(111, "instant_voice_reply")
 
+    // TODO(b/279735475): Tracking Bug
+    @JvmField val NEW_LIGHT_BAR_LOGIC = unreleasedFlag(279735475, "new_light_bar_logic")
+
     /**
      * This flag is server-controlled and should stay as [unreleasedFlag] since we never want to
      * enable it on release builds.
@@ -68,8 +71,6 @@
     val NOTIFICATION_MEMORY_LOGGING_ENABLED =
         unreleasedFlag(119, "notification_memory_logging_enabled")
 
-    @JvmField val USE_ROUNDNESS_SOURCETYPES = releasedFlag(116, "use_roundness_sourcetype")
-
     @JvmField
     val SIMPLIFIED_APPEAR_FRACTION =
         releasedFlag(259395680, "simplified_appear_fraction")
@@ -77,6 +78,13 @@
     // TODO(b/257315550): Tracking Bug
     val NO_HUN_FOR_OLD_WHEN = releasedFlag(118, "no_hun_for_old_when")
 
+    /** Makes sure notification panel is updated before the user switch is complete. */
+    // TODO(b/278873737): Tracking Bug
+    @JvmField
+    val LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE =
+            unreleasedFlag(278873737, "load_notifications_before_the_user_switch_is_complete",
+                    teamfood = true)
+
     // TODO(b/277338665): Tracking Bug
     @JvmField
     val NOTIFICATION_SHELF_REFACTOR =
@@ -198,11 +206,6 @@
             )
 
     /** Whether to inflate the bouncer view on a background thread. */
-    // TODO(b/272091103): Tracking Bug
-    @JvmField
-    val ASYNC_INFLATE_BOUNCER = releasedFlag(229, "async_inflate_bouncer")
-
-    /** Whether to inflate the bouncer view on a background thread. */
     // TODO(b/273341787): Tracking Bug
     @JvmField
     val PREVENT_BYPASS_KEYGUARD = releasedFlag(230, "prevent_bypass_keyguard")
@@ -217,6 +220,22 @@
     val LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP =
         unreleasedFlag(232, "lock_screen_long_press_directly_opens_wallpaper_picker")
 
+    /** Whether to run the new udfps keyguard refactor code. */
+    // TODO(b/279440316): Tracking bug.
+    @JvmField
+    val REFACTOR_UDFPS_KEYGUARD_VIEWS = unreleasedFlag(233, "refactor_udfps_keyguard_views")
+
+    /** Provide new auth messages on the bouncer. */
+    // TODO(b/277961132): Tracking bug.
+    @JvmField
+    val REVAMPED_BOUNCER_MESSAGES =
+        unreleasedFlag(234, "revamped_bouncer_messages")
+
+    /** Whether to delay showing bouncer UI when face auth or active unlock are enrolled. */
+    // TODO(b/279794160): Tracking bug.
+    @JvmField
+    val DELAY_BOUNCER = unreleasedFlag(235, "delay_bouncer")
+
     // 300 - power menu
     // TODO(b/254512600): Tracking Bug
     @JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
@@ -255,7 +274,7 @@
         )
 
     @JvmField
-    val QS_PIPELINE_NEW_HOST = unreleasedFlag(504, "qs_pipeline_new_host", teamfood = false)
+    val QS_PIPELINE_NEW_HOST = unreleasedFlag(504, "qs_pipeline_new_host", teamfood = true)
 
     // TODO(b/278068252): Tracking Bug
     @JvmField
@@ -372,7 +391,7 @@
     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")
+    val MEDIA_RETAIN_SESSIONS = unreleasedFlag(913, "media_retain_sessions")
 
     // TODO(b/266739309): Tracking Bug
     @JvmField
@@ -382,10 +401,10 @@
     val MEDIA_RESUME_PROGRESS = releasedFlag(915, "media_resume_progress")
 
     // TODO(b/267166152) : Tracking Bug
-    val MEDIA_RETAIN_RECOMMENDATIONS = releasedFlag(916, "media_retain_recommendations")
+    val MEDIA_RETAIN_RECOMMENDATIONS = unreleasedFlag(916, "media_retain_recommendations")
 
     // TODO(b/270437894): Tracking Bug
-    val MEDIA_REMOTE_RESUME = releasedFlag(917, "media_remote_resume")
+    val MEDIA_REMOTE_RESUME = unreleasedFlag(917, "media_remote_resume")
 
     // 1000 - dock
     val SIMULATE_DOCK_THROUGH_CHARGING = releasedFlag(1000, "simulate_dock_through_charging")
@@ -581,6 +600,8 @@
 
     // 1700 - clipboard
     @JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior")
+    // TODO(b/278714186) Tracking Bug
+    @JvmField val CLIPBOARD_IMAGE_TIMEOUT = unreleasedFlag(1702, "clipboard_image_timeout")
 
     // 1800 - shade container
     // TODO(b/265944639): Tracking Bug
@@ -604,12 +625,14 @@
     // TODO(b/269132640): Tracking Bug
     @JvmField
     val APP_PANELS_REMOVE_APPS_ALLOWED =
-        unreleasedFlag(2003, "app_panels_remove_apps_allowed", teamfood = true)
+        releasedFlag(2003, "app_panels_remove_apps_allowed")
 
-    // 2200 - udfps
+    // 2200 - biometrics (udfps, sfps, BiometricPrompt, etc.)
     // TODO(b/259264861): Tracking Bug
     @JvmField val UDFPS_NEW_TOUCH_DETECTION = releasedFlag(2200, "udfps_new_touch_detection")
     @JvmField val UDFPS_ELLIPSE_DETECTION = releasedFlag(2201, "udfps_ellipse_detection")
+    // TODO(b/278622168): Tracking Bug
+    @JvmField val BIOMETRIC_BP_STRONG = unreleasedFlag(2202, "biometric_bp_strong")
 
     // 2300 - stylus
     @JvmField val TRACK_STYLUS_EVER_USED = releasedFlag(2300, "track_stylus_ever_used")
@@ -673,6 +696,11 @@
 
     // TODO(b/272805037): Tracking Bug
     @JvmField
-    val ADVANCED_VPN_ENABLED = unreleasedFlag(2800, name = "AdvancedVpn__enable_feature",
-            namespace = "vpn", teamfood = true)
+    val ADVANCED_VPN_ENABLED = releasedFlag(2800, name = "AdvancedVpn__enable_feature",
+            namespace = "vpn")
+
+    // TODO(b/278761837): Tracking Bug
+    @JvmField
+    val USE_NEW_ACTIVITY_STARTER = unreleasedFlag(2801, name = "use_new_activity_starter",
+            teamfood = true)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index d3b6fc2..f64ed60 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -128,6 +128,7 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -240,6 +241,7 @@
     private final ScreenshotHelper mScreenshotHelper;
     private final SysuiColorExtractor mSysuiColorExtractor;
     private final IStatusBarService mStatusBarService;
+    protected final LightBarController mLightBarController;
     protected final NotificationShadeWindowController mNotificationShadeWindowController;
     private final IWindowManager mIWindowManager;
     private final Executor mBackgroundExecutor;
@@ -349,6 +351,7 @@
             MetricsLogger metricsLogger,
             SysuiColorExtractor colorExtractor,
             IStatusBarService statusBarService,
+            LightBarController lightBarController,
             NotificationShadeWindowController notificationShadeWindowController,
             IWindowManager iWindowManager,
             @Background Executor backgroundExecutor,
@@ -381,6 +384,7 @@
         mUiEventLogger = uiEventLogger;
         mSysuiColorExtractor = colorExtractor;
         mStatusBarService = statusBarService;
+        mLightBarController = lightBarController;
         mNotificationShadeWindowController = notificationShadeWindowController;
         mIWindowManager = iWindowManager;
         mBackgroundExecutor = backgroundExecutor;
@@ -694,6 +698,7 @@
         ActionsDialogLite dialog = new ActionsDialogLite(mContext,
                 com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActionsLite,
                 mAdapter, mOverflowAdapter, mSysuiColorExtractor, mStatusBarService,
+                mLightBarController,
                 mNotificationShadeWindowController, this::onRefresh, mKeyguardShowing,
                 mPowerAdapter, mUiEventLogger, mCentralSurfacesOptional, mKeyguardUpdateMonitor,
                 mLockPatternUtils);
@@ -2192,6 +2197,7 @@
         protected final SysuiColorExtractor mColorExtractor;
         private boolean mKeyguardShowing;
         protected float mScrimAlpha;
+        protected final LightBarController mLightBarController;
         protected final NotificationShadeWindowController mNotificationShadeWindowController;
         private ListPopupWindow mOverflowPopup;
         private Dialog mPowerOptionsDialog;
@@ -2267,6 +2273,7 @@
         ActionsDialogLite(Context context, int themeRes, MyAdapter adapter,
                 MyOverflowAdapter overflowAdapter,
                 SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService,
+                LightBarController lightBarController,
                 NotificationShadeWindowController notificationShadeWindowController,
                 Runnable onRefreshCallback, boolean keyguardShowing,
                 MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger,
@@ -2282,6 +2289,7 @@
             mPowerOptionsAdapter = powerAdapter;
             mColorExtractor = sysuiColorExtractor;
             mStatusBarService = statusBarService;
+            mLightBarController = lightBarController;
             mNotificationShadeWindowController = notificationShadeWindowController;
             mOnRefreshCallback = onRefreshCallback;
             mKeyguardShowing = keyguardShowing;
@@ -2474,6 +2482,7 @@
         @Override
         protected void start() {
             mGlobalActionsLayout.updateList();
+            mLightBarController.setGlobalActionsVisible(true);
 
             if (mBackgroundDrawable instanceof ScrimDrawable) {
                 mColorExtractor.addOnColorsChangedListener(this);
@@ -2504,6 +2513,7 @@
 
         @Override
         protected void stop() {
+            mLightBarController.setGlobalActionsVisible(false);
             mColorExtractor.removeOnColorsChangedListener(this);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
index d3fe2c5..8c0cfba 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
@@ -23,6 +23,7 @@
 import android.text.TextUtils;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.VisibleForTesting;
 
 import com.android.keyguard.logging.KeyguardLogger;
 import com.android.systemui.Dumpable;
@@ -74,7 +75,9 @@
 
     // Executor that will show the next message after a delay
     private final DelayableExecutor mExecutor;
-    @Nullable private ShowNextIndication mShowNextIndicationRunnable;
+
+    @VisibleForTesting
+    @Nullable ShowNextIndication mShowNextIndicationRunnable;
 
     // List of indication types to show. The next indication to show is always at index 0
     private final List<Integer> mIndicationQueue = new ArrayList<>();
@@ -111,6 +114,12 @@
         cancelScheduledIndication();
     }
 
+    /** Destroy ViewController, removing any listeners. */
+    public void destroy() {
+        super.destroy();
+        onViewDetached();
+    }
+
     /**
      * Update the indication type with the given String.
      * @param type of indication
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 107e685..8b6bd24 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -243,7 +243,7 @@
                         Slog.e(TAG, "Called mergeAnimation, but finish callback is missing");
                         return;
                     }
-                    runner.onAnimationCancelled(false /* isKeyguardOccluded */);
+                    runner.onAnimationCancelled();
                     currentFinishCB.onTransitionFinished(null /* wct */, null /* t */);
                 } catch (RemoteException e) {
                     // nothing, we'll just let it finish on its own I guess.
@@ -418,7 +418,7 @@
         }
 
         @Override // Binder interface
-        public void onAnimationCancelled(boolean isKeyguardOccluded) {
+        public void onAnimationCancelled() {
             mKeyguardViewMediator.cancelKeyguardExitAnimation();
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 2d1b7ae..2925d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -792,7 +792,8 @@
             // Translate up from the bottom.
             surfaceBehindMatrix.setTranslate(
                     surfaceBehindRemoteAnimationTarget.localBounds.left.toFloat(),
-                    surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
+                    surfaceBehindRemoteAnimationTarget.localBounds.top.toFloat() +
+                            surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
             )
 
             // Scale up from a point at the center-bottom of the surface.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 7a2013e..1a126d7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -959,20 +959,15 @@
                 @Nullable private ValueAnimator mOccludeByDreamAnimator;
 
                 @Override
-                public void onAnimationCancelled(boolean isKeyguardOccluded) {
+                public void onAnimationCancelled() {
                     mContext.getMainExecutor().execute(() -> {
                         if (mOccludeByDreamAnimator != null) {
                             mOccludeByDreamAnimator.cancel();
                         }
                     });
-                    // The value of isKeyguardOccluded here may come from mergeAnimation, which
-                    // isn't reliable. In all cases, after running or cancelling this animation,
-                    // keyguard should be occluded.
+
+                    Log.d(TAG, "OccludeByDreamAnimator#onAnimationCancelled. Set occluded = true");
                     setOccluded(true /* isOccluded */, false /* animate */);
-                    if (DEBUG) {
-                        Log.d(TAG, "Occlude by Dream animation cancelled. Occluded state is now: "
-                                + mOccluded);
-                    }
                 }
 
                 @Override
@@ -984,6 +979,7 @@
                         // Usually we rely on animation completion to synchronize occluded status,
                         // but there was no animation to play, so just update it now.
                         setOccluded(true /* isOccluded */, false /* animate */);
+                        finishedCallback.onAnimationFinished();
                     }
                 }
 
@@ -991,11 +987,8 @@
                         RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
                         IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
                     if (apps == null || apps.length == 0 || apps[0] == null) {
-                        if (DEBUG) {
-                            Log.d(TAG, "No apps provided to the OccludeByDream runner; "
-                                    + "skipping occluding animation.");
-                        }
-                        finishedCallback.onAnimationFinished();
+                        Log.d(TAG, "No apps provided to the OccludeByDream runner; "
+                                + "skipping occluding animation.");
                         return false;
                     }
 
@@ -1005,7 +998,6 @@
                     if (!isDream) {
                         Log.w(TAG, "The occluding app isn't Dream; "
                                 + "finishing up. Please check that the config is correct.");
-                        finishedCallback.onAnimationFinished();
                         return false;
                     }
 
@@ -1071,17 +1063,14 @@
                 private final Matrix mUnoccludeMatrix = new Matrix();
 
                 @Override
-                public void onAnimationCancelled(boolean isKeyguardOccluded) {
+                public void onAnimationCancelled() {
                     mContext.getMainExecutor().execute(() -> {
                         if (mUnoccludeAnimator != null) {
                             mUnoccludeAnimator.cancel();
                         }
                     });
 
-                    setOccluded(isKeyguardOccluded /* isOccluded */, false /* animate */);
-                    Log.d(TAG, "Unocclude animation cancelled. Occluded state is now: "
-                            + mOccluded);
-
+                    Log.d(TAG, "Unocclude animation cancelled.");
                     mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_OCCLUSION);
                 }
 
@@ -1610,8 +1599,9 @@
     }
 
     private void doKeyguardLaterForChildProfilesLocked() {
-        UserManager um = UserManager.get(mContext);
-        for (int profileId : um.getEnabledProfileIds(UserHandle.myUserId())) {
+        for (UserInfo profile : mUserTracker.getUserProfiles()) {
+            if (!profile.isEnabled()) continue;
+            final int profileId = profile.id;
             if (mLockPatternUtils.isSeparateProfileChallengeEnabled(profileId)) {
                 long userTimeout = getLockTimeout(profileId);
                 if (userTimeout == 0) {
@@ -1634,8 +1624,9 @@
     }
 
     private void doKeyguardForChildProfilesLocked() {
-        UserManager um = UserManager.get(mContext);
-        for (int profileId : um.getEnabledProfileIds(UserHandle.myUserId())) {
+        for (UserInfo profile : mUserTracker.getUserProfiles()) {
+            if (!profile.isEnabled()) continue;
+            final int profileId = profile.id;
             if (mLockPatternUtils.isSeparateProfileChallengeEnabled(profileId)) {
                 lockProfile(profileId);
             }
@@ -3402,9 +3393,9 @@
         }
 
         @Override
-        public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException {
+        public void onAnimationCancelled() throws RemoteException {
             if (mRunner != null) {
-                mRunner.onAnimationCancelled(isKeyguardOccluded);
+                mRunner.onAnimationCancelled();
             }
         }
 
@@ -3450,13 +3441,9 @@
         }
 
         @Override
-        public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException {
-            super.onAnimationCancelled(isKeyguardOccluded);
-
-            Log.d(TAG, "Occlude animation cancelled by WM. "
-                    + "Setting occluded state to: " + isKeyguardOccluded);
-            setOccluded(isKeyguardOccluded /* occluded */, false /* animate */);
-
+        public void onAnimationCancelled() throws RemoteException {
+            super.onAnimationCancelled();
+            Log.d(TAG, "Occlude animation cancelled by WM.");
             mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_OCCLUSION);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
index b92499e..b7ba201 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
@@ -56,11 +56,11 @@
         tscl.registerTaskStackListener(mLockListener);
     }
 
-    private void startWorkChallengeInTask(ActivityManager.RunningTaskInfo info) {
+    private void startWorkChallengeInTask(ActivityManager.RunningTaskInfo info, int userId) {
         String packageName = info.baseActivity != null ? info.baseActivity.getPackageName() : "";
         Intent intent = new Intent(KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER)
                 .setComponent(new ComponentName(mContext, WorkLockActivity.class))
-                .putExtra(Intent.EXTRA_USER_ID, info.userId)
+                .putExtra(Intent.EXTRA_USER_ID, userId)
                 .putExtra(Intent.EXTRA_PACKAGE_NAME, packageName)
                 .addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -76,10 +76,11 @@
         } else {
             // Starting the activity inside the task failed. We can't be sure why, so to be
             // safe just remove the whole task if it still exists.
+            Log.w(TAG, "Failed to start work lock activity, will remove task=" + info.taskId);
             try {
                 mIatm.removeTask(info.taskId);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed to get description for task=" + info.taskId);
+                Log.e(TAG, "Failed to remove task=" + info.taskId);
             }
         }
     }
@@ -112,8 +113,8 @@
 
     private final TaskStackChangeListener mLockListener = new TaskStackChangeListener() {
         @Override
-        public void onTaskProfileLocked(ActivityManager.RunningTaskInfo info) {
-            startWorkChallengeInTask(info);
+        public void onTaskProfileLocked(ActivityManager.RunningTaskInfo info, int userId) {
+            startWorkChallengeInTask(info, userId);
         }
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
index 5f2178df..5b71a2e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -32,6 +32,8 @@
 import com.android.systemui.dagger.qualifiers.Application
 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.keyguard.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -42,6 +44,7 @@
 import com.android.systemui.keyguard.shared.model.FailedAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.HelpAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.SuccessAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.WakefulnessModel
 import com.android.systemui.log.FaceAuthenticationLogger
 import com.android.systemui.log.SessionTracker
@@ -63,6 +66,7 @@
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.launchIn
@@ -135,6 +139,7 @@
     @FaceDetectTableLog private val faceDetectLog: TableLogBuffer,
     @FaceAuthTableLog private val faceAuthLog: TableLogBuffer,
     private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+    private val featureFlags: FeatureFlags,
     dumpManager: DumpManager,
 ) : DeviceEntryFaceAuthRepository, Dumpable {
     private var authCancellationSignal: CancellationSignal? = null
@@ -212,15 +217,21 @@
                 .collect(Collectors.toSet())
         dumpManager.registerCriticalDumpable("DeviceEntryFaceAuthRepositoryImpl", this)
 
-        observeFaceAuthGatingChecks()
-        observeFaceDetectGatingChecks()
-        observeFaceAuthResettingConditions()
-        listenForSchedulingWatchdog()
+        if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) {
+            observeFaceAuthGatingChecks()
+            observeFaceDetectGatingChecks()
+            observeFaceAuthResettingConditions()
+            listenForSchedulingWatchdog()
+        }
     }
 
     private fun listenForSchedulingWatchdog() {
         keyguardTransitionInteractor.anyStateToGoneTransition
-            .onEach { faceManager?.scheduleWatchdog() }
+            .filter { it.transitionState == TransitionState.FINISHED }
+            .onEach {
+                faceAuthLogger.watchdogScheduled()
+                faceManager?.scheduleWatchdog()
+            }
             .launchIn(applicationScope)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
index 9b94cdb..148d425 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
@@ -41,17 +41,6 @@
     var receivedDownTouch = false
     val isVisible: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
 
-    private val keyguardStateControllerCallback: KeyguardStateController.Callback =
-        object : KeyguardStateController.Callback {
-            override fun onUnlockedChanged() {
-                maybeHide()
-            }
-        }
-
-    init {
-        keyguardStateController.addCallback(keyguardStateControllerCallback)
-    }
-
     /**
      * Sets the correct bouncer states to show the alternate bouncer if it can show.
      *
@@ -102,11 +91,18 @@
         return (systemClock.uptimeMillis() - bouncerRepository.lastAlternateBouncerVisibleTime) >
             MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS
     }
-
-    private fun maybeHide() {
+    /**
+     * Should only be called through StatusBarKeyguardViewManager which propagates the source of
+     * truth to other concerned controllers. Will hide the alternate bouncer if it's no longer
+     * allowed to show.
+     *
+     * @return true if the alternate bouncer was newly hidden, else false.
+     */
+    fun maybeHide(): Boolean {
         if (isVisibleState() && !canShowAlternateBouncerForFingerprint()) {
-            hide()
+            return hide()
         }
+        return false
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
new file mode 100644
index 0000000..252982f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.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.systemui.keyguard.domain.interactor
+
+import android.content.Context
+import androidx.annotation.DimenRes
+import com.android.systemui.R
+import com.android.systemui.common.ui.data.repository.ConfigurationRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.doze.util.BurnInHelperWrapper
+import com.android.systemui.util.time.SystemClock
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.stateIn
+
+/** Encapsulates business-logic related to Ambient Display burn-in offsets. */
+@ExperimentalCoroutinesApi
+@SysUISingleton
+class BurnInInteractor
+@Inject
+constructor(
+    private val context: Context,
+    private val burnInHelperWrapper: BurnInHelperWrapper,
+    @Application private val scope: CoroutineScope,
+    private val configurationRepository: ConfigurationRepository,
+    private val systemClock: SystemClock,
+) {
+    private val _dozeTimeTick = MutableStateFlow<Long>(0)
+    val dozeTimeTick: StateFlow<Long> = _dozeTimeTick.asStateFlow()
+
+    val udfpsBurnInXOffset: StateFlow<Int> =
+        burnInOffsetDefinedInPixels(R.dimen.udfps_burn_in_offset_x, isXAxis = true)
+    val udfpsBurnInYOffset: StateFlow<Int> =
+        burnInOffsetDefinedInPixels(R.dimen.udfps_burn_in_offset_y, isXAxis = false)
+    val udfpsBurnInProgress: StateFlow<Float> =
+        dozeTimeTick
+            .mapLatest { burnInHelperWrapper.burnInProgressOffset() }
+            .stateIn(scope, SharingStarted.Lazily, burnInHelperWrapper.burnInProgressOffset())
+
+    fun dozeTimeTick() {
+        _dozeTimeTick.value = systemClock.uptimeMillis()
+    }
+
+    /**
+     * Use for max burn-in offsets that are NOT specified in pixels. This flow will recalculate the
+     * max burn-in offset on any configuration changes. If the max burn-in offset is specified in
+     * pixels, use [burnInOffsetDefinedInPixels].
+     */
+    private fun burnInOffset(
+        @DimenRes maxBurnInOffsetResourceId: Int,
+        isXAxis: Boolean,
+    ): StateFlow<Int> {
+        return configurationRepository.onAnyConfigurationChange
+            .flatMapLatest {
+                val maxBurnInOffsetPixels =
+                    context.resources.getDimensionPixelSize(maxBurnInOffsetResourceId)
+                dozeTimeTick.mapLatest { calculateOffset(maxBurnInOffsetPixels, isXAxis) }
+            }
+            .stateIn(
+                scope,
+                SharingStarted.Lazily,
+                calculateOffset(
+                    context.resources.getDimensionPixelSize(maxBurnInOffsetResourceId),
+                    isXAxis,
+                )
+            )
+    }
+
+    /**
+     * Use for max burn-in offBurn-in offsets that ARE specified in pixels. This flow will apply the
+     * a scale for any resolution changes. If the max burn-in offset is specified in dp, use
+     * [burnInOffset].
+     */
+    private fun burnInOffsetDefinedInPixels(
+        @DimenRes maxBurnInOffsetResourceId: Int,
+        isXAxis: Boolean,
+    ): StateFlow<Int> {
+        return configurationRepository.scaleForResolution
+            .flatMapLatest { scale ->
+                val maxBurnInOffsetPixels =
+                    context.resources.getDimensionPixelSize(maxBurnInOffsetResourceId)
+                dozeTimeTick.mapLatest { calculateOffset(maxBurnInOffsetPixels, isXAxis, scale) }
+            }
+            .stateIn(
+                scope,
+                SharingStarted.WhileSubscribed(),
+                calculateOffset(
+                    context.resources.getDimensionPixelSize(maxBurnInOffsetResourceId),
+                    isXAxis,
+                    configurationRepository.getResolutionScale(),
+                )
+            )
+    }
+
+    private fun calculateOffset(
+        maxBurnInOffsetPixels: Int,
+        isXAxis: Boolean,
+        scale: Float = 1f
+    ): Int {
+        return (burnInHelperWrapper.burnInOffset(maxBurnInOffsetPixels, isXAxis) * scale).toInt()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index 1fbfff9..c0d5abc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -48,6 +48,7 @@
         listenForOccludedToDreaming()
         listenForOccludedToAodOrDozing()
         listenForOccludedToGone()
+        listenForOccludedToAlternateBouncer()
     }
 
     private fun listenForOccludedToDreaming() {
@@ -167,6 +168,28 @@
         }
     }
 
+    private fun listenForOccludedToAlternateBouncer() {
+        scope.launch {
+            keyguardInteractor.alternateBouncerShowing
+                .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
+                .collect { (isAlternateBouncerShowing, lastStartedTransitionStep) ->
+                    if (
+                        isAlternateBouncerShowing &&
+                            lastStartedTransitionStep.to == KeyguardState.OCCLUDED
+                    ) {
+                        keyguardTransitionRepository.startTransition(
+                            TransitionInfo(
+                                ownerName = name,
+                                from = KeyguardState.OCCLUDED,
+                                to = KeyguardState.ALTERNATE_BOUNCER,
+                                animator = getAnimator(),
+                            )
+                        )
+                    }
+                }
+        }
+    }
+
     private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
         return ValueAnimator().apply {
             setInterpolator(Interpolators.LINEAR)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
index 94961cb..a681c43 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
@@ -48,10 +48,51 @@
 
     override fun start() {
         listenForPrimaryBouncerToGone()
-        listenForPrimaryBouncerToLockscreenAodOrDozing()
+        listenForPrimaryBouncerToAodOrDozing()
+        listenForPrimaryBouncerToLockscreenOrOccluded()
     }
 
-    private fun listenForPrimaryBouncerToLockscreenAodOrDozing() {
+    private fun listenForPrimaryBouncerToLockscreenOrOccluded() {
+        scope.launch {
+            keyguardInteractor.primaryBouncerShowing
+                .sample(
+                    combine(
+                        keyguardInteractor.wakefulnessModel,
+                        keyguardTransitionInteractor.startedKeyguardTransitionStep,
+                        keyguardInteractor.isKeyguardOccluded,
+                        ::toTriple
+                    ),
+                    ::toQuad
+                )
+                .collect { (isBouncerShowing, wakefulnessState, lastStartedTransitionStep, occluded)
+                    ->
+                    if (
+                        !isBouncerShowing &&
+                            lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER &&
+                            (wakefulnessState.state == WakefulnessState.AWAKE ||
+                                wakefulnessState.state == WakefulnessState.STARTING_TO_WAKE)
+                    ) {
+                        val to =
+                            if (occluded) {
+                                KeyguardState.OCCLUDED
+                            } else {
+                                KeyguardState.LOCKSCREEN
+                            }
+
+                        keyguardTransitionRepository.startTransition(
+                            TransitionInfo(
+                                ownerName = name,
+                                from = KeyguardState.PRIMARY_BOUNCER,
+                                to = to,
+                                animator = getAnimator(),
+                            )
+                        )
+                    }
+                }
+        }
+    }
+
+    private fun listenForPrimaryBouncerToAodOrDozing() {
         scope.launch {
             keyguardInteractor.primaryBouncerShowing
                 .sample(
@@ -68,21 +109,17 @@
                     ->
                     if (
                         !isBouncerShowing &&
-                            lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER
+                            lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER &&
+                            (wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP ||
+                                wakefulnessState.state == WakefulnessState.ASLEEP)
                     ) {
                         val to =
-                            if (
-                                wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP ||
-                                    wakefulnessState.state == WakefulnessState.ASLEEP
-                            ) {
-                                if (isAodAvailable) {
-                                    KeyguardState.AOD
-                                } else {
-                                    KeyguardState.DOZING
-                                }
+                            if (isAodAvailable) {
+                                KeyguardState.AOD
                             } else {
-                                KeyguardState.LOCKSCREEN
+                                KeyguardState.DOZING
                             }
+
                         keyguardTransitionRepository.startTransition(
                             TransitionInfo(
                                 ownerName = name,
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 3b3ec39..c45faf0 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
@@ -32,4 +32,15 @@
      * PIN hinting is enabled
      */
     const val DEFAULT_PIN_LENGTH = 6
+
+    object ColorId {
+        const val TITLE = com.android.internal.R.attr.materialColorOnSurface
+        const val PIN_SHAPES = com.android.internal.R.attr.materialColorOnSurfaceVariant
+        const val NUM_PAD_BACKGROUND = com.android.internal.R.attr.materialColorSurfaceContainerHigh
+        const val NUM_PAD_BACKGROUND_PRESSED = com.android.internal.R.attr.materialColorPrimaryFixed
+        const val NUM_PAD_PRESSED = com.android.internal.R.attr.materialColorOnPrimaryFixed
+        const val NUM_PAD_KEY = com.android.internal.R.attr.materialColorOnSurface
+        const val NUM_PAD_BUTTON = com.android.internal.R.attr.materialColorOnSecondaryFixed
+        const val EMERGENCY_BUTTON = com.android.internal.R.attr.materialColorTertiaryFixed
+    }
 }
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 6bbc6f6..c1aefc7 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
@@ -112,8 +112,6 @@
                         viewModel.isShowing.collect { isShowing ->
                             view.visibility = if (isShowing) View.VISIBLE else View.INVISIBLE
                             if (isShowing) {
-                                // Reset Security Container entirely.
-                                view.visibility = View.VISIBLE
                                 securityContainerController.reinflateViewFlipper {
                                     // Reset Security Container entirely.
                                     securityContainerController.onBouncerVisibilityChanged(
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 9aecb5d..951f0bd 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
@@ -21,6 +21,7 @@
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
+import android.graphics.Rect
 import android.hardware.display.DisplayManager
 import android.os.Bundle
 import android.os.IBinder
@@ -33,13 +34,15 @@
 import com.android.keyguard.ClockEventController
 import com.android.keyguard.KeyguardClockSwitch
 import com.android.systemui.R
+import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.ui.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.shared.quickaffordance.shared.model.KeyguardPreviewConstants
+import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
 import com.android.systemui.statusbar.phone.KeyguardBottomAreaView
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedInject
@@ -59,6 +62,8 @@
     private val clockController: ClockEventController,
     private val clockRegistry: ClockRegistry,
     private val broadcastDispatcher: BroadcastDispatcher,
+    private val lockscreenSmartspaceController: LockscreenSmartspaceController,
+    private val udfpsOverlayInteractor: UdfpsOverlayInteractor,
     @Assisted bundle: Bundle,
 ) {
 
@@ -67,7 +72,7 @@
     private val height: Int = bundle.getInt(KEY_VIEW_HEIGHT)
     private val shouldHighlightSelectedAffordance: Boolean =
         bundle.getBoolean(
-            KeyguardQuickAffordancePreviewConstants.KEY_HIGHLIGHT_QUICK_AFFORDANCES,
+            KeyguardPreviewConstants.KEY_HIGHLIGHT_QUICK_AFFORDANCES,
             false,
         )
     private val shouldHideClock: Boolean =
@@ -79,6 +84,7 @@
         get() = host.surfacePackage
 
     private var clockView: View? = null
+    private var smartSpaceView: View? = null
 
     private val disposables = mutableSetOf<DisposableHandle>()
     private var isDestroyed = false
@@ -87,7 +93,7 @@
         bottomAreaViewModel.enablePreviewMode(
             initiallySelectedSlotId =
                 bundle.getString(
-                    KeyguardQuickAffordancePreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID,
+                    KeyguardPreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID,
                 ),
             shouldHighlightSelectedAffordance = shouldHighlightSelectedAffordance,
         )
@@ -108,9 +114,12 @@
             val rootView = FrameLayout(context)
 
             setUpBottomArea(rootView)
-            if (!shouldHideClock) {
-                setUpClock(rootView)
-            }
+
+            setUpSmartspace(rootView)
+
+            setUpUdfps(rootView)
+
+            setUpClock(rootView)
 
             rootView.measure(
                 View.MeasureSpec.makeMeasureSpec(
@@ -147,9 +156,73 @@
 
     fun destroy() {
         isDestroyed = true
+        lockscreenSmartspaceController.disconnect()
         disposables.forEach { it.dispose() }
     }
 
+    /**
+     * Hides or shows smartspace
+     *
+     * @param hide TRUE hides smartspace, FALSE shows smartspace
+     */
+    fun hideSmartspace(hide: Boolean) {
+        runBlocking(mainDispatcher) {
+            smartSpaceView?.visibility = if (hide) View.INVISIBLE else View.VISIBLE
+        }
+    }
+
+    /**
+     * This sets up and shows a non-interactive smart space
+     *
+     * The top padding is as follows: Status bar height + clock top margin + keyguard smart space
+     * top offset
+     *
+     * The start padding is as follows: Clock padding start + Below clock padding start
+     *
+     * The end padding is as follows: Below clock padding end
+     */
+    private fun setUpSmartspace(parentView: ViewGroup) {
+        if (
+            !lockscreenSmartspaceController.isEnabled() ||
+                !lockscreenSmartspaceController.isDateWeatherDecoupled()
+        ) {
+            return
+        }
+
+        smartSpaceView = lockscreenSmartspaceController.buildAndConnectDateView(parentView)
+
+        val topPadding: Int =
+            with(context.resources) {
+                getDimensionPixelSize(R.dimen.status_bar_header_height_keyguard) +
+                    getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset) +
+                    getDimensionPixelSize(R.dimen.keyguard_clock_top_margin)
+            }
+
+        val startPadding: Int =
+            with(context.resources) {
+                getDimensionPixelSize(R.dimen.clock_padding_start) +
+                    getDimensionPixelSize(R.dimen.below_clock_padding_start)
+            }
+
+        val endPadding: Int =
+            context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end)
+
+        smartSpaceView?.let {
+            it.setPaddingRelative(startPadding, topPadding, endPadding, 0)
+            it.isClickable = false
+
+            parentView.addView(
+                it,
+                FrameLayout.LayoutParams(
+                    FrameLayout.LayoutParams.MATCH_PARENT,
+                    FrameLayout.LayoutParams.WRAP_CONTENT,
+                ),
+            )
+        }
+
+        smartSpaceView?.alpha = if (shouldHighlightSelectedAffordance) DIM_ALPHA else 1.0f
+    }
+
     private fun setUpBottomArea(parentView: ViewGroup) {
         val bottomAreaView =
             LayoutInflater.from(context)
@@ -170,6 +243,33 @@
         )
     }
 
+    private fun setUpUdfps(parentView: ViewGroup) {
+        val sensorBounds = udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds
+
+        // If sensorBounds are default rect, then there is no UDFPS
+        if (sensorBounds == Rect()) {
+            return
+        }
+
+        // Place the UDFPS view in the proper sensor location
+        val fingerprintLayoutParams =
+            FrameLayout.LayoutParams(sensorBounds.width(), sensorBounds.height())
+        fingerprintLayoutParams.setMarginsRelative(
+            sensorBounds.left,
+            sensorBounds.top,
+            sensorBounds.right,
+            sensorBounds.bottom
+        )
+        val finger =
+            LayoutInflater.from(context)
+                .inflate(
+                    R.layout.udfps_keyguard_view_internal,
+                    parentView,
+                    false,
+                ) as View
+        parentView.addView(finger, fingerprintLayoutParams)
+    }
+
     private fun setUpClock(parentView: ViewGroup) {
         val clockChangeListener =
             object : ClockRegistry.ClockChangeListener {
@@ -206,18 +306,31 @@
 
     private fun onClockChanged(parentView: ViewGroup) {
         clockController.clock = clockRegistry.createCurrentClock()
-        clockController.clock
-            ?.largeClock
-            ?.events
-            ?.onTargetRegionChanged(KeyguardClockSwitch.getLargeClockRegion(parentView))
-        clockView?.let { parentView.removeView(it) }
-        clockView =
-            clockController.clock?.largeClock?.view?.apply {
-                if (shouldHighlightSelectedAffordance) {
-                    alpha = DIM_ALPHA
+
+        if (!shouldHideClock) {
+            val largeClock = clockController.clock?.largeClock
+
+            largeClock
+                ?.events
+                ?.onTargetRegionChanged(KeyguardClockSwitch.getLargeClockRegion(parentView))
+
+            clockView?.let { parentView.removeView(it) }
+            clockView =
+                largeClock?.view?.apply {
+                    if (shouldHighlightSelectedAffordance) {
+                        alpha = DIM_ALPHA
+                    }
+                    parentView.addView(this)
+                    visibility = View.VISIBLE
                 }
-                parentView.addView(this)
-            }
+        } else {
+            clockView?.visibility = View.GONE
+        }
+
+        // Hide smart space if the clock has weather display; otherwise show it
+        val hasCustomWeatherDataDisplay =
+            clockController.clock?.largeClock?.config?.hasCustomWeatherDataDisplay == true
+        hideSmartspace(hasCustomWeatherDataDisplay)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
index 6d95882..3869b23 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
@@ -29,7 +29,7 @@
 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.shared.quickaffordance.shared.model.KeyguardQuickAffordancePreviewConstants
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
@@ -114,13 +114,18 @@
             }
 
             when (message.what) {
-                KeyguardQuickAffordancePreviewConstants.MESSAGE_ID_SLOT_SELECTED -> {
+                KeyguardPreviewConstants.MESSAGE_ID_SLOT_SELECTED -> {
                     message.data
                         .getString(
-                            KeyguardQuickAffordancePreviewConstants.KEY_SLOT_ID,
+                            KeyguardPreviewConstants.KEY_SLOT_ID,
                         )
                         ?.let { slotId -> renderer.onSlotSelected(slotId = slotId) }
                 }
+                KeyguardPreviewConstants.MESSAGE_ID_HIDE_SMART_SPACE -> {
+                    message.data
+                        .getBoolean(KeyguardPreviewConstants.KEY_HIDE_SMART_SPACE)
+                        .let { hide -> renderer.hideSmartspace(hide) }
+                }
                 else -> requestDestruction(this)
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
index efd3ad6..8e93281 100644
--- a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
@@ -261,4 +261,8 @@
             { "Attempting face auth again because of HW error: retry attempt $int1" }
         )
     }
+
+    fun watchdogScheduled() {
+        logBuffer.log(TAG, DEBUG, "FaceManager Biometric watchdog scheduled.")
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt b/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt
index edc278d..4300f37 100644
--- a/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.plugins.log.LogBuffer
 import com.android.systemui.plugins.log.LogLevel.DEBUG
 import com.android.systemui.plugins.log.LogLevel.ERROR
+import com.google.errorprone.annotations.CompileTimeConstant
 import javax.inject.Inject
 
 private const val TAG = "ScreenDecorationsLog"
@@ -131,4 +132,36 @@
     fun onSensorLocationChanged() {
         logBuffer.log(TAG, DEBUG, "AuthControllerCallback in ScreenDecorations triggered")
     }
+
+    fun cameraProtectionShownOrHidden(
+        faceDetectionRunning: Boolean,
+        biometricPromptShown: Boolean,
+        requestedState: Boolean,
+        currentlyShowing: Boolean
+    ) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            {
+                bool1 = faceDetectionRunning
+                bool2 = biometricPromptShown
+                bool3 = requestedState
+                bool4 = currentlyShowing
+            },
+            {
+                "isFaceDetectionRunning: $bool1, " +
+                    "isBiometricPromptShowing: $bool2, " +
+                    "requestedState: $bool3, " +
+                    "currentState: $bool4"
+            }
+        )
+    }
+
+    fun biometricEvent(@CompileTimeConstant info: String) {
+        logBuffer.log(TAG, DEBUG, info)
+    }
+
+    fun cameraProtectionEvent(@CompileTimeConstant cameraProtectionEvent: String) {
+        logBuffer.log(TAG, DEBUG, cameraProtectionEvent)
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/DreamLog.kt
similarity index 62%
copy from packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
copy to packages/SystemUI/src/com/android/systemui/log/dagger/DreamLog.kt
index 7ded90f..cb9913ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesStartableModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/DreamLog.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,15 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.phone.dagger;
+package com.android.systemui.log.dagger
 
-import dagger.Module;
-import dagger.multibindings.Multibinds;
+import javax.inject.Qualifier
 
-import java.util.Set;
-
-@Module
-interface CentralSurfacesStartableModule {
-    @Multibinds
-    Set<CentralSurfacesComponent.Startable> multibindStartables();
-}
+/** A [com.android.systemui.log.LogBuffer] for dream-related logging. */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class DreamLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 077ee02..658f6a0 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -440,4 +440,14 @@
     public static LogBuffer provideKeyguardLogBuffer(LogBufferFactory factory) {
         return factory.create("KeyguardLog", 250);
     }
+
+    /**
+     * Provides a {@link LogBuffer} for dream-related logs.
+     */
+    @Provides
+    @SysUISingleton
+    @DreamLog
+    public static LogBuffer provideDreamLogBuffer(LogBufferFactory factory) {
+        return factory.create("DreamLog", 250);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/LogProxy.kt b/packages/SystemUI/src/com/android/systemui/log/table/LogProxy.kt
new file mode 100644
index 0000000..53886aa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/table/LogProxy.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.table
+
+import android.util.Log
+import javax.inject.Inject
+
+/** Dagger-friendly interface so we can inject a fake [android.util.Log] in tests */
+interface LogProxy {
+    /** verbose log */
+    fun v(tag: String, message: String)
+
+    /** debug log */
+    fun d(tag: String, message: String)
+
+    /** info log */
+    fun i(tag: String, message: String)
+
+    /** warning log */
+    fun w(tag: String, message: String)
+
+    /** error log */
+    fun e(tag: String, message: String)
+
+    /** wtf log */
+    fun wtf(tag: String, message: String)
+}
+
+class LogProxyDefault @Inject constructor() : LogProxy {
+    override fun v(tag: String, message: String) {
+        Log.v(tag, message)
+    }
+
+    override fun d(tag: String, message: String) {
+        Log.d(tag, message)
+    }
+
+    override fun i(tag: String, message: String) {
+        Log.i(tag, message)
+    }
+
+    override fun w(tag: String, message: String) {
+        Log.w(tag, message)
+    }
+
+    override fun e(tag: String, message: String) {
+        Log.e(tag, message)
+    }
+
+    override fun wtf(tag: String, message: String) {
+        Log.wtf(tag, message)
+    }
+}
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 42fdd68..592044e 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt
@@ -27,19 +27,27 @@
  */
 data class TableChange(
     var timestamp: Long = 0,
-    var columnPrefix: String = "",
-    var columnName: String = "",
-    var isInitial: Boolean = false,
-    var type: DataType = DataType.EMPTY,
-    var bool: Boolean = false,
-    var int: Int? = null,
-    var str: String? = null,
+    private var columnPrefix: String = "",
+    private var columnName: String = "",
+    private var isInitial: Boolean = false,
+    private var type: DataType = DataType.EMPTY,
+    private var bool: Boolean = false,
+    private var int: Int? = null,
+    private var str: String? = null,
 ) {
+    init {
+        // Truncate any strings that were passed into the constructor. [reset] and [set] will take
+        // care of the rest of the truncation.
+        this.columnPrefix = columnPrefix.take(MAX_STRING_LENGTH)
+        this.columnName = columnName.take(MAX_STRING_LENGTH)
+        this.str = str?.take(MAX_STRING_LENGTH)
+    }
+
     /** Resets to default values so that the object can be recycled. */
     fun reset(timestamp: Long, columnPrefix: String, columnName: String, isInitial: Boolean) {
         this.timestamp = timestamp
-        this.columnPrefix = columnPrefix
-        this.columnName = columnName
+        this.columnPrefix = columnPrefix.take(MAX_STRING_LENGTH)
+        this.columnName = columnName.take(MAX_STRING_LENGTH)
         this.isInitial = isInitial
         this.type = DataType.EMPTY
         this.bool = false
@@ -50,7 +58,7 @@
     /** Sets this to store a string change. */
     fun set(value: String?) {
         type = DataType.STRING
-        str = value
+        str = value?.take(MAX_STRING_LENGTH)
     }
 
     /** Sets this to store a boolean change. */
@@ -89,6 +97,8 @@
         }
     }
 
+    fun getColumnName() = columnName
+
     fun getVal(): String {
         val value =
             when (type) {
@@ -109,5 +119,8 @@
 
     companion object {
         @VisibleForTesting const val IS_INITIAL_PREFIX = "**"
+        // Don't allow any strings larger than this length so that we have a hard upper limit on the
+        // size of the data stored by the buffer.
+        @VisibleForTesting const val MAX_STRING_LENGTH = 500
     }
 }
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 faaa205..8babfc9 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
@@ -19,10 +19,17 @@
 import android.os.Trace
 import com.android.systemui.Dumpable
 import com.android.systemui.common.buffer.RingBuffer
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.plugins.log.LogcatEchoTracker
 import com.android.systemui.util.time.SystemClock
 import java.io.PrintWriter
 import java.text.SimpleDateFormat
 import java.util.Locale
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.launch
 
 /**
  * A logger that logs changes in table format.
@@ -73,12 +80,18 @@
     maxSize: Int,
     private val name: String,
     private val systemClock: SystemClock,
+    private val logcatEchoTracker: LogcatEchoTracker,
+    @Background private val bgDispatcher: CoroutineDispatcher,
+    private val coroutineScope: CoroutineScope,
+    private val localLogcat: LogProxy = LogProxyDefault(),
 ) : Dumpable {
     init {
         if (maxSize <= 0) {
             throw IllegalArgumentException("maxSize must be > 0")
         }
     }
+    // For local logcat, send messages across this channel so the background job can process them
+    private val logMessageChannel = Channel<TableChange>(capacity = 10)
 
     private val buffer = RingBuffer(maxSize) { TableChange() }
 
@@ -105,6 +118,16 @@
             tableLogBuffer = this,
         )
 
+    /** Start this log buffer logging in the background */
+    internal fun init() {
+        coroutineScope.launch(bgDispatcher) {
+            while (!logMessageChannel.isClosedForReceive) {
+                val log = logMessageChannel.receive()
+                echoToDesiredEndpoints(log)
+            }
+        }
+    }
+
     /**
      * Log the differences between [prevVal] and [newVal].
      *
@@ -189,6 +212,7 @@
         Trace.beginSection("TableLogBuffer#logChange(string)")
         val change = obtain(timestamp, prefix, columnName, isInitial)
         change.set(value)
+        tryAddMessage(change)
         Trace.endSection()
     }
 
@@ -202,6 +226,7 @@
         Trace.beginSection("TableLogBuffer#logChange(boolean)")
         val change = obtain(timestamp, prefix, columnName, isInitial)
         change.set(value)
+        tryAddMessage(change)
         Trace.endSection()
     }
 
@@ -215,9 +240,14 @@
         Trace.beginSection("TableLogBuffer#logChange(int)")
         val change = obtain(timestamp, prefix, columnName, isInitial)
         change.set(value)
+        tryAddMessage(change)
         Trace.endSection()
     }
 
+    private fun tryAddMessage(change: TableChange) {
+        logMessageChannel.trySend(change)
+    }
+
     // TODO(b/259454430): Add additional change types here.
 
     @Synchronized
@@ -258,6 +288,17 @@
         Trace.endSection()
     }
 
+    private fun echoToDesiredEndpoints(change: TableChange) {
+        if (
+            logcatEchoTracker.isBufferLoggable(bufferName = name, LogLevel.DEBUG) ||
+                logcatEchoTracker.isTagLoggable(change.getColumnName(), LogLevel.DEBUG)
+        ) {
+            if (change.hasData()) {
+                localLogcat.d(name, change.logcatRepresentation())
+            }
+        }
+    }
+
     @Synchronized
     override fun dump(pw: PrintWriter, args: Array<out String>) {
         pw.println(HEADER_PREFIX + name)
@@ -284,6 +325,12 @@
         pw.println()
     }
 
+    /** Transforms an individual [TableChange] into a String for logcat */
+    private fun TableChange.logcatRepresentation(): String {
+        val formattedTimestamp = TABLE_LOG_DATE_FORMAT.format(timestamp)
+        return "$formattedTimestamp$SEPARATOR${getName()}$SEPARATOR${getVal()}"
+    }
+
     /**
      * A private implementation of [TableRowLogger].
      *
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
index 06668d3..42e742d 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
@@ -17,10 +17,15 @@
 package com.android.systemui.log.table
 
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.log.LogBufferHelper.Companion.adjustMaxSize
+import com.android.systemui.plugins.log.LogcatEchoTracker
 import com.android.systemui.util.time.SystemClock
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
 
 @SysUISingleton
 class TableLogBufferFactory
@@ -28,6 +33,9 @@
 constructor(
     private val dumpManager: DumpManager,
     private val systemClock: SystemClock,
+    private val logcatEchoTracker: LogcatEchoTracker,
+    @Background private val bgDispatcher: CoroutineDispatcher,
+    @Application private val coroutineScope: CoroutineScope,
 ) {
     private val existingBuffers = mutableMapOf<String, TableLogBuffer>()
 
@@ -44,8 +52,17 @@
         name: String,
         maxSize: Int,
     ): TableLogBuffer {
-        val tableBuffer = TableLogBuffer(adjustMaxSize(maxSize), name, systemClock)
+        val tableBuffer =
+            TableLogBuffer(
+                adjustMaxSize(maxSize),
+                name,
+                systemClock,
+                logcatEchoTracker,
+                bgDispatcher,
+                coroutineScope,
+            )
         dumpManager.registerNormalDumpable(name, tableBuffer)
+        tableBuffer.init()
         return tableBuffer
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
index 52d4171..aec7b5f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
@@ -20,7 +20,10 @@
 import android.content.res.Configuration
 import android.content.res.Resources
 import android.media.projection.IMediaProjection
+import android.media.projection.IMediaProjectionManager.EXTRA_USER_REVIEW_GRANTED_CONSENT
 import android.media.projection.MediaProjectionManager.EXTRA_MEDIA_PROJECTION
+import android.media.projection.ReviewGrantedConsentResult.RECORD_CANCEL
+import android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_TASK
 import android.os.Binder
 import android.os.Bundle
 import android.os.IBinder
@@ -67,6 +70,11 @@
     private lateinit var controller: MediaProjectionAppSelectorController
     private lateinit var recentsViewController: MediaProjectionRecentsViewController
     private lateinit var component: MediaProjectionAppSelectorComponent
+    // Indicate if we are under the media projection security flow
+    // i.e. when a host app reuses consent token, review the permission and update it to the service
+    private var reviewGrantedConsentRequired = false
+    // If an app is selected, set to true so that we don't send RECORD_CANCEL in onDestroy
+    private var taskSelected = false
 
     override fun getLayoutResource() = R.layout.media_projection_app_selector
 
@@ -85,6 +93,9 @@
             component.personalProfileUserHandle
         )
 
+        reviewGrantedConsentRequired =
+            intent.getBooleanExtra(EXTRA_USER_REVIEW_GRANTED_CONSENT, false)
+
         super.onCreate(bundle)
         controller.init()
     }
@@ -149,6 +160,16 @@
     }
 
     override fun onDestroy() {
+        // onDestroy is also called when an app is selected, in that case we only want to send
+        // RECORD_CONTENT_TASK but not RECORD_CANCEL
+        if (!taskSelected) {
+            // TODO(b/272010156): Return result to PermissionActivity and update service there
+            MediaProjectionServiceHelper.setReviewedConsentIfNeeded(
+                RECORD_CANCEL,
+                reviewGrantedConsentRequired,
+                /* projection= */ null
+            )
+        }
         activityLauncher.destroy()
         controller.destroy()
         super.onDestroy()
@@ -163,6 +184,7 @@
     }
 
     override fun returnSelectedApp(launchCookie: IBinder) {
+        taskSelected = true
         if (intent.hasExtra(EXTRA_CAPTURE_REGION_RESULT_RECEIVER)) {
             // The client requested to return the result in the result receiver instead of
             // activity result, let's send the media projection to the result receiver
@@ -174,7 +196,11 @@
             val captureRegion = MediaProjectionCaptureTarget(launchCookie)
             val data = Bundle().apply { putParcelable(KEY_CAPTURE_TARGET, captureRegion) }
             resultReceiver.send(RESULT_OK, data)
+            // TODO(b/279175710): Ensure consent result is always set here. Skipping this for now
+            //  in ScreenMediaRecorder, since we know the permission grant (projection) is never
+            //  reused in that scenario.
         } else {
+            // TODO(b/272010156): Return result to PermissionActivity and update service there
             // Return the media projection instance as activity result
             val mediaProjectionBinder = intent.getIBinderExtra(EXTRA_MEDIA_PROJECTION)
             val projection = IMediaProjection.Stub.asInterface(mediaProjectionBinder)
@@ -185,6 +211,11 @@
             intent.putExtra(EXTRA_MEDIA_PROJECTION, projection.asBinder())
             setResult(RESULT_OK, intent)
             setForceSendResultForMediaProjection()
+            MediaProjectionServiceHelper.setReviewedConsentIfNeeded(
+                RECORD_CONTENT_TASK,
+                reviewGrantedConsentRequired,
+                projection
+            )
         }
 
         finish()
@@ -228,7 +259,7 @@
             putExtra(Intent.EXTRA_INTENT, queryIntent)
 
             // Update the title of the chooser
-            val title = resources.getString(R.string.media_projection_permission_app_selector_title)
+            val title = resources.getString(R.string.screen_share_permission_app_selector_title)
             putExtra(Intent.EXTRA_TITLE, title)
 
             // Select host app's profile tab by default
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index ccddd1d..28adfbb 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -16,11 +16,16 @@
 
 package com.android.systemui.media;
 
+import static android.media.projection.IMediaProjectionManager.EXTRA_PACKAGE_REUSING_GRANTED_CONSENT;
+import static android.media.projection.IMediaProjectionManager.EXTRA_USER_REVIEW_GRANTED_CONSENT;
+import static android.media.projection.ReviewGrantedConsentResult.RECORD_CANCEL;
+import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
 import static com.android.systemui.screenrecord.ScreenShareOptionKt.ENTIRE_SCREEN;
 import static com.android.systemui.screenrecord.ScreenShareOptionKt.SINGLE_APP;
 
+import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AlertDialog;
@@ -30,12 +35,10 @@
 import android.content.pm.PackageManager;
 import android.graphics.Typeface;
 import android.media.projection.IMediaProjection;
-import android.media.projection.IMediaProjectionManager;
 import android.media.projection.MediaProjectionManager;
+import android.media.projection.ReviewGrantedConsentResult;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.text.BidiFormatter;
 import android.text.SpannableString;
@@ -55,10 +58,10 @@
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.util.Utils;
 
-import javax.inject.Inject;
-
 import dagger.Lazy;
 
+import javax.inject.Inject;
+
 public class MediaProjectionPermissionActivity extends Activity
         implements DialogInterface.OnClickListener {
     private static final String TAG = "MediaProjectionPermissionActivity";
@@ -70,10 +73,13 @@
 
     private String mPackageName;
     private int mUid;
-    private IMediaProjectionManager mService;
 
     private AlertDialog mDialog;
 
+    // Indicates if user must review already-granted consent that the MediaProjection app is
+    // attempting to re-use.
+    private boolean mReviewGrantedConsentRequired = false;
+
     @Inject
     public MediaProjectionPermissionActivity(FeatureFlags featureFlags,
             Lazy<ScreenCaptureDevicePolicyResolver> screenCaptureDevicePolicyResolver) {
@@ -85,13 +91,23 @@
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        mPackageName = getCallingPackage();
-        IBinder b = ServiceManager.getService(MEDIA_PROJECTION_SERVICE);
-        mService = IMediaProjectionManager.Stub.asInterface(b);
+        final Intent launchingIntent = getIntent();
+        mReviewGrantedConsentRequired = launchingIntent.getBooleanExtra(
+                EXTRA_USER_REVIEW_GRANTED_CONSENT, false);
 
+        mPackageName = getCallingPackage();
+
+        // This activity is launched directly by an app, or system server. System server provides
+        // the package name through the intent if so.
         if (mPackageName == null) {
-            finish();
-            return;
+            if (launchingIntent.hasExtra(EXTRA_PACKAGE_REUSING_GRANTED_CONSENT)) {
+                mPackageName = launchingIntent.getStringExtra(
+                        EXTRA_PACKAGE_REUSING_GRANTED_CONSENT);
+            } else {
+                setResult(RESULT_CANCELED);
+                finish(RECORD_CANCEL, /* projection= */ null);
+                return;
+            }
         }
 
         PackageManager packageManager = getPackageManager();
@@ -100,25 +116,36 @@
             aInfo = packageManager.getApplicationInfo(mPackageName, 0);
             mUid = aInfo.uid;
         } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "unable to look up package name", e);
-            finish();
+            Log.e(TAG, "Unable to look up package name", e);
+            setResult(RESULT_CANCELED);
+            finish(RECORD_CANCEL, /* projection= */ null);
             return;
         }
 
         try {
-            if (mService.hasProjectionPermission(mUid, mPackageName)) {
-                setResult(RESULT_OK, getMediaProjectionIntent(mUid, mPackageName));
-                finish();
+            if (MediaProjectionServiceHelper.hasProjectionPermission(mUid, mPackageName)) {
+                final IMediaProjection projection =
+                        MediaProjectionServiceHelper.createOrReuseProjection(mUid, mPackageName,
+                                mReviewGrantedConsentRequired);
+                // Automatically grant consent if a system-privileged component is recording.
+                final Intent intent = new Intent();
+                intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION,
+                        projection.asBinder());
+                setResult(RESULT_OK, intent);
+                finish(RECORD_CONTENT_DISPLAY, projection);
                 return;
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error checking projection permissions", e);
-            finish();
+            setResult(RESULT_CANCELED);
+            finish(RECORD_CANCEL, /* projection= */ null);
             return;
         }
 
         if (mFeatureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)) {
             if (showScreenCaptureDisabledDialogIfNeeded()) {
+                setResult(RESULT_CANCELED);
+                finish(RECORD_CANCEL, /* projection= */ null);
                 return;
             }
         }
@@ -130,8 +157,8 @@
         CharSequence dialogTitle = null;
         String appName = null;
         if (Utils.isHeadlessRemoteDisplayProvider(packageManager, mPackageName)) {
-            dialogText = getString(R.string.media_projection_dialog_service_text);
-            dialogTitle = getString(R.string.media_projection_dialog_service_title);
+            dialogText = getString(R.string.media_projection_sys_service_dialog_warning);
+            dialogTitle = getString(R.string.media_projection_sys_service_dialog_title);
         } else {
             String label = aInfo.loadLabel(packageManager).toString();
 
@@ -161,7 +188,7 @@
                     paint, MAX_APP_NAME_SIZE_PX, TextUtils.TruncateAt.END).toString();
             appName = BidiFormatter.getInstance().unicodeWrap(unsanitizedAppName);
 
-            String actionText = getString(R.string.media_projection_dialog_text, appName);
+            String actionText = getString(R.string.media_projection_dialog_warning, appName);
             SpannableString message = new SpannableString(actionText);
 
             int appNameIndex = actionText.indexOf(appName);
@@ -178,7 +205,7 @@
                 ScreenShareOption selectedOption =
                         ((MediaProjectionPermissionDialog) mDialog).getSelectedScreenShareOption();
                 grantMediaProjectionPermission(selectedOption.getMode());
-            }, appName);
+            }, () -> finish(RECORD_CANCEL, /* projection= */ null), appName);
         } else {
             AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this,
                     R.style.Theme_SystemUI_Dialog)
@@ -191,7 +218,6 @@
         }
 
         setUpDialog(mDialog);
-
         mDialog.show();
     }
 
@@ -207,6 +233,12 @@
     public void onClick(DialogInterface dialog, int which) {
         if (which == AlertDialog.BUTTON_POSITIVE) {
             grantMediaProjectionPermission(ENTIRE_SCREEN);
+        } else {
+            if (mDialog != null) {
+                mDialog.dismiss();
+            }
+            setResult(RESULT_CANCELED);
+            finish(RECORD_CANCEL, /* projection= */ null);
         }
     }
 
@@ -240,15 +272,25 @@
     private void grantMediaProjectionPermission(int screenShareMode) {
         try {
             if (screenShareMode == ENTIRE_SCREEN) {
-                setResult(RESULT_OK, getMediaProjectionIntent(mUid, mPackageName));
+                final IMediaProjection projection =
+                        MediaProjectionServiceHelper.createOrReuseProjection(mUid, mPackageName,
+                                mReviewGrantedConsentRequired);
+                final Intent intent = new Intent();
+                intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION,
+                        projection.asBinder());
+                setResult(RESULT_OK, intent);
+                finish(RECORD_CONTENT_DISPLAY, projection);
             }
             if (isPartialScreenSharingEnabled() && screenShareMode == SINGLE_APP) {
-                IMediaProjection projection = createProjection(mUid, mPackageName);
-                final Intent intent = new Intent(this, MediaProjectionAppSelectorActivity.class);
+                IMediaProjection projection = MediaProjectionServiceHelper.createOrReuseProjection(
+                        mUid, mPackageName, mReviewGrantedConsentRequired);
+                final Intent intent = new Intent(this,
+                        MediaProjectionAppSelectorActivity.class);
                 intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION,
                         projection.asBinder());
                 intent.putExtra(MediaProjectionAppSelectorActivity.EXTRA_HOST_APP_USER_HANDLE,
                         getHostUserHandle());
+                intent.putExtra(EXTRA_USER_REVIEW_GRANTED_CONSENT, mReviewGrantedConsentRequired);
                 intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
 
                 // Start activity from the current foreground user to avoid creating a separate
@@ -259,11 +301,11 @@
         } catch (RemoteException e) {
             Log.e(TAG, "Error granting projection permission", e);
             setResult(RESULT_CANCELED);
+            finish(RECORD_CANCEL, /* projection= */ null);
         } finally {
             if (mDialog != null) {
                 mDialog.dismiss();
             }
-            finish();
         }
     }
 
@@ -271,22 +313,22 @@
         return UserHandle.getUserHandleForUid(getLaunchedFromUid());
     }
 
-    private IMediaProjection createProjection(int uid, String packageName) throws RemoteException {
-        return mService.createProjection(uid, packageName,
-                MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */);
+    @Override
+    public void finish() {
+        // Default to cancelling recording when user needs to review consent.
+        finish(RECORD_CANCEL, /* projection= */ null);
     }
 
-    private Intent getMediaProjectionIntent(int uid, String packageName)
-            throws RemoteException {
-        IMediaProjection projection = createProjection(uid, packageName);
-        Intent intent = new Intent();
-        intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, projection.asBinder());
-        return intent;
+    private void finish(@ReviewGrantedConsentResult int consentResult,
+            @Nullable IMediaProjection projection) {
+        MediaProjectionServiceHelper.setReviewedConsentIfNeeded(
+                consentResult, mReviewGrantedConsentRequired, projection);
+        super.finish();
     }
 
     private void onDialogDismissedOrCancelled(DialogInterface dialogInterface) {
         if (!isFinishing()) {
-            finish();
+            finish(RECORD_CANCEL, /* projection= */ null);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionServiceHelper.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionServiceHelper.kt
new file mode 100644
index 0000000..9e616e2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionServiceHelper.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media
+
+import android.content.Context
+import android.media.projection.IMediaProjection
+import android.media.projection.IMediaProjectionManager
+import android.media.projection.MediaProjectionManager
+import android.media.projection.ReviewGrantedConsentResult
+import android.os.RemoteException
+import android.os.ServiceManager
+import android.util.Log
+
+/**
+ * Helper class that handles the media projection service related actions. It simplifies invoking
+ * the MediaProjectionManagerService and updating the permission consent.
+ */
+class MediaProjectionServiceHelper {
+    companion object {
+        private const val TAG = "MediaProjectionServiceHelper"
+        private val service =
+            IMediaProjectionManager.Stub.asInterface(
+                ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE)
+            )
+
+        @JvmStatic
+        @Throws(RemoteException::class)
+        fun hasProjectionPermission(uid: Int, packageName: String) =
+            service.hasProjectionPermission(uid, packageName)
+
+        @JvmStatic
+        @Throws(RemoteException::class)
+        fun createOrReuseProjection(
+            uid: Int,
+            packageName: String,
+            reviewGrantedConsentRequired: Boolean
+        ): IMediaProjection {
+            val existingProjection =
+                if (reviewGrantedConsentRequired) service.getProjection(uid, packageName) else null
+            return existingProjection
+                ?: service.createProjection(
+                    uid,
+                    packageName,
+                    MediaProjectionManager.TYPE_SCREEN_CAPTURE,
+                    false /* permanentGrant */
+                )
+        }
+
+        /**
+         * This method is called when a host app reuses the consent token. If the token is being
+         * used more than once, ask the user to review their consent and send the reviewed result.
+         *
+         * @param consentResult consent result to update
+         * @param reviewGrantedConsentRequired if user must review already-granted consent that the
+         *   host app is attempting to reuse
+         * @param projection projection token associated with the consent result, or null if the
+         *   result is for cancelling.
+         */
+        @JvmStatic
+        fun setReviewedConsentIfNeeded(
+            @ReviewGrantedConsentResult consentResult: Int,
+            reviewGrantedConsentRequired: Boolean,
+            projection: IMediaProjection?
+        ) {
+            // Only send the result to the server, when the user needed to review the re-used
+            // consent token.
+            if (
+                reviewGrantedConsentRequired && consentResult != ReviewGrantedConsentResult.UNKNOWN
+            ) {
+                try {
+                    service.setUserReviewGrantedConsentResult(consentResult, projection)
+                } catch (e: RemoteException) {
+                    // If we are unable to pass back the result, capture continues with blank frames
+                    Log.e(TAG, "Unable to set required consent result for token re-use", e)
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index 2a8168b..05e04a1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -88,18 +88,9 @@
         private final IBinder mToken;
         private final Ringtone mRingtone;
 
-        public Client(IBinder token, Uri uri, UserHandle user, AudioAttributes aa) {
-            this(token, uri, user, aa, null);
-        }
-
-        Client(IBinder token, Uri uri, UserHandle user, AudioAttributes aa,
-                @Nullable VolumeShaper.Configuration volumeShaperConfig) {
+        Client(IBinder token, Ringtone ringtone) {
             mToken = token;
-
-            mRingtone = new Ringtone(getContextForUser(user), false);
-            mRingtone.setAudioAttributesField(aa);
-            mRingtone.setUri(uri, volumeShaperConfig);
-            mRingtone.createLocalMediaPlayer();
+            mRingtone = ringtone;
         }
 
         @Override
@@ -129,11 +120,28 @@
             Client client;
             synchronized (mClients) {
                 client = mClients.get(token);
-                if (client == null) {
-                    final UserHandle user = Binder.getCallingUserHandle();
-                    client = new Client(token, uri, user, aa, volumeShaperConfig);
-                    token.linkToDeath(client, 0);
-                    mClients.put(token, client);
+            }
+            // Don't hold the lock while constructing the ringtone, since it can be slow. The caller
+            // shouldn't call play on the same ringtone from 2 threads, so this shouldn't race and
+            // waste the build.
+            if (client == null) {
+                final UserHandle user = Binder.getCallingUserHandle();
+                Ringtone ringtone = new Ringtone(getContextForUser(user), false);
+                ringtone.setAudioAttributesField(aa);
+                ringtone.setUri(uri, volumeShaperConfig);
+                ringtone.createLocalMediaPlayer();
+                synchronized (mClients) {
+                    client = mClients.get(token);
+                    if (client == null) {
+                        client = new Client(token, ringtone);
+                        token.linkToDeath(client, 0);
+                        mClients.put(token, client);
+                        ringtone = null;  // "owned" by the client now.
+                    }
+                }
+                // Clean up ringtone if it was abandoned (a client already existed).
+                if (ringtone != null) {
+                    ringtone.stop();
                 }
             }
             client.mRingtone.setLooping(looping);
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 9997730..fa42114 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
@@ -43,7 +43,6 @@
 import android.net.Uri
 import android.os.Parcelable
 import android.os.Process
-import android.os.RemoteException
 import android.os.UserHandle
 import android.provider.Settings
 import android.service.notification.StatusBarNotification
@@ -53,7 +52,6 @@
 import android.util.Pair as APair
 import androidx.media.utils.MediaConstants
 import com.android.internal.logging.InstanceId
-import com.android.internal.statusbar.IStatusBarService
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.Dumpable
 import com.android.systemui.R
@@ -139,8 +137,6 @@
         expiryTimeMs = 0,
     )
 
-const val MEDIA_TITLE_ERROR_MESSAGE = "Invalid media data: title is null or blank."
-
 fun isMediaNotification(sbn: StatusBarNotification): Boolean {
     return sbn.notification.isMediaNotification()
 }
@@ -185,7 +181,6 @@
     private val logger: MediaUiEventLogger,
     private val smartspaceManager: SmartspaceManager,
     private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
-    private val statusBarService: IStatusBarService,
 ) : Dumpable, BcSmartspaceDataPlugin.SmartspaceTargetListener {
 
     companion object {
@@ -257,7 +252,6 @@
         mediaFlags: MediaFlags,
         logger: MediaUiEventLogger,
         smartspaceManager: SmartspaceManager,
-        statusBarService: IStatusBarService,
         keyguardUpdateMonitor: KeyguardUpdateMonitor,
     ) : this(
         context,
@@ -283,7 +277,6 @@
         logger,
         smartspaceManager,
         keyguardUpdateMonitor,
-        statusBarService,
     )
 
     private val appChangeReceiver =
@@ -385,21 +378,21 @@
 
     fun onNotificationAdded(key: String, sbn: StatusBarNotification) {
         if (useQsMediaPlayer && isMediaNotification(sbn)) {
-            var isNewlyActiveEntry = false
+            var logEvent = false
             Assert.isMainThread()
             val oldKey = findExistingEntry(key, sbn.packageName)
             if (oldKey == null) {
                 val instanceId = logger.getNewInstanceId()
                 val temp = LOADING.copy(packageName = sbn.packageName, instanceId = instanceId)
                 mediaEntries.put(key, temp)
-                isNewlyActiveEntry = true
+                logEvent = true
             } else if (oldKey != key) {
                 // Resume -> active conversion; move to new key
                 val oldData = mediaEntries.remove(oldKey)!!
-                isNewlyActiveEntry = true
+                logEvent = true
                 mediaEntries.put(key, oldData)
             }
-            loadMediaData(key, sbn, oldKey, isNewlyActiveEntry)
+            loadMediaData(key, sbn, oldKey, logEvent)
         } else {
             onNotificationRemoved(key)
         }
@@ -482,9 +475,9 @@
         key: String,
         sbn: StatusBarNotification,
         oldKey: String?,
-        isNewlyActiveEntry: Boolean = false,
+        logEvent: Boolean = false
     ) {
-        backgroundExecutor.execute { loadMediaDataInBg(key, sbn, oldKey, isNewlyActiveEntry) }
+        backgroundExecutor.execute { loadMediaDataInBg(key, sbn, oldKey, logEvent) }
     }
 
     /** Add a listener for changes in this class */
@@ -608,11 +601,9 @@
         }
     }
 
-    private fun removeEntry(key: String, logEvent: Boolean = true) {
+    private fun removeEntry(key: String) {
         mediaEntries.remove(key)?.let {
-            if (logEvent) {
-                logger.logMediaRemoved(it.appUid, it.packageName, it.instanceId)
-            }
+            logger.logMediaRemoved(it.appUid, it.packageName, it.instanceId)
         }
         notifyMediaDataRemoved(key)
     }
@@ -760,7 +751,7 @@
         key: String,
         sbn: StatusBarNotification,
         oldKey: String?,
-        isNewlyActiveEntry: Boolean = false,
+        logEvent: Boolean = false
     ) {
         val token =
             sbn.notification.extras.getParcelable(
@@ -774,34 +765,6 @@
         val metadata = mediaController.metadata
         val notif: Notification = sbn.notification
 
-        // Song name
-        var song: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE)
-        if (song == null) {
-            song = metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)
-        }
-        if (song == null) {
-            song = HybridGroupManager.resolveTitle(notif)
-        }
-        // Media data must have a title.
-        if (song.isNullOrBlank()) {
-            try {
-                statusBarService.onNotificationError(
-                    sbn.packageName,
-                    sbn.tag,
-                    sbn.id,
-                    sbn.uid,
-                    sbn.initialPid,
-                    MEDIA_TITLE_ERROR_MESSAGE,
-                    sbn.user.identifier
-                )
-            } catch (e: RemoteException) {
-                Log.e(TAG, "cancelNotification failed: $e")
-            }
-            // Only add log for media removed if active media is updated with invalid title.
-            foregroundExecutor.execute { removeEntry(key, !isNewlyActiveEntry) }
-            return
-        }
-
         val appInfo =
             notif.extras.getParcelable(
                 Notification.EXTRA_BUILDER_APPLICATION_INFO,
@@ -830,6 +793,15 @@
         // App Icon
         val smallIcon = sbn.notification.smallIcon
 
+        // Song name
+        var song: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE)
+        if (song == null) {
+            song = metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)
+        }
+        if (song == null) {
+            song = HybridGroupManager.resolveTitle(notif)
+        }
+
         // Explicit Indicator
         var isExplicit = false
         if (mediaFlags.isExplicitIndicatorEnabled()) {
@@ -901,7 +873,7 @@
         val instanceId = currentEntry?.instanceId ?: logger.getNewInstanceId()
         val appUid = appInfo?.uid ?: Process.INVALID_UID
 
-        if (isNewlyActiveEntry) {
+        if (logEvent) {
             logSingleVsMultipleMediaAdded(appUid, sbn.packageName, instanceId)
             logger.logActiveMediaAdded(appUid, sbn.packageName, instanceId, playbackLocation)
         } else if (playbackLocation != currentEntry?.playbackLocation) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
index 120704c..3fc3ad6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
@@ -154,6 +154,7 @@
             get() = controller?.sessionToken
         private var started = false
         private var playbackType = PLAYBACK_TYPE_UNKNOWN
+        private var playbackVolumeControlId: String? = null
         private var current: MediaDeviceData? = null
             set(value) {
                 val sameWithoutIcon = value != null && value.equalsWithoutIcon(field)
@@ -181,6 +182,7 @@
                     localMediaManager.startScan()
                     muteAwaitConnectionManager?.startListening()
                     playbackType = controller?.playbackInfo?.playbackType ?: PLAYBACK_TYPE_UNKNOWN
+                    playbackVolumeControlId = controller?.playbackInfo?.volumeControlId
                     controller?.registerCallback(this)
                     updateCurrent()
                     started = true
@@ -209,6 +211,8 @@
                 println("    current device is ${current?.name}")
                 val type = controller?.playbackInfo?.playbackType
                 println("    PlaybackType=$type (1 for local, 2 for remote) cached=$playbackType")
+                val volumeControlId = controller?.playbackInfo?.volumeControlId
+                println("    volumeControlId=$volumeControlId cached= $playbackVolumeControlId")
                 println("    routingSession=$routingSession")
                 println("    selectedRoutes=$selectedRoutes")
             }
@@ -217,10 +221,15 @@
         @WorkerThread
         override fun onAudioInfoChanged(info: MediaController.PlaybackInfo?) {
             val newPlaybackType = info?.playbackType ?: PLAYBACK_TYPE_UNKNOWN
-            if (newPlaybackType == playbackType) {
+            val newPlaybackVolumeControlId = info?.volumeControlId
+            if (
+                newPlaybackType == playbackType &&
+                    newPlaybackVolumeControlId == playbackVolumeControlId
+            ) {
                 return
             }
             playbackType = newPlaybackType
+            playbackVolumeControlId = newPlaybackVolumeControlId
             updateCurrent()
         }
 
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 ab39442..1e9a466 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
@@ -67,6 +67,7 @@
 import com.android.systemui.util.time.SystemClock
 import com.android.systemui.util.traceSection
 import java.io.PrintWriter
+import java.util.Locale
 import java.util.TreeMap
 import javax.inject.Inject
 import javax.inject.Provider
@@ -166,6 +167,9 @@
             }
         }
 
+    private var carouselLocale: Locale? = null
+
+    /** Whether the media card currently has the "expanded" layout */
     @VisibleForTesting
     var currentlyExpanded = true
         set(value) {
@@ -217,6 +221,15 @@
                 updatePlayers(recreateMedia = false)
                 inflateSettingsButton()
             }
+
+            override fun onLocaleListChanged() {
+                // Update players only if system primary language changes.
+                if (carouselLocale != context.resources.configuration.locales.get(0)) {
+                    carouselLocale = context.resources.configuration.locales.get(0)
+                    updatePlayers(recreateMedia = true)
+                    inflateSettingsButton()
+                }
+            }
         }
 
     private val keyguardUpdateMonitorCallback =
@@ -261,6 +274,7 @@
                 this::logSmartspaceImpression,
                 logger
             )
+        carouselLocale = context.resources.configuration.locales.get(0)
         isRtl = context.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
         inflateSettingsButton()
         mediaContent = mediaCarousel.requireViewById(R.id.media_carousel)
@@ -501,6 +515,7 @@
         mediaHostStatesManager.addCallback(
             object : MediaHostStatesManager.Callback {
                 override fun onHostStateChanged(location: Int, mediaHostState: MediaHostState) {
+                    updateUserVisibility()
                     if (location == desiredLocation) {
                         onDesiredLocationChanged(desiredLocation, mediaHostState, animate = false)
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
index 54237ce..49e1665 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
@@ -257,7 +257,7 @@
             if (value && (isLockScreenShadeVisibleToUser() || isHomeScreenShadeVisibleToUser())) {
                 mediaCarouselController.logSmartspaceImpression(value)
             }
-            mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
+            updateUserVisibility()
         }
 
     /**
@@ -460,8 +460,7 @@
                     ) {
                         mediaCarouselController.logSmartspaceImpression(qsExpanded)
                     }
-                    mediaCarouselController.mediaCarouselScrollHandler.visibleToUser =
-                        isVisibleToUser()
+                    updateUserVisibility()
                 }
 
                 override fun onDozeAmountChanged(linear: Float, eased: Float) {
@@ -480,8 +479,7 @@
                         qsExpanded = false
                         closeGuts()
                     }
-                    mediaCarouselController.mediaCarouselScrollHandler.visibleToUser =
-                        isVisibleToUser()
+                    updateUserVisibility()
                 }
 
                 override fun onExpandedChanged(isExpanded: Boolean) {
@@ -489,8 +487,7 @@
                     if (isHomeScreenShadeVisibleToUser()) {
                         mediaCarouselController.logSmartspaceImpression(qsExpanded)
                     }
-                    mediaCarouselController.mediaCarouselScrollHandler.visibleToUser =
-                        isVisibleToUser()
+                    updateUserVisibility()
                 }
             }
         )
@@ -532,9 +529,7 @@
             }
         )
 
-        mediaCarouselController.updateUserVisibility = {
-            mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
-        }
+        mediaCarouselController.updateUserVisibility = this::updateUserVisibility
         mediaCarouselController.updateHostVisibility = {
             mediaHosts.forEach { it?.updateViewVisibility() }
         }
@@ -1180,11 +1175,15 @@
         return isCrossFadeAnimatorRunning
     }
 
-    /** Returns true when the media card could be visible to the user if existed. */
-    private fun isVisibleToUser(): Boolean {
-        return isLockScreenVisibleToUser() ||
-            isLockScreenShadeVisibleToUser() ||
-            isHomeScreenShadeVisibleToUser()
+    /** Update whether or not the media carousel could be visible to the user */
+    private fun updateUserVisibility() {
+        val shadeVisible =
+            isLockScreenVisibleToUser() ||
+                isLockScreenShadeVisibleToUser() ||
+                isHomeScreenShadeVisibleToUser()
+        val mediaVisible = qsExpanded || hasActiveMediaOrRecommendation
+        mediaCarouselController.mediaCarouselScrollHandler.visibleToUser =
+            shadeVisible && mediaVisible
     }
 
     private fun isLockScreenVisibleToUser(): Boolean {
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 9ebc8e4..8e014c6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -126,10 +126,11 @@
     private final LocalBluetoothManager mLocalBluetoothManager;
     private final ActivityStarter mActivityStarter;
     private final DialogLaunchAnimator mDialogLaunchAnimator;
-    private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
     private final CommonNotifCollection mNotifCollection;
     private final Object mMediaDevicesLock = new Object();
     @VisibleForTesting
+    final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
+    @VisibleForTesting
     final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
     final List<MediaDevice> mCachedMediaDevices = new CopyOnWriteArrayList<>();
     private final List<MediaItem> mMediaItemList = new CopyOnWriteArrayList<>();
@@ -713,7 +714,7 @@
             dividerItems.forEach((key, item) -> {
                 finalMediaItems.add(key, item);
             });
-            finalMediaItems.add(new MediaItem());
+            attachConnectNewDeviceItemIfNeeded(finalMediaItems);
             mMediaItemList.clear();
             mMediaItemList.addAll(finalMediaItems);
         }
@@ -749,7 +750,7 @@
                     finalMediaItems.add(new MediaItem(device));
                 }
             }
-            finalMediaItems.add(new MediaItem());
+            attachConnectNewDeviceItemIfNeeded(finalMediaItems);
             mMediaItemList.clear();
             mMediaItemList.addAll(finalMediaItems);
         }
@@ -760,6 +761,13 @@
                 new MediaItem(title, MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
     }
 
+    private void attachConnectNewDeviceItemIfNeeded(List<MediaItem> mediaItems) {
+        // Attach "Connect a device" item only when current output is not remote and not a group
+        if (!isCurrentConnectedDeviceRemote() && getSelectedMediaDevice().size() == 1) {
+            mediaItems.add(new MediaItem());
+        }
+    }
+
     private void attachRangeInfo(List<MediaDevice> devices) {
         for (MediaDevice mediaDevice : devices) {
             if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
@@ -1251,7 +1259,8 @@
         return null;
     }
 
-    private final MediaController.Callback mCb = new MediaController.Callback() {
+    @VisibleForTesting
+    final MediaController.Callback mCb = new MediaController.Callback() {
         @Override
         public void onMetadataChanged(MediaMetadata metadata) {
             mCallback.onMediaChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskLabelLoader.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskLabelLoader.kt
index eadcb93..1be8b70 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskLabelLoader.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskLabelLoader.kt
@@ -20,6 +20,7 @@
 import android.content.ComponentName
 import android.content.pm.PackageManager
 import android.os.UserHandle
+import android.util.Log
 import com.android.systemui.dagger.qualifiers.Background
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
@@ -36,18 +37,27 @@
     private val packageManager: PackageManager
 ) : RecentTaskLabelLoader {
 
+    private val TAG = "RecentTaskLabelLoader"
+
     override suspend fun loadLabel(
         @UserIdInt userId: Int,
         componentName: ComponentName
     ): CharSequence? =
         withContext(coroutineDispatcher) {
-            val userHandle = UserHandle(userId)
-            val appInfo =
-                packageManager.getApplicationInfo(
-                    componentName.packageName,
-                    PackageManager.ApplicationInfoFlags.of(0 /* no flags */)
-                )
-            val label = packageManager.getApplicationLabel(appInfo)
-            return@withContext packageManager.getUserBadgedLabel(label, userHandle)
+            var badgedLabel: CharSequence? = null
+            try {
+                val appInfo =
+                    packageManager.getApplicationInfoAsUser(
+                        componentName.packageName,
+                        PackageManager.ApplicationInfoFlags.of(0 /* no flags */),
+                        userId
+                    )
+                val label = packageManager.getApplicationLabel(appInfo)
+                val userHandle = UserHandle(userId)
+                badgedLabel = packageManager.getUserBadgedLabel(label, userHandle)
+            } catch (e: PackageManager.NameNotFoundException) {
+                Log.e(TAG, "Unable to get application info", e)
+            }
+            return@withContext badgedLabel
         }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt
index 64f97f2..2d75359 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt
@@ -68,7 +68,7 @@
                     }
                     launch {
                         val label = labelLoader.loadLabel(task.userId, component)
-                        root.contentDescription = label
+                        root.contentDescription = label ?: root.context.getString(R.string.unknown)
                     }
                 }
                 launch {
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 96e9756..91bb7898 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -60,15 +60,21 @@
 private const val MIN_DURATION_COMMITTED_ANIMATION = 80L
 private const val MIN_DURATION_COMMITTED_AFTER_FLING_ANIMATION = 120L
 private const val MIN_DURATION_INACTIVE_BEFORE_FLUNG_ANIMATION = 50L
-private const val MIN_DURATION_INACTIVE_BEFORE_ACTIVE_ANIMATION = 80L
+private const val MIN_DURATION_INACTIVE_BEFORE_ACTIVE_ANIMATION = 160F
+private const val MIN_DURATION_ENTRY_BEFORE_ACTIVE_ANIMATION = 10F
+internal const val MAX_DURATION_ENTRY_BEFORE_ACTIVE_ANIMATION = 100F
 private const val MIN_DURATION_FLING_ANIMATION = 160L
 
 private const val MIN_DURATION_ENTRY_TO_ACTIVE_CONSIDERED_AS_FLING = 100L
 private const val MIN_DURATION_INACTIVE_TO_ACTIVE_CONSIDERED_AS_FLING = 400L
 
 private const val POP_ON_FLING_DELAY = 60L
-private const val POP_ON_FLING_SCALE = 2f
-private const val POP_ON_COMMITTED_SCALE = 3f
+private const val POP_ON_FLING_VELOCITY = 2f
+private const val POP_ON_COMMITTED_VELOCITY = 3f
+private const val POP_ON_ACTIVE_MAX_VELOCITY = 2.5f
+private const val POP_ON_ACTIVE_MIN_VELOCITY = 4.5f
+private const val POP_ON_INACTIVE_MAX_VELOCITY = -1.05f
+private const val POP_ON_INACTIVE_MIN_VELOCITY = -1.5f
 
 internal val VIBRATE_ACTIVATED_EFFECT =
         VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)
@@ -156,13 +162,22 @@
 
     private var gestureEntryTime = 0L
     private var gestureInactiveTime = 0L
-    private var gesturePastActiveThresholdWhileInactiveTime = 0L
 
     private val elapsedTimeSinceInactive
         get() = SystemClock.uptimeMillis() - gestureInactiveTime
     private val elapsedTimeSinceEntry
         get() = SystemClock.uptimeMillis() - gestureEntryTime
 
+
+    private var pastThresholdWhileEntryOrInactiveTime = 0L
+    private var entryToActiveDelay = 0F
+    private val entryToActiveDelayCalculation = {
+        convertVelocityToAnimationFactor(
+            valueOnFastVelocity = MIN_DURATION_ENTRY_BEFORE_ACTIVE_ANIMATION,
+            valueOnSlowVelocity = MAX_DURATION_ENTRY_BEFORE_ACTIVE_ANIMATION,
+        )
+    }
+
     // Whether the current gesture has moved a sufficiently large amount,
     // so that we can unambiguously start showing the ENTRY animation
     private var hasPassedDragSlop = false
@@ -306,7 +321,9 @@
             MotionEvent.ACTION_UP -> {
                 when (currentState) {
                     GestureState.ENTRY -> {
-                        if (isFlungAwayFromEdge(endX = event.x)) {
+                        if (isFlungAwayFromEdge(endX = event.x) ||
+                            previousXTranslation > params.staticTriggerThreshold
+                        ) {
                             updateArrowState(GestureState.ACTIVE)
                             updateArrowState(GestureState.FLUNG)
                         } else {
@@ -394,12 +411,29 @@
     }
 
     private fun updateArrowStateOnMove(yTranslation: Float, xTranslation: Float) {
-
         val isWithinYActivationThreshold = xTranslation * 2 >= yTranslation
-
+        val isPastStaticThreshold = xTranslation > params.staticTriggerThreshold
         when (currentState) {
             GestureState.ENTRY -> {
-                if (xTranslation > params.staticTriggerThreshold) {
+                if (isPastThresholdToActive(
+                        isPastThreshold = isPastStaticThreshold,
+                        dynamicDelay = entryToActiveDelayCalculation
+                    )
+                ) {
+                    updateArrowState(GestureState.ACTIVE)
+                }
+            }
+            GestureState.INACTIVE -> {
+                val isPastDynamicReactivationThreshold =
+                    totalTouchDeltaInactive >= params.reactivationTriggerThreshold
+
+                if (isPastThresholdToActive(
+                        isPastThreshold = isPastStaticThreshold &&
+                                isPastDynamicReactivationThreshold &&
+                                isWithinYActivationThreshold,
+                        delay = MIN_DURATION_INACTIVE_BEFORE_ACTIVE_ANIMATION
+                    )
+                ) {
                     updateArrowState(GestureState.ACTIVE)
                 }
             }
@@ -408,43 +442,12 @@
                     totalTouchDeltaActive <= params.deactivationTriggerThreshold
                 val isMinDurationElapsed =
                     elapsedTimeSinceEntry > MIN_DURATION_ACTIVE_BEFORE_INACTIVE_ANIMATION
-
-                if (isMinDurationElapsed && (!isWithinYActivationThreshold ||
-                            isPastDynamicDeactivationThreshold)
-                ) {
+                val isPastAllThresholds =
+                    !isWithinYActivationThreshold || isPastDynamicDeactivationThreshold
+                if (isPastAllThresholds && isMinDurationElapsed) {
                     updateArrowState(GestureState.INACTIVE)
                 }
             }
-            GestureState.INACTIVE -> {
-                val isPastStaticThreshold =
-                    xTranslation > params.staticTriggerThreshold
-                val isPastDynamicReactivationThreshold =
-                    totalTouchDeltaInactive >= params.reactivationTriggerThreshold
-                val isPastAllThresholds = isPastStaticThreshold &&
-                        isPastDynamicReactivationThreshold &&
-                        isWithinYActivationThreshold
-                val isPastAllThresholdsForFirstTime = isPastAllThresholds &&
-                        gesturePastActiveThresholdWhileInactiveTime == 0L
-
-                gesturePastActiveThresholdWhileInactiveTime = when {
-                    isPastAllThresholdsForFirstTime -> SystemClock.uptimeMillis()
-                    isPastAllThresholds -> gesturePastActiveThresholdWhileInactiveTime
-                    else -> 0L
-                }
-
-                val elapsedTimePastAllThresholds =
-                    SystemClock.uptimeMillis() - gesturePastActiveThresholdWhileInactiveTime
-
-                val isPastMinimumInactiveToActiveDuration =
-                    elapsedTimePastAllThresholds > MIN_DURATION_INACTIVE_BEFORE_ACTIVE_ANIMATION
-
-                if (isPastAllThresholds && isPastMinimumInactiveToActiveDuration) {
-                    // The minimum duration adds the 'edge stickiness'
-                    // factor before pulling it off edge
-                    updateArrowState(GestureState.ACTIVE)
-                }
-            }
-
             else -> {}
         }
     }
@@ -672,6 +675,28 @@
         return flingDistance > minFlingDistance && isPastFlingVelocityThreshold
     }
 
+    private fun isPastThresholdToActive(
+        isPastThreshold: Boolean,
+        delay: Float? = null,
+        dynamicDelay: () -> Float = { delay ?: 0F }
+    ): Boolean {
+        val resetValue = 0L
+        val isPastThresholdForFirstTime = pastThresholdWhileEntryOrInactiveTime == resetValue
+
+        if (!isPastThreshold) {
+            pastThresholdWhileEntryOrInactiveTime = resetValue
+            return false
+        }
+
+        if (isPastThresholdForFirstTime) {
+            pastThresholdWhileEntryOrInactiveTime = SystemClock.uptimeMillis()
+            entryToActiveDelay = dynamicDelay()
+        }
+        val timePastThreshold = SystemClock.uptimeMillis() - pastThresholdWhileEntryOrInactiveTime
+
+        return timePastThreshold > entryToActiveDelay
+    }
+
     private fun playWithBackgroundWidthAnimation(
             onEnd: DelayedOnAnimationEndListener,
             delay: Long = 0L
@@ -886,33 +911,16 @@
             }
             GestureState.ACTIVE -> {
                 previousXTranslationOnActiveOffset = previousXTranslation
-
                 updateRestingArrowDimens()
-
                 vibratorHelper.cancel()
                 mainHandler.postDelayed(10L) {
                     vibratorHelper.vibrate(VIBRATE_ACTIVATED_EFFECT)
                 }
-
-                val minimumPop = 2f
-                val maximumPop = 4.5f
-
-                when (previousState) {
-                    GestureState.ENTRY -> {
-                        val startingVelocity = convertVelocityToSpringStartingVelocity(
-                            valueOnFastVelocity = minimumPop,
-                            valueOnSlowVelocity = maximumPop,
-                            fastVelocityBound = 1f,
-                            slowVelocityBound = 0.5f,
-                        )
-                        mView.popOffEdge(startingVelocity)
-                    }
-                    GestureState.INACTIVE -> {
-                        mView.popOffEdge(maximumPop)
-                    }
-
-                    else -> {}
-                }
+                val startingVelocity = convertVelocityToAnimationFactor(
+                    valueOnFastVelocity = POP_ON_ACTIVE_MAX_VELOCITY,
+                    valueOnSlowVelocity = POP_ON_ACTIVE_MIN_VELOCITY,
+                )
+                mView.popOffEdge(startingVelocity)
             }
 
             GestureState.INACTIVE -> {
@@ -925,9 +933,9 @@
                 // so that gesture progress in this state is consistent regardless of entry
                 totalTouchDeltaInactive = params.deactivationTriggerThreshold
 
-                val startingVelocity = convertVelocityToSpringStartingVelocity(
-                        valueOnFastVelocity = -1.05f,
-                        valueOnSlowVelocity = -1.50f
+                val startingVelocity = convertVelocityToAnimationFactor(
+                        valueOnFastVelocity = POP_ON_INACTIVE_MAX_VELOCITY,
+                        valueOnSlowVelocity = POP_ON_INACTIVE_MIN_VELOCITY
                 )
                 mView.popOffEdge(startingVelocity)
 
@@ -935,7 +943,9 @@
                 updateRestingArrowDimens()
             }
             GestureState.FLUNG -> {
-                mainHandler.postDelayed(POP_ON_FLING_DELAY) { mView.popScale(POP_ON_FLING_SCALE) }
+                mainHandler.postDelayed(POP_ON_FLING_DELAY) {
+                    mView.popScale(POP_ON_FLING_VELOCITY)
+                }
                 updateRestingArrowDimens()
                 mainHandler.postDelayed(onEndSetCommittedStateListener.runnable,
                         MIN_DURATION_FLING_ANIMATION)
@@ -951,7 +961,7 @@
                     mainHandler.postDelayed(onEndSetGoneStateListener.runnable,
                             MIN_DURATION_COMMITTED_AFTER_FLING_ANIMATION)
                 } else {
-                    mView.popScale(POP_ON_COMMITTED_SCALE)
+                    mView.popScale(POP_ON_COMMITTED_VELOCITY)
                     mainHandler.postDelayed(onAlphaEndSetGoneStateListener.runnable,
                             MIN_DURATION_COMMITTED_ANIMATION)
                 }
@@ -968,11 +978,11 @@
         }
     }
 
-    private fun convertVelocityToSpringStartingVelocity(
+    private fun convertVelocityToAnimationFactor(
             valueOnFastVelocity: Float,
             valueOnSlowVelocity: Float,
-            fastVelocityBound: Float = 3f,
-            slowVelocityBound: Float = 0f,
+            fastVelocityBound: Float = 1f,
+            slowVelocityBound: Float = 0.5f,
     ): Float {
         val factor = velocityTracker?.run {
             computeCurrentVelocity(PX_PER_MS)
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 41e3e6d..9a1efc3 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -15,6 +15,8 @@
  */
 package com.android.systemui.navigationbar.gestural;
 
+import static android.view.InputDevice.SOURCE_MOUSE;
+import static android.view.InputDevice.SOURCE_TOUCHPAD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
 
 import static com.android.systemui.classifier.Classifier.BACK_GESTURE;
@@ -937,10 +939,12 @@
             mMLResults = 0;
             mLogGesture = false;
             mInRejectedExclusion = false;
-            boolean isWithinInsets = isWithinInsets((int) ev.getX(), (int) ev.getY());
             // Trackpad back gestures don't have zones, so we don't need to check if the down event
-            // is within insets.
+            // is within insets. Also we don't allow back for button press from the trackpad, and
+            // yet we do with a mouse.
+            boolean isWithinInsets = isWithinInsets((int) ev.getX(), (int) ev.getY());
             mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed
+                    && !isButtonPressFromTrackpad(ev)
                     && (isTrackpadMultiFingerSwipe || isWithinInsets)
                     && !mGestureBlockingActivityRunning
                     && !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
@@ -1047,6 +1051,11 @@
         mProtoTracer.scheduleFrameUpdate();
     }
 
+    private boolean isButtonPressFromTrackpad(MotionEvent ev) {
+        int sources = InputManager.getInstance().getInputDevice(ev.getDeviceId()).getSources();
+        return (sources & (SOURCE_MOUSE | SOURCE_TOUCHPAD)) == sources && ev.getButtonState() != 0;
+    }
+
     private void dispatchToBackAnimation(MotionEvent event) {
         if (mBackAnimation != null) {
             mVelocityTracker.addMovement(event);
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 876c74a..182ece7 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -153,7 +153,7 @@
                 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 = createSpring(500f, 0.76f),
+                horizontalTranslationSpring = createSpring(800f, 0.76f),
                 verticalTranslationSpring = createSpring(30000f, 1f),
                 scaleSpring = createSpring(120f, 0.8f),
                 arrowDimens = ArrowDimens(
@@ -205,8 +205,8 @@
         activeIndicator = BackIndicatorDimens(
                 horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin),
                 scale = getDimenFloat(R.dimen.navigation_edge_active_scale),
-                horizontalTranslationSpring = createSpring(1000f, 0.7f),
-                scaleSpring = createSpring(450f, 0.39f),
+                horizontalTranslationSpring = createSpring(1000f, 0.8f),
+                scaleSpring = createSpring(325f, 0.55f),
                 scalePivotX = getDimen(R.dimen.navigation_edge_active_background_width),
                 arrowDimens = ArrowDimens(
                         length = getDimen(R.dimen.navigation_edge_active_arrow_length),
@@ -253,7 +253,7 @@
                                 getDimen(R.dimen.navigation_edge_pre_threshold_edge_corners),
                         farCornerRadius =
                                 getDimen(R.dimen.navigation_edge_pre_threshold_far_corners),
-                        widthSpring = createSpring(400f, 0.65f),
+                        widthSpring = createSpring(650f, 1f),
                         heightSpring = createSpring(1500f, 0.45f),
                         farCornerRadiusSpring = createSpring(300f, 1f),
                         edgeCornerRadiusSpring = createSpring(250f, 0.5f),
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivity.kt b/packages/SystemUI/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivity.kt
new file mode 100644
index 0000000..c209a00
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivity.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.notetask
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
+import javax.inject.Inject
+
+/**
+ * An internal proxy activity that starts the notes role setting.
+ *
+ * This activity is introduced mainly for the error handling of the notes app lock screen shortcut
+ * picker, which only supports package + action but not extras. See
+ * [KeyguardQuickAffordanceConfig.PickerScreenState.Disabled.actionComponentName].
+ */
+class LaunchNotesRoleSettingsTrampolineActivity
+@Inject
+constructor(
+    private val controller: NoteTaskController,
+) : ComponentActivity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        val entryPoint =
+            if (intent?.action == ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE) {
+                NoteTaskEntryPoint.QUICK_AFFORDANCE
+            } else {
+                null
+            }
+        controller.startNotesRoleSetting(this, entryPoint)
+        finish()
+    }
+
+    companion object {
+        const val ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE =
+            "com.android.systemui.action.MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index aab898e..7e9b346 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -31,18 +31,16 @@
 import android.content.pm.PackageManager
 import android.content.pm.ShortcutManager
 import android.graphics.drawable.Icon
-import android.os.Build
 import android.os.UserHandle
 import android.os.UserManager
-import android.util.Log
 import android.widget.Toast
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
+import com.android.systemui.log.DebugLogger.debugLog
 import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
 import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser
-import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
 import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shared.system.ActivityManagerKt.isInForeground
@@ -93,10 +91,10 @@
         if (info.launchMode != NoteTaskLaunchMode.AppBubble) return
 
         if (isExpanding) {
-            logDebug { "onBubbleExpandChanged - expanding: $info" }
+            debugLog { "onBubbleExpandChanged - expanding: $info" }
             eventLogger.logNoteTaskOpened(info)
         } else {
-            logDebug { "onBubbleExpandChanged - collapsing: $info" }
+            debugLog { "onBubbleExpandChanged - collapsing: $info" }
             eventLogger.logNoteTaskClosed(info)
         }
     }
@@ -113,6 +111,43 @@
         )
     }
 
+    /** Starts the notes role setting. */
+    fun startNotesRoleSetting(activityContext: Context, entryPoint: NoteTaskEntryPoint?) {
+        val user =
+            if (entryPoint == null) {
+                userTracker.userHandle
+            } else {
+                getUserForHandlingNotesTaking(entryPoint)
+            }
+        activityContext.startActivityAsUser(
+            Intent(Intent.ACTION_MANAGE_DEFAULT_APP).apply {
+                putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NOTES)
+            },
+            user
+        )
+    }
+
+    /**
+     * Returns the [UserHandle] of an android user that should handle the notes taking [entryPoint].
+     *
+     * On company owned personally enabled (COPE) devices, if the given [entryPoint] is in the
+     * [FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES] list, the default notes app in the work
+     * profile user will always be launched.
+     *
+     * On non managed devices or devices with other management modes, the current [UserHandle] is
+     * returned.
+     */
+    fun getUserForHandlingNotesTaking(entryPoint: NoteTaskEntryPoint): UserHandle =
+        if (
+            entryPoint in FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES &&
+                devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile
+        ) {
+            userTracker.userProfiles.firstOrNull { userManager.isManagedProfile(it.id) }?.userHandle
+                ?: userTracker.userHandle
+        } else {
+            userTracker.userHandle
+        }
+
     /**
      * Shows a note task. How the task is shown will depend on when the method is invoked.
      *
@@ -123,30 +158,13 @@
      * bubble is already opened.
      *
      * That will let users open other apps in full screen, and take contextual notes.
-     *
-     * On company owned personally enabled (COPE) devices, if the given [entryPoint] is in the
-     * [FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES] list, the default notes app in the work
-     * profile user will always be launched.
      */
     fun showNoteTask(
         entryPoint: NoteTaskEntryPoint,
     ) {
         if (!isEnabled) return
 
-        val user: UserHandle =
-            if (
-                entryPoint in FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES &&
-                    devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile
-            ) {
-                userTracker.userProfiles
-                    .firstOrNull { userManager.isManagedProfile(it.id) }
-                    ?.userHandle
-                    ?: userTracker.userHandle
-            } else {
-                userTracker.userHandle
-            }
-
-        showNoteTaskAsUser(entryPoint, user)
+        showNoteTaskAsUser(entryPoint, getUserForHandlingNotesTaking(entryPoint))
     }
 
     /** A variant of [showNoteTask] which launches note task in the given [user]. */
@@ -169,14 +187,14 @@
             isKeyguardLocked &&
                 devicePolicyManager.areKeyguardShortcutsDisabled(userId = user.identifier)
         ) {
-            logDebug { "Enterprise policy disallows launching note app when the screen is locked." }
+            debugLog { "Enterprise policy disallows launching note app when the screen is locked." }
             return
         }
 
         val info = resolver.resolveInfo(entryPoint, isKeyguardLocked, user)
 
         if (info == null) {
-            logDebug { "Default notes app isn't set" }
+            debugLog { "Default notes app isn't set" }
             showNoDefaultNotesAppToast()
             return
         }
@@ -185,7 +203,7 @@
 
         try {
             // TODO(b/266686199): We should handle when app not available. For now, we log.
-            logDebug { "onShowNoteTask - start: $info on user#${user.identifier}" }
+            debugLog { "onShowNoteTask - start: $info on user#${user.identifier}" }
             when (info.launchMode) {
                 is NoteTaskLaunchMode.AppBubble -> {
                     val intent = createNoteTaskIntent(info)
@@ -193,7 +211,7 @@
                         Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
                     bubbles.showOrHideAppBubble(intent, user, icon)
                     // App bubble logging happens on `onBubbleExpandChanged`.
-                    logDebug { "onShowNoteTask - opened as app bubble: $info" }
+                    debugLog { "onShowNoteTask - opened as app bubble: $info" }
                 }
                 is NoteTaskLaunchMode.Activity -> {
                     if (activityManager.isInForeground(info.packageName)) {
@@ -201,20 +219,20 @@
                         val intent = createHomeIntent()
                         context.startActivityAsUser(intent, user)
                         eventLogger.logNoteTaskClosed(info)
-                        logDebug { "onShowNoteTask - closed as activity: $info" }
+                        debugLog { "onShowNoteTask - closed as activity: $info" }
                     } else {
                         val intent = createNoteTaskIntent(info)
                         context.startActivityAsUser(intent, user)
                         eventLogger.logNoteTaskOpened(info)
-                        logDebug { "onShowNoteTask - opened as activity: $info" }
+                        debugLog { "onShowNoteTask - opened as activity: $info" }
                     }
                 }
             }
-            logDebug { "onShowNoteTask - success: $info" }
+            debugLog { "onShowNoteTask - success: $info" }
         } catch (e: ActivityNotFoundException) {
-            logDebug { "onShowNoteTask - failed: $info" }
+            debugLog { "onShowNoteTask - failed: $info" }
         }
-        logDebug { "onShowNoteTask - completed: $info" }
+        debugLog { "onShowNoteTask - completed: $info" }
     }
 
     @VisibleForTesting
@@ -231,8 +249,6 @@
      * Widget Picker to all users.
      */
     fun setNoteTaskShortcutEnabled(value: Boolean, user: UserHandle) {
-        val componentName = ComponentName(context, CreateNoteTaskShortcutActivity::class.java)
-
         val enabledState =
             if (value) {
                 PackageManager.COMPONENT_ENABLED_STATE_ENABLED
@@ -249,13 +265,14 @@
             } else {
                 context.createContextAsUser(user, /* flags= */ 0)
             }
+
         userContext.packageManager.setComponentEnabledSetting(
-            componentName,
+            SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT,
             enabledState,
             PackageManager.DONT_KILL_APP,
         )
 
-        logDebug { "setNoteTaskShortcutEnabled - completed: $isEnabled" }
+        debugLog { "setNoteTaskShortcutEnabled - completed: $isEnabled" }
     }
 
     /**
@@ -284,12 +301,33 @@
 
     /** @see OnRoleHoldersChangedListener */
     fun onRoleHoldersChanged(roleName: String, user: UserHandle) {
-        if (roleName == ROLE_NOTES) updateNoteTaskAsUser(user)
+        if (roleName != ROLE_NOTES) return
+
+        if (user == userTracker.userHandle) {
+            updateNoteTaskAsUser(user)
+        } else {
+            // TODO(b/278729185): Replace fire and forget service with a bounded service.
+            val intent = NoteTaskControllerUpdateService.createIntent(context)
+            context.startServiceAsUser(intent, user)
+        }
     }
 
     companion object {
         val TAG = NoteTaskController::class.simpleName.orEmpty()
 
+        /**
+         * IMPORTANT! The shortcut package name and class should be synchronized with Settings:
+         * [com.android.settings.notetask.shortcut.CreateNoteTaskShortcutActivity].
+         *
+         * Changing the package name or class is a breaking change.
+         */
+        @VisibleForTesting
+        val SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT =
+            ComponentName(
+                "com.android.settings",
+                "com.android.settings.notetask.shortcut.CreateNoteTaskShortcutActivity",
+            )
+
         const val SHORTCUT_ID = "note_task_shortcut_id"
 
         /**
@@ -333,11 +371,6 @@
         }
     }
 
-/** [Log.println] a [Log.DEBUG] message, only when [Build.IS_DEBUGGABLE]. */
-private inline fun Any.logDebug(message: () -> String) {
-    if (Build.IS_DEBUGGABLE) Log.d(this::class.java.simpleName.orEmpty(), message())
-}
-
 /** Creates an [Intent] which forces the current app to background by calling home. */
 private fun createHomeIntent(): Intent =
     Intent(Intent.ACTION_MAIN).apply {
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskControllerUpdateService.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskControllerUpdateService.kt
new file mode 100644
index 0000000..26b35cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskControllerUpdateService.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.notetask
+
+import android.content.Context
+import android.content.Intent
+import androidx.lifecycle.LifecycleService
+import javax.inject.Inject
+
+/**
+ * A fire & forget service for updating note task shortcuts.
+ *
+ * The main use is to update shortcuts in different user by launching it using `startServiceAsUser`.
+ * The service will open with access to a context from that user, trigger
+ * [NoteTaskController.updateNoteTaskAsUser] and [stopSelf] immediately.
+ *
+ * The fire and forget approach was created due to its simplicity but may use unnecessary resources
+ * by recreating the services. We will investigate its impacts and consider to move to a bounded
+ * services - the implementation is more complex as a bounded service is asynchronous by default.
+ *
+ * TODO(b/278729185): Replace fire and forget service with a bounded service.
+ */
+@InternalNoteTaskApi
+class NoteTaskControllerUpdateService
+@Inject
+constructor(
+    val controller: NoteTaskController,
+) : LifecycleService() {
+
+    override fun onCreate() {
+        super.onCreate()
+        // TODO(b/278729185): Replace fire and forget service with a bounded service.
+        controller.updateNoteTaskAsUser(user)
+        stopSelf()
+    }
+
+    companion object {
+        fun createIntent(context: Context): Intent =
+            Intent(context, NoteTaskControllerUpdateService::class.java)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
index 1839dfd..4d5173a 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
@@ -14,14 +14,16 @@
  * limitations under the License.
  */
 
+@file:OptIn(InternalNoteTaskApi::class)
+
 package com.android.systemui.notetask
 
 import android.app.Activity
+import android.app.Service
 import android.app.role.RoleManager
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.notetask.quickaffordance.NoteTaskQuickAffordanceModule
-import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
 import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
 import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity
 import dagger.Binds
@@ -34,14 +36,18 @@
 @Module(includes = [NoteTaskQuickAffordanceModule::class])
 interface NoteTaskModule {
 
+    @[Binds IntoMap ClassKey(NoteTaskControllerUpdateService::class)]
+    fun NoteTaskControllerUpdateService.bindNoteTaskControllerUpdateService(): Service
+
     @[Binds IntoMap ClassKey(LaunchNoteTaskActivity::class)]
     fun LaunchNoteTaskActivity.bindNoteTaskLauncherActivity(): Activity
 
     @[Binds IntoMap ClassKey(LaunchNoteTaskManagedProfileProxyActivity::class)]
     fun LaunchNoteTaskManagedProfileProxyActivity.bindNoteTaskLauncherProxyActivity(): Activity
 
-    @[Binds IntoMap ClassKey(CreateNoteTaskShortcutActivity::class)]
-    fun CreateNoteTaskShortcutActivity.bindNoteTaskShortcutActivity(): Activity
+    @[Binds IntoMap ClassKey(LaunchNotesRoleSettingsTrampolineActivity::class)]
+    fun LaunchNotesRoleSettingsTrampolineActivity.bindLaunchNotesRoleSettingsTrampolineActivity():
+        Activity
 
     companion object {
 
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 2da5b76..444407c 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
@@ -16,9 +16,12 @@
 
 package com.android.systemui.notetask.quickaffordance
 
+import android.app.role.OnRoleHoldersChangedListener
+import android.app.role.RoleManager
 import android.content.Context
 import android.hardware.input.InputSettings
 import android.os.Build
+import android.os.UserHandle
 import android.os.UserManager
 import android.util.Log
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -27,17 +30,22 @@
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.data.quickaffordance.BuiltInKeyguardQuickAffordanceKeys
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.LockScreenState
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.PickerScreenState
 import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
+import com.android.systemui.notetask.LaunchNotesRoleSettingsTrampolineActivity.Companion.ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE
 import com.android.systemui.notetask.NoteTaskController
 import com.android.systemui.notetask.NoteTaskEnabledKey
-import com.android.systemui.notetask.NoteTaskEntryPoint
+import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
+import com.android.systemui.notetask.NoteTaskInfoResolver
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract.LockScreenQuickAffordances.AffordanceTable.COMPONENT_NAME_SEPARATOR
 import com.android.systemui.stylus.StylusManager
 import dagger.Lazy
+import java.util.concurrent.Executor
 import javax.inject.Inject
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.channels.trySendBlocking
@@ -49,13 +57,16 @@
 class NoteTaskQuickAffordanceConfig
 @Inject
 constructor(
-    context: Context,
+    private val context: Context,
     private val controller: NoteTaskController,
+    private val noteTaskInfoResolver: NoteTaskInfoResolver,
     private val stylusManager: StylusManager,
+    private val roleManager: RoleManager,
     private val keyguardMonitor: KeyguardUpdateMonitor,
     private val userManager: UserManager,
     private val lazyRepository: Lazy<KeyguardQuickAffordanceRepository>,
     @NoteTaskEnabledKey private val isEnabled: Boolean,
+    @Background private val backgroundExecutor: Executor,
 ) : KeyguardQuickAffordanceConfig {
 
     override val key = BuiltInKeyguardQuickAffordanceKeys.CREATE_NOTE
@@ -73,15 +84,24 @@
         val configSelectedFlow = repository.createConfigSelectedFlow(key)
         val stylusEverUsedFlow = stylusManager.createStylusEverUsedFlow(context)
         val userUnlockedFlow = userManager.createUserUnlockedFlow(keyguardMonitor)
-        combine(userUnlockedFlow, stylusEverUsedFlow, configSelectedFlow) {
+        val defaultNotesAppFlow =
+            roleManager.createNotesRoleFlow(backgroundExecutor, controller, noteTaskInfoResolver)
+        combine(userUnlockedFlow, stylusEverUsedFlow, configSelectedFlow, defaultNotesAppFlow) {
                 isUserUnlocked,
                 isStylusEverUsed,
-                isConfigSelected ->
+                isConfigSelected,
+                isDefaultNotesAppSet ->
                 logDebug { "lockScreenState:isUserUnlocked=$isUserUnlocked" }
                 logDebug { "lockScreenState:isStylusEverUsed=$isStylusEverUsed" }
                 logDebug { "lockScreenState:isConfigSelected=$isConfigSelected" }
+                logDebug { "lockScreenState:isDefaultNotesAppSet=$isDefaultNotesAppSet" }
 
-                if (isEnabled && isUserUnlocked && (isConfigSelected || isStylusEverUsed)) {
+                if (
+                    isEnabled &&
+                        isUserUnlocked &&
+                        isDefaultNotesAppSet &&
+                        (isConfigSelected || isStylusEverUsed)
+                ) {
                     val contentDescription = ContentDescription.Resource(pickerNameResourceId)
                     val icon = Icon.Resource(pickerIconResourceId, contentDescription)
                     LockScreenState.Visible(icon)
@@ -92,15 +112,34 @@
             .onEach { state -> logDebug { "lockScreenState=$state" } }
     }
 
-    override suspend fun getPickerScreenState() =
-        if (isEnabled) {
-            PickerScreenState.Default()
-        } else {
-            PickerScreenState.UnavailableOnDevice
+    override suspend fun getPickerScreenState(): PickerScreenState {
+        val isDefaultNotesAppSet =
+            noteTaskInfoResolver.resolveInfo(
+                QUICK_AFFORDANCE,
+                user = controller.getUserForHandlingNotesTaking(QUICK_AFFORDANCE)
+            ) != null
+        return when {
+            isEnabled && isDefaultNotesAppSet -> PickerScreenState.Default()
+            isEnabled -> {
+                PickerScreenState.Disabled(
+                    listOf(
+                        context.getString(
+                            R.string.keyguard_affordance_enablement_dialog_notes_app_instruction
+                        )
+                    ),
+                    context.getString(
+                        R.string.keyguard_affordance_enablement_dialog_notes_app_action
+                    ),
+                    "${context.packageName}$COMPONENT_NAME_SEPARATOR" +
+                        "$ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE",
+                )
+            }
+            else -> PickerScreenState.UnavailableOnDevice
         }
+    }
 
     override fun onTriggered(expandable: Expandable?): OnTriggeredResult {
-        controller.showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
+        controller.showNoteTask(entryPoint = QUICK_AFFORDANCE)
         return OnTriggeredResult.Handled
     }
 }
@@ -129,6 +168,27 @@
     awaitClose { unregisterCallback(callback) }
 }
 
+private fun RoleManager.createNotesRoleFlow(
+    executor: Executor,
+    noteTaskController: NoteTaskController,
+    noteTaskInfoResolver: NoteTaskInfoResolver,
+) = callbackFlow {
+    fun isDefaultNotesAppSetForUser() =
+        noteTaskInfoResolver.resolveInfo(
+            QUICK_AFFORDANCE,
+            user = noteTaskController.getUserForHandlingNotesTaking(QUICK_AFFORDANCE)
+        ) != null
+
+    trySendBlocking(isDefaultNotesAppSetForUser())
+    val callback = OnRoleHoldersChangedListener { roleName, _ ->
+        if (roleName == RoleManager.ROLE_NOTES) {
+            trySendBlocking(isDefaultNotesAppSetForUser())
+        }
+    }
+    addOnRoleHoldersChangedListenerAsUser(executor, callback, UserHandle.ALL)
+    awaitClose { removeOnRoleHoldersChangedListenerAsUser(callback, UserHandle.ALL) }
+}
+
 private fun KeyguardQuickAffordanceRepository.createConfigSelectedFlow(key: String) =
     selections.map { selected ->
         selected.values.flatten().any { selectedConfig -> selectedConfig.key == key }
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
deleted file mode 100644
index 0cfb0a5..0000000
--- a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.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.
- */
-
-@file:OptIn(InternalNoteTaskApi::class)
-
-package com.android.systemui.notetask.shortcut
-
-import android.app.Activity
-import android.app.role.RoleManager
-import android.content.pm.ShortcutManager
-import android.os.Bundle
-import androidx.activity.ComponentActivity
-import com.android.systemui.notetask.InternalNoteTaskApi
-import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
-import javax.inject.Inject
-
-/**
- * Activity responsible for create a shortcut for notes action. If the shortcut is enabled, a new
- * shortcut will appear in the widget picker. If the shortcut is selected, the Activity here will be
- * launched, creating a new shortcut for [CreateNoteTaskShortcutActivity], and will finish.
- *
- * @see <a
- *   href="https://developer.android.com/develop/ui/views/launch/shortcuts/creating-shortcuts#custom-pinned">Creating
- *   a custom shortcut activity</a>
- */
-class CreateNoteTaskShortcutActivity
-@Inject
-constructor(
-    private val roleManager: RoleManager,
-    private val shortcutManager: ShortcutManager,
-) : ComponentActivity() {
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-
-        val shortcutInfo = roleManager.createNoteShortcutInfoAsUser(context = this, user)
-        val shortcutIntent = shortcutManager.createShortcutResultIntent(shortcutInfo)
-        setResult(Activity.RESULT_OK, shortcutIntent)
-
-        finish()
-    }
-}
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 0f38d32..8ca13b9 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
@@ -18,12 +18,11 @@
 
 import android.content.Context
 import android.content.Intent
-import android.os.Build
 import android.os.Bundle
 import android.os.UserHandle
 import android.os.UserManager
-import android.util.Log
 import androidx.activity.ComponentActivity
+import com.android.systemui.log.DebugLogger.debugLog
 import com.android.systemui.notetask.NoteTaskController
 import com.android.systemui.notetask.NoteTaskEntryPoint
 import com.android.systemui.settings.UserTracker
@@ -68,7 +67,7 @@
         val mainUser: UserHandle? = userManager.mainUser
         if (userManager.isManagedProfile) {
             if (mainUser == null) {
-                logDebug { "Can't find the main user. Skipping the notes app launch." }
+                debugLog { "Can't find the main user. Skipping the notes app launch." }
             } else {
                 controller.startNoteTaskProxyActivityForUser(mainUser)
             }
@@ -89,8 +88,3 @@
         }
     }
 }
-
-/** [Log.println] a [Log.DEBUG] message, only when [Build.IS_DEBUGGABLE]. */
-private inline fun Any.logDebug(message: () -> String) {
-    if (Build.IS_DEBUGGABLE) Log.d(this::class.java.simpleName.orEmpty(), message())
-}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index 79167f2..166ba9f 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -15,6 +15,7 @@
 package com.android.systemui.privacy
 
 import android.content.Context
+import android.content.res.Configuration
 import android.util.AttributeSet
 import android.view.Gravity.CENTER_VERTICAL
 import android.view.Gravity.END
@@ -102,6 +103,11 @@
                 R.string.ongoing_privacy_chip_content_multiple_apps, typesText)
     }
 
+    override fun onConfigurationChanged(newConfig: Configuration?) {
+        super.onConfigurationChanged(newConfig)
+        updateResources()
+    }
+
     private fun updateResources() {
         iconMargin = context.resources
                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_margin)
@@ -110,8 +116,11 @@
         iconColor =
                 Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
 
+        val height = context.resources
+                .getDimensionPixelSize(R.dimen.ongoing_appops_chip_height)
         val padding = context.resources
                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
+        iconsContainer.layoutParams.height = height
         iconsContainer.setPaddingRelative(padding, 0, padding, 0)
         iconsContainer.background = context.getDrawable(R.drawable.statusbar_privacy_chip_bg)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt b/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
index 6f645b5..995c6a4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
@@ -26,7 +26,9 @@
 import javax.inject.Inject
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.shade.ShadeModule.Companion.SHADE_HEADER
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import javax.inject.Named
 
 interface ChipVisibilityListener {
     fun onChipVisibilityRefreshed(visible: Boolean)
@@ -45,10 +47,10 @@
 class HeaderPrivacyIconsController @Inject constructor(
     private val privacyItemController: PrivacyItemController,
     private val uiEventLogger: UiEventLogger,
-    private val privacyChip: OngoingPrivacyChip,
+    @Named(SHADE_HEADER) private val privacyChip: OngoingPrivacyChip,
     private val privacyDialogController: PrivacyDialogController,
     private val privacyLogger: PrivacyLogger,
-    private val iconContainer: StatusIconContainer,
+    @Named(SHADE_HEADER) private val iconContainer: StatusIconContainer,
     private val permissionManager: PermissionManager,
     @Background private val backgroundExecutor: Executor,
     @Main private val uiExecutor: Executor,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index b7f9f6b..1afc885 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -38,7 +38,9 @@
  */
 public class QSContainerImpl extends FrameLayout implements Dumpable {
 
+    private int mFancyClippingLeftInset;
     private int mFancyClippingTop;
+    private int mFancyClippingRightInset;
     private int mFancyClippingBottom;
     private final float[] mFancyClippingRadii = new float[] {0, 0, 0, 0, 0, 0, 0, 0};
     private  final Path mFancyClippingPath = new Path();
@@ -53,6 +55,7 @@
     private boolean mQsDisabled;
     private int mContentHorizontalPadding = -1;
     private boolean mClippingEnabled;
+    private boolean mIsFullWidth;
 
     public QSContainerImpl(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -237,7 +240,8 @@
     /**
      * Clip QS bottom using a concave shape.
      */
-    public void setFancyClipping(int top, int bottom, int radius, boolean enabled) {
+    public void setFancyClipping(int leftInset, int top, int rightInset, int bottom, int radius,
+            boolean enabled, boolean fullWidth) {
         boolean updatePath = false;
         if (mFancyClippingRadii[0] != radius) {
             mFancyClippingRadii[0] = radius;
@@ -246,10 +250,18 @@
             mFancyClippingRadii[3] = radius;
             updatePath = true;
         }
+        if (mFancyClippingLeftInset != leftInset) {
+            mFancyClippingLeftInset = leftInset;
+            updatePath = true;
+        }
         if (mFancyClippingTop != top) {
             mFancyClippingTop = top;
             updatePath = true;
         }
+        if (mFancyClippingRightInset != rightInset) {
+            mFancyClippingRightInset = rightInset;
+            updatePath = true;
+        }
         if (mFancyClippingBottom != bottom) {
             mFancyClippingBottom = bottom;
             updatePath = true;
@@ -258,6 +270,10 @@
             mClippingEnabled = enabled;
             updatePath = true;
         }
+        if (mIsFullWidth != fullWidth) {
+            mIsFullWidth = fullWidth;
+            updatePath = true;
+        }
 
         if (updatePath) {
             updateClippingPath();
@@ -281,15 +297,21 @@
             return;
         }
 
-        mFancyClippingPath.addRoundRect(0, mFancyClippingTop, getWidth(),
+        int clippingLeft = mIsFullWidth ? -mFancyClippingLeftInset : 0;
+        int clippingRight = mIsFullWidth ? getWidth() + mFancyClippingRightInset : getWidth();
+        mFancyClippingPath.addRoundRect(clippingLeft, mFancyClippingTop, clippingRight,
                 mFancyClippingBottom, mFancyClippingRadii, Path.Direction.CW);
         invalidate();
     }
 
     @Override
     public void dump(PrintWriter pw, String[] args) {
-        pw.println(getClass().getSimpleName() + " updateClippingPath: top("
-                + mFancyClippingTop + ") bottom(" + mFancyClippingBottom  + ") mClippingEnabled("
-                + mClippingEnabled + ")");
+        pw.println(getClass().getSimpleName() + " updateClippingPath: "
+                + "leftInset(" + mFancyClippingLeftInset + ") "
+                + "top(" + mFancyClippingTop + ") "
+                + "rightInset(" + mFancyClippingRightInset + ") "
+                + "bottom(" + mFancyClippingBottom  + ") "
+                + "mClippingEnabled(" + mClippingEnabled + ") "
+                + "mIsFullWidth(" + mIsFullWidth + ")");
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 584d27f8..fd3f701 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -18,9 +18,10 @@
 
 import static com.android.systemui.media.dagger.MediaModule.QS_PANEL;
 import static com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL;
-import static com.android.systemui.statusbar.disableflags.DisableFlagsLogger.DisableState;
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
+import static com.android.systemui.statusbar.disableflags.DisableFlagsLogger.DisableState;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.content.res.Configuration;
@@ -119,6 +120,7 @@
     private final QSLogger mLogger;
     private final FooterActionsController mFooterActionsController;
     private final FooterActionsViewModel.Factory mFooterActionsViewModelFactory;
+    private final FooterActionsViewBinder mFooterActionsViewBinder;
     private final ListeningAndVisibilityLifecycleOwner mListeningAndVisibilityLifecycleOwner;
     private boolean mShowCollapsedOnKeyguard;
     private boolean mLastKeyguardAndExpanded;
@@ -176,6 +178,7 @@
             DumpManager dumpManager, QSLogger qsLogger,
             FooterActionsController footerActionsController,
             FooterActionsViewModel.Factory footerActionsViewModelFactory,
+            FooterActionsViewBinder footerActionsViewBinder,
             LargeScreenShadeInterpolator largeScreenShadeInterpolator,
             FeatureFlags featureFlags) {
         mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
@@ -192,6 +195,7 @@
         mDumpManager = dumpManager;
         mFooterActionsController = footerActionsController;
         mFooterActionsViewModelFactory = footerActionsViewModelFactory;
+        mFooterActionsViewBinder = footerActionsViewBinder;
         mListeningAndVisibilityLifecycleOwner = new ListeningAndVisibilityLifecycleOwner();
     }
 
@@ -284,7 +288,7 @@
 
         if (!ComposeFacade.INSTANCE.isComposeAvailable()) {
             Log.d(TAG, "Binding the View implementation of the QS footer actions");
-            FooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
+            mFooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
                     mListeningAndVisibilityLifecycleOwner);
             return;
         }
@@ -392,9 +396,11 @@
     }
 
     @Override
-    public void setFancyClipping(int top, int bottom, int cornerRadius, boolean visible) {
+    public void setFancyClipping(int leftInset, int top, int rightInset, int bottom,
+            int cornerRadius, boolean visible, boolean fullWidth) {
         if (getView() instanceof QSContainerImpl) {
-            ((QSContainerImpl) getView()).setFancyClipping(top, bottom, cornerRadius, visible);
+            ((QSContainerImpl) getView()).setFancyClipping(leftInset, top, rightInset, bottom,
+                    cornerRadius, visible, fullWidth);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
index 0bce1f7..b70b94b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
@@ -719,7 +719,8 @@
                 String name = vpnName != null ? vpnName : vpnNameWorkProfile;
                 String namedVp = mDpm.getResources().getString(
                         QS_DIALOG_MANAGEMENT_NAMED_VPN,
-                        () -> mContext.getString(R.string.monitoring_description_named_vpn, name),
+                        () -> mContext.getString(
+                                R.string.monitoring_description_managed_device_named_vpn, name),
                         name);
                 message.append(namedVp);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
index 1921586..9c9ad33 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
@@ -33,27 +33,27 @@
 import com.android.systemui.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.ui.binder.IconViewBinder
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.people.ui.view.PeopleViewBinder.bind
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsForegroundServicesButtonViewModel
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
+import javax.inject.Inject
 import kotlin.math.roundToInt
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
 
 /** A ViewBinder for [FooterActionsViewBinder]. */
-object FooterActionsViewBinder {
+@SysUISingleton
+class FooterActionsViewBinder @Inject constructor() {
     /** Create a view that can later be [bound][bind] to a [FooterActionsViewModel]. */
-    @JvmStatic
     fun create(context: Context): LinearLayout {
         return LayoutInflater.from(context).inflate(R.layout.footer_actions, /* root= */ null)
             as LinearLayout
     }
 
     /** Bind [view] to [viewModel]. */
-    @JvmStatic
     fun bind(
         view: LinearLayout,
         viewModel: FooterActionsViewModel,
@@ -98,6 +98,11 @@
         var previousForegroundServices: FooterActionsForegroundServicesButtonViewModel? = null
         var previousUserSwitcher: FooterActionsButtonViewModel? = null
 
+        // Set the initial visibility on the View directly so that we don't briefly show it for a
+        // few frames before [viewModel.isVisible] is collected.
+        view.isInvisible = !viewModel.isVisible.value
+
+        // Listen for ViewModel updates when the View is attached.
         view.repeatWhenAttached {
             val attachedScope = this.lifecycleScope
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
index 3a9098a..b3596a2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
@@ -64,7 +64,7 @@
      * the UI should still participate to the layout it is included in (i.e. in the View world it
      * should be INVISIBLE, not GONE).
      */
-    private val _isVisible = MutableStateFlow(true)
+    private val _isVisible = MutableStateFlow(false)
     val isVisible: StateFlow<Boolean> = _isVisible.asStateFlow()
 
     /** The alpha the UI rendering this ViewModel should have. */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 4a31998..b806683 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -385,6 +385,11 @@
         super.onInitializeAccessibilityNodeInfo(info)
         // Clear selected state so it is not announce by talkback.
         info.isSelected = false
+        info.text = if (TextUtils.isEmpty(secondaryLabel.text)) {
+            "${label.text}"
+        } else {
+            "${label.text}, ${secondaryLabel.text}"
+        }
         if (lastDisabledByPolicy) {
             info.addAction(
                     AccessibilityNodeInfo.AccessibilityAction(
@@ -402,12 +407,6 @@
                 accessibilityClass
             }
             if (Switch::class.java.name == accessibilityClass) {
-                val label = resources.getString(
-                        if (tileState) R.string.switch_bar_on else R.string.switch_bar_off)
-                // Set the text here for tests in
-                // android.platform.test.scenario.sysui.quicksettings. Can be removed when
-                // UiObject2 has a new getStateDescription() API and tests are updated.
-                info.text = label
                 info.isChecked = tileState
                 info.isCheckable = true
                 if (isLongClickable) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index f16f0dc..ffe5489 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -458,13 +458,28 @@
                 getTileSpec(), mLastTileState, arg == null ? "null" : arg.toString());
         if (arg instanceof CellularCallbackInfo) {
             mLastTileState = LAST_STATE_CELLULAR;
-            handleUpdateCellularState(state, arg);
+            CellularCallbackInfo cb = (CellularCallbackInfo) arg;
+            CellularCallbackInfo cellularInfo = new CellularCallbackInfo();
+            synchronized (cb) {
+                cb.copyTo(cellularInfo);
+            }
+            handleUpdateCellularState(state, cellularInfo);
         } else if (arg instanceof WifiCallbackInfo) {
             mLastTileState = LAST_STATE_WIFI;
-            handleUpdateWifiState(state, arg);
+            WifiCallbackInfo cb = (WifiCallbackInfo) arg;
+            WifiCallbackInfo wifiInfo = new WifiCallbackInfo();
+            synchronized (cb) {
+                cb.copyTo(wifiInfo);
+            }
+            handleUpdateWifiState(state, wifiInfo);
         } else if (arg instanceof EthernetCallbackInfo) {
             mLastTileState = LAST_STATE_ETHERNET;
-            handleUpdateEthernetState(state, arg);
+            EthernetCallbackInfo cb = (EthernetCallbackInfo) arg;
+            EthernetCallbackInfo ethernetInfo = new EthernetCallbackInfo();
+            synchronized (cb) {
+                cb.copyTo(ethernetInfo);
+            }
+            handleUpdateEthernetState(state, ethernetInfo);
         } else {
             // handleUpdateState will be triggered when user expands the QuickSetting panel with
             // arg = null, in this case the last updated CellularCallbackInfo or WifiCallbackInfo
@@ -476,11 +491,11 @@
                 }
                 handleUpdateCellularState(state, cellularInfo);
             } else if (mLastTileState == LAST_STATE_WIFI) {
-                WifiCallbackInfo mifiInfo = new WifiCallbackInfo();
+                WifiCallbackInfo wifiInfo = new WifiCallbackInfo();
                 synchronized (mSignalCallback.mWifiInfo) {
-                    mSignalCallback.mWifiInfo.copyTo(mifiInfo);
+                    mSignalCallback.mWifiInfo.copyTo(wifiInfo);
                 }
-                handleUpdateWifiState(state, mifiInfo);
+                handleUpdateWifiState(state, wifiInfo);
             } else if (mLastTileState == LAST_STATE_ETHERNET) {
                 EthernetCallbackInfo ethernetInfo = new EthernetCallbackInfo();
                 synchronized (mSignalCallback.mEthernetInfo) {
@@ -667,11 +682,16 @@
         }
 
         @Override
+        @NonNull
         public Drawable getDrawable(Context context) {
             SignalDrawable d = new SignalDrawable(context);
             d.setLevel(getState());
             return d;
         }
+        @Override
+        public String toString() {
+            return String.format("SignalIcon[mState=0x%08x]", mState);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 7f7f8ad6..2d9f7dd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -68,6 +68,7 @@
     private final SensorPrivacyManager mPrivacyManager;
     private final BatteryController mBatteryController;
     private final SettingObserver mSetting;
+    private final boolean mAllowRotationResolver;
 
     @Inject
     public RotationLockTile(
@@ -105,6 +106,8 @@
             }
         };
         mBatteryController.observe(getLifecycle(), this);
+        mAllowRotationResolver = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_allowRotationResolver);
     }
 
     @Override
@@ -145,7 +148,7 @@
 
         final boolean powerSave = mBatteryController.isPowerSave();
         final boolean cameraLocked = mPrivacyManager.isSensorPrivacyEnabled(CAMERA);
-        final boolean cameraRotation =
+        final boolean cameraRotation = mAllowRotationResolver &&
                 !powerSave && !cameraLocked && hasSufficientPermission(mContext)
                         && mController.isCameraRotationEnabled();
         state.value = !rotationLocked;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index 5ea1c0b..4b22edc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -23,15 +23,16 @@
 import android.util.Log;
 
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 
+import dagger.Lazy;
+
 import java.util.Optional;
 
 import javax.inject.Inject;
 
-import dagger.Lazy;
-
 /**
  * An implementation of the Recents interface which proxies to the OverviewProxyService.
  */
@@ -44,13 +45,15 @@
 
     private Handler mHandler;
     private final OverviewProxyService mOverviewProxyService;
+    private final ActivityStarter mActivityStarter;
 
     @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
     @Inject
     public OverviewProxyRecentsImpl(Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
-            OverviewProxyService overviewProxyService) {
+            OverviewProxyService overviewProxyService, ActivityStarter activityStarter) {
         mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mOverviewProxyService = overviewProxyService;
+        mActivityStarter = activityStarter;
     }
 
     @Override
@@ -101,7 +104,7 @@
             final Optional<CentralSurfaces> centralSurfacesOptional =
                     mCentralSurfacesOptionalLazy.get();
             if (centralSurfacesOptional.map(CentralSurfaces::isKeyguardShowing).orElse(false)) {
-                centralSurfacesOptional.get().executeRunnableDismissingKeyguard(
+                mActivityStarter.executeRunnableDismissingKeyguard(
                         () -> mHandler.post(toggleRecents), null, true /* dismissShade */,
                         false /* afterKeyguardGone */,
                         true /* deferred */);
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt
index db0052a..b340043 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt
@@ -43,6 +43,7 @@
 ) : SystemUIDialog(context), AdapterView.OnItemSelectedListener {
     private lateinit var dialogTitle: TextView
     private lateinit var startButton: TextView
+    private lateinit var cancelButton: TextView
     private lateinit var warning: TextView
     private lateinit var screenShareModeSpinner: Spinner
     var selectedScreenShareOption: ScreenShareOption = screenShareOptions.first()
@@ -56,8 +57,8 @@
         setContentView(R.layout.screen_share_dialog)
         dialogTitle = findViewById(R.id.screen_share_dialog_title)
         warning = findViewById(R.id.text_warning)
-        startButton = findViewById(R.id.button_start)
-        findViewById<TextView>(R.id.button_cancel).setOnClickListener { dismiss() }
+        startButton = findViewById(android.R.id.button1)
+        cancelButton = findViewById(android.R.id.button2)
         updateIcon()
         initScreenShareOptions()
         createOptionsView(getOptionsViewLayoutId())
@@ -117,6 +118,10 @@
         startButton.setOnClickListener(listener)
     }
 
+    protected fun setCancelButtonOnClickListener(listener: View.OnClickListener?) {
+        cancelButton.setOnClickListener(listener)
+    }
+
     // Create additional options that is shown under the share mode spinner
     // Eg. the audio and tap toggles in SysUI Recorder
     @LayoutRes protected open fun getOptionsViewLayoutId(): Int? = null
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt
index c5a82ce1..f4f5f66 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt
@@ -23,48 +23,55 @@
 class MediaProjectionPermissionDialog(
     context: Context?,
     private val onStartRecordingClicked: Runnable,
+    private val onCancelClicked: Runnable,
     private val appName: String?
 ) : BaseScreenSharePermissionDialog(context, createOptionList(appName), appName) {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        // TODO(b/270018943): Handle the case of System sharing (not recording nor casting)
         if (appName == null) {
-            setDialogTitle(R.string.media_projection_permission_dialog_system_service_title)
+            setDialogTitle(R.string.media_projection_entry_cast_permission_dialog_title)
+            setStartButtonText(R.string.media_projection_entry_cast_permission_dialog_continue)
         } else {
-            setDialogTitle(R.string.media_projection_permission_dialog_title)
+            setDialogTitle(R.string.media_projection_entry_app_permission_dialog_title)
+            setStartButtonText(R.string.media_projection_entry_app_permission_dialog_continue)
         }
-        setStartButtonText(R.string.media_projection_permission_dialog_continue)
         setStartButtonOnClickListener {
             // Note that it is important to run this callback before dismissing, so that the
             // callback can disable the dialog exit animation if it wants to.
             onStartRecordingClicked.run()
             dismiss()
         }
+        setCancelButtonOnClickListener {
+            onCancelClicked.run()
+            dismiss()
+        }
     }
 
     companion object {
         private fun createOptionList(appName: String?): List<ScreenShareOption> {
             val singleAppWarningText =
                 if (appName == null) {
-                    R.string.media_projection_permission_dialog_system_service_warning_single_app
+                    R.string.media_projection_entry_cast_permission_dialog_warning_single_app
                 } else {
-                    R.string.media_projection_permission_dialog_warning_single_app
+                    R.string.media_projection_entry_app_permission_dialog_warning_single_app
                 }
             val entireScreenWarningText =
                 if (appName == null) {
-                    R.string.media_projection_permission_dialog_system_service_warning_entire_screen
+                    R.string.media_projection_entry_cast_permission_dialog_warning_entire_screen
                 } else {
-                    R.string.media_projection_permission_dialog_warning_entire_screen
+                    R.string.media_projection_entry_app_permission_dialog_warning_entire_screen
                 }
 
             return listOf(
                 ScreenShareOption(
                     mode = ENTIRE_SCREEN,
-                    spinnerText = R.string.media_projection_permission_dialog_option_entire_screen,
+                    spinnerText = R.string.screen_share_permission_dialog_option_entire_screen,
                     warningText = entireScreenWarningText
                 ),
                 ScreenShareOption(
                     mode = SINGLE_APP,
-                    spinnerText = R.string.media_projection_permission_dialog_option_single_app,
+                    spinnerText = R.string.screen_share_permission_dialog_option_single_app,
                     warningText = singleAppWarningText
                 )
             )
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 4349bd7..84f358c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -33,6 +33,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Log;
@@ -60,11 +61,10 @@
     public static final int REQUEST_CODE = 2;
 
     private static final int USER_ID_NOT_SPECIFIED = -1;
-    private static final int NOTIFICATION_RECORDING_ID = 4274;
-    private static final int NOTIFICATION_PROCESSING_ID = 4275;
-    private static final int NOTIFICATION_VIEW_ID = 4273;
+    private static final int NOTIF_BASE_ID = 4273;
     private static final String TAG = "RecordingService";
     private static final String CHANNEL_ID = "screen_record";
+    private static final String GROUP_KEY = "screen_record_saved";
     private static final String EXTRA_RESULT_CODE = "extra_resultCode";
     private static final String EXTRA_PATH = "extra_path";
     private static final String EXTRA_AUDIO_SOURCE = "extra_useAudio";
@@ -89,6 +89,7 @@
     private final UiEventLogger mUiEventLogger;
     private final NotificationManager mNotificationManager;
     private final UserContextProvider mUserContextTracker;
+    private int mNotificationId = NOTIF_BASE_ID;
 
     @Inject
     public RecordingService(RecordingController controller, @LongRunning Executor executor,
@@ -134,14 +135,23 @@
         }
         String action = intent.getAction();
         Log.d(TAG, "onStartCommand " + action);
+        NotificationChannel channel = new NotificationChannel(
+                CHANNEL_ID,
+                getString(R.string.screenrecord_title),
+                NotificationManager.IMPORTANCE_DEFAULT);
+        channel.setDescription(getString(R.string.screenrecord_channel_description));
+        channel.enableVibration(true);
+        mNotificationManager.createNotificationChannel(channel);
 
         int currentUserId = mUserContextTracker.getUserContext().getUserId();
         UserHandle currentUser = new UserHandle(currentUserId);
         switch (action) {
             case ACTION_START:
+                // Get a unique ID for this recording's notifications
+                mNotificationId = NOTIF_BASE_ID + (int) SystemClock.uptimeMillis();
                 mAudioSource = ScreenRecordingAudioSource
                         .values()[intent.getIntExtra(EXTRA_AUDIO_SOURCE, 0)];
-                Log.d(TAG, "recording with audio source" + mAudioSource);
+                Log.d(TAG, "recording with audio source " + mAudioSource);
                 mShowTaps = intent.getBooleanExtra(EXTRA_SHOW_TAPS, false);
                 MediaProjectionCaptureTarget captureTarget =
                         intent.getParcelableExtra(EXTRA_CAPTURE_TARGET,
@@ -169,7 +179,7 @@
                 } else {
                     updateState(false);
                     createErrorNotification();
-                    stopForeground(true);
+                    stopForeground(STOP_FOREGROUND_DETACH);
                     stopSelf();
                     return Service.START_NOT_STICKY;
                 }
@@ -200,7 +210,7 @@
                     startActivity(Intent.createChooser(shareIntent, shareLabel)
                             .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
                     // Remove notification
-                    mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser);
+                    mNotificationManager.cancelAsUser(null, mNotificationId, currentUser);
                     return false;
                 }, false, false);
 
@@ -260,24 +270,16 @@
     @VisibleForTesting
     protected void createErrorNotification() {
         Resources res = getResources();
-        NotificationChannel channel = new NotificationChannel(
-                CHANNEL_ID,
-                getString(R.string.screenrecord_name),
-                NotificationManager.IMPORTANCE_DEFAULT);
-        channel.setDescription(getString(R.string.screenrecord_channel_description));
-        channel.enableVibration(true);
-        mNotificationManager.createNotificationChannel(channel);
-
         Bundle extras = new Bundle();
         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
-                res.getString(R.string.screenrecord_name));
+                res.getString(R.string.screenrecord_title));
         String notificationTitle = res.getString(R.string.screenrecord_start_error);
 
         Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
                 .setSmallIcon(R.drawable.ic_screenrecord)
                 .setContentTitle(notificationTitle)
                 .addExtras(extras);
-        startForeground(NOTIFICATION_RECORDING_ID, builder.build());
+        startForeground(mNotificationId, builder.build());
     }
 
     @VisibleForTesting
@@ -288,17 +290,9 @@
     @VisibleForTesting
     protected void createRecordingNotification() {
         Resources res = getResources();
-        NotificationChannel channel = new NotificationChannel(
-                CHANNEL_ID,
-                getString(R.string.screenrecord_name),
-                NotificationManager.IMPORTANCE_DEFAULT);
-        channel.setDescription(getString(R.string.screenrecord_channel_description));
-        channel.enableVibration(true);
-        mNotificationManager.createNotificationChannel(channel);
-
         Bundle extras = new Bundle();
         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
-                res.getString(R.string.screenrecord_name));
+                res.getString(R.string.screenrecord_title));
 
         String notificationTitle = mAudioSource == ScreenRecordingAudioSource.NONE
                 ? res.getString(R.string.screenrecord_ongoing_screen_only)
@@ -323,7 +317,7 @@
                 .setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
                 .addAction(stopAction)
                 .addExtras(extras);
-        startForeground(NOTIFICATION_RECORDING_ID, builder.build());
+        startForeground(mNotificationId, builder.build());
     }
 
     @VisibleForTesting
@@ -335,13 +329,14 @@
 
         Bundle extras = new Bundle();
         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
-                res.getString(R.string.screenrecord_name));
+                res.getString(R.string.screenrecord_title));
 
-        Notification.Builder builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID)
+        Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
                 .setContentTitle(notificationTitle)
                 .setContentText(
                         getResources().getString(R.string.screenrecord_background_processing_label))
                 .setSmallIcon(R.drawable.ic_screenrecord)
+                .setGroup(GROUP_KEY)
                 .addExtras(extras);
         return builder.build();
     }
@@ -365,7 +360,7 @@
 
         Bundle extras = new Bundle();
         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
-                getResources().getString(R.string.screenrecord_name));
+                getResources().getString(R.string.screenrecord_title));
 
         Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
                 .setSmallIcon(R.drawable.ic_screenrecord)
@@ -378,6 +373,7 @@
                         PendingIntent.FLAG_IMMUTABLE))
                 .addAction(shareAction)
                 .setAutoCancel(true)
+                .setGroup(GROUP_KEY)
                 .addExtras(extras);
 
         // Add thumbnail if available
@@ -391,6 +387,24 @@
         return builder.build();
     }
 
+    /**
+     * Adds a group notification so that save notifications from multiple recordings are
+     * grouped together, and the foreground service recording notification is not
+     */
+    private void postGroupNotification(UserHandle currentUser) {
+        Bundle extras = new Bundle();
+        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
+                getResources().getString(R.string.screenrecord_title));
+        Notification groupNotif = new Notification.Builder(this, CHANNEL_ID)
+                .setSmallIcon(R.drawable.ic_screenrecord)
+                .setContentTitle(getResources().getString(R.string.screenrecord_save_title))
+                .setGroup(GROUP_KEY)
+                .setGroupSummary(true)
+                .setExtras(extras)
+                .build();
+        mNotificationManager.notifyAsUser(TAG, NOTIF_BASE_ID, groupNotif, currentUser);
+    }
+
     private void stopService() {
         stopService(USER_ID_NOT_SPECIFIED);
     }
@@ -423,27 +437,26 @@
             Log.e(TAG, "stopRecording called, but recorder was null");
         }
         updateState(false);
+        stopForeground(STOP_FOREGROUND_DETACH);
         stopSelf();
     }
 
     private void saveRecording(int userId) {
         UserHandle currentUser = new UserHandle(userId);
-        mNotificationManager.notifyAsUser(null, NOTIFICATION_PROCESSING_ID,
+        mNotificationManager.notifyAsUser(null, mNotificationId,
                 createProcessingNotification(), currentUser);
 
         mLongExecutor.execute(() -> {
             try {
                 Log.d(TAG, "saving recording");
                 Notification notification = createSaveNotification(getRecorder().save());
-                if (!mController.isRecording()) {
-                    mNotificationManager.notifyAsUser(null, NOTIFICATION_VIEW_ID, notification,
-                            currentUser);
-                }
+                postGroupNotification(currentUser);
+                mNotificationManager.notifyAsUser(null, mNotificationId,  notification,
+                        currentUser);
             } catch (IOException e) {
                 Log.e(TAG, "Error saving screen recording: " + e.getMessage());
                 showErrorToast(R.string.screenrecord_delete_error);
-            } finally {
-                mNotificationManager.cancelAsUser(null, NOTIFICATION_PROCESSING_ID, currentUser);
+                mNotificationManager.cancelAsUser(null, mNotificationId, currentUser);
             }
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
index efa45a4..2a21aaa 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
@@ -100,7 +100,7 @@
         window.addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
 
         window.setGravity(Gravity.CENTER);
-        setTitle(R.string.screenrecord_name);
+        setTitle(R.string.screenrecord_title);
 
         setContentView(R.layout.screen_record_dialog);
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
index 30509e2..bfaf3d0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
@@ -62,8 +62,8 @@
     private lateinit var options: Spinner
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        setDialogTitle(R.string.screenrecord_start_label)
-        setStartButtonText(R.string.screenrecord_start_recording)
+        setDialogTitle(R.string.screenrecord_permission_dialog_title)
+        setStartButtonText(R.string.screenrecord_permission_dialog_continue)
         setStartButtonOnClickListener { v: View? ->
             onStartRecordingClicked?.run()
             if (selectedScreenShareOption.mode == ENTIRE_SCREEN) {
@@ -186,13 +186,13 @@
             return listOf(
                 ScreenShareOption(
                     ENTIRE_SCREEN,
-                    R.string.screenrecord_option_entire_screen,
-                    R.string.screenrecord_warning_entire_screen
+                    R.string.screen_share_permission_dialog_option_entire_screen,
+                    R.string.screenrecord_permission_dialog_warning_entire_screen
                 ),
                 ScreenShareOption(
                     SINGLE_APP,
-                    R.string.screenrecord_option_single_app,
-                    R.string.screenrecord_warning_single_app
+                    R.string.screen_share_permission_dialog_option_single_app,
+                    R.string.screenrecord_permission_dialog_warning_single_app
                 )
             )
         }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
index aa8e2c0..187019a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
@@ -154,5 +154,5 @@
             }
         }
 
-        override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {}
+        override fun onAnimationCancelled() {}
     }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
index 4f5cb72..3aefcb3 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
@@ -33,11 +33,9 @@
 import android.view.RemoteAnimationAdapter;
 import android.view.WindowManagerGlobal;
 
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-
-import java.util.Optional;
 
 import javax.inject.Inject;
 
@@ -48,20 +46,20 @@
 public class ActionProxyReceiver extends BroadcastReceiver {
     private static final String TAG = "ActionProxyReceiver";
 
-    private final CentralSurfaces mCentralSurfaces;
     private final ActivityManagerWrapper mActivityManagerWrapper;
     private final ScreenshotSmartActions mScreenshotSmartActions;
     private final DisplayTracker mDisplayTracker;
+    private final ActivityStarter mActivityStarter;
 
     @Inject
-    public ActionProxyReceiver(Optional<CentralSurfaces> centralSurfacesOptional,
-            ActivityManagerWrapper activityManagerWrapper,
+    public ActionProxyReceiver(ActivityManagerWrapper activityManagerWrapper,
             ScreenshotSmartActions screenshotSmartActions,
-            DisplayTracker displayTracker) {
-        mCentralSurfaces = centralSurfacesOptional.orElse(null);
+            DisplayTracker displayTracker,
+            ActivityStarter activityStarter) {
         mActivityManagerWrapper = activityManagerWrapper;
         mScreenshotSmartActions = screenshotSmartActions;
         mDisplayTracker = displayTracker;
+        mActivityStarter = activityStarter;
     }
 
     @Override
@@ -92,13 +90,9 @@
 
         };
 
-        if (mCentralSurfaces != null) {
-            mCentralSurfaces.executeRunnableDismissingKeyguard(startActivityRunnable, null,
-                    true /* dismissShade */, true /* afterKeyguardGone */,
-                    true /* deferred */);
-        } else {
-            startActivityRunnable.run();
-        }
+        mActivityStarter.executeRunnableDismissingKeyguard(startActivityRunnable, null,
+                true /* dismissShade */, true /* afterKeyguardGone */,
+                true /* deferred */);
 
         if (intent.getBooleanExtra(EXTRA_SMART_ACTIONS_ENABLED, false)) {
             String actionType = Intent.ACTION_EDIT.equals(intent.getAction())
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index c9d1da38..77a65b2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -150,7 +150,7 @@
                 }
 
                 @Override
-                public void onAnimationCancelled(boolean isKeyguardOccluded) {
+                public void onAnimationCancelled() {
                 }
             };
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt
index 4cb91e1..14e875d2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt
@@ -21,53 +21,44 @@
 import androidx.lifecycle.LifecycleService
 import androidx.lifecycle.lifecycleScope
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.shade.ShadeExpansionStateManager
-import com.android.systemui.statusbar.phone.CentralSurfaces
+import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
-import java.util.Optional
-import javax.inject.Inject
 
-/**
- * Provides state from the main SystemUI process on behalf of the Screenshot process.
- */
-internal class ScreenshotProxyService @Inject constructor(
+/** Provides state from the main SystemUI process on behalf of the Screenshot process. */
+internal class ScreenshotProxyService
+@Inject
+constructor(
     private val mExpansionMgr: ShadeExpansionStateManager,
-    private val mCentralSurfacesOptional: Optional<CentralSurfaces>,
     @Main private val mMainDispatcher: CoroutineDispatcher,
+    private val activityStarter: ActivityStarter,
 ) : LifecycleService() {
 
-    private val mBinder: IBinder = object : IScreenshotProxy.Stub() {
-        /**
-         * @return true when the notification shade is partially or fully expanded.
-         */
-        override fun isNotificationShadeExpanded(): Boolean {
-            val expanded = !mExpansionMgr.isClosed()
-            Log.d(TAG, "isNotificationShadeExpanded(): $expanded")
-            return expanded
-        }
+    private val mBinder: IBinder =
+        object : IScreenshotProxy.Stub() {
+            /** @return true when the notification shade is partially or fully expanded. */
+            override fun isNotificationShadeExpanded(): Boolean {
+                val expanded = !mExpansionMgr.isClosed()
+                Log.d(TAG, "isNotificationShadeExpanded(): $expanded")
+                return expanded
+            }
 
-        override fun dismissKeyguard(callback: IOnDoneCallback) {
-            lifecycleScope.launch {
-                executeAfterDismissing(callback)
+            override fun dismissKeyguard(callback: IOnDoneCallback) {
+                lifecycleScope.launch { executeAfterDismissing(callback) }
             }
         }
-    }
 
     private suspend fun executeAfterDismissing(callback: IOnDoneCallback) =
         withContext(mMainDispatcher) {
-            mCentralSurfacesOptional.ifPresentOrElse(
-                    {
-                        it.executeRunnableDismissingKeyguard(
-                                Runnable {
-                                    callback.onDone(true)
-                                }, null,
-                                true /* dismissShade */, true /* afterKeyguardGone */,
-                                true /* deferred */
-                        )
-                    },
-                    { callback.onDone(false) }
+            activityStarter.executeRunnableDismissingKeyguard(
+                Runnable { callback.onDone(true) },
+                null,
+                true /* dismissShade */,
+                true /* afterKeyguardGone */,
+                true /* deferred */
             )
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
index b3d31f2..7e0f504 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
@@ -19,12 +19,12 @@
 import android.view.ViewGroup
 import androidx.constraintlayout.widget.ConstraintSet
 import com.android.systemui.R
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
+import com.android.systemui.dagger.SysUISingleton
 
 /**
  * Standard implementation of [CombinedShadeHeadersConstraintManager].
  */
-@CentralSurfacesComponent.CentralSurfacesScope
+@SysUISingleton
 object CombinedShadeHeadersConstraintManagerImpl : CombinedShadeHeadersConstraintManager {
 
     override fun privacyChipVisibilityConstraints(visible: Boolean): ConstraintsChanges {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
index b445000..5850a84 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
@@ -47,19 +47,36 @@
             viewsIdToTranslate =
                 setOf(
                     ViewIdToTranslate(R.id.quick_settings_panel, START, filterShade),
-                    ViewIdToTranslate(R.id.notification_stack_scroller, END, filterShade),
-                    ViewIdToTranslate(R.id.statusIcons, END, filterShade),
-                    ViewIdToTranslate(R.id.privacy_container, END, filterShade),
-                    ViewIdToTranslate(R.id.batteryRemainingIcon, END, filterShade),
-                    ViewIdToTranslate(R.id.carrier_group, END, filterShade),
-                    ViewIdToTranslate(R.id.clock, START, filterShade),
-                    ViewIdToTranslate(R.id.date, START, filterShade)),
+                    ViewIdToTranslate(R.id.notification_stack_scroller, END, filterShade)),
             progressProvider = progressProvider)
     }
 
+    private val translateAnimatorStatusBar by lazy {
+        UnfoldConstantTranslateAnimator(
+            viewsIdToTranslate =
+            setOf(
+                ViewIdToTranslate(R.id.statusIcons, END, filterShade),
+                ViewIdToTranslate(R.id.privacy_container, END, filterShade),
+                ViewIdToTranslate(R.id.batteryRemainingIcon, END, filterShade),
+                ViewIdToTranslate(R.id.carrier_group, END, filterShade),
+                ViewIdToTranslate(R.id.clock, START, filterShade),
+                ViewIdToTranslate(R.id.date, START, filterShade)
+            ),
+            progressProvider = progressProvider
+        )
+    }
+
     fun setup(root: ViewGroup) {
         val translationMax =
             context.resources.getDimensionPixelSize(R.dimen.notification_side_paddings).toFloat()
         translateAnimator.init(root, translationMax)
+        val splitShadeStatusBarViewGroup: ViewGroup? =
+            root.findViewById(R.id.split_shade_status_bar)
+        if (splitShadeStatusBarViewGroup != null) {
+            translateAnimatorStatusBar.init(
+                splitShadeStatusBarViewGroup,
+                translationMax
+            )
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
index 1cdacb9..af3cc86 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
@@ -27,9 +27,6 @@
 import android.view.MotionEvent;
 import android.widget.FrameLayout;
 
-import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.TapAgainView;
-
 /** The shade view. */
 public final class NotificationPanelView extends FrameLayout {
     static final boolean DEBUG = false;
@@ -93,10 +90,6 @@
         mRtlChangeListener = listener;
     }
 
-    public TapAgainView getTapAgainView() {
-        return findViewById(R.id.shade_falsing_tap_again);
-    }
-
     /** Sets the touch handler for this view. */
     public void setOnTouchListener(NotificationPanelViewController.TouchHandler touchHandler) {
         super.setOnTouchListener(touchHandler);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index d28ccff..137a99ef 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -59,8 +59,6 @@
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.hardware.biometrics.SensorLocationInternal;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.PowerManager;
@@ -224,8 +222,6 @@
 import com.android.systemui.util.time.SystemClock;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
-import kotlin.Unit;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -236,6 +232,8 @@
 import javax.inject.Inject;
 import javax.inject.Provider;
 
+import kotlin.Unit;
+
 import kotlinx.coroutines.CoroutineDispatcher;
 
 @CentralSurfacesComponent.CentralSurfacesScope
@@ -410,7 +408,8 @@
     private int mDisplayRightInset = 0; // in pixels
     private int mDisplayLeftInset = 0; // in pixels
 
-    private final KeyguardClockPositionAlgorithm
+    @VisibleForTesting
+    KeyguardClockPositionAlgorithm
             mClockPositionAlgorithm =
             new KeyguardClockPositionAlgorithm();
     private final KeyguardClockPositionAlgorithm.Result
@@ -1493,11 +1492,9 @@
                         ? 1.0f : mInterpolatedDarkAmount;
 
         float udfpsAodTopLocation = -1f;
-        if (mUpdateMonitor.isUdfpsEnrolled() && mAuthController.getUdfpsProps().size() > 0) {
-            FingerprintSensorPropertiesInternal props = mAuthController.getUdfpsProps().get(0);
-            final SensorLocationInternal location = props.getLocation();
-            udfpsAodTopLocation = location.sensorLocationY - location.sensorRadius
-                    - mUdfpsMaxYBurnInOffset;
+        if (mUpdateMonitor.isUdfpsEnrolled() && mAuthController.getUdfpsLocation() != null) {
+            udfpsAodTopLocation = mAuthController.getUdfpsLocation().y
+                    - mAuthController.getUdfpsRadius() - mUdfpsMaxYBurnInOffset;
         }
 
         mClockPositionAlgorithm.setup(
@@ -4089,7 +4086,7 @@
 
         if (!mFalsingManager.isUnlockingDisabled() && qsFullyExpanded
                 && mFalsingCollector.shouldEnforceBouncer()) {
-            mCentralSurfaces.executeRunnableDismissingKeyguard(null, null,
+            mActivityStarter.executeRunnableDismissingKeyguard(null, null,
                     false, true, false);
         }
         if (DEBUG_DRAWABLE) {
@@ -4477,7 +4474,7 @@
         mDisplayTopInset = combinedInsets.top;
         mDisplayRightInset = combinedInsets.right;
         mDisplayLeftInset = combinedInsets.left;
-        mQsController.setDisplayInsets(mDisplayRightInset, mDisplayLeftInset);
+        mQsController.setDisplayInsets(mDisplayLeftInset, mDisplayRightInset);
 
         mNavigationBarBottomHeight = insets.getStableInsetBottom();
         updateMaxHeadsUpTranslation();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index ebbf1b5..7cc257b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -163,6 +163,7 @@
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mStatusBarWindowStateController = statusBarWindowStateController;
         mLockIconViewController = lockIconViewController;
+        mLockIconViewController.init();
         mService = centralSurfaces;
         mNotificationShadeWindowController = controller;
         mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index ef14d1c..a1fa8fb 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -70,6 +70,7 @@
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.data.repository.ShadeRepository;
 import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -84,11 +85,13 @@
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
+import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.LargeScreenUtils;
 
@@ -115,6 +118,7 @@
     private final PulseExpansionHandler mPulseExpansionHandler;
     private final ShadeExpansionStateManager mShadeExpansionStateManager;
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private final LightBarController mLightBarController;
     private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
     private final NotificationShadeDepthController mDepthController;
@@ -134,8 +138,10 @@
     private final LockscreenGestureLogger mLockscreenGestureLogger;
     private final ShadeLogger mShadeLog;
     private final KeyguardFaceAuthInteractor mKeyguardFaceAuthInteractor;
+    private final CastController mCastController;
     private final FeatureFlags mFeatureFlags;
     private final InteractionJankMonitor mInteractionJankMonitor;
+    private final ShadeRepository mShadeRepository;
     private final FalsingManager mFalsingManager;
     private final AccessibilityManager mAccessibilityManager;
     private final MetricsLogger mMetricsLogger;
@@ -300,6 +306,7 @@
             NotificationRemoteInputManager remoteInputManager,
             ShadeExpansionStateManager shadeExpansionStateManager,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            LightBarController lightBarController,
             NotificationStackScrollLayoutController notificationStackScrollLayoutController,
             LockscreenShadeTransitionController lockscreenShadeTransitionController,
             NotificationShadeDepthController notificationShadeDepthController,
@@ -321,7 +328,9 @@
             FeatureFlags featureFlags,
             InteractionJankMonitor interactionJankMonitor,
             ShadeLogger shadeLog,
-            KeyguardFaceAuthInteractor keyguardFaceAuthInteractor
+            KeyguardFaceAuthInteractor keyguardFaceAuthInteractor,
+            ShadeRepository shadeRepository,
+            CastController castController
     ) {
         mPanelViewControllerLazy = panelViewControllerLazy;
         mPanelView = panelView;
@@ -340,6 +349,7 @@
         mRemoteInputManager = remoteInputManager;
         mShadeExpansionStateManager = shadeExpansionStateManager;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+        mLightBarController = lightBarController;
         mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         mDepthController = notificationShadeDepthController;
@@ -361,8 +371,10 @@
         mMetricsLogger = metricsLogger;
         mShadeLog = shadeLog;
         mKeyguardFaceAuthInteractor = keyguardFaceAuthInteractor;
+        mCastController = castController;
         mFeatureFlags = featureFlags;
         mInteractionJankMonitor = interactionJankMonitor;
+        mShadeRepository = shadeRepository;
 
         mLockscreenShadeTransitionController.addCallback(new LockscreenShadeTransitionCallback());
     }
@@ -875,7 +887,9 @@
     }
 
     void setOverScrollAmount(int overExpansion) {
-        mQs.setOverScrollAmount(overExpansion);
+        if (mQs != null) {
+            mQs.setOverScrollAmount(overExpansion);
+        }
     }
 
     private void setOverScrolling(boolean overscrolling) {
@@ -1001,6 +1015,7 @@
 
         mDepthController.setQsPanelExpansion(qsExpansionFraction);
         mStatusBarKeyguardViewManager.setQsExpansion(qsExpansionFraction);
+        mShadeRepository.setQsExpansion(qsExpansionFraction);
 
         // TODO (b/265193930): remove dependency on NPVC
         float shadeExpandedFraction = mBarState == KEYGUARD
@@ -1009,6 +1024,9 @@
         mShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
         mShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
         mShadeHeaderController.setQsVisible(mVisible);
+
+        // Update the light bar
+        mLightBarController.setQsExpanded(mFullyExpanded);
     }
 
     float getLockscreenShadeDragProgress() {
@@ -1183,7 +1201,9 @@
         mLastClipBounds.set(left, top, right, bottom);
         if (mIsFullWidth) {
             clipStatusView = qsVisible;
-            float screenCornerRadius = mRecordingController.isRecording() ? 0 : mScreenCornerRadius;
+            float screenCornerRadius =
+                    mRecordingController.isRecording() || mCastController.hasConnectedCastDevice()
+                            ? 0 : mScreenCornerRadius;
             radius = (int) MathUtils.lerp(screenCornerRadius, mScrimCornerRadius,
                     Math.min(top / (float) mScrimCornerRadius, 1f));
             mScrimController.setNotificationBottomRadius(radius);
@@ -1212,10 +1232,13 @@
             mVisible = qsVisible;
             mQs.setQsVisible(qsVisible);
             mQs.setFancyClipping(
+                    mDisplayLeftInset,
                     clipTop,
+                    mDisplayRightInset,
                     clipBottom,
                     radius,
-                    qsVisible && !mSplitShadeEnabled);
+                    qsVisible && !mSplitShadeEnabled,
+                    mIsFullWidth);
 
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
index f4b1cc5..20313c3 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.shade
 
 import android.annotation.IntDef
+import android.os.Trace
+import android.os.Trace.TRACE_TAG_APP as TRACE_TAG
 import android.util.Log
 import androidx.annotation.FloatRange
 import com.android.systemui.dagger.SysUISingleton
@@ -153,6 +155,14 @@
                 if (fullyClosed) " fullyClosed" else ""
         )
 
+        if (Trace.isTagEnabled(TRACE_TAG)) {
+            Trace.traceCounter(TRACE_TAG, "panel_expansion", (fraction * 100).toInt())
+            if (state != oldState) {
+                Trace.asyncTraceForTrackEnd(TRACE_TAG, TRACK_NAME, 0)
+                Trace.asyncTraceForTrackBegin(TRACE_TAG, TRACK_NAME, state.panelStateToString(), 0)
+            }
+        }
+
         val expansionChangeEvent =
             ShadeExpansionChangeEvent(fraction, expanded, tracking, dragDownPxAmount)
         expansionListeners.forEach { it.onPanelExpansionChanged(expansionChangeEvent) }
@@ -211,6 +221,10 @@
         if (!DEBUG) return
         Log.v(TAG, msg)
     }
+
+    companion object {
+        private const val TRACK_NAME = "ShadeExpansionState"
+    }
 }
 
 /** Enum for the current state of the panel. */
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
index f0815e9..86ae4ec 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
@@ -41,6 +41,7 @@
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.battery.BatteryMeterViewController
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.demomode.DemoMode
 import com.android.systemui.demomode.DemoModeController
 import com.android.systemui.dump.DumpManager
@@ -52,14 +53,13 @@
 import com.android.systemui.shade.ShadeHeaderController.Companion.LARGE_SCREEN_HEADER_TRANSITION_ID
 import com.android.systemui.shade.ShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
 import com.android.systemui.shade.ShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
+import com.android.systemui.shade.ShadeModule.Companion.SHADE_HEADER
 import com.android.systemui.shade.carrier.ShadeCarrierGroup
 import com.android.systemui.shade.carrier.ShadeCarrierGroupController
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.phone.StatusBarIconController
 import com.android.systemui.statusbar.phone.StatusBarLocation
 import com.android.systemui.statusbar.phone.StatusIconContainer
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
-import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.SHADE_HEADER
 import com.android.systemui.statusbar.policy.Clock
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.NextAlarmController
@@ -79,7 +79,7 @@
  * * [LARGE_SCREEN_HEADER_TRANSITION_ID]: [LARGE_SCREEN_HEADER_CONSTRAINT] for all other
  *   configurations
  */
-@CentralSurfacesScope
+@SysUISingleton
 class ShadeHeaderController
 @Inject
 constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
index 4c6673c..b7551cf 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
@@ -16,19 +16,36 @@
 
 package com.android.systemui.shade
 
+import android.content.ContentResolver
+import android.os.Handler
 import android.view.LayoutInflater
+import android.view.ViewStub
+import androidx.constraintlayout.motion.widget.MotionLayout
+import com.android.keyguard.LockIconView
 import com.android.systemui.CoreStartable
 import com.android.systemui.R
+import com.android.systemui.battery.BatteryMeterView
+import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.biometrics.AuthRippleController
 import com.android.systemui.biometrics.AuthRippleView
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.privacy.OngoingPrivacyChip
+import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
+import com.android.systemui.statusbar.phone.StatusIconContainer
+import com.android.systemui.statusbar.phone.TapAgainView
+import com.android.systemui.statusbar.policy.BatteryController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.tuner.TunerService
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
 import dagger.multibindings.ClassKey
 import dagger.multibindings.IntoMap
+import javax.inject.Named
 
 /** Module for classes related to the notification shade. */
 @Module
@@ -40,6 +57,8 @@
     abstract fun bindAuthRippleController(controller: AuthRippleController): CoreStartable
 
     companion object {
+        const val SHADE_HEADER = "large_screen_shade_header"
+
         @Provides
         @SysUISingleton
         // TODO(b/277762009): Do something similar to
@@ -89,5 +108,93 @@
         ): AuthRippleView? {
             return notificationShadeWindowView.findViewById(R.id.auth_ripple)
         }
+
+        // TODO(b/277762009): Only allow this view's controller to inject the view. See above.
+        @Provides
+        @SysUISingleton
+        fun providesLockIconView(
+            notificationShadeWindowView: NotificationShadeWindowView,
+        ): LockIconView {
+            return notificationShadeWindowView.findViewById(R.id.lock_icon_view)
+        }
+
+        // TODO(b/277762009): Only allow this view's controller to inject the view. See above.
+        @Provides
+        @SysUISingleton
+        fun providesTapAgainView(
+            notificationPanelView: NotificationPanelView,
+        ): TapAgainView {
+            return notificationPanelView.findViewById(R.id.shade_falsing_tap_again)
+        }
+
+        // TODO(b/277762009): Only allow this view's controller to inject the view. See above.
+        @Provides
+        @SysUISingleton
+        @Named(SHADE_HEADER)
+        fun providesShadeHeaderView(
+            notificationShadeWindowView: NotificationShadeWindowView,
+        ): MotionLayout {
+            val stub = notificationShadeWindowView.findViewById<ViewStub>(R.id.qs_header_stub)
+            val layoutId = R.layout.combined_qs_header
+            stub.layoutResource = layoutId
+            return stub.inflate() as MotionLayout
+        }
+
+        @Provides
+        @SysUISingleton
+        fun providesCombinedShadeHeadersConstraintManager(): CombinedShadeHeadersConstraintManager {
+            return CombinedShadeHeadersConstraintManagerImpl
+        }
+
+        // TODO(b/277762009): Only allow this view's controller to inject the view. See above.
+        @Provides
+        @SysUISingleton
+        @Named(SHADE_HEADER)
+        fun providesBatteryMeterView(@Named(SHADE_HEADER) view: MotionLayout): BatteryMeterView {
+            return view.findViewById(R.id.batteryRemainingIcon)
+        }
+
+        @Provides
+        @SysUISingleton
+        @Named(SHADE_HEADER)
+        fun providesBatteryMeterViewController(
+            @Named(SHADE_HEADER) batteryMeterView: BatteryMeterView,
+            userTracker: UserTracker,
+            configurationController: ConfigurationController,
+            tunerService: TunerService,
+            @Main mainHandler: Handler,
+            contentResolver: ContentResolver,
+            featureFlags: FeatureFlags,
+            batteryController: BatteryController,
+        ): BatteryMeterViewController {
+            return BatteryMeterViewController(
+                batteryMeterView,
+                userTracker,
+                configurationController,
+                tunerService,
+                mainHandler,
+                contentResolver,
+                featureFlags,
+                batteryController,
+            )
+        }
+
+        @Provides
+        @SysUISingleton
+        @Named(SHADE_HEADER)
+        fun providesOngoingPrivacyChip(
+            @Named(SHADE_HEADER) header: MotionLayout,
+        ): OngoingPrivacyChip {
+            return header.findViewById(R.id.privacy_chip)
+        }
+
+        @Provides
+        @SysUISingleton
+        @Named(SHADE_HEADER)
+        fun providesStatusIconContainer(
+            @Named(SHADE_HEADER) header: MotionLayout,
+        ): StatusIconContainer {
+            return header.findViewById(R.id.statusIcons)
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
index bf7a2be..44c8e48 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
@@ -25,11 +25,23 @@
 import javax.inject.Inject
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
 
 interface ShadeRepository {
     /** ShadeModel information regarding shade expansion events */
     val shadeModel: Flow<ShadeModel>
+
+    /** Amount qs has expanded. Quick Settings can be expanded without the full shade expansion. */
+    val qsExpansion: StateFlow<Float>
+
+    /** Amount shade has expanded with regard to the UDFPS location */
+    val udfpsTransitionToFullShadeProgress: StateFlow<Float>
+
+    fun setQsExpansion(qsExpansion: Float)
+    fun setUdfpsTransitionToFullShadeProgress(progress: Float)
 }
 
 /** Business logic for shade interactions */
@@ -62,6 +74,20 @@
             }
             .distinctUntilChanged()
 
+    private val _qsExpansion = MutableStateFlow(0f)
+    override val qsExpansion: StateFlow<Float> = _qsExpansion.asStateFlow()
+
+    private var _udfpsTransitionToFullShadeProgress = MutableStateFlow(0f)
+    override val udfpsTransitionToFullShadeProgress: StateFlow<Float> =
+        _udfpsTransitionToFullShadeProgress.asStateFlow()
+    override fun setQsExpansion(qsExpansion: Float) {
+        _qsExpansion.value = qsExpansion
+    }
+
+    override fun setUdfpsTransitionToFullShadeProgress(progress: Float) {
+        _udfpsTransitionToFullShadeProgress.value = progress
+    }
+
     companion object {
         private const val TAG = "ShadeRepository"
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
index 07b6869..b6970ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -20,6 +20,7 @@
 import android.content.res.Resources
 import android.os.SystemProperties
 import android.os.Trace
+import android.os.Trace.TRACE_TAG_APP
 import android.util.IndentingPrintWriter
 import android.util.MathUtils
 import android.view.CrossWindowBlurListeners
@@ -43,8 +44,8 @@
 ) : Dumpable {
     val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius)
     val maxBlurRadius = resources.getDimensionPixelSize(R.dimen.max_window_blur_radius)
-    private val traceCookie = System.identityHashCode(this)
     private var lastAppliedBlur = 0
+    private var earlyWakeupEnabled = false
 
     init {
         dumpManager.registerDumpable(javaClass.name, this)
@@ -72,6 +73,26 @@
     }
 
     /**
+     * This method should be called before [applyBlur] so that, if needed, we can set the
+     * early-wakeup flag in SurfaceFlinger.
+     */
+    fun prepareBlur(viewRootImpl: ViewRootImpl?, radius: Int) {
+        if (viewRootImpl == null || !viewRootImpl.surfaceControl.isValid ||
+            !supportsBlursOnWindows() || earlyWakeupEnabled
+        ) {
+            return
+        }
+        if (lastAppliedBlur == 0 && radius != 0) {
+            Trace.asyncTraceForTrackBegin(TRACE_TAG_APP, TRACK_NAME, EARLY_WAKEUP_SLICE_NAME, 0)
+            earlyWakeupEnabled = true
+            createTransaction().use {
+                it.setEarlyWakeupStart()
+                it.apply()
+            }
+        }
+    }
+
+    /**
      * Applies background blurs to a {@link ViewRootImpl}.
      *
      * @param viewRootImpl The window root.
@@ -85,14 +106,20 @@
         createTransaction().use {
             if (supportsBlursOnWindows()) {
                 it.setBackgroundBlurRadius(viewRootImpl.surfaceControl, radius)
-                if (lastAppliedBlur == 0 && radius != 0) {
-                    Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, TRACK_NAME,
-                            EARLY_WAKEUP_SLICE_NAME, traceCookie)
+                if (!earlyWakeupEnabled && lastAppliedBlur == 0 && radius != 0) {
+                    Trace.asyncTraceForTrackBegin(
+                        TRACE_TAG_APP,
+                        TRACK_NAME,
+                        EARLY_WAKEUP_SLICE_NAME,
+                        0
+                    )
                     it.setEarlyWakeupStart()
+                    earlyWakeupEnabled = true
                 }
-                if (lastAppliedBlur != 0 && radius == 0) {
+                if (earlyWakeupEnabled && lastAppliedBlur != 0 && radius == 0) {
                     it.setEarlyWakeupEnd()
-                    Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, TRACK_NAME, traceCookie)
+                    Trace.asyncTraceForTrackEnd(TRACE_TAG_APP, TRACK_NAME, 0)
+                    earlyWakeupEnabled = false
                 }
                 lastAppliedBlur = radius
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 142689e..ea5a1c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -335,6 +335,9 @@
             R.id.keyguard_indication_text_bottom);
         mInitialTextColorState = mTopIndicationView != null
                 ? mTopIndicationView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
+        if (mRotateTextViewController != null) {
+            mRotateTextViewController.destroy();
+        }
         mRotateTextViewController = new KeyguardIndicationRotateTextViewController(
                 mLockScreenIndicationView,
                 mExecutor,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LegacyNotificationShelfControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/LegacyNotificationShelfControllerImpl.java
index 4ef2063..dcd9dc3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LegacyNotificationShelfControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LegacyNotificationShelfControllerImpl.java
@@ -52,7 +52,6 @@
         mActivatableNotificationViewController = activatableNotificationViewController;
         mKeyguardBypassController = keyguardBypassController;
         mStatusBarStateController = statusBarStateController;
-        mView.useRoundnessSourceTypes(featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES));
         mView.setSensitiveRevealAnimEndabled(featureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM));
         mOnAttachStateChangeListener = new View.OnAttachStateChangeListener() {
             @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index faf592e..7f016f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -26,11 +26,13 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.media.controls.ui.MediaHierarchyManager
+import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.QS
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeViewController
+import com.android.systemui.shade.data.repository.ShadeRepository
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
@@ -62,16 +64,18 @@
     private val mediaHierarchyManager: MediaHierarchyManager,
     private val scrimTransitionController: LockscreenShadeScrimTransitionController,
     private val keyguardTransitionControllerFactory:
-        LockscreenShadeKeyguardTransitionController.Factory,
+    LockscreenShadeKeyguardTransitionController.Factory,
     private val depthController: NotificationShadeDepthController,
     private val context: Context,
     private val splitShadeOverScrollerFactory: SplitShadeLockScreenOverScroller.Factory,
     private val singleShadeOverScrollerFactory: SingleShadeLockScreenOverScroller.Factory,
+    private val activityStarter: ActivityStarter,
     wakefulnessLifecycle: WakefulnessLifecycle,
     configurationController: ConfigurationController,
     falsingManager: FalsingManager,
     dumpManager: DumpManager,
     qsTransitionControllerFactory: LockscreenShadeQsTransitionController.Factory,
+    private val shadeRepository: ShadeRepository,
 ) : Dumpable {
     private var pulseHeight: Float = 0f
     @get:VisibleForTesting
@@ -305,7 +309,7 @@
             if (nsslController.isInLockedDownShade()) {
                 logger.logDraggedDownLockDownShade(startingChild)
                 statusBarStateController.setLeaveOpenOnKeyguardHide(true)
-                centralSurfaces.dismissKeyguardThenExecute(OnDismissAction {
+                activityStarter.dismissKeyguardThenExecute(OnDismissAction {
                     nextHideKeyguardNeedsNoAnimation = true
                     false
                 }, cancelRunnable, false /* afterKeyguardGone */)
@@ -447,6 +451,7 @@
         }
 
         val udfpsProgress = MathUtils.saturate(dragDownAmount / udfpsTransitionDistance)
+        shadeRepository.setUdfpsTransitionToFullShadeProgress(udfpsProgress)
         udfpsKeyguardViewController?.setTransitionToFullShadeProgress(udfpsProgress)
 
         val statusBarProgress = MathUtils.saturate(dragDownAmount / statusBarTransitionDistance)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index cac4251..e6e3e7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -16,6 +16,7 @@
 package com.android.systemui.statusbar;
 
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
+
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 
 import android.app.KeyguardManager;
@@ -47,6 +48,8 @@
 import com.android.systemui.dagger.SysUISingleton;
 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.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.recents.OverviewProxyService;
@@ -59,14 +62,14 @@
 import com.android.systemui.util.ListenerSet;
 import com.android.systemui.util.settings.SecureSettings;
 
+import dagger.Lazy;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.inject.Inject;
 
-import dagger.Lazy;
-
 /**
  * Handles keeping track of the current user, profiles, and various things related to hiding
  * contents, redacting notifications, and the lockscreen.
@@ -99,7 +102,7 @@
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final NotificationClickNotifier mClickNotifier;
     private final Lazy<OverviewProxyService> mOverviewProxyServiceLazy;
-
+    private final FeatureFlags mFeatureFlags;
     private boolean mShowLockscreenNotifications;
     private boolean mAllowLockscreenRemoteInput;
     private LockPatternUtils mLockPatternUtils;
@@ -174,6 +177,21 @@
             new UserTracker.Callback() {
                 @Override
                 public void onUserChanged(int newUser, @NonNull Context userContext) {
+                    if (!mFeatureFlags.isEnabled(
+                            Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE)) {
+                        handleUserChange(newUser);
+                    }
+                }
+
+                @Override
+                public void onUserChanging(int newUser, @NonNull Context userContext) {
+                    if (mFeatureFlags.isEnabled(
+                            Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE)) {
+                        handleUserChange(newUser);
+                    }
+                }
+
+                private void handleUserChange(int newUser) {
                     mCurrentUserId = newUser;
                     updateCurrentProfilesCache();
 
@@ -216,7 +234,8 @@
             KeyguardStateController keyguardStateController,
             SecureSettings secureSettings,
             DumpManager dumpManager,
-            LockPatternUtils lockPatternUtils) {
+            LockPatternUtils lockPatternUtils,
+            FeatureFlags featureFlags) {
         mContext = context;
         mMainHandler = mainHandler;
         mDevicePolicyManager = devicePolicyManager;
@@ -234,6 +253,7 @@
         mDeviceProvisionedController = deviceProvisionedController;
         mSecureSettings = secureSettings;
         mKeyguardStateController = keyguardStateController;
+        mFeatureFlags = featureFlags;
 
         dumpManager.registerDumpable(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 8dc7842..a3bd247 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -189,12 +189,7 @@
             scheduleUpdate()
         }
 
-    /**
-     * Callback that updates the window blur value and is called only once per frame.
-     */
-    @VisibleForTesting
-    val updateBlurCallback = Choreographer.FrameCallback {
-        updateScheduled = false
+    private fun computeBlurAndZoomOut(): Pair<Int, Float> {
         val animationRadius = MathUtils.constrain(shadeAnimation.radius,
                 blurUtils.minBlurRadius.toFloat(), blurUtils.maxBlurRadius.toFloat())
         val expansionRadius = blurUtils.blurRadiusOfRatio(
@@ -232,6 +227,16 @@
         // Brightness slider removes blur, but doesn't affect zooms
         blur = (blur * (1f - brightnessMirrorSpring.ratio)).toInt()
 
+        return Pair(blur, zoomOut)
+    }
+
+    /**
+     * Callback that updates the window blur value and is called only once per frame.
+     */
+    @VisibleForTesting
+    val updateBlurCallback = Choreographer.FrameCallback {
+        updateScheduled = false
+        val (blur, zoomOut) = computeBlurAndZoomOut()
         val opaque = scrimsVisible && !blursDisabledForAppLaunch
         Trace.traceCounter(Trace.TRACE_TAG_APP, "shade_blur_radius", blur)
         blurUtils.applyBlur(root.viewRootImpl, blur, opaque)
@@ -441,6 +446,8 @@
             return
         }
         updateScheduled = true
+        val (blur, _) = computeBlurAndZoomOut()
+        blurUtils.prepareBlur(root.viewRootImpl, blur)
         choreographer.postFrameCallback(updateBlurCallback)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 7eb63da..49c7950 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -44,7 +44,6 @@
 import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
-import com.android.systemui.statusbar.notification.LegacySourceType;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -128,13 +127,6 @@
         setClipToPadding(false);
         mShelfIcons.setIsStaticLayout(false);
         requestRoundness(/* top = */ 1f, /* bottom = */ 1f, BASE_VALUE, /* animate = */ false);
-
-        if (!mUseRoundnessSourceTypes) {
-            // Setting this to first in section to get the clipping to the top roundness correct.
-            // This value determines the way we are clipping to the top roundness of the overall
-            // shade
-            setFirstInSection(true);
-        }
         updateResources();
     }
 
@@ -569,17 +561,8 @@
                 * mAmbientState.getExpansionFraction();
         final float cornerAnimationTop = shelfStart - cornerAnimationDistance;
 
-        final SourceType sourceType;
-        if (mUseRoundnessSourceTypes) {
-            sourceType = SHELF_SCROLL;
-        } else {
-            sourceType = LegacySourceType.OnScroll;
-        }
-
         final float topValue;
-        if (!mUseRoundnessSourceTypes && anv.isFirstInSection()) {
-            topValue = 1f;
-        } else if (viewStart >= cornerAnimationTop) {
+        if (viewStart >= cornerAnimationTop) {
             // Round top corners within animation bounds
             topValue = MathUtils.saturate(
                     (viewStart - cornerAnimationTop) / cornerAnimationDistance);
@@ -588,12 +571,10 @@
             // Reset top and bottom corners outside of animation bounds.
             topValue = 0f;
         }
-        anv.requestTopRoundness(topValue, sourceType, /* animate = */ false);
+        anv.requestTopRoundness(topValue, SHELF_SCROLL, /* animate = */ false);
 
         final float bottomValue;
-        if (!mUseRoundnessSourceTypes && anv.isLastInSection()) {
-            bottomValue = 1f;
-        } else if (viewEnd >= cornerAnimationTop) {
+        if (viewEnd >= cornerAnimationTop) {
             // Round bottom corners within animation bounds
             bottomValue = MathUtils.saturate(
                     (viewEnd - cornerAnimationTop) / cornerAnimationDistance);
@@ -602,7 +583,7 @@
             // Reset top and bottom corners outside of animation bounds.
             bottomValue = 0f;
         }
-        anv.requestBottomRoundness(bottomValue, sourceType, /* animate = */ false);
+        anv.requestBottomRoundness(bottomValue, SHELF_SCROLL, /* animate = */ false);
     }
 
     private boolean isViewAffectedBySwipe(ExpandableView expandableView) {
@@ -1100,15 +1081,6 @@
         child.requestRoundnessReset(SHELF_SCROLL);
     }
 
-    /**
-     * This method resets the OnScroll roundness of a view to 0f
-     * <p>
-     * Note: This should be the only class that handles roundness {@code SourceType.OnScroll}
-     */
-    public static void resetLegacyOnScrollRoundness(ExpandableView expandableView) {
-        expandableView.requestRoundnessReset(LegacySourceType.OnScroll);
-    }
-
     @Override
     public void dump(PrintWriter pwOriginal, String[] args) {
         IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index 976924a..821a172 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -87,13 +87,8 @@
             bypassController.isPulseExpanding = value
             if (changed) {
                 if (value) {
-                    val topEntry = headsUpManager.topEntry
-                    topEntry?.let {
-                        roundnessManager.setTrackingHeadsUp(it.row)
-                    }
                     lockscreenShadeTransitionController.onPulseExpansionStarted()
                 } else {
-                    roundnessManager.setTrackingHeadsUp(null)
                     if (!leavingLockscreen) {
                         bypassController.maybePerformPendingUnlock()
                         pulseExpandAbortListener?.run()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
index a37b2a9..58d7054 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar;
 
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.app.RemoteInput;
 import android.content.Context;
@@ -55,6 +56,13 @@
 
     private final RemoteInputControllerLogger mLogger;
 
+    /**
+     * RemoteInput Active's last emitted value. It's added for debugging purpose to directly see
+     * its last emitted value. As RemoteInputController holds weak reference, isRemoteInputActive
+     * in dump may not reflect the last emitted value of  Active.
+     */
+    @Nullable private Boolean mLastAppliedRemoteInputActive = null;
+
     public RemoteInputController(Delegate delegate,
             RemoteInputUriController remoteInputUriController,
             RemoteInputControllerLogger logger) {
@@ -217,6 +225,7 @@
         for (int i = 0; i < N; i++) {
             mCallbacks.get(i).onRemoteInputActive(remoteInputActive);
         }
+        mLastAppliedRemoteInputActive = remoteInputActive;
     }
 
     /**
@@ -323,6 +332,8 @@
 
     /** dump debug info; called by {@link NotificationRemoteInputManager} */
     public void dump(@NonNull IndentingPrintWriter pw) {
+        pw.print("mLastAppliedRemoteInputActive: ");
+        pw.println((Object) mLastAppliedRemoteInputActive);
         pw.print("isRemoteInputActive: ");
         pw.println(isRemoteInputActive()); // Note that this prunes the mOpen list, printed later.
         pw.println("mOpen: " + mOpen.size());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 7755003..129c859 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -26,6 +26,7 @@
 import android.app.ActivityManager;
 import android.app.Notification;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -75,9 +76,9 @@
      */
     private static final float DARK_ALPHA_BOOST = 0.67f;
     /**
-     * Status icons are currently drawn with the intention of being 17dp tall, but we
-     * want to scale them (in a way that doesn't require an asset dump) down 2dp. So
-     * 17dp * (15 / 17) = 15dp, the new height. After the first call to {@link #reloadDimens} all
+     * Status icons are currently drawn with the intention of being 17sp tall, but we
+     * want to scale them (in a way that doesn't require an asset dump) down 2sp. So
+     * 17sp * (15 / 17) = 15sp, the new height. After the first call to {@link #reloadDimens} all
      * values will be in px.
      */
     private float mSystemIconDesiredHeight = 15f;
@@ -144,7 +145,7 @@
     private String mNumberText;
     private StatusBarNotification mNotification;
     private final boolean mBlocked;
-    private int mDensity;
+    private Configuration mConfiguration;
     private boolean mNightMode;
     private float mIconScale = 1.0f;
     private final Paint mDotPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -198,9 +199,8 @@
         mNumberPain.setAntiAlias(true);
         setNotification(sbn);
         setScaleType(ScaleType.CENTER);
-        mDensity = context.getResources().getDisplayMetrics().densityDpi;
-        Configuration configuration = context.getResources().getConfiguration();
-        mNightMode = (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+        mConfiguration = new Configuration(context.getResources().getConfiguration());
+        mNightMode = (mConfiguration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
                 == Configuration.UI_MODE_NIGHT_YES;
         initializeDecorColor();
         reloadDimens();
@@ -214,7 +214,7 @@
         mAlwaysScaleIcon = true;
         reloadDimens();
         maybeUpdateIconScaleDimens();
-        mDensity = context.getResources().getDisplayMetrics().densityDpi;
+        mConfiguration = new Configuration(context.getResources().getConfiguration());
     }
 
     /** Should always be preceded by {@link #reloadDimens()} */
@@ -231,12 +231,17 @@
     private void updateIconScaleForNotifications() {
         final float imageBounds = mIncreasedSize ?
                 mStatusBarIconDrawingSizeIncreased : mStatusBarIconDrawingSize;
-        final int outerBounds = mStatusBarIconSize;
-        mIconScale = imageBounds / (float)outerBounds;
+        float iconHeight = getIconHeight();
+        if (iconHeight != 0) {
+            mIconScale = imageBounds / iconHeight;
+        } else {
+            final int outerBounds = mStatusBarIconSize;
+            mIconScale = imageBounds / (float) outerBounds;
+        }
         updatePivot();
     }
 
-    // Makes sure that all icons are scaled to the same height (15dp). If we cannot get a height
+    // Makes sure that all icons are scaled to the same height (15sp). If we cannot get a height
     // for the icon, it uses the default SCALE (15f / 17f) which is the old behavior
     private void updateIconScaleForSystemIcons() {
         float iconHeight = getIconHeight();
@@ -267,12 +272,10 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        int density = newConfig.densityDpi;
-        if (density != mDensity) {
-            mDensity = density;
-            reloadDimens();
-            updateDrawable();
-            maybeUpdateIconScaleDimens();
+        final int configDiff = newConfig.diff(mConfiguration);
+        mConfiguration.setTo(newConfig);
+        if ((configDiff & (ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_FONT_SCALE)) != 0) {
+            updateIconDimens();
         }
         boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
                 == Configuration.UI_MODE_NIGHT_YES;
@@ -282,6 +285,15 @@
         }
     }
 
+    /**
+     * Update the icon dimens and drawable with current resources
+     */
+    public void updateIconDimens() {
+        reloadDimens();
+        updateDrawable();
+        maybeUpdateIconScaleDimens();
+    }
+
     private void reloadDimens() {
         boolean applyRadius = mDotRadius == mStaticDotRadius;
         Resources res = getResources();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
index 76ff97d..212f2c215 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
@@ -448,10 +448,3 @@
             }
     }
 }
-
-@Deprecated("Use SourceType.from() instead", ReplaceWith("SourceType.from()"))
-enum class LegacySourceType : SourceType {
-    DefaultValue,
-    OnDismissAnimation,
-    OnScroll,
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImpl.kt
index 8aa6b81..d95d593 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImpl.kt
@@ -32,7 +32,7 @@
 @SysUISingleton
 class NotifLiveDataStoreImpl @Inject constructor(
     @Main private val mainExecutor: Executor
-) : NotifLiveDataStore {
+) : NotifLiveDataStore, PipelineDumpable {
     private val hasActiveNotifsPrivate = NotifLiveDataImpl(
         name = "hasActiveNotifs",
         initialValue = false,
@@ -66,6 +66,12 @@
             ).forEach { dispatcher -> dispatcher.invoke() }
         }
     }
+
+    override fun dumpPipeline(d: PipelineDumper) {
+        d.dump("activeNotifListPrivate", activeNotifListPrivate)
+        d.dump("activeNotifCountPrivate", activeNotifCountPrivate)
+        d.dump("hasActiveNotifsPrivate", hasActiveNotifsPrivate)
+    }
 }
 
 /** Read-write implementation of [NotifLiveData] */
@@ -73,7 +79,7 @@
     private val name: String,
     initialValue: T,
     @Main private val mainExecutor: Executor
-) : NotifLiveData<T> {
+) : NotifLiveData<T>, PipelineDumpable {
     private val syncObservers = ListenerSet<Observer<T>>()
     private val asyncObservers = ListenerSet<Observer<T>>()
     private val atomicValue = AtomicReference(initialValue)
@@ -134,4 +140,9 @@
         syncObservers.remove(observer)
         asyncObservers.remove(observer)
     }
+
+    override fun dumpPipeline(d: PipelineDumper) {
+        d.dump("syncObservers", syncObservers)
+        d.dump("asyncObservers", asyncObservers)
+    }
 }
\ No newline at end of file
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CoreCoordinator.kt
similarity index 61%
copy from services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java
copy to packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CoreCoordinator.kt
index 7c339d2..75e461c 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CoreCoordinator.kt
@@ -13,15 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.systemui.statusbar.notification.collection.coordinator
 
-package com.android.server.companion.datatransfer.contextsync;
+import com.android.systemui.statusbar.notification.collection.PipelineDumpable
 
-/** Callback for call metadata syncing. */
-public abstract class CallMetadataSyncCallback {
-
-    abstract void processCallControlAction(int crossDeviceCallId, int callControlAction);
-
-    abstract void requestCrossDeviceSync(int userId);
-
-    abstract void updateStatus(int userId, boolean shouldSyncCallMetadata);
-}
+/**
+ * A special type of [Coordinator] that is also a core part of the pipeline, and so is also a
+ * [PipelineDumpable].
+ */
+interface CoreCoordinator : Coordinator, PipelineDumpable
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt
index 8e307ec..dc8ff63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreImpl
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.PipelineDumper
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
 import com.android.systemui.statusbar.notification.collection.render.requireSummary
 import javax.inject.Inject
@@ -32,13 +33,17 @@
 @CoordinatorScope
 class DataStoreCoordinator @Inject internal constructor(
     private val notifLiveDataStoreImpl: NotifLiveDataStoreImpl
-) : Coordinator {
+) : CoreCoordinator {
 
     override fun attach(pipeline: NotifPipeline) {
         pipeline.addOnAfterRenderListListener { entries, _ -> onAfterRenderList(entries) }
     }
 
-    fun onAfterRenderList(entries: List<ListEntry>) {
+    override fun dumpPipeline(d: PipelineDumper) {
+        d.dump("notifLiveDataStoreImpl", notifLiveDataStoreImpl)
+    }
+
+    private fun onAfterRenderList(entries: List<ListEntry>) {
         val flatEntryList = flattenedEntryList(entries)
         notifLiveDataStoreImpl.setActiveNotifList(flatEntryList)
     }
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 02ce0d4..e5953cf 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
@@ -15,7 +15,6 @@
  */
 package com.android.systemui.statusbar.notification.collection.coordinator
 
-import com.android.systemui.statusbar.notification.NotifPipelineFlags
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.PipelineDumpable
 import com.android.systemui.statusbar.notification.collection.PipelineDumper
@@ -32,7 +31,6 @@
 
 @CoordinatorScope
 class NotifCoordinatorsImpl @Inject constructor(
-        notifPipelineFlags: NotifPipelineFlags,
         sectionStyleProvider: SectionStyleProvider,
         dataStoreCoordinator: DataStoreCoordinator,
         hideLocallyDismissedNotifsCoordinator: HideLocallyDismissedNotifsCoordinator,
@@ -61,6 +59,7 @@
         dismissibilityCoordinator: DismissibilityCoordinator,
 ) : NotifCoordinators {
 
+    private val mCoreCoordinators: MutableList<CoreCoordinator> = ArrayList()
     private val mCoordinators: MutableList<Coordinator> = ArrayList()
     private val mOrderedSections: MutableList<NotifSectioner> = ArrayList()
 
@@ -68,11 +67,8 @@
      * Creates all the coordinators.
      */
     init {
-        // TODO(b/208866714): formalize the system by which some coordinators may be required by the
-        //  pipeline, such as this DataStoreCoordinator which cannot be removed, as it's a critical
-        //  glue between the pipeline and parts of SystemUI which depend on pipeline output via the
-        //  NotifLiveDataStore.
-        mCoordinators.add(dataStoreCoordinator)
+        // Attach core coordinators.
+        mCoreCoordinators.add(dataStoreCoordinator)
 
         // Attach normal coordinators.
         mCoordinators.add(hideLocallyDismissedNotifsCoordinator)
@@ -122,6 +118,9 @@
      * [Pluggable]s, [NotifCollectionListener]s and [NotifLifetimeExtender]s.
      */
     override fun attach(pipeline: NotifPipeline) {
+        for (c in mCoreCoordinators) {
+            c.attach(pipeline)
+        }
         for (c in mCoordinators) {
             c.attach(pipeline)
         }
@@ -133,7 +132,8 @@
      * as they are dumped in the RenderStageManager instead.
      */
     override fun dumpPipeline(d: PipelineDumper) = with(d) {
-        dump("coordinators", mCoordinators)
+        dump("core coordinators", mCoreCoordinators)
+        dump("normal coordinators", mCoordinators)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
index 1c96e8c..62a0d13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
@@ -19,6 +19,7 @@
 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.render.GroupExpansionManagerImpl
 import com.android.systemui.statusbar.notification.collection.render.NotifStackController
 import com.android.systemui.statusbar.notification.collection.render.NotifStats
 import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
@@ -32,11 +33,13 @@
  */
 @CoordinatorScope
 class StackCoordinator @Inject internal constructor(
+    private val groupExpansionManagerImpl: GroupExpansionManagerImpl,
     private val notificationIconAreaController: NotificationIconAreaController
 ) : Coordinator {
 
     override fun attach(pipeline: NotifPipeline) {
         pipeline.addOnAfterRenderListListener(::onAfterRenderList)
+        groupExpansionManagerImpl.attach(pipeline)
     }
 
     fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManager.java
index d2df07e..30386ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManager.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.notification.collection.render;
 
-import com.android.systemui.Dumpable;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 
@@ -25,7 +24,7 @@
  * expanded/collapsed state of a single notification which is tracked within each
  * ExpandableNotificationRow.
  */
-public interface GroupExpansionManager extends Dumpable {
+public interface GroupExpansionManager {
 
     /**
      * Register a listener for group expansion changes
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
index 1b3f83d..4568c0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
@@ -16,12 +16,15 @@
 
 package com.android.systemui.statusbar.notification.collection.render;
 
+import androidx.annotation.NonNull;
+
+import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dump.DumpManager;
 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.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.coordinator.Coordinator;
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener;
 
 import java.io.PrintWriter;
@@ -36,7 +39,8 @@
  * expanded state.
  */
 @SysUISingleton
-public class GroupExpansionManagerImpl implements GroupExpansionManager, Coordinator {
+public class GroupExpansionManagerImpl implements GroupExpansionManager, Dumpable {
+    private final DumpManager mDumpManager;
     private final GroupMembershipManager mGroupMembershipManager;
     private final Set<OnGroupExpansionChangeListener> mOnGroupChangeListeners = new HashSet<>();
 
@@ -44,7 +48,9 @@
     private final Set<NotificationEntry> mExpandedGroups = new HashSet<>();
 
     @Inject
-    public GroupExpansionManagerImpl(GroupMembershipManager groupMembershipManager) {
+    public GroupExpansionManagerImpl(DumpManager dumpManager,
+            GroupMembershipManager groupMembershipManager) {
+        mDumpManager = dumpManager;
         mGroupMembershipManager = groupMembershipManager;
     }
 
@@ -61,8 +67,8 @@
         mExpandedGroups.removeIf(expandedGroup -> !renderingSummaries.contains(expandedGroup));
     };
 
-    @Override
     public void attach(NotifPipeline pipeline) {
+        mDumpManager.registerDumpable(this);
         pipeline.addOnBeforeRenderListListener(mNotifTracker);
     }
 
@@ -102,11 +108,11 @@
     }
 
     @Override
-    public void dump(PrintWriter pw, String[] args) {
+    public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
         pw.println("NotificationEntryExpansion state:");
-        pw.println("  # expanded groups: " +  mExpandedGroups.size());
+        pw.println("  mExpandedGroups: " + mExpandedGroups.size());
         for (NotificationEntry entry : mExpandedGroups) {
-            pw.println("    summary key of expanded group: " + entry.getKey());
+            pw.println("  * " + entry.getKey());
         }
     }
 
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 766ad88..285dd97 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
@@ -110,7 +110,6 @@
     protected Point mTargetPoint;
     private boolean mDismissed;
     private boolean mRefocusOnDismiss;
-    protected boolean mUseRoundnessSourceTypes;
 
     public ActivatableNotificationView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -709,18 +708,10 @@
         mTouchHandler = touchHandler;
     }
 
-    /**
-     * Enable the support for rounded corner based on the SourceType
-     * @param enabled true if is supported
-     */
-    public void useRoundnessSourceTypes(boolean enabled) {
-        mUseRoundnessSourceTypes = enabled;
-    }
-
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        if (mUseRoundnessSourceTypes && !mOnDetachResetRoundness.isEmpty()) {
+        if (!mOnDetachResetRoundness.isEmpty()) {
             for (SourceType sourceType : mOnDetachResetRoundness) {
                 requestRoundnessReset(sourceType);
             }
@@ -742,12 +733,16 @@
         super.dump(pw, args);
         if (DUMP_VERBOSE) {
             DumpUtilsKt.withIncreasedIndent(pw, () -> {
-                pw.println("mBackgroundNormal: " + mBackgroundNormal);
-                if (mBackgroundNormal != null) {
-                    DumpUtilsKt.withIncreasedIndent(pw, () -> {
-                        mBackgroundNormal.dump(pw, args);
-                    });
-                }
+                dumpBackgroundView(pw, args);
+            });
+        }
+    }
+
+    protected void dumpBackgroundView(IndentingPrintWriter pw, String[] args) {
+        pw.println("Background View: " + mBackgroundNormal);
+        if (DUMP_VERBOSE && mBackgroundNormal != null) {
+            DumpUtilsKt.withIncreasedIndent(pw, () -> {
+                mBackgroundNormal.dump(pw, args);
             });
         }
     }
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 e468a59..1dc58b5 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
@@ -87,7 +87,6 @@
 import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
 import com.android.systemui.statusbar.notification.FeedbackIcon;
 import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
-import com.android.systemui.statusbar.notification.LegacySourceType;
 import com.android.systemui.statusbar.notification.NotificationFadeAware;
 import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
 import com.android.systemui.statusbar.notification.NotificationUtils;
@@ -866,9 +865,6 @@
         }
         onAttachedChildrenCountChanged();
         row.setIsChildInGroup(false, null);
-        if (!mUseRoundnessSourceTypes) {
-            row.requestBottomRoundness(0.0f, LegacySourceType.DefaultValue, /* animate = */ false);
-        }
     }
 
     /**
@@ -884,10 +880,6 @@
             if (child.keepInParentForDismissAnimation()) {
                 mChildrenContainer.removeNotification(child);
                 child.setIsChildInGroup(false, null);
-                if (!mUseRoundnessSourceTypes) {
-                    LegacySourceType sourceType = LegacySourceType.DefaultValue;
-                    child.requestBottomRoundness(0f, sourceType, /* animate = */ false);
-                }
                 child.setKeepInParentForDismissAnimation(false);
                 logKeepInParentChildDetached(child);
                 childCountChanged = true;
@@ -942,9 +934,7 @@
             mNotificationParent.updateBackgroundForGroupState();
         }
         updateBackgroundClipping();
-        if (mUseRoundnessSourceTypes) {
-            updateBaseRoundness();
-        }
+        updateBaseRoundness();
     }
 
     @Override
@@ -1054,15 +1044,13 @@
         if (isAboveShelf() != wasAboveShelf) {
             mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
         }
-        if (mUseRoundnessSourceTypes) {
-            if (pinned) {
-                // Should be animated if someone explicitly set it to 0 and the row is shown.
-                boolean animated = mAnimatePinnedRoundness && isShown();
-                requestRoundness(/* top = */ 1f, /* bottom = */ 1f, PINNED, animated);
-            } else {
-                requestRoundnessReset(PINNED);
-                mAnimatePinnedRoundness = true;
-            }
+        if (pinned) {
+            // Should be animated if someone explicitly set it to 0 and the row is shown.
+            boolean animated = mAnimatePinnedRoundness && isShown();
+            requestRoundness(/* top = */ 1f, /* bottom = */ 1f, PINNED, animated);
+        } else {
+            requestRoundnessReset(PINNED);
+            mAnimatePinnedRoundness = true;
         }
     }
 
@@ -1879,7 +1867,6 @@
             mChildrenContainer.setIsLowPriority(mIsLowPriority);
             mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
             mChildrenContainer.onNotificationUpdated();
-            mChildrenContainer.useRoundnessSourceTypes(mUseRoundnessSourceTypes);
 
             mTranslateableViews.add(mChildrenContainer);
         });
@@ -2308,24 +2295,6 @@
         mBackgroundNormal.setExpandAnimationSize(params.getWidth(), actualHeight);
     }
 
-    @Override
-    public float getTopRoundness() {
-        if (!mUseRoundnessSourceTypes && mExpandAnimationRunning) {
-            return mTopRoundnessDuringLaunchAnimation;
-        }
-
-        return super.getTopRoundness();
-    }
-
-    @Override
-    public float getBottomRoundness() {
-        if (!mUseRoundnessSourceTypes && mExpandAnimationRunning) {
-            return mBottomRoundnessDuringLaunchAnimation;
-        }
-
-        return super.getBottomRoundness();
-    }
-
     public void setExpandAnimationRunning(boolean expandAnimationRunning) {
         if (expandAnimationRunning) {
             setAboveShelf(true);
@@ -3481,18 +3450,11 @@
 
     private void applyChildrenRoundness() {
         if (mIsSummaryWithChildren) {
-            if (mUseRoundnessSourceTypes) {
-                mChildrenContainer.requestRoundness(
-                        /* top = */ getTopRoundness(),
-                        /* bottom = */ getBottomRoundness(),
-                        /* sourceType = */ FROM_PARENT,
-                        /* animate = */ false);
-            } else {
-                mChildrenContainer.requestBottomRoundness(
-                        getBottomRoundness(),
-                        LegacySourceType.DefaultValue,
-                        /* animate = */ false);
-            }
+            mChildrenContainer.requestRoundness(
+                    /* top = */ getTopRoundness(),
+                    /* bottom = */ getBottomRoundness(),
+                    /* sourceType = */ FROM_PARENT,
+                    /* animate = */ false);
         }
     }
 
@@ -3631,6 +3593,7 @@
         // Skip super call; dump viewState ourselves
         pw.println("Notification: " + mEntry.getKey());
         DumpUtilsKt.withIncreasedIndent(pw, () -> {
+            pw.println(this);
             pw.print("visibility: " + getVisibility());
             pw.print(", alpha: " + getAlpha());
             pw.print(", translation: " + getTranslation());
@@ -3650,6 +3613,7 @@
                 pw.println("no viewState!!!");
             }
             pw.println(getRoundableState().debugString());
+            dumpBackgroundView(pw, args);
 
             int transientViewCount = mChildrenContainer == null
                     ? 0 : mChildrenContainer.getTransientViewCount();
@@ -3709,24 +3673,10 @@
         }
     }
 
-    /**
-     * Enable the support for rounded corner based on the SourceType
-     * @param enabled true if is supported
-     */
-    @Override
-    public void useRoundnessSourceTypes(boolean enabled) {
-        super.useRoundnessSourceTypes(enabled);
-        if (mChildrenContainer != null) {
-            mChildrenContainer.useRoundnessSourceTypes(mUseRoundnessSourceTypes);
-        }
-    }
-
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        if (mUseRoundnessSourceTypes) {
-            updateBaseRoundness();
-        }
+        updateBaseRoundness();
     }
 
     /** Set whether this notification may show a snooze action. */
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 9bf05cb..1acc9f9 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
@@ -261,8 +261,6 @@
                 mStatusBarStateController.removeCallback(mStatusBarStateListener);
             }
         });
-        mView.useRoundnessSourceTypes(
-                mFeatureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES));
     }
 
     private final StatusBarStateController.StateListener mStatusBarStateListener =
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 5edff5f..3e01dd3 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
@@ -40,6 +40,7 @@
 import com.android.systemui.statusbar.notification.RoundableState;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.util.Compile;
 import com.android.systemui.util.DumpUtilsKt;
 
 import java.io.PrintWriter;
@@ -52,7 +53,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;
+    protected static final boolean DUMP_VERBOSE =
+            Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
 
     private RoundableState mRoundableState = null;
     protected OnHeightChangedListener mOnHeightChangedListener;
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 da8d2d5..647505c 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
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static com.android.systemui.util.ColorUtilKt.hexColorString;
+
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.Canvas;
@@ -27,6 +29,9 @@
 import android.util.AttributeSet;
 import android.view.View;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.android.internal.util.ArrayUtils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
@@ -44,6 +49,7 @@
     private int mClipTopAmount;
     private int mClipBottomAmount;
     private int mTintColor;
+    @Nullable private Integer mRippleColor;
     private final float[] mCornerRadii = new float[8];
     private boolean mBottomIsRounded;
     private boolean mBottomAmountClips = true;
@@ -127,6 +133,7 @@
             unscheduleDrawable(mBackground);
         }
         mBackground = background;
+        mRippleColor = null;
         mBackground.mutate();
         if (mBackground != null) {
             mBackground.setCallback(this);
@@ -215,6 +222,9 @@
         if (mBackground instanceof RippleDrawable) {
             RippleDrawable ripple = (RippleDrawable) mBackground;
             ripple.setColor(ColorStateList.valueOf(color));
+            mRippleColor = color;
+        } else {
+            mRippleColor = null;
         }
     }
 
@@ -290,7 +300,7 @@
     }
 
     @Override
-    public void dump(PrintWriter pw, String[] args) {
+    public void dump(PrintWriter pw, @NonNull String[] args) {
         pw.println("mDontModifyCorners: " + mDontModifyCorners);
         pw.println("mClipTopAmount: " + mClipTopAmount);
         pw.println("mClipBottomAmount: " + mClipBottomAmount);
@@ -299,5 +309,8 @@
         pw.println("mBottomAmountClips: " + mBottomAmountClips);
         pw.println("mActualWidth: " + mActualWidth);
         pw.println("mActualHeight: " + mActualHeight);
+        pw.println("mTintColor: " + hexColorString(mTintColor));
+        pw.println("mRippleColor: " + hexColorString(mRippleColor));
+        pw.println("mBackground: " + mBackground);
     }
 }
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 e6e6b99..0c4b092 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
@@ -49,6 +49,7 @@
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.settings.UserContextProvider;
@@ -73,8 +74,6 @@
 
 import javax.inject.Inject;
 
-import dagger.Lazy;
-
 /**
  * Handles various NotificationGuts related tasks, such as binding guts to a row, opening and
  * closing guts, and keeping track of the currently exposed notification guts.
@@ -107,7 +106,6 @@
     private NotificationListContainer mListContainer;
     private OnSettingsClickListener mOnSettingsClickListener;
 
-    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
     private final Handler mMainHandler;
     private final Handler mBgHandler;
     private final Optional<BubblesManager> mBubblesManagerOptional;
@@ -121,10 +119,10 @@
     private final ShadeController mShadeController;
     private NotifGutsViewListener mGutsListener;
     private final HeadsUpManagerPhone mHeadsUpManagerPhone;
+    private final ActivityStarter mActivityStarter;
 
     @Inject
     public NotificationGutsManager(Context context,
-            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             @Main Handler mainHandler,
             @Background Handler bgHandler,
             AccessibilityManager accessibilityManager,
@@ -144,9 +142,9 @@
             StatusBarStateController statusBarStateController,
             DeviceProvisionedController deviceProvisionedController,
             MetricsLogger metricsLogger,
-            HeadsUpManagerPhone headsUpManagerPhone) {
+            HeadsUpManagerPhone headsUpManagerPhone,
+            ActivityStarter activityStarter) {
         mContext = context;
-        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mMainHandler = mainHandler;
         mBgHandler = bgHandler;
         mAccessibilityManager = accessibilityManager;
@@ -167,6 +165,7 @@
         mDeviceProvisionedController = deviceProvisionedController;
         mMetricsLogger = metricsLogger;
         mHeadsUpManagerPhone = headsUpManagerPhone;
+        mActivityStarter = activityStarter;
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter,
@@ -551,19 +550,15 @@
                             .setLeaveOpenOnKeyguardHide(true);
                 }
 
-                Optional<CentralSurfaces> centralSurfacesOptional =
-                        mCentralSurfacesOptionalLazy.get();
-                if (centralSurfacesOptional.isPresent()) {
-                    Runnable r = () -> mMainHandler.post(
-                            () -> openGutsInternal(view, x, y, menuItem));
-                    centralSurfacesOptional.get().executeRunnableDismissingKeyguard(
-                            r,
-                            null /* cancelAction */,
-                            false /* dismissShade */,
-                            true /* afterKeyguardGone */,
-                            true /* deferred */);
-                    return true;
-                }
+                Runnable r = () -> mMainHandler.post(
+                        () -> openGutsInternal(view, x, y, menuItem));
+                mActivityStarter.executeRunnableDismissingKeyguard(
+                        r,
+                        null /* cancelAction */,
+                        false /* dismissShade */,
+                        true /* afterKeyguardGone */,
+                        true /* deferred */);
+                return true;
                 /**
                  * When {@link CentralSurfaces} doesn't exist, falling through to call
                  * {@link #openGutsInternal(View,int,int,NotificationMenuRowPlugin.MenuItem)}.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 9a777ea..2c59c2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -72,7 +72,6 @@
     private View mFeedbackIcon;
     private boolean mIsLowPriority;
     private boolean mTransformLowPriorityTitle;
-    private boolean mUseRoundnessSourceTypes;
     private RoundnessChangedListener mRoundnessChangedListener;
 
     protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
@@ -122,7 +121,7 @@
 
     @Override
     public void applyRoundnessAndInvalidate() {
-        if (mUseRoundnessSourceTypes && mRoundnessChangedListener != null) {
+        if (mRoundnessChangedListener != null) {
             // We cannot apply the rounded corner to this View, so our parents (in drawChild()) will
             // clip our canvas. So we should invalidate our parent.
             mRoundnessChangedListener.applyRoundnessAndInvalidate();
@@ -377,15 +376,6 @@
     }
 
     /**
-     * Enable the support for rounded corner based on the SourceType
-     *
-     * @param enabled true if is supported
-     */
-    public void useRoundnessSourceTypes(boolean enabled) {
-        mUseRoundnessSourceTypes = enabled;
-    }
-
-    /**
      * Interface that handle the Roundness changes
      */
     public interface RoundnessChangedListener {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
index 99c6ddb..12956ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
@@ -81,7 +81,6 @@
         ActivatableNotificationViewBinder.bind(viewModel, shelf, falsingManager)
         shelf.apply {
             setRefactorFlagEnabled(true)
-            useRoundnessSourceTypes(featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES))
             setSensitiveRevealAnimEndabled(featureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM))
             // TODO(278765923): Replace with eventual NotificationIconContainerViewBinder#bind()
             notificationIconAreaController.setShelfIcons(shelfIcons)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 160a230..d18757d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -45,9 +45,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.NotificationGroupingUtil;
-import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.notification.FeedbackIcon;
-import com.android.systemui.statusbar.notification.LegacySourceType;
 import com.android.systemui.statusbar.notification.NotificationFadeAware;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.Roundable;
@@ -133,7 +131,6 @@
     private int mUntruncatedChildCount;
     private boolean mContainingNotificationIsFaded = false;
     private RoundableState mRoundableState;
-    private boolean mUseRoundnessSourceTypes;
 
     public NotificationChildrenContainer(Context context) {
         this(context, null);
@@ -328,13 +325,6 @@
         row.setContentTransformationAmount(0, false /* isLastChild */);
         row.setNotificationFaded(mContainingNotificationIsFaded);
 
-        if (!mUseRoundnessSourceTypes) {
-            // This is a workaround, the NotificationShelf should be the owner of `OnScroll`
-            // roundness.
-            // Here we should reset the `OnScroll` roundness only on top-level rows.
-            NotificationShelf.resetLegacyOnScrollRoundness(row);
-        }
-
         // It doesn't make sense to keep old animations around, lets cancel them!
         ExpandableViewState viewState = row.getViewState();
         if (viewState != null) {
@@ -342,9 +332,7 @@
             row.cancelAppearDrawing();
         }
 
-        if (mUseRoundnessSourceTypes) {
-            applyRoundnessAndInvalidate();
-        }
+        applyRoundnessAndInvalidate();
     }
 
     private void ensureRemovedFromTransientContainer(View v) {
@@ -379,10 +367,8 @@
             mGroupingUtil.restoreChildNotification(row);
         }
 
-        if (mUseRoundnessSourceTypes) {
-            row.requestRoundnessReset(FROM_PARENT, /* animate = */ false);
-            applyRoundnessAndInvalidate();
-        }
+        row.requestRoundnessReset(FROM_PARENT, /* animate = */ false);
+        applyRoundnessAndInvalidate();
     }
 
     /**
@@ -409,10 +395,7 @@
                             getContext(),
                             mNotificationHeader,
                             mContainingNotification);
-            mNotificationHeaderWrapper.useRoundnessSourceTypes(mUseRoundnessSourceTypes);
-            if (mUseRoundnessSourceTypes) {
-                mNotificationHeaderWrapper.setOnRoundnessChangedListener(this::invalidate);
-            }
+            mNotificationHeaderWrapper.setOnRoundnessChangedListener(this::invalidate);
             addView(mNotificationHeader, 0);
             invalidate();
         } else {
@@ -450,12 +433,7 @@
                                 getContext(),
                                 mNotificationHeaderLowPriority,
                                 mContainingNotification);
-                mNotificationHeaderWrapperLowPriority.useRoundnessSourceTypes(
-                        mUseRoundnessSourceTypes
-                );
-                if (mUseRoundnessSourceTypes) {
-                    mNotificationHeaderWrapper.setOnRoundnessChangedListener(this::invalidate);
-                }
+                mNotificationHeaderWrapper.setOnRoundnessChangedListener(this::invalidate);
                 addView(mNotificationHeaderLowPriority, 0);
                 invalidate();
             } else {
@@ -891,7 +869,7 @@
 
             isCanvasChanged = true;
             canvas.save();
-            if (mUseRoundnessSourceTypes && translation != 0f) {
+            if (translation != 0f) {
                 clipPath.offset(translation, 0f);
                 canvas.clipPath(clipPath);
                 clipPath.offset(-translation, 0f);
@@ -1444,40 +1422,30 @@
     @Override
     public void applyRoundnessAndInvalidate() {
         boolean last = true;
-        if (mUseRoundnessSourceTypes) {
-            if (mNotificationHeaderWrapper != null) {
-                mNotificationHeaderWrapper.requestTopRoundness(
-                        /* value = */ getTopRoundness(),
-                        /* sourceType = */ FROM_PARENT,
-                        /* animate = */ false
-                );
-            }
-            if (mNotificationHeaderWrapperLowPriority != null) {
-                mNotificationHeaderWrapperLowPriority.requestTopRoundness(
-                        /* value = */ getTopRoundness(),
-                        /* sourceType = */ FROM_PARENT,
-                        /* animate = */ false
-                );
-            }
+        if (mNotificationHeaderWrapper != null) {
+            mNotificationHeaderWrapper.requestTopRoundness(
+                    /* value = */ getTopRoundness(),
+                    /* sourceType = */ FROM_PARENT,
+                    /* animate = */ false
+            );
+        }
+        if (mNotificationHeaderWrapperLowPriority != null) {
+            mNotificationHeaderWrapperLowPriority.requestTopRoundness(
+                    /* value = */ getTopRoundness(),
+                    /* sourceType = */ FROM_PARENT,
+                    /* animate = */ false
+            );
         }
         for (int i = mAttachedChildren.size() - 1; i >= 0; i--) {
             ExpandableNotificationRow child = mAttachedChildren.get(i);
             if (child.getVisibility() == View.GONE) {
                 continue;
             }
-            if (mUseRoundnessSourceTypes) {
-                child.requestRoundness(
-                        /* top = */ 0f,
-                        /* bottom = */ last ? getBottomRoundness() : 0f,
-                        /* sourceType = */ FROM_PARENT,
-                        /* animate = */ false);
-            } else {
-                child.requestRoundness(
-                        /* top = */ 0f,
-                        /* bottom = */ last ? getBottomRoundness() : 0f,
-                        LegacySourceType.DefaultValue,
-                        /* animate = */ isShown());
-            }
+            child.requestRoundness(
+                    /* top = */ 0f,
+                    /* bottom = */ last ? getBottomRoundness() : 0f,
+                    /* sourceType = */ FROM_PARENT,
+                    /* animate = */ false);
             last = false;
         }
         Roundable.super.applyRoundnessAndInvalidate();
@@ -1537,15 +1505,6 @@
         return mNotificationHeaderWrapper;
     }
 
-    /**
-     * Enable the support for rounded corner based on the SourceType
-     *
-     * @param enabled true if is supported
-     */
-    public void useRoundnessSourceTypes(boolean enabled) {
-        mUseRoundnessSourceTypes = enabled;
-    }
-
     public String debugString() {
         return TAG + " { "
                 + "visibility: " + getVisibility()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index fde8c4d..fa1843e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -16,24 +16,13 @@
 
 package com.android.systemui.statusbar.notification.stack;
 
-import android.content.res.Resources;
-import android.util.MathUtils;
-
 import androidx.annotation.NonNull;
 
 import com.android.systemui.Dumpable;
-import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
-import com.android.systemui.statusbar.notification.LegacySourceType;
-import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
 import com.android.systemui.statusbar.notification.Roundable;
 import com.android.systemui.statusbar.notification.SourceType;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.logging.NotificationRoundnessLogger;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 
 import java.io.PrintWriter;
@@ -50,64 +39,27 @@
     private static final String TAG = "NotificationRoundnessManager";
     private static final SourceType DISMISS_ANIMATION = SourceType.from("DismissAnimation");
 
-    private final ExpandableView[] mFirstInSectionViews;
-    private final ExpandableView[] mLastInSectionViews;
-    private final ExpandableView[] mTmpFirstInSectionViews;
-    private final ExpandableView[] mTmpLastInSectionViews;
-    private final NotificationRoundnessLogger mNotifLogger;
     private final DumpManager mDumpManager;
-    private boolean mExpanded;
     private HashSet<ExpandableView> mAnimatedChildren;
-    private Runnable mRoundingChangedCallback;
-    private ExpandableNotificationRow mTrackedHeadsUp;
-    private float mAppearFraction;
     private boolean mRoundForPulsingViews;
     private boolean mIsClearAllInProgress;
 
     private ExpandableView mSwipedView = null;
     private Roundable mViewBeforeSwipedView = null;
     private Roundable mViewAfterSwipedView = null;
-    private boolean mUseRoundnessSourceTypes;
 
     @Inject
-    NotificationRoundnessManager(
-            NotificationSectionsFeatureManager sectionsFeatureManager,
-            NotificationRoundnessLogger notifLogger,
-            DumpManager dumpManager,
-            FeatureFlags featureFlags) {
-        int numberOfSections = sectionsFeatureManager.getNumberOfBuckets();
-        mFirstInSectionViews = new ExpandableView[numberOfSections];
-        mLastInSectionViews = new ExpandableView[numberOfSections];
-        mTmpFirstInSectionViews = new ExpandableView[numberOfSections];
-        mTmpLastInSectionViews = new ExpandableView[numberOfSections];
-        mNotifLogger = notifLogger;
+    NotificationRoundnessManager(DumpManager dumpManager) {
         mDumpManager = dumpManager;
-        mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
-
         mDumpManager.registerDumpable(TAG, this);
     }
 
     @Override
     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
-        pw.println("mFirstInSectionViews: length=" + mFirstInSectionViews.length);
-        pw.println(dumpViews(mFirstInSectionViews));
-        pw.println("mLastInSectionViews: length=" + mLastInSectionViews.length);
-        pw.println(dumpViews(mFirstInSectionViews));
-        if (mTrackedHeadsUp != null) {
-            pw.println("trackedHeadsUp=" + mTrackedHeadsUp.getEntry());
-        }
         pw.println("roundForPulsingViews=" + mRoundForPulsingViews);
         pw.println("isClearAllInProgress=" + mIsClearAllInProgress);
     }
 
-    public void updateView(ExpandableView view, boolean animate) {
-        if (mUseRoundnessSourceTypes) return;
-        boolean changed = updateViewWithoutCallback(view, animate);
-        if (changed) {
-            mRoundingChangedCallback.run();
-        }
-    }
-
     public boolean isViewAffectedBySwipe(ExpandableView expandableView) {
         return expandableView != null
                 && (expandableView == mSwipedView
@@ -115,58 +67,6 @@
                 || expandableView == mViewAfterSwipedView);
     }
 
-    boolean updateViewWithoutCallback(
-            ExpandableView view,
-            boolean animate) {
-        if (mUseRoundnessSourceTypes) return false;
-        if (view == null
-                || view == mViewBeforeSwipedView
-                || view == mViewAfterSwipedView) {
-            return false;
-        }
-
-        final boolean isTopChanged = view.requestTopRoundness(
-                getRoundnessDefaultValue(view, true /* top */),
-                LegacySourceType.DefaultValue,
-                animate);
-
-        final boolean isBottomChanged = view.requestBottomRoundness(
-                getRoundnessDefaultValue(view, /* top = */ false),
-                LegacySourceType.DefaultValue,
-                animate);
-
-        final boolean isFirstInSection = isFirstInSection(view);
-        final boolean isLastInSection = isLastInSection(view);
-
-        view.setFirstInSection(isFirstInSection);
-        view.setLastInSection(isLastInSection);
-
-        mNotifLogger.onCornersUpdated(view, isFirstInSection,
-                isLastInSection, isTopChanged, isBottomChanged);
-
-        return (isFirstInSection || isLastInSection) && (isTopChanged || isBottomChanged);
-    }
-
-    private boolean isFirstInSection(ExpandableView view) {
-        if (mUseRoundnessSourceTypes) return false;
-        for (int i = 0; i < mFirstInSectionViews.length; i++) {
-            if (view == mFirstInSectionViews[i]) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean isLastInSection(ExpandableView view) {
-        if (mUseRoundnessSourceTypes) return false;
-        for (int i = mLastInSectionViews.length - 1; i >= 0; i--) {
-            if (view == mLastInSectionViews[i]) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     void setViewsAffectedBySwipe(
             Roundable viewBefore,
             ExpandableView viewSwiped,
@@ -180,34 +80,27 @@
         if (mSwipedView != null) oldViews.add(mSwipedView);
         if (mViewAfterSwipedView != null) oldViews.add(mViewAfterSwipedView);
 
-        final SourceType source;
-        if (mUseRoundnessSourceTypes) {
-            source = DISMISS_ANIMATION;
-        } else {
-            source = LegacySourceType.OnDismissAnimation;
-        }
-
         mViewBeforeSwipedView = viewBefore;
         if (viewBefore != null) {
             oldViews.remove(viewBefore);
-            viewBefore.requestRoundness(/* top = */ 0f, /* bottom = */ 1f, source);
+            viewBefore.requestRoundness(/* top = */ 0f, /* bottom = */ 1f, DISMISS_ANIMATION);
         }
 
         mSwipedView = viewSwiped;
         if (viewSwiped != null) {
             oldViews.remove(viewSwiped);
-            viewSwiped.requestRoundness(/* top = */ 1f, /* bottom = */ 1f, source);
+            viewSwiped.requestRoundness(/* top = */ 1f, /* bottom = */ 1f, DISMISS_ANIMATION);
         }
 
         mViewAfterSwipedView = viewAfter;
         if (viewAfter != null) {
             oldViews.remove(viewAfter);
-            viewAfter.requestRoundness(/* top = */ 1f, /* bottom = */ 0f, source);
+            viewAfter.requestRoundness(/* top = */ 1f, /* bottom = */ 0f, DISMISS_ANIMATION);
         }
 
         // After setting the current Views, reset the views that are still present in the set.
         for (Roundable oldView : oldViews) {
-            oldView.requestRoundnessReset(source);
+            oldView.requestRoundnessReset(DISMISS_ANIMATION);
         }
     }
 
@@ -229,143 +122,6 @@
         return mRoundForPulsingViews;
     }
 
-    private float getRoundnessDefaultValue(Roundable view, boolean top) {
-        if (mUseRoundnessSourceTypes) return 0f;
-
-        if (view == null) {
-            return 0f;
-        }
-        if (view == mViewBeforeSwipedView
-                || view == mSwipedView
-                || view == mViewAfterSwipedView) {
-            return 1f;
-        }
-        if (view instanceof ExpandableNotificationRow
-                && ((ExpandableNotificationRow) view).canViewBeCleared()
-                && mIsClearAllInProgress) {
-            return 1.0f;
-        }
-        if (view instanceof ExpandableView) {
-            ExpandableView expandableView = (ExpandableView) view;
-            if ((expandableView.isPinned()
-                    || (expandableView.isHeadsUpAnimatingAway()) && !mExpanded)) {
-                return 1.0f;
-            }
-            if (isFirstInSection(expandableView) && top) {
-                return 1.0f;
-            }
-            if (isLastInSection(expandableView) && !top) {
-                return 1.0f;
-            }
-
-            if (view == mTrackedHeadsUp) {
-                // If we're pushing up on a headsup the appear fraction is < 0 and it needs to
-                // still be rounded.
-                return MathUtils.saturate(1.0f - mAppearFraction);
-            }
-            if (expandableView.showingPulsing() && mRoundForPulsingViews) {
-                return 1.0f;
-            }
-            if (expandableView.isChildInGroup()) {
-                return 0f;
-            }
-            final Resources resources = expandableView.getResources();
-            return resources.getDimension(R.dimen.notification_corner_radius_small)
-                    / resources.getDimension(R.dimen.notification_corner_radius);
-        }
-        return 0f;
-    }
-
-    public void setExpanded(float expandedHeight, float appearFraction) {
-        if (mUseRoundnessSourceTypes) return;
-        mExpanded = expandedHeight != 0.0f;
-        mAppearFraction = appearFraction;
-        if (mTrackedHeadsUp != null) {
-            updateView(mTrackedHeadsUp, false /* animate */);
-        }
-    }
-
-    public void updateRoundedChildren(NotificationSection[] sections) {
-        if (mUseRoundnessSourceTypes) return;
-        boolean anyChanged = false;
-        for (int i = 0; i < sections.length; i++) {
-            mTmpFirstInSectionViews[i] = mFirstInSectionViews[i];
-            mTmpLastInSectionViews[i] = mLastInSectionViews[i];
-            mFirstInSectionViews[i] = sections[i].getFirstVisibleChild();
-            mLastInSectionViews[i] = sections[i].getLastVisibleChild();
-        }
-        anyChanged |= handleRemovedOldViews(sections, mTmpFirstInSectionViews, true);
-        anyChanged |= handleRemovedOldViews(sections, mTmpLastInSectionViews, false);
-        anyChanged |= handleAddedNewViews(sections, mTmpFirstInSectionViews, true);
-        anyChanged |= handleAddedNewViews(sections, mTmpLastInSectionViews, false);
-        if (anyChanged) {
-            mRoundingChangedCallback.run();
-        }
-
-        mNotifLogger.onSectionCornersUpdated(sections, anyChanged);
-    }
-
-    private boolean handleRemovedOldViews(
-            NotificationSection[] sections,
-            ExpandableView[] oldViews,
-            boolean first) {
-        if (mUseRoundnessSourceTypes) return false;
-        boolean anyChanged = false;
-        for (ExpandableView oldView : oldViews) {
-            if (oldView != null) {
-                boolean isStillPresent = false;
-                boolean adjacentSectionChanged = false;
-                for (NotificationSection section : sections) {
-                    ExpandableView newView =
-                            (first ? section.getFirstVisibleChild()
-                                    : section.getLastVisibleChild());
-                    if (newView == oldView) {
-                        isStillPresent = true;
-                        if (oldView.isFirstInSection() != isFirstInSection(oldView)
-                                || oldView.isLastInSection() != isLastInSection(oldView)) {
-                            adjacentSectionChanged = true;
-                        }
-                        break;
-                    }
-                }
-                if (!isStillPresent || adjacentSectionChanged) {
-                    anyChanged = true;
-                    if (!oldView.isRemoved()) {
-                        updateViewWithoutCallback(oldView, oldView.isShown());
-                    }
-                }
-            }
-        }
-        return anyChanged;
-    }
-
-    private boolean handleAddedNewViews(
-            NotificationSection[] sections,
-            ExpandableView[] oldViews,
-            boolean first) {
-        if (mUseRoundnessSourceTypes) return false;
-        boolean anyChanged = false;
-        for (NotificationSection section : sections) {
-            ExpandableView newView =
-                    (first ? section.getFirstVisibleChild() : section.getLastVisibleChild());
-            if (newView != null) {
-                boolean wasAlreadyPresent = false;
-                for (ExpandableView oldView : oldViews) {
-                    if (oldView == newView) {
-                        wasAlreadyPresent = true;
-                        break;
-                    }
-                }
-                if (!wasAlreadyPresent) {
-                    anyChanged = true;
-                    updateViewWithoutCallback(newView,
-                            newView.isShown() && !mAnimatedChildren.contains(newView));
-                }
-            }
-        }
-        return anyChanged;
-    }
-
     public void setAnimatedChildren(HashSet<ExpandableView> animatedChildren) {
         mAnimatedChildren = animatedChildren;
     }
@@ -379,51 +135,7 @@
         return mAnimatedChildren.contains(view);
     }
 
-    public void setOnRoundingChangedCallback(Runnable roundingChangedCallback) {
-        mRoundingChangedCallback = roundingChangedCallback;
-    }
-
-    public void setTrackingHeadsUp(ExpandableNotificationRow row) {
-        ExpandableNotificationRow previous = mTrackedHeadsUp;
-        mTrackedHeadsUp = row;
-        if (previous != null) {
-            updateView(previous, true /* animate */);
-        }
-    }
-
     public void setShouldRoundPulsingViews(boolean shouldRoundPulsingViews) {
         mRoundForPulsingViews = shouldRoundPulsingViews;
     }
-
-    private String dumpViews(ExpandableView[] views) {
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < views.length; i++) {
-            if (views[i] == null) continue;
-
-            sb.append("\t")
-                    .append("[").append(i).append("] ")
-                    .append("isPinned=").append(views[i].isPinned()).append(" ")
-                    .append("isFirstInSection=").append(views[i].isFirstInSection()).append(" ")
-                    .append("isLastInSection=").append(views[i].isLastInSection()).append(" ");
-
-            if (views[i] instanceof ExpandableNotificationRow) {
-                sb.append("entry=");
-                dumpEntry(((ExpandableNotificationRow) views[i]).getEntry(), sb);
-            }
-
-            sb.append("\n");
-        }
-        return sb.toString();
-    }
-
-    private void dumpEntry(NotificationEntry entry, StringBuilder sb) {
-        sb.append("NotificationEntry{key=").append(entry.getKey()).append(" ");
-
-        if (entry.getSection() != null) {
-            sb.append(" section=")
-                    .append(entry.getSection().getLabel());
-        }
-
-        sb.append("}");
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 070b439..fd064ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -19,8 +19,6 @@
 import android.util.Log
 import android.view.View
 import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.media.controls.ui.KeyguardMediaController
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
 import com.android.systemui.statusbar.notification.SourceType
@@ -51,12 +49,9 @@
     @IncomingHeader private val incomingHeaderController: SectionHeaderController,
     @PeopleHeader private val peopleHeaderController: SectionHeaderController,
     @AlertingHeader private val alertingHeaderController: SectionHeaderController,
-    @SilentHeader private val silentHeaderController: SectionHeaderController,
-    featureFlags: FeatureFlags
+    @SilentHeader private val silentHeaderController: SectionHeaderController
 ) : SectionProvider {
 
-    private val useRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES)
-
     private val configurationListener = object : ConfigurationController.ConfigurationListener {
         override fun onLocaleListChanged() {
             reinflateViews()
@@ -196,35 +191,33 @@
             isSectionChanged || changed
         }
 
-        if (useRoundnessSourceTypes) {
-            val newFirstChildren = sections.mapNotNull { it.firstVisibleChild }
-            val newLastChildren = sections.mapNotNull { it.lastVisibleChild }
+        val newFirstChildren = sections.mapNotNull { it.firstVisibleChild }
+        val newLastChildren = sections.mapNotNull { it.lastVisibleChild }
 
-            // Update the roundness of Views that weren't already in the first/last position
-            newFirstChildren.forEach { firstChild ->
-                val wasFirstChild = oldFirstChildren.remove(firstChild)
-                if (!wasFirstChild) {
-                    val notAnimatedChild = !notificationRoundnessManager.isAnimatedChild(firstChild)
-                    val animated = firstChild.isShown && notAnimatedChild
-                    firstChild.requestTopRoundness(1f, SECTION, animated)
-                }
+        // Update the roundness of Views that weren't already in the first/last position
+        newFirstChildren.forEach { firstChild ->
+            val wasFirstChild = oldFirstChildren.remove(firstChild)
+            if (!wasFirstChild) {
+                val notAnimatedChild = !notificationRoundnessManager.isAnimatedChild(firstChild)
+                val animated = firstChild.isShown && notAnimatedChild
+                firstChild.requestTopRoundness(1f, SECTION, animated)
             }
-            newLastChildren.forEach { lastChild ->
-                val wasLastChild = oldLastChildren.remove(lastChild)
-                if (!wasLastChild) {
-                    val notAnimatedChild = !notificationRoundnessManager.isAnimatedChild(lastChild)
-                    val animated = lastChild.isShown && notAnimatedChild
-                    lastChild.requestBottomRoundness(1f, SECTION, animated)
-                }
+        }
+        newLastChildren.forEach { lastChild ->
+            val wasLastChild = oldLastChildren.remove(lastChild)
+            if (!wasLastChild) {
+                val notAnimatedChild = !notificationRoundnessManager.isAnimatedChild(lastChild)
+                val animated = lastChild.isShown && notAnimatedChild
+                lastChild.requestBottomRoundness(1f, SECTION, animated)
             }
+        }
 
-            // The Views left in the set are no longer in the first/last position
-            oldFirstChildren.forEach { noMoreFirstChild ->
-                noMoreFirstChild.requestTopRoundness(0f, SECTION)
-            }
-            oldLastChildren.forEach { noMoreLastChild ->
-                noMoreLastChild.requestBottomRoundness(0f, SECTION)
-            }
+        // The Views left in the set are no longer in the first/last position
+        oldFirstChildren.forEach { noMoreFirstChild ->
+            noMoreFirstChild.requestTopRoundness(0f, SECTION)
+        }
+        oldLastChildren.forEach { noMoreLastChild ->
+            noMoreLastChild.requestBottomRoundness(0f, SECTION)
         }
 
         if (DEBUG) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 5c322d7..edff877 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -89,6 +89,7 @@
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -199,7 +200,6 @@
     private Set<Integer> mDebugTextUsedYPositions;
     private final boolean mDebugRemoveAnimation;
     private final boolean mSimplifiedAppearFraction;
-    private final boolean mUseRoundnessSourceTypes;
     private final boolean mSensitiveRevealAnimEndabled;
     private boolean mAnimatedInsets;
 
@@ -319,6 +319,7 @@
     };
     private NotificationStackScrollLogger mLogger;
     private CentralSurfaces mCentralSurfaces;
+    private ActivityStarter mActivityStarter;
     private final int[] mTempInt2 = new int[2];
     private boolean mGenerateChildOrderChangedEvent;
     private final HashSet<Runnable> mAnimationFinishedRunnables = new HashSet<>();
@@ -623,7 +624,6 @@
         mDebugLines = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES);
         mDebugRemoveAnimation = featureFlags.isEnabled(Flags.NSSL_DEBUG_REMOVE_ANIMATION);
         mSimplifiedAppearFraction = featureFlags.isEnabled(Flags.SIMPLIFIED_APPEAR_FRACTION);
-        mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
         mSensitiveRevealAnimEndabled = featureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM);
         setAnimatedInsetsEnabled(featureFlags.isEnabled(Flags.ANIMATED_NOTIFICATION_SHADE_INSETS));
         mSectionsManager = Dependency.get(NotificationSectionsManager.class);
@@ -3132,10 +3132,6 @@
             mAnimateNextSectionBoundsChange = false;
         }
         mAmbientState.setLastVisibleBackgroundChild(lastChild);
-        if (!mUseRoundnessSourceTypes) {
-            // TODO: Refactor SectionManager and put the RoundnessManager there.
-            mController.getNotificationRoundnessManager().updateRoundedChildren(mSections);
-        }
         mAnimateBottomOnLayout = false;
         invalidate();
     }
@@ -3582,9 +3578,7 @@
 
     @ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM)
     protected StackScrollAlgorithm createStackScrollAlgorithm(Context context) {
-        StackScrollAlgorithm stackScrollAlgorithm = new StackScrollAlgorithm(context, this);
-        stackScrollAlgorithm.useRoundnessSourceTypes(mUseRoundnessSourceTypes);
-        return stackScrollAlgorithm;
+        return new StackScrollAlgorithm(context, this);
     }
 
     /**
@@ -4189,10 +4183,7 @@
             mCentralSurfaces.resetUserExpandedStates();
             clearTemporaryViews();
             clearUserLockedViews();
-            if (mSwipeHelper.isSwiping()) {
-                mSwipeHelper.resetSwipeState();
-                updateContinuousShadowDrawing();
-            }
+            cancelActiveSwipe();
         }
     }
 
@@ -4264,6 +4255,9 @@
             if (!mIsExpanded) {
                 mGroupExpansionManager.collapseGroups();
                 mExpandHelper.cancelImmediately();
+                if (!mIsExpansionChanging) {
+                    cancelActiveSwipe();
+                }
             }
             updateNotificationAnimationStates();
             updateChronometers();
@@ -4814,6 +4808,10 @@
         this.mCentralSurfaces = centralSurfaces;
     }
 
+    public void setActivityStarter(ActivityStarter activityStarter) {
+        mActivityStarter = activityStarter;
+    }
+
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     void requestAnimateEverything() {
         if (mIsExpanded && mAnimationsEnabled) {
@@ -5579,7 +5577,7 @@
             Intent intent = showHistory
                     ? new Intent(Settings.ACTION_NOTIFICATION_HISTORY)
                     : new Intent(Settings.ACTION_NOTIFICATION_SETTINGS);
-            mCentralSurfaces.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
+            mActivityStarter.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
         });
         setEmptyShadeView(view);
         updateEmptyShadeView(
@@ -6113,7 +6111,11 @@
         }
     }
 
-    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
+    private void cancelActiveSwipe() {
+        mSwipeHelper.resetSwipeState();
+        updateContinuousShadowDrawing();
+    }
+
     void updateContinuousShadowDrawing() {
         boolean continuousShadowUpdate = mAnimationRunning
                 || mSwipeHelper.isSwiping();
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 b69ce38..7b046d6 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
@@ -61,8 +61,8 @@
 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.media.controls.ui.KeyguardMediaController;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
@@ -125,8 +125,6 @@
 import com.android.systemui.util.Compile;
 import com.android.systemui.util.settings.SecureSettings;
 
-import kotlin.Unit;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
@@ -194,10 +192,10 @@
     private int mBarState;
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
     private final FeatureFlags mFeatureFlags;
-    private final boolean mUseRoundnessSourceTypes;
     private final NotificationTargetsHelper mNotificationTargetsHelper;
     private final SecureSettings mSecureSettings;
     private final NotificationDismissibilityProvider mDismissibilityProvider;
+    private final ActivityStarter mActivityStarter;
 
     private View mLongPressedView;
 
@@ -487,7 +485,7 @@
                     mView.addSwipedOutView(view);
                     mFalsingCollector.onNotificationDismissed();
                     if (mFalsingCollector.shouldEnforceBouncer()) {
-                        mCentralSurfaces.executeRunnableDismissingKeyguard(
+                        mActivityStarter.executeRunnableDismissingKeyguard(
                                 null,
                                 null /* cancelAction */,
                                 false /* dismissShade */,
@@ -592,36 +590,12 @@
                 }
 
                 @Override
-                public void onHeadsUpPinned(NotificationEntry entry) {
-                    if (!mUseRoundnessSourceTypes) {
-                        mNotificationRoundnessManager.updateView(
-                                entry.getRow(),
-                                /* animate = */ false);
-                    }
-                }
-
-                @Override
-                public void onHeadsUpUnPinned(NotificationEntry entry) {
-                    if (!mUseRoundnessSourceTypes) {
-                        ExpandableNotificationRow row = entry.getRow();
-                        // update the roundedness posted, because we might be animating away the
-                        // headsup soon, so no need to set the roundedness to 0 and then back to 1.
-                        row.post(() -> mNotificationRoundnessManager.updateView(row,
-                                true /* animate */));
-                    }
-                }
-
-                @Override
                 public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
                     long numEntries = mHeadsUpManager.getAllEntries().count();
                     NotificationEntry topEntry = mHeadsUpManager.getTopEntry();
                     mView.setNumHeadsUp(numEntries);
                     mView.setTopHeadsUpEntry(topEntry);
                     generateHeadsUpAnimation(entry, isHeadsUp);
-                    if (!mUseRoundnessSourceTypes) {
-                        ExpandableNotificationRow row = entry.getRow();
-                        mNotificationRoundnessManager.updateView(row, true /* animate */);
-                    }
                 }
             };
 
@@ -678,7 +652,8 @@
             FeatureFlags featureFlags,
             NotificationTargetsHelper notificationTargetsHelper,
             SecureSettings secureSettings,
-            NotificationDismissibilityProvider dismissibilityProvider) {
+            NotificationDismissibilityProvider dismissibilityProvider,
+            ActivityStarter activityStarter) {
         mView = view;
         mStackStateLogger = stackLogger;
         mLogger = logger;
@@ -720,10 +695,10 @@
         mShadeController = shadeController;
         mNotifIconAreaController = notifIconAreaController;
         mFeatureFlags = featureFlags;
-        mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
         mNotificationTargetsHelper = notificationTargetsHelper;
         mSecureSettings = secureSettings;
         mDismissibilityProvider = dismissibilityProvider;
+        mActivityStarter = activityStarter;
         updateResources();
         setUpView();
     }
@@ -734,6 +709,7 @@
         mView.setLogger(mLogger);
         mView.setTouchHandler(new TouchHandler());
         mView.setCentralSurfaces(mCentralSurfaces);
+        mView.setActivityStarter(mActivityStarter);
         mView.setClearAllAnimationListener(this::onAnimationEnd);
         mView.setClearAllListener((selection) -> mUiEventLogger.log(
                 NotificationPanelEvent.fromSelection(selection)));
@@ -786,11 +762,6 @@
 
         mLockscreenUserManager.addUserChangedListener(mLockscreenUserChangeListener);
 
-        if (!mUseRoundnessSourceTypes) {
-            mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate);
-            mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded);
-        }
-
         mVisibilityLocationProviderDelegator.setDelegate(this::isInVisibleLocation);
 
         mTunerService.addTunable(
@@ -817,7 +788,7 @@
                 mView.generateRemoveAnimation(mKeyguardMediaController.getSinglePaneContainer());
             }
             mView.requestChildrenUpdate();
-            return Unit.INSTANCE;
+            return kotlin.Unit.INSTANCE;
         });
 
         // attach callback, and then call it to update mView immediately
@@ -956,7 +927,6 @@
 
     public void setTrackingHeadsUp(ExpandableNotificationRow expandableNotificationRow) {
         mView.setTrackingHeadsUp(expandableNotificationRow);
-        mNotificationRoundnessManager.setTrackingHeadsUp(expandableNotificationRow);
     }
 
     public void wakeUpFromPulse() {
@@ -1774,9 +1744,6 @@
         @Override
         public void bindRow(ExpandableNotificationRow row) {
             row.setHeadsUpAnimatingAwayListener(animatingAway -> {
-                if (!mUseRoundnessSourceTypes) {
-                    mNotificationRoundnessManager.updateView(row, false);
-                }
                 NotificationEntry entry = row.getEntry();
                 mHeadsUpAppearanceController.updateHeader(entry);
                 mHeadsUpAppearanceController.updateHeadsUpAndPulsingRoundness(entry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index 91f53b6..993c3801 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -35,7 +35,6 @@
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
@@ -69,7 +68,6 @@
     private boolean mIsExpanded;
     private boolean mPulsing;
     private final NotificationRoundnessManager mNotificationRoundnessManager;
-    private final boolean mUseRoundnessSourceTypes;
 
     NotificationSwipeHelper(
             Resources resources,
@@ -81,7 +79,6 @@
             NotificationRoundnessManager notificationRoundnessManager) {
         super(callback, resources, viewConfiguration, falsingManager, featureFlags);
         mNotificationRoundnessManager = notificationRoundnessManager;
-        mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
         mMenuListener = menuListener;
         mCallback = callback;
         mFalsingCheck = () -> resetExposedMenuView(true /* animate */, true /* force */);
@@ -323,8 +320,7 @@
     protected void prepareDismissAnimation(View view, Animator anim) {
         super.prepareDismissAnimation(view, anim);
 
-        if (mUseRoundnessSourceTypes
-                && view instanceof ExpandableNotificationRow
+        if (view instanceof ExpandableNotificationRow
                 && mNotificationRoundnessManager.isClearAllInProgress()) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) view;
             anim.addListener(new AnimatorListenerAdapter() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
index 8b6d6a4f..02662f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
@@ -4,7 +4,6 @@
 import androidx.core.view.isVisible
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.statusbar.notification.Roundable
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
@@ -20,7 +19,6 @@
 constructor(
     featureFlags: FeatureFlags,
 ) {
-    private val useRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES)
 
     /**
      * This method looks for views that can be rounded (and implement [Roundable]) during a
@@ -48,10 +46,6 @@
         if (notificationParent != null && childrenContainer != null) {
             // We are inside a notification group
 
-            if (!useRoundnessSourceTypes) {
-                return RoundableTargets(null, null, null)
-            }
-
             val visibleGroupChildren = childrenContainer.attachedChildren.filter { it.isVisible }
             val indexOfParentSwipedView = visibleGroupChildren.indexOf(viewSwiped)
 
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 3060473..92d767a 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
@@ -34,7 +34,6 @@
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.NotificationShelf;
-import com.android.systemui.statusbar.notification.LegacySourceType;
 import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -75,7 +74,6 @@
     private float mQuickQsOffsetHeight;
     private float mSmallCornerRadius;
     private float mLargeCornerRadius;
-    private boolean mUseRoundnessSourceTypes;
 
     public StackScrollAlgorithm(
             Context context,
@@ -836,12 +834,8 @@
                 row.isLastInSection() ? 1f : (mSmallCornerRadius / mLargeCornerRadius);
         final float bottomValue = computeCornerRoundnessForPinnedHun(mHostView.getHeight(),
                 ambientState.getStackY(), getMaxAllowedChildHeight(row), originalCornerRadius);
-        if (mUseRoundnessSourceTypes) {
-            row.requestBottomRoundness(bottomValue, STACK_SCROLL_ALGO);
-            row.addOnDetachResetRoundness(STACK_SCROLL_ALGO);
-        } else {
-            row.requestBottomRoundness(bottomValue, LegacySourceType.OnScroll);
-        }
+        row.requestBottomRoundness(bottomValue, STACK_SCROLL_ALGO);
+        row.addOnDetachResetRoundness(STACK_SCROLL_ALGO);
     }
 
     @VisibleForTesting
@@ -979,14 +973,6 @@
         this.mIsExpanded = isExpanded;
     }
 
-    /**
-     * Enable the support for rounded corner based on the SourceType
-     * @param enabled true if is supported
-     */
-    public void useRoundnessSourceTypes(boolean enabled) {
-        mUseRoundnessSourceTypes = enabled;
-    }
-
     public static class StackScrollAlgorithmState {
 
         /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
new file mode 100644
index 0000000..d9dc887
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -0,0 +1,867 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import android.app.ActivityManager
+import android.app.ActivityOptions
+import android.app.ActivityTaskManager
+import android.app.PendingIntent
+import android.app.TaskStackBuilder
+import android.content.Context
+import android.content.Intent
+import android.os.RemoteException
+import android.os.UserHandle
+import android.provider.Settings
+import android.util.Log
+import android.view.RemoteAnimationAdapter
+import android.view.View
+import android.view.WindowManager
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.ActivityIntentHelper
+import com.android.systemui.R
+import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.animation.ActivityLaunchAnimator.PendingIntentStarter
+import com.android.systemui.animation.DelegateLaunchAnimatorController
+import com.android.systemui.assist.AssistManager
+import com.android.systemui.camera.CameraIntents.Companion.isInsecureCameraIntent
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyguard.KeyguardViewMediator
+import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.shade.ShadeController
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.statusbar.window.StatusBarWindowController
+import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.kotlin.getOrNull
+import dagger.Lazy
+import java.util.Optional
+import javax.inject.Inject
+
+/** Handles start activity logic in SystemUI. */
+@SysUISingleton
+class ActivityStarterImpl
+@Inject
+constructor(
+    private val centralSurfacesOptLazy: Lazy<Optional<CentralSurfaces>>,
+    private val assistManagerLazy: Lazy<AssistManager>,
+    private val dozeServiceHostLazy: Lazy<DozeServiceHost>,
+    private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>,
+    private val keyguardViewMediatorLazy: Lazy<KeyguardViewMediator>,
+    private val shadeControllerLazy: Lazy<ShadeController>,
+    private val statusBarKeyguardViewManagerLazy: Lazy<StatusBarKeyguardViewManager>,
+    private val activityLaunchAnimator: ActivityLaunchAnimator,
+    private val context: Context,
+    private val lockScreenUserManager: NotificationLockscreenUserManager,
+    private val statusBarWindowController: StatusBarWindowController,
+    private val wakefulnessLifecycle: WakefulnessLifecycle,
+    private val keyguardStateController: KeyguardStateController,
+    private val statusBarStateController: SysuiStatusBarStateController,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    private val deviceProvisionedController: DeviceProvisionedController,
+    private val userTracker: UserTracker,
+    private val activityIntentHelper: ActivityIntentHelper,
+    @Main private val mainExecutor: DelayableExecutor,
+) : ActivityStarter {
+    companion object {
+        const val TAG = "ActivityStarterImpl"
+    }
+
+    private val centralSurfaces: CentralSurfaces?
+        get() = centralSurfacesOptLazy.get().getOrNull()
+
+    private val activityStarterInternal = ActivityStarterInternal()
+
+    override fun startPendingIntentDismissingKeyguard(intent: PendingIntent) {
+        activityStarterInternal.startPendingIntentDismissingKeyguard(intent = intent)
+    }
+
+    override fun startPendingIntentDismissingKeyguard(
+        intent: PendingIntent,
+        intentSentUiThreadCallback: Runnable?,
+    ) {
+        activityStarterInternal.startPendingIntentDismissingKeyguard(
+            intent = intent,
+            intentSentUiThreadCallback = intentSentUiThreadCallback,
+        )
+    }
+
+    override fun startPendingIntentDismissingKeyguard(
+        intent: PendingIntent,
+        intentSentUiThreadCallback: Runnable?,
+        associatedView: View?,
+    ) {
+        activityStarterInternal.startPendingIntentDismissingKeyguard(
+            intent = intent,
+            intentSentUiThreadCallback = intentSentUiThreadCallback,
+            associatedView = associatedView,
+        )
+    }
+
+    override fun startPendingIntentDismissingKeyguard(
+        intent: PendingIntent,
+        intentSentUiThreadCallback: Runnable?,
+        animationController: ActivityLaunchAnimator.Controller?,
+    ) {
+        activityStarterInternal.startPendingIntentDismissingKeyguard(
+            intent = intent,
+            intentSentUiThreadCallback = intentSentUiThreadCallback,
+            animationController = animationController,
+        )
+    }
+
+    /**
+     * TODO(b/279084380): Change callers to just call startActivityDismissingKeyguard and deprecate
+     *   this.
+     */
+    override fun startActivity(intent: Intent, dismissShade: Boolean) {
+        activityStarterInternal.startActivityDismissingKeyguard(
+            intent = intent,
+            dismissShade = dismissShade,
+        )
+    }
+
+    /**
+     * TODO(b/279084380): Change callers to just call startActivityDismissingKeyguard and deprecate
+     *   this.
+     */
+    override fun startActivity(intent: Intent, onlyProvisioned: Boolean, dismissShade: Boolean) {
+        activityStarterInternal.startActivityDismissingKeyguard(
+            intent = intent,
+            onlyProvisioned = onlyProvisioned,
+            dismissShade = dismissShade,
+        )
+    }
+
+    /**
+     * TODO(b/279084380): Change callers to just call startActivityDismissingKeyguard and deprecate
+     *   this.
+     */
+    override fun startActivity(
+        intent: Intent,
+        dismissShade: Boolean,
+        callback: ActivityStarter.Callback?,
+    ) {
+        activityStarterInternal.startActivityDismissingKeyguard(
+            intent = intent,
+            dismissShade = dismissShade,
+            callback = callback,
+        )
+    }
+
+    /**
+     * TODO(b/279084380): Change callers to just call startActivityDismissingKeyguard and deprecate
+     *   this.
+     */
+    override fun startActivity(
+        intent: Intent,
+        onlyProvisioned: Boolean,
+        dismissShade: Boolean,
+        flags: Int,
+    ) {
+        activityStarterInternal.startActivityDismissingKeyguard(
+            intent = intent,
+            onlyProvisioned = onlyProvisioned,
+            dismissShade = dismissShade,
+            flags = flags,
+        )
+    }
+
+    override fun startActivity(
+        intent: Intent,
+        dismissShade: Boolean,
+        animationController: ActivityLaunchAnimator.Controller?,
+        showOverLockscreenWhenLocked: Boolean,
+    ) {
+        activityStarterInternal.startActivity(
+            intent = intent,
+            dismissShade = dismissShade,
+            animationController = animationController,
+            showOverLockscreenWhenLocked = showOverLockscreenWhenLocked,
+        )
+    }
+    override fun startActivity(
+        intent: Intent,
+        dismissShade: Boolean,
+        animationController: ActivityLaunchAnimator.Controller?,
+        showOverLockscreenWhenLocked: Boolean,
+        userHandle: UserHandle?,
+    ) {
+        activityStarterInternal.startActivity(
+            intent = intent,
+            dismissShade = dismissShade,
+            animationController = animationController,
+            showOverLockscreenWhenLocked = showOverLockscreenWhenLocked,
+            userHandle = userHandle,
+        )
+    }
+
+    override fun postStartActivityDismissingKeyguard(intent: PendingIntent) {
+        postOnUiThread {
+            activityStarterInternal.startPendingIntentDismissingKeyguard(
+                intent = intent,
+            )
+        }
+    }
+
+    override fun postStartActivityDismissingKeyguard(
+        intent: PendingIntent,
+        animationController: ActivityLaunchAnimator.Controller?
+    ) {
+        postOnUiThread {
+            activityStarterInternal.startPendingIntentDismissingKeyguard(
+                intent = intent,
+                animationController = animationController,
+            )
+        }
+    }
+
+    override fun postStartActivityDismissingKeyguard(intent: Intent, delay: Int) {
+        postOnUiThread(delay) {
+            activityStarterInternal.startActivityDismissingKeyguard(intent = intent)
+        }
+    }
+
+    override fun postStartActivityDismissingKeyguard(
+        intent: Intent,
+        delay: Int,
+        animationController: ActivityLaunchAnimator.Controller?,
+    ) {
+        postOnUiThread(delay) {
+            activityStarterInternal.startActivityDismissingKeyguard(
+                intent = intent,
+                animationController = animationController,
+            )
+        }
+    }
+
+    override fun postStartActivityDismissingKeyguard(
+        intent: Intent,
+        delay: Int,
+        animationController: ActivityLaunchAnimator.Controller?,
+        customMessage: String?,
+    ) {
+        postOnUiThread(delay) {
+            activityStarterInternal.startActivityDismissingKeyguard(
+                intent = intent,
+                animationController = animationController,
+                customMessage = customMessage,
+            )
+        }
+    }
+
+    override fun dismissKeyguardThenExecute(
+        action: OnDismissAction,
+        cancel: Runnable?,
+        afterKeyguardGone: Boolean,
+    ) {
+        activityStarterInternal.dismissKeyguardThenExecute(
+            action = action,
+            cancel = cancel,
+            afterKeyguardGone = afterKeyguardGone,
+        )
+    }
+
+    override fun dismissKeyguardThenExecute(
+        action: OnDismissAction,
+        cancel: Runnable?,
+        afterKeyguardGone: Boolean,
+        customMessage: String?,
+    ) {
+        activityStarterInternal.dismissKeyguardThenExecute(
+            action = action,
+            cancel = cancel,
+            afterKeyguardGone = afterKeyguardGone,
+            customMessage = customMessage,
+        )
+    }
+
+    override fun startActivityDismissingKeyguard(
+        intent: Intent,
+        onlyProvisioned: Boolean,
+        dismissShade: Boolean,
+        disallowEnterPictureInPictureWhileLaunching: Boolean,
+        callback: ActivityStarter.Callback?,
+        flags: Int,
+        animationController: ActivityLaunchAnimator.Controller?,
+        userHandle: UserHandle?,
+    ) {
+        activityStarterInternal.startActivityDismissingKeyguard(
+            intent = intent,
+            onlyProvisioned = onlyProvisioned,
+            dismissShade = dismissShade,
+            disallowEnterPictureInPictureWhileLaunching =
+                disallowEnterPictureInPictureWhileLaunching,
+            callback = callback,
+            flags = flags,
+            animationController = animationController,
+            userHandle = userHandle,
+        )
+    }
+
+    override fun executeRunnableDismissingKeyguard(
+        runnable: Runnable?,
+        cancelAction: Runnable?,
+        dismissShade: Boolean,
+        afterKeyguardGone: Boolean,
+        deferred: Boolean,
+    ) {
+        activityStarterInternal.executeRunnableDismissingKeyguard(
+            runnable = runnable,
+            cancelAction = cancelAction,
+            dismissShade = dismissShade,
+            afterKeyguardGone = afterKeyguardGone,
+            deferred = deferred,
+        )
+    }
+
+    override fun executeRunnableDismissingKeyguard(
+        runnable: Runnable?,
+        cancelAction: Runnable?,
+        dismissShade: Boolean,
+        afterKeyguardGone: Boolean,
+        deferred: Boolean,
+        willAnimateOnKeyguard: Boolean,
+        customMessage: String?,
+    ) {
+        activityStarterInternal.executeRunnableDismissingKeyguard(
+            runnable = runnable,
+            cancelAction = cancelAction,
+            dismissShade = dismissShade,
+            afterKeyguardGone = afterKeyguardGone,
+            deferred = deferred,
+            willAnimateOnKeyguard = willAnimateOnKeyguard,
+            customMessage = customMessage,
+        )
+    }
+
+    override fun postQSRunnableDismissingKeyguard(runnable: Runnable?) {
+        postOnUiThread {
+            statusBarStateController.setLeaveOpenOnKeyguardHide(true)
+            activityStarterInternal.executeRunnableDismissingKeyguard(
+                runnable = { runnable?.let { postOnUiThread(runnable = it) } },
+            )
+        }
+    }
+
+    private fun postOnUiThread(delay: Int = 0, runnable: Runnable) {
+        mainExecutor.executeDelayed(runnable, delay.toLong())
+    }
+
+    /**
+     * Encapsulates the activity logic for activity starter.
+     *
+     * Logic is duplicated in {@link CentralSurfacesImpl}
+     */
+    private inner class ActivityStarterInternal {
+        /** Starts an activity after dismissing keyguard. */
+        fun startActivityDismissingKeyguard(
+            intent: Intent,
+            onlyProvisioned: Boolean = false,
+            dismissShade: Boolean = false,
+            disallowEnterPictureInPictureWhileLaunching: Boolean = false,
+            callback: ActivityStarter.Callback? = null,
+            flags: Int = 0,
+            animationController: ActivityLaunchAnimator.Controller? = null,
+            userHandle: UserHandle? = null,
+            customMessage: String? = null,
+        ) {
+            val userHandle: UserHandle = userHandle ?: getActivityUserHandle(intent)
+
+            if (onlyProvisioned && !deviceProvisionedController.isDeviceProvisioned) return
+
+            val willLaunchResolverActivity: Boolean =
+                activityIntentHelper.wouldLaunchResolverActivity(
+                    intent,
+                    lockScreenUserManager.currentUserId
+                )
+
+            val animate =
+                animationController != null &&
+                    !willLaunchResolverActivity &&
+                    centralSurfaces?.shouldAnimateLaunch(true /* isActivityIntent */) == true
+            val animController =
+                wrapAnimationController(
+                    animationController = animationController,
+                    dismissShade = dismissShade,
+                    isLaunchForActivity = true,
+                )
+
+            // If we animate, we will dismiss the shade only once the animation is done. This is
+            // taken care of by the StatusBarLaunchAnimationController.
+            val dismissShadeDirectly = dismissShade && animController == null
+
+            val runnable = Runnable {
+                assistManagerLazy.get().hideAssist()
+                intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
+                intent.addFlags(flags)
+                val result = intArrayOf(ActivityManager.START_CANCELED)
+                activityLaunchAnimator.startIntentWithAnimation(
+                    animController,
+                    animate,
+                    intent.getPackage()
+                ) { adapter: RemoteAnimationAdapter? ->
+                    val options =
+                        ActivityOptions(
+                            CentralSurfaces.getActivityOptions(centralSurfaces!!.displayId, adapter)
+                        )
+
+                    // We know that the intent of the caller is to dismiss the keyguard and
+                    // this runnable is called right after the keyguard is solved, so we tell
+                    // WM that we should dismiss it to avoid flickers when opening an activity
+                    // that can also be shown over the keyguard.
+                    options.setDismissKeyguard()
+                    options.setDisallowEnterPictureInPictureWhileLaunching(
+                        disallowEnterPictureInPictureWhileLaunching
+                    )
+                    if (isInsecureCameraIntent(intent)) {
+                        // Normally an activity will set it's requested rotation
+                        // animation on its window. However when launching an activity
+                        // causes the orientation to change this is too late. In these cases
+                        // the default animation is used. This doesn't look good for
+                        // the camera (as it rotates the camera contents out of sync
+                        // with physical reality). So, we ask the WindowManager to
+                        // force the cross fade animation if an orientation change
+                        // happens to occur during the launch.
+                        options.rotationAnimationHint =
+                            WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS
+                    }
+                    if (Settings.Panel.ACTION_VOLUME == intent.action) {
+                        // Settings Panel is implemented as activity(not a dialog), so
+                        // underlying app is paused and may enter picture-in-picture mode
+                        // as a result.
+                        // So we need to disable picture-in-picture mode here
+                        // if it is volume panel.
+                        options.setDisallowEnterPictureInPictureWhileLaunching(true)
+                    }
+                    try {
+                        result[0] =
+                            ActivityTaskManager.getService()
+                                .startActivityAsUser(
+                                    null,
+                                    context.basePackageName,
+                                    context.attributionTag,
+                                    intent,
+                                    intent.resolveTypeIfNeeded(context.contentResolver),
+                                    null,
+                                    null,
+                                    0,
+                                    Intent.FLAG_ACTIVITY_NEW_TASK,
+                                    null,
+                                    options.toBundle(),
+                                    userHandle.identifier,
+                                )
+                    } catch (e: RemoteException) {
+                        Log.w(TAG, "Unable to start activity", e)
+                    }
+                    result[0]
+                }
+                callback?.onActivityStarted(result[0])
+            }
+            val cancelRunnable = Runnable {
+                callback?.onActivityStarted(ActivityManager.START_CANCELED)
+            }
+            // Do not deferKeyguard when occluded because, when keyguard is occluded,
+            // we do not launch the activity until keyguard is done.
+            val occluded = (keyguardStateController.isShowing && keyguardStateController.isOccluded)
+            val deferred = !occluded
+            executeRunnableDismissingKeyguard(
+                runnable,
+                cancelRunnable,
+                dismissShadeDirectly,
+                willLaunchResolverActivity,
+                deferred,
+                animate,
+                customMessage,
+            )
+        }
+
+        /** Starts a pending intent after dismissing keyguard. */
+        fun startPendingIntentDismissingKeyguard(
+            intent: PendingIntent,
+            intentSentUiThreadCallback: Runnable? = null,
+            associatedView: View? = null,
+            animationController: ActivityLaunchAnimator.Controller? = null,
+        ) {
+            val animationController =
+                if (associatedView is ExpandableNotificationRow) {
+                    centralSurfaces?.getAnimatorControllerFromNotification(associatedView)
+                } else animationController
+
+            val willLaunchResolverActivity =
+                (intent.isActivity &&
+                    activityIntentHelper.wouldPendingLaunchResolverActivity(
+                        intent,
+                        lockScreenUserManager.currentUserId,
+                    ))
+
+            val animate =
+                !willLaunchResolverActivity &&
+                    animationController != null &&
+                    centralSurfaces?.shouldAnimateLaunch(intent.isActivity) == true
+
+            // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we
+            // run the animation on the keyguard). The animation will take care of (instantly)
+            // collapsing the shade and hiding the keyguard once it is done.
+            val collapse = !animate
+            executeRunnableDismissingKeyguard(
+                runnable = {
+                    try {
+                        // We wrap animationCallback with a StatusBarLaunchAnimatorController so
+                        // that the shade is collapsed after the animation (or when it is cancelled,
+                        // aborted, etc).
+                        val controller: ActivityLaunchAnimator.Controller? =
+                            wrapAnimationController(
+                                animationController = animationController,
+                                dismissShade = true,
+                                isLaunchForActivity = intent.isActivity,
+                            )
+                        activityLaunchAnimator.startPendingIntentWithAnimation(
+                            controller,
+                            animate,
+                            intent.creatorPackage,
+                            object : PendingIntentStarter {
+                                override fun startPendingIntent(
+                                    animationAdapter: RemoteAnimationAdapter?
+                                ): Int {
+                                    val options =
+                                        ActivityOptions(
+                                            CentralSurfaces.getActivityOptions(
+                                                centralSurfaces!!.displayId,
+                                                animationAdapter
+                                            )
+                                        )
+                                    // TODO b/221255671: restrict this to only be set for
+                                    // notifications
+                                    options.isEligibleForLegacyPermissionPrompt = true
+                                    return intent.sendAndReturnResult(
+                                        null,
+                                        0,
+                                        null,
+                                        null,
+                                        null,
+                                        null,
+                                        options.toBundle()
+                                    )
+                                }
+                            },
+                        )
+                    } catch (e: PendingIntent.CanceledException) {
+                        // the stack trace isn't very helpful here.
+                        // Just log the exception message.
+                        Log.w(TAG, "Sending intent failed: $e")
+                        if (!collapse) {
+                            // executeRunnableDismissingKeyguard did not collapse for us already.
+                            centralSurfaces?.collapsePanelOnMainThread()
+                        }
+                        // TODO: Dismiss Keyguard.
+                    }
+                    if (intent.isActivity) {
+                        assistManagerLazy.get().hideAssist()
+                    }
+                    intentSentUiThreadCallback?.let { postOnUiThread(runnable = it) }
+                },
+                afterKeyguardGone = willLaunchResolverActivity,
+                dismissShade = collapse,
+                willAnimateOnKeyguard = animate,
+            )
+        }
+
+        /** Starts an Activity. */
+        fun startActivity(
+            intent: Intent,
+            dismissShade: Boolean = false,
+            animationController: ActivityLaunchAnimator.Controller? = null,
+            showOverLockscreenWhenLocked: Boolean = false,
+            userHandle: UserHandle? = null,
+        ) {
+            val userHandle = userHandle ?: getActivityUserHandle(intent)
+            // Make sure that we dismiss the keyguard if it is directly dismissible or when we don't
+            // want to show the activity above it.
+            if (keyguardStateController.isUnlocked || !showOverLockscreenWhenLocked) {
+                startActivityDismissingKeyguard(
+                    intent = intent,
+                    onlyProvisioned = false,
+                    dismissShade = dismissShade,
+                    disallowEnterPictureInPictureWhileLaunching = false,
+                    callback = null,
+                    flags = 0,
+                    animationController = animationController,
+                    userHandle = userHandle,
+                )
+                return
+            }
+
+            val animate =
+                animationController != null &&
+                    centralSurfaces?.shouldAnimateLaunch(
+                        /* isActivityIntent= */ true,
+                        showOverLockscreenWhenLocked
+                    ) == true
+
+            var controller: ActivityLaunchAnimator.Controller? = null
+            if (animate) {
+                // Wrap the animation controller to dismiss the shade and set
+                // mIsLaunchingActivityOverLockscreen during the animation.
+                val delegate =
+                    wrapAnimationController(
+                        animationController = animationController,
+                        dismissShade = dismissShade,
+                        isLaunchForActivity = true,
+                    )
+                delegate?.let {
+                    controller =
+                        object : DelegateLaunchAnimatorController(delegate) {
+                            override fun onIntentStarted(willAnimate: Boolean) {
+                                delegate?.onIntentStarted(willAnimate)
+                                if (willAnimate) {
+                                    centralSurfaces?.setIsLaunchingActivityOverLockscreen(true)
+                                }
+                            }
+
+                            override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
+                                super.onLaunchAnimationStart(isExpandingFullyAbove)
+
+                                // Double check that the keyguard is still showing and not going
+                                // away, but if so set the keyguard occluded. Typically, WM will let
+                                // KeyguardViewMediator know directly, but we're overriding that to
+                                // play the custom launch animation, so we need to take care of that
+                                // here. The unocclude animation is not overridden, so WM will call
+                                // KeyguardViewMediator's unocclude animation runner when the
+                                // activity is exited.
+                                if (
+                                    keyguardStateController.isShowing &&
+                                        !keyguardStateController.isKeyguardGoingAway
+                                ) {
+                                    Log.d(TAG, "Setting occluded = true in #startActivity.")
+                                    keyguardViewMediatorLazy
+                                        .get()
+                                        .setOccluded(true /* isOccluded */, true /* animate */)
+                                }
+                            }
+
+                            override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
+                                // Set mIsLaunchingActivityOverLockscreen to false before actually
+                                // finishing the animation so that we can assume that
+                                // mIsLaunchingActivityOverLockscreen being true means that we will
+                                // collapse the shade (or at least run the post collapse runnables)
+                                // later on.
+                                centralSurfaces?.setIsLaunchingActivityOverLockscreen(false)
+                                delegate?.onLaunchAnimationEnd(isExpandingFullyAbove)
+                            }
+
+                            override fun onLaunchAnimationCancelled(
+                                newKeyguardOccludedState: Boolean?
+                            ) {
+                                if (newKeyguardOccludedState != null) {
+                                    keyguardViewMediatorLazy
+                                        .get()
+                                        .setOccluded(newKeyguardOccludedState, false /* animate */)
+                                }
+
+                                // Set mIsLaunchingActivityOverLockscreen to false before actually
+                                // finishing the animation so that we can assume that
+                                // mIsLaunchingActivityOverLockscreen being true means that we will
+                                // collapse the shade (or at least run the // post collapse
+                                // runnables) later on.
+                                centralSurfaces?.setIsLaunchingActivityOverLockscreen(false)
+                                delegate.onLaunchAnimationCancelled(newKeyguardOccludedState)
+                            }
+                        }
+                }
+            } else if (dismissShade) {
+                // The animation will take care of dismissing the shade at the end of the animation.
+                // If we don't animate, collapse it directly.
+                centralSurfaces?.collapseShade()
+            }
+
+            // We should exit the dream to prevent the activity from starting below the
+            // dream.
+            if (keyguardUpdateMonitor.isDreaming) {
+                centralSurfaces?.awakenDreams()
+            }
+
+            activityLaunchAnimator.startIntentWithAnimation(
+                controller,
+                animate,
+                intent.getPackage(),
+                showOverLockscreenWhenLocked
+            ) { adapter: RemoteAnimationAdapter? ->
+                TaskStackBuilder.create(context)
+                    .addNextIntent(intent)
+                    .startActivities(
+                        CentralSurfaces.getActivityOptions(centralSurfaces!!.displayId, adapter),
+                        userHandle
+                    )
+            }
+        }
+
+        /** Executes an action after dismissing keyguard. */
+        fun dismissKeyguardThenExecute(
+            action: OnDismissAction,
+            cancel: Runnable? = null,
+            afterKeyguardGone: Boolean = false,
+            customMessage: String? = null,
+        ) {
+            if (
+                !action.willRunAnimationOnKeyguard() &&
+                    wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP &&
+                    keyguardStateController.canDismissLockScreen() &&
+                    !statusBarStateController.leaveOpenOnKeyguardHide() &&
+                    dozeServiceHostLazy.get().isPulsing
+            ) {
+                // Reuse the biometric wake-and-unlock transition if we dismiss keyguard from a
+                // pulse.
+                // TODO: Factor this transition out of BiometricUnlockController.
+                biometricUnlockControllerLazy
+                    .get()
+                    .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING)
+            }
+            if (keyguardStateController.isShowing) {
+                statusBarKeyguardViewManagerLazy
+                    .get()
+                    .dismissWithAction(action, cancel, afterKeyguardGone, customMessage)
+            } else {
+                // If the keyguard isn't showing but the device is dreaming, we should exit the
+                // dream.
+                if (keyguardUpdateMonitor.isDreaming) {
+                    centralSurfaces?.awakenDreams()
+                }
+                action.onDismiss()
+            }
+        }
+
+        /** Executes an action after dismissing keyguard. */
+        fun executeRunnableDismissingKeyguard(
+            runnable: Runnable? = null,
+            cancelAction: Runnable? = null,
+            dismissShade: Boolean = false,
+            afterKeyguardGone: Boolean = false,
+            deferred: Boolean = false,
+            willAnimateOnKeyguard: Boolean = false,
+            customMessage: String? = null,
+        ) {
+            val onDismissAction: OnDismissAction =
+                object : OnDismissAction {
+                    override fun onDismiss(): Boolean {
+                        if (runnable != null) {
+                            if (
+                                keyguardStateController.isShowing &&
+                                    keyguardStateController.isOccluded
+                            ) {
+                                statusBarKeyguardViewManagerLazy
+                                    .get()
+                                    .addAfterKeyguardGoneRunnable(runnable)
+                            } else {
+                                mainExecutor.execute(runnable)
+                            }
+                        }
+                        if (dismissShade) {
+                            if (
+                                shadeControllerLazy.get().isExpandedVisible &&
+                                    !statusBarKeyguardViewManagerLazy.get().isBouncerShowing
+                            ) {
+                                shadeControllerLazy.get().animateCollapseShadeDelayed()
+                            } else {
+                                // Do it after DismissAction has been processed to conserve the
+                                // needed ordering.
+                                postOnUiThread {
+                                    shadeControllerLazy.get().runPostCollapseRunnables()
+                                }
+                            }
+                        }
+                        return deferred
+                    }
+
+                    override fun willRunAnimationOnKeyguard(): Boolean {
+                        return willAnimateOnKeyguard
+                    }
+                }
+            dismissKeyguardThenExecute(
+                onDismissAction,
+                cancelAction,
+                afterKeyguardGone,
+                customMessage,
+            )
+        }
+
+        /**
+         * Return a [ActivityLaunchAnimator.Controller] wrapping `animationController` so that:
+         * - if it launches in the notification shade window and `dismissShade` is true, then the
+         *   shade will be instantly dismissed at the end of the animation.
+         * - if it launches in status bar window, it will make the status bar window match the
+         *   device size during the animation (that way, the animation won't be clipped by the
+         *   status bar size).
+         *
+         * @param animationController the controller that is wrapped and will drive the main
+         *   animation.
+         * @param dismissShade whether the notification shade will be dismissed at the end of the
+         *   animation. This is ignored if `animationController` is not animating in the shade
+         *   window.
+         * @param isLaunchForActivity whether the launch is for an activity.
+         */
+        private fun wrapAnimationController(
+            animationController: ActivityLaunchAnimator.Controller?,
+            dismissShade: Boolean,
+            isLaunchForActivity: Boolean,
+        ): ActivityLaunchAnimator.Controller? {
+            if (animationController == null) {
+                return null
+            }
+            val rootView = animationController.launchContainer.rootView
+            val controllerFromStatusBar: Optional<ActivityLaunchAnimator.Controller> =
+                statusBarWindowController.wrapAnimationControllerIfInStatusBar(
+                    rootView,
+                    animationController
+                )
+            if (controllerFromStatusBar.isPresent) {
+                return controllerFromStatusBar.get()
+            }
+
+            centralSurfaces?.let {
+                // If the view is not in the status bar, then we are animating a view in the shade.
+                // We have to make sure that we collapse it when the animation ends or is cancelled.
+                if (dismissShade) {
+                    return StatusBarLaunchAnimatorController(
+                        animationController,
+                        it,
+                        isLaunchForActivity
+                    )
+                }
+            }
+
+            return animationController
+        }
+
+        /** Retrieves the current user handle to start the Activity. */
+        private fun getActivityUserHandle(intent: Intent): UserHandle {
+            val packages: Array<String> =
+                context.resources.getStringArray(R.array.system_ui_packages)
+            for (pkg in packages) {
+                if (intent.component == null) break
+                if (pkg == intent.component.packageName) {
+                    return UserHandle(UserHandle.myUserId())
+                }
+            }
+            return userTracker.userHandle
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index f579d30..4e69069 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -45,7 +45,8 @@
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.RemoteTransitionAdapter;
 import com.android.systemui.navigationbar.NavigationBarView;
-import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter.Callback;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.qs.QSPanelController;
 import com.android.systemui.shade.NotificationShadeWindowView;
@@ -53,11 +54,13 @@
 import com.android.systemui.shade.ShadeViewController;
 import com.android.systemui.statusbar.LightRevealScrim;
 import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.util.Compile;
 
 import java.io.PrintWriter;
 
-public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwner {
+/** */
+public interface CentralSurfaces extends Dumpable, LifecycleOwner {
     boolean MULTIUSER_DEBUG = false;
     // Should match the values in PhoneWindowManager
     String SYSTEM_DIALOG_REASON_KEY = "reason";
@@ -230,29 +233,33 @@
 
     boolean isShadeDisabled();
 
-    @Override
+    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
     void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
             int flags);
 
-    @Override
+    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
     void startActivity(Intent intent, boolean dismissShade);
 
-    @Override
+    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
+    void startActivity(Intent intent, boolean dismissShade,
+            @Nullable ActivityLaunchAnimator.Controller animationController);
+
+    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
     void startActivity(Intent intent, boolean dismissShade,
             @Nullable ActivityLaunchAnimator.Controller animationController,
             boolean showOverLockscreenWhenLocked);
 
-    @Override
+    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
     void startActivity(Intent intent, boolean dismissShade,
             @Nullable ActivityLaunchAnimator.Controller animationController,
             boolean showOverLockscreenWhenLocked, UserHandle userHandle);
 
     boolean isLaunchingActivityOverLockscreen();
 
-    @Override
+    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
     void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade);
 
-    @Override
+    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
     void startActivity(Intent intent, boolean dismissShade, Callback callback);
 
     boolean isWakeUpComingFromTouch();
@@ -315,19 +322,34 @@
 
     float getDisplayHeight();
 
+    /** Starts an activity intent that dismisses keyguard.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
             boolean dismissShade, int flags);
 
+    /** Starts an activity intent that dismisses keyguard.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
             boolean dismissShade);
 
+    /** Starts an activity intent that dismisses keyguard.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
             boolean dismissShade, boolean disallowEnterPictureInPictureWhileLaunching,
             Callback callback, int flags,
             @Nullable ActivityLaunchAnimator.Controller animationController,
             UserHandle userHandle);
 
-    /** Starts an activity intent that dismisses keyguard. */
+    /** Starts an activity intent that dismisses keyguard.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
             boolean dismissShade, boolean disallowEnterPictureInPictureWhileLaunching,
             Callback callback, int flags,
@@ -352,29 +374,70 @@
 
     void resetUserExpandedStates();
 
-    @Override
+    /**
+     * Dismisses Keyguard and executes an action afterwards.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
             boolean afterKeyguardGone);
 
+    /**
+     * Dismisses Keyguard and executes an action afterwards.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
+    void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
+            boolean afterKeyguardGone, @Nullable String customMessage);
+
     void setLockscreenUser(int newUserId);
 
-    @Override
+    /**
+     * Starts a QS runnable on the main thread and dismisses keyguard.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void postQSRunnableDismissingKeyguard(Runnable runnable);
 
-    @Override
+    /**
+     * Starts an activity on the main thread with a delay.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void postStartActivityDismissingKeyguard(PendingIntent intent);
 
-    @Override
+    /**
+     * Starts an activity on the main thread with a delay.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void postStartActivityDismissingKeyguard(PendingIntent intent,
             @Nullable ActivityLaunchAnimator.Controller animationController);
 
-    @Override
+    /**
+     * Starts an activity on the main thread with a delay.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void postStartActivityDismissingKeyguard(Intent intent, int delay);
 
-    @Override
+    /**
+     * Starts an activity on the main thread with a delay.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
     void postStartActivityDismissingKeyguard(Intent intent, int delay,
             @Nullable ActivityLaunchAnimator.Controller animationController);
 
+    /**
+     * Starts an activity on the main thread with a delay.
+     *
+     * Please use ActivityStarter instead of using these methods directly.
+     */
+    void postStartActivityDismissingKeyguard(Intent intent, int delay,
+            @Nullable ActivityLaunchAnimator.Controller animationController,
+            @Nullable String customMessage);
+
     void showKeyguard();
 
     boolean hideKeyguard();
@@ -468,18 +531,14 @@
 
     void awakenDreams();
 
-    @Override
     void startPendingIntentDismissingKeyguard(PendingIntent intent);
 
-    @Override
     void startPendingIntentDismissingKeyguard(
             PendingIntent intent, @Nullable Runnable intentSentUiThreadCallback);
 
-    @Override
     void startPendingIntentDismissingKeyguard(PendingIntent intent,
             Runnable intentSentUiThreadCallback, View associatedView);
 
-    @Override
     void startPendingIntentDismissingKeyguard(
             PendingIntent intent, @Nullable Runnable intentSentUiThreadCallback,
             @Nullable ActivityLaunchAnimator.Controller animationController);
@@ -554,4 +613,15 @@
             mDeviceId = deviceId;
         }
     }
+
+    /**
+     * Sets launching activity over LS state in central surfaces.
+     */
+    void setIsLaunchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen);
+
+    /**
+     * Gets an animation controller from a notification row.
+     */
+    ActivityLaunchAnimator.Controller getAnimatorControllerFromNotification(
+            ExpandableNotificationRow associatedView);
 }
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 c0a7a34..37e77766 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -50,6 +50,7 @@
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.QSPanelController;
 import com.android.systemui.settings.UserTracker;
@@ -102,6 +103,7 @@
     private final boolean mVibrateOnOpening;
     private final VibrationEffect mCameraLaunchGestureVibrationEffect;
     private final SystemBarAttributesListener mSystemBarAttributesListener;
+    private final ActivityStarter mActivityStarter;
     private final Lazy<CameraLauncher> mCameraLauncherLazy;
     private final QuickSettingsController mQsController;
     private final QSHost mQSHost;
@@ -138,7 +140,8 @@
             SystemBarAttributesListener systemBarAttributesListener,
             Lazy<CameraLauncher> cameraLauncherLazy,
             UserTracker userTracker,
-            QSHost qsHost) {
+            QSHost qsHost,
+            ActivityStarter activityStarter) {
         mCentralSurfaces = centralSurfaces;
         mQsController = quickSettingsController;
         mContext = context;
@@ -170,6 +173,7 @@
         mCameraLaunchGestureVibrationEffect = getCameraGestureVibrationEffect(
                 mVibratorOptional, resources);
         mSystemBarAttributesListener = systemBarAttributesListener;
+        mActivityStarter = activityStarter;
     }
 
     @Override
@@ -375,7 +379,7 @@
         if (!mKeyguardStateController.isShowing()) {
             final Intent cameraIntent = CameraIntents.getInsecureCameraIntent(mContext);
             cameraIntent.putExtra(CameraIntents.EXTRA_LAUNCH_SOURCE, source);
-            mCentralSurfaces.startActivityDismissingKeyguard(cameraIntent,
+            mActivityStarter.startActivityDismissingKeyguard(cameraIntent,
                     false /* onlyProvisioned */, true /* dismissShade */,
                     true /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */, 0,
                     null /* animationController */, mUserTracker.getUserHandle());
@@ -432,7 +436,7 @@
         // app-side haptic experimentation.
 
         if (!mKeyguardStateController.isShowing()) {
-            mCentralSurfaces.startActivityDismissingKeyguard(emergencyIntent,
+            mActivityStarter.startActivityDismissingKeyguard(emergencyIntent,
                     false /* onlyProvisioned */, true /* dismissShade */,
                     true /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */, 0,
                     null /* animationController */, mUserTracker.getUserHandle());
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 5654772..263566e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -168,6 +168,8 @@
 import com.android.systemui.navigationbar.NavigationBarController;
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.notetask.NoteTaskController;
+import com.android.systemui.plugins.ActivityStarter.Callback;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.OverlayPlugin;
@@ -281,6 +283,9 @@
  * <b>If at all possible, please avoid adding additional code to this monstrous class! Our goal is
  * to break up this class into many small classes, and any code added here will slow down that goal.
  * </b>
+ *
+ * Note that ActivityStarter logic here is deprecated and should be added here as well as
+ * {@link ActivityStarterImpl}
  */
 @SysUISingleton
 public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
@@ -1637,10 +1642,7 @@
 
     private void inflateStatusBarWindow() {
         if (mCentralSurfacesComponent != null) {
-            // Tear down
-            for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
-                s.stop();
-            }
+            Log.e(TAG, "CentralSurfacesComponent being recreated; this is unexpected.");
         }
         mCentralSurfacesComponent = mCentralSurfacesComponentFactory.create();
         mFragmentService.addFragmentInstantiationProvider(
@@ -1660,7 +1662,6 @@
         mShadeController.setNotificationPanelViewController(npvc);
         mShadeController.setNotificationShadeWindowViewController(
                 mNotificationShadeWindowViewController);
-        mCentralSurfacesComponent.getLockIconViewController().init();
         mStackScrollerController =
                 mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
         mQsController = mCentralSurfacesComponent.getQuickSettingsController();
@@ -1682,11 +1683,6 @@
                 mCentralSurfacesComponent.getCentralSurfacesCommandQueueCallbacks();
         // Connect in to the status bar manager service
         mCommandQueue.addCallback(mCommandQueueCallbacks);
-
-        // Perform all other initialization for CentralSurfacesScope
-        for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
-            s.start();
-        }
     }
 
     protected void startKeyguard() {
@@ -1798,17 +1794,27 @@
         return (mDisabled1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
             int flags) {
         startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, flags);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startActivity(Intent intent, boolean dismissShade) {
         startActivityDismissingKeyguard(intent, false /* onlyProvisioned */, dismissShade);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
+    @Override
+    public void startActivity(Intent intent, boolean dismissShade,
+            @androidx.annotation.Nullable ActivityLaunchAnimator.Controller animationController) {
+        startActivity(intent, dismissShade, animationController, false);
+    }
+
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startActivity(Intent intent, boolean dismissShade,
             @Nullable ActivityLaunchAnimator.Controller animationController,
@@ -1817,6 +1823,7 @@
                 getActivityUserHandle(intent));
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startActivity(Intent intent, boolean dismissShade,
             @Nullable ActivityLaunchAnimator.Controller animationController,
@@ -2414,6 +2421,7 @@
         return mDisplayId;
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
             boolean dismissShade, int flags) {
@@ -2422,12 +2430,14 @@
                 flags, null /* animationController */, getActivityUserHandle(intent));
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
             boolean dismissShade) {
         startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, 0);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
             boolean dismissShade, boolean disallowEnterPictureInPictureWhileLaunching,
@@ -2439,6 +2449,7 @@
                 userHandle, null /* customMessage */);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
             final boolean dismissShade, final boolean disallowEnterPictureInPictureWhileLaunching,
@@ -2549,6 +2560,8 @@
      *                     animation. This is ignored if {@code animationController} is not
      *                     animating in the shade window.
      * @param isLaunchForActivity whether the launch is for an activity.
+     *
+     * Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too.
      */
     @Nullable
     private ActivityLaunchAnimator.Controller wrapAnimationController(
@@ -2578,6 +2591,8 @@
         mStatusBarKeyguardViewManager.readyForKeyguardDone();
     }
 
+
+     /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void executeRunnableDismissingKeyguard(final Runnable runnable,
             final Runnable cancelAction,
@@ -2588,6 +2603,7 @@
                 deferred, false /* willAnimateOnKeyguard */, null /* customMessage */);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void executeRunnableDismissingKeyguard(final Runnable runnable,
             final Runnable cancelAction,
@@ -2698,16 +2714,19 @@
                 afterKeyguardGone /* afterKeyguardGone */);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
         dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
             boolean afterKeyguardGone) {
         dismissKeyguardThenExecute(action, cancelAction, afterKeyguardGone, null);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
             boolean afterKeyguardGone, String customMessage) {
@@ -2909,6 +2928,7 @@
                 | ((currentlyInsecure ? 1 : 0) << 12);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
         mMainExecutor.execute(() -> {
@@ -2918,11 +2938,13 @@
         });
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void postStartActivityDismissingKeyguard(PendingIntent intent) {
         postStartActivityDismissingKeyguard(intent, null /* animationController */);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void postStartActivityDismissingKeyguard(final PendingIntent intent,
             @Nullable ActivityLaunchAnimator.Controller animationController) {
@@ -2930,11 +2952,13 @@
                 null /* intentSentUiThreadCallback */, animationController));
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
         postStartActivityDismissingKeyguard(intent, delay, null /* animationController */);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void postStartActivityDismissingKeyguard(Intent intent, int delay,
             @Nullable ActivityLaunchAnimator.Controller animationController) {
@@ -2942,6 +2966,7 @@
                 null /* customMessage */);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void postStartActivityDismissingKeyguard(Intent intent, int delay,
             @Nullable ActivityLaunchAnimator.Controller animationController,
@@ -3648,9 +3673,6 @@
                         /* wakingUp= */ true,
                         mShouldDelayWakeUpAnimation);
 
-                if (!mKeyguardBypassController.getBypassEnabled()) {
-                    mHeadsUpManager.releaseAllImmediately();
-                }
                 updateVisibleToUser();
                 updateIsKeyguard();
                 mDozeServiceHost.stopDozing();
@@ -4092,11 +4114,13 @@
         dismissKeyguardThenExecute(onDismissAction, afterKeyguardGone);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startPendingIntentDismissingKeyguard(final PendingIntent intent) {
         startPendingIntentDismissingKeyguard(intent, null);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startPendingIntentDismissingKeyguard(
             final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback) {
@@ -4104,6 +4128,7 @@
                 (ActivityLaunchAnimator.Controller) null);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startPendingIntentDismissingKeyguard(PendingIntent intent,
             Runnable intentSentUiThreadCallback, View associatedView) {
@@ -4117,6 +4142,7 @@
                 animationController);
     }
 
+    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
     @Override
     public void startPendingIntentDismissingKeyguard(
             final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback,
@@ -4540,6 +4566,8 @@
      *  launched as user of the current process.
      * @param intent
      * @return UserHandle
+     *
+     * Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too.
      */
     private UserHandle getActivityUserHandle(Intent intent) {
         String[] packages = mContext.getResources().getStringArray(R.array.system_ui_packages);
@@ -4562,4 +4590,15 @@
                 && mBiometricUnlockController.getMode()
                 != BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
     }
+
+    @Override
+    public void setIsLaunchingActivityOverLockscreen(boolean isLaunchingActivityOverLockscreen) {
+        mIsLaunchingActivityOverLockscreen = isLaunchingActivityOverLockscreen;
+    }
+
+    @Override
+    public ActivityLaunchAnimator.Controller getAnimatorControllerFromNotification(
+            ExpandableNotificationRow associatedView) {
+        return mNotificationAnimationProvider.getAnimatorController(associatedView);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 89c3946..618120d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -37,6 +37,7 @@
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.doze.DozeReceiver;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.keyguard.domain.interactor.BurnInInteractor;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.shade.ShadeViewController;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -56,10 +57,12 @@
 
 import javax.inject.Inject;
 
+import kotlinx.coroutines.ExperimentalCoroutinesApi;
+
 /**
  * Implementation of DozeHost for SystemUI.
  */
-@SysUISingleton
+@ExperimentalCoroutinesApi @SysUISingleton
 public final class DozeServiceHost implements DozeHost {
     private static final String TAG = "DozeServiceHost";
     private final ArrayList<Callback> mCallbacks = new ArrayList<>();
@@ -89,6 +92,7 @@
     private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     private final AuthController mAuthController;
     private final NotificationIconAreaController mNotificationIconAreaController;
+    private final BurnInInteractor mBurnInInteractor;
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private ShadeViewController mNotificationPanel;
     private View mAmbientIndicationContainer;
@@ -110,7 +114,8 @@
             NotificationShadeWindowController notificationShadeWindowController,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             AuthController authController,
-            NotificationIconAreaController notificationIconAreaController) {
+            NotificationIconAreaController notificationIconAreaController,
+            BurnInInteractor burnInInteractor) {
         super();
         mDozeLog = dozeLog;
         mPowerManager = powerManager;
@@ -129,6 +134,7 @@
         mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
         mAuthController = authController;
         mNotificationIconAreaController = notificationIconAreaController;
+        mBurnInInteractor = burnInInteractor;
         mHeadsUpManagerPhone.addListener(mOnHeadsUpChangedListener);
     }
 
@@ -304,6 +310,7 @@
         if (mAmbientIndicationContainer instanceof DozeReceiver) {
             ((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick();
         }
+        mBurnInInteractor.dozeTimeTick();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index e705afc..f15dcc3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -27,8 +27,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ViewClippingUtil;
 import com.android.systemui.R;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.ShadeHeadsUpTracker;
@@ -78,7 +76,6 @@
     private final DarkIconDispatcher mDarkIconDispatcher;
     private final ShadeViewController mShadeViewController;
     private final NotificationRoundnessManager mNotificationRoundnessManager;
-    private final boolean mUseRoundnessSourceTypes;
     private final Consumer<ExpandableNotificationRow>
             mSetTrackingHeadsUp = this::setTrackingHeadsUp;
     private final BiConsumer<Float, Float> mSetExpandedHeight = this::setAppearFraction;
@@ -120,14 +117,12 @@
             NotificationStackScrollLayoutController stackScrollerController,
             ShadeViewController shadeViewController,
             NotificationRoundnessManager notificationRoundnessManager,
-            FeatureFlags featureFlags,
             HeadsUpStatusBarView headsUpStatusBarView,
             Clock clockView,
             @Named(OPERATOR_NAME_FRAME_VIEW) Optional<View> operatorNameViewOptional) {
         super(headsUpStatusBarView);
         mNotificationIconAreaController = notificationIconAreaController;
         mNotificationRoundnessManager = notificationRoundnessManager;
-        mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
         mHeadsUpManager = headsUpManager;
 
         // We may be mid-HUN-expansion when this controller is re-created (for example, if the user
@@ -408,21 +403,19 @@
      * @param entry target notification
      */
     public void updateHeadsUpAndPulsingRoundness(NotificationEntry entry) {
-        if (mUseRoundnessSourceTypes) {
-            ExpandableNotificationRow row = entry.getRow();
-            boolean isTrackedChild = row == mTrackedChild;
-            if (row.isPinned() || row.isHeadsUpAnimatingAway() || isTrackedChild) {
-                float roundness = MathUtils.saturate(1f - mAppearFraction);
-                row.requestRoundness(roundness, roundness, HEADS_UP);
+        ExpandableNotificationRow row = entry.getRow();
+        boolean isTrackedChild = row == mTrackedChild;
+        if (row.isPinned() || row.isHeadsUpAnimatingAway() || isTrackedChild) {
+            float roundness = MathUtils.saturate(1f - mAppearFraction);
+            row.requestRoundness(roundness, roundness, HEADS_UP);
+        } else {
+            row.requestRoundnessReset(HEADS_UP);
+        }
+        if (mNotificationRoundnessManager.shouldRoundNotificationPulsing()) {
+            if (row.showingPulsing()) {
+                row.requestRoundness(/* top = */ 1f, /* bottom = */ 1f, PULSING);
             } else {
-                row.requestRoundnessReset(HEADS_UP);
-            }
-            if (mNotificationRoundnessManager.shouldRoundNotificationPulsing()) {
-                if (row.showingPulsing()) {
-                    row.requestRoundness(/* top = */ 1f, /* bottom = */ 1f, PULSING);
-                } else {
-                    row.requestRoundnessReset(PULSING);
-                }
+                row.requestRoundnessReset(PULSING);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 534edb9..a058bf8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -25,6 +25,7 @@
 import android.annotation.ColorInt;
 import android.content.Context;
 import android.graphics.Rect;
+import android.util.Log;
 import android.view.InsetsFlags;
 import android.view.ViewDebug;
 import android.view.WindowInsetsController.Appearance;
@@ -35,13 +36,17 @@
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.util.Compile;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Date;
 
 import javax.inject.Inject;
 
@@ -51,10 +56,14 @@
 @SysUISingleton
 public class LightBarController implements BatteryController.BatteryStateChangeCallback, Dumpable {
 
+    private static final String TAG = "LightBarController";
+    private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
+
     private static final float NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD = 0.1f;
 
     private final SysuiDarkIconDispatcher mStatusBarIconController;
     private final BatteryController mBatteryController;
+    private final boolean mUseNewLightBarLogic;
     private BiometricUnlockController mBiometricUnlockController;
 
     private LightBarTransitionsController mNavigationBarController;
@@ -67,13 +76,17 @@
     private final int mLightIconColor;
 
     /**
-     * Whether the navigation bar should be light factoring in already how much alpha the scrim has
+     * Whether the navigation bar should be light factoring in already how much alpha the scrim has.
+     * "Light" refers to the background color of the navigation bar, so when this is true,
+     * it's referring to a state where the navigation bar icons are tinted dark.
      */
     private boolean mNavigationLight;
 
     /**
-     * Whether the flags indicate that a light status bar is requested. This doesn't factor in the
-     * scrim alpha yet.
+     * Whether the flags indicate that a light navigation bar is requested.
+     * "Light" refers to the background color of the navigation bar, so when this is true,
+     * it's referring to a state where the navigation bar icons would be tinted dark.
+     * This doesn't factor in the scrim alpha yet.
      */
     private boolean mHasLightNavigationBar;
 
@@ -82,22 +95,34 @@
      * {@link #mNavigationLight} {@code false}.
      */
     private boolean mForceDarkForScrim;
+    /**
+     * {@code true} if {@link #mHasLightNavigationBar} should be ignored and forcefully make
+     * {@link #mNavigationLight} {@code true}.
+     */
+    private boolean mForceLightForScrim;
 
     private boolean mQsCustomizing;
+    private boolean mQsExpanded;
+    private boolean mGlobalActionsVisible;
 
     private boolean mDirectReplying;
     private boolean mNavbarColorManagedByIme;
 
     private boolean mIsCustomizingForBackNav;
 
+    private String mLastSetScrimStateLog;
+    private String mLastNavigationBarAppearanceChangedLog;
+
     @Inject
     public LightBarController(
             Context ctx,
             DarkIconDispatcher darkIconDispatcher,
             BatteryController batteryController,
             NavigationModeController navModeController,
+            FeatureFlags featureFlags,
             DumpManager dumpManager,
             DisplayTracker displayTracker) {
+        mUseNewLightBarLogic = featureFlags.isEnabled(Flags.NEW_LIGHT_BAR_LOGIC);
         mDarkIconColor = ctx.getColor(R.color.dark_mode_icon_color_single_tone);
         mLightIconColor = ctx.getColor(R.color.light_mode_icon_color_single_tone);
         mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher;
@@ -159,9 +184,42 @@
             final boolean last = mNavigationLight;
             mHasLightNavigationBar = isLight(appearance, navigationBarMode,
                     APPEARANCE_LIGHT_NAVIGATION_BARS);
-            mNavigationLight = mHasLightNavigationBar
-                    && (mDirectReplying && mNavbarColorManagedByIme || !mForceDarkForScrim)
-                    && !mQsCustomizing;
+            if (mUseNewLightBarLogic) {
+                final boolean ignoreScrimForce = mDirectReplying && mNavbarColorManagedByIme;
+                final boolean darkForScrim = mForceDarkForScrim && !ignoreScrimForce;
+                final boolean lightForScrim = mForceLightForScrim && !ignoreScrimForce;
+                final boolean darkForQs = mQsCustomizing || mQsExpanded || mGlobalActionsVisible;
+                mNavigationLight =
+                        ((mHasLightNavigationBar && !darkForScrim) || lightForScrim) && !darkForQs;
+                mLastNavigationBarAppearanceChangedLog = "onNavigationBarAppearanceChanged()"
+                        + " appearance=" + appearance
+                        + " nbModeChanged=" + nbModeChanged
+                        + " navigationBarMode=" + navigationBarMode
+                        + " navbarColorManagedByIme=" + navbarColorManagedByIme
+                        + " mHasLightNavigationBar=" + mHasLightNavigationBar
+                        + " ignoreScrimForce=" + ignoreScrimForce
+                        + " darkForScrim=" + darkForScrim
+                        + " lightForScrim=" + lightForScrim
+                        + " darkForQs=" + darkForQs
+                        + " mNavigationLight=" + mNavigationLight
+                        + " last=" + last
+                        + " timestamp=" + new Date();
+                if (DEBUG) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+            } else {
+                mNavigationLight = mHasLightNavigationBar
+                        && (mDirectReplying && mNavbarColorManagedByIme || !mForceDarkForScrim)
+                        && !mQsCustomizing;
+                mLastNavigationBarAppearanceChangedLog = "onNavigationBarAppearanceChanged()"
+                        + " appearance=" + appearance
+                        + " nbModeChanged=" + nbModeChanged
+                        + " navigationBarMode=" + navigationBarMode
+                        + " navbarColorManagedByIme=" + navbarColorManagedByIme
+                        + " mHasLightNavigationBar=" + mHasLightNavigationBar
+                        + " mNavigationLight=" + mNavigationLight
+                        + " last=" + last
+                        + " timestamp=" + new Date();
+                if (DEBUG) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+            }
             if (mNavigationLight != last) {
                 updateNavigation();
             }
@@ -188,6 +246,20 @@
         reevaluate();
     }
 
+    /** Set if Quick Settings is fully expanded, which affects notification scrim visibility */
+    public void setQsExpanded(boolean expanded) {
+        if (mQsExpanded == expanded) return;
+        mQsExpanded = expanded;
+        reevaluate();
+    }
+
+    /** Set if Global Actions dialog is visible, which requires dark mode (light buttons) */
+    public void setGlobalActionsVisible(boolean visible) {
+        if (mGlobalActionsVisible == visible) return;
+        mGlobalActionsVisible = visible;
+        reevaluate();
+    }
+
     /**
      * Controls the light status bar temporarily for back navigation.
      * @param appearance the custmoized appearance.
@@ -225,16 +297,52 @@
 
     public void setScrimState(ScrimState scrimState, float scrimBehindAlpha,
             GradientColors scrimInFrontColor) {
-        boolean forceDarkForScrimLast = mForceDarkForScrim;
-        // For BOUNCER/BOUNCER_SCRIMMED cases, we assume that alpha is always below threshold.
-        // This enables IMEs to control the navigation bar color.
-        // For other cases, scrim should be able to veto the light navigation bar.
-        mForceDarkForScrim = scrimState != ScrimState.BOUNCER
-                && scrimState != ScrimState.BOUNCER_SCRIMMED
-                && scrimBehindAlpha >= NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD
-                && !scrimInFrontColor.supportsDarkText();
-        if (mHasLightNavigationBar && (mForceDarkForScrim != forceDarkForScrimLast)) {
-            reevaluate();
+        if (mUseNewLightBarLogic) {
+            boolean forceDarkForScrimLast = mForceDarkForScrim;
+            boolean forceLightForScrimLast = mForceLightForScrim;
+            final boolean forceForScrim =
+                    scrimBehindAlpha >= NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD;
+            final boolean scrimColorIsLight = scrimInFrontColor.supportsDarkText();
+
+            mForceDarkForScrim = forceForScrim && !scrimColorIsLight;
+            mForceLightForScrim = forceForScrim && scrimColorIsLight;
+            if (mHasLightNavigationBar) {
+                if (mForceDarkForScrim != forceDarkForScrimLast) reevaluate();
+            } else {
+                if (mForceLightForScrim != forceLightForScrimLast) reevaluate();
+            }
+            mLastSetScrimStateLog = "setScrimState()"
+                    + " scrimState=" + scrimState
+                    + " scrimBehindAlpha=" + scrimBehindAlpha
+                    + " scrimInFrontColor=" + scrimInFrontColor
+                    + " forceForScrim=" + forceForScrim
+                    + " scrimColorIsLight=" + scrimColorIsLight
+                    + " mHasLightNavigationBar=" + mHasLightNavigationBar
+                    + " mForceDarkForScrim=" + mForceDarkForScrim
+                    + " mForceLightForScrim=" + mForceLightForScrim
+                    + " timestamp=" + new Date();
+            if (DEBUG) Log.d(TAG, mLastSetScrimStateLog);
+        } else {
+            boolean forceDarkForScrimLast = mForceDarkForScrim;
+            // For BOUNCER/BOUNCER_SCRIMMED cases, we assume that alpha is always below threshold.
+            // This enables IMEs to control the navigation bar color.
+            // For other cases, scrim should be able to veto the light navigation bar.
+            // NOTE: this was also wrong for S and has been removed in the new logic.
+            mForceDarkForScrim = scrimState != ScrimState.BOUNCER
+                    && scrimState != ScrimState.BOUNCER_SCRIMMED
+                    && scrimBehindAlpha >= NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD
+                    && !scrimInFrontColor.supportsDarkText();
+            if (mHasLightNavigationBar && (mForceDarkForScrim != forceDarkForScrimLast)) {
+                reevaluate();
+            }
+            mLastSetScrimStateLog = "setScrimState()"
+                    + " scrimState=" + scrimState
+                    + " scrimBehindAlpha=" + scrimBehindAlpha
+                    + " scrimInFrontColor=" + scrimInFrontColor
+                    + " mHasLightNavigationBar=" + mHasLightNavigationBar
+                    + " mForceDarkForScrim=" + mForceDarkForScrim
+                    + " timestamp=" + new Date();
+            if (DEBUG) Log.d(TAG, mLastSetScrimStateLog);
         }
     }
 
@@ -309,16 +417,24 @@
             pw.print(mAppearanceRegions[i].toString()); pw.print(" isLight="); pw.println(isLight);
         }
 
-        pw.print(" mNavigationLight="); pw.print(mNavigationLight);
+        pw.print(" mNavigationLight="); pw.println(mNavigationLight);
         pw.print(" mHasLightNavigationBar="); pw.println(mHasLightNavigationBar);
-
+        pw.println();
         pw.print(" mStatusBarMode="); pw.print(mStatusBarMode);
         pw.print(" mNavigationBarMode="); pw.println(mNavigationBarMode);
-
-        pw.print(" mForceDarkForScrim="); pw.print(mForceDarkForScrim);
-        pw.print(" mQsCustomizing="); pw.print(mQsCustomizing);
+        pw.println();
+        pw.print(" mForceDarkForScrim="); pw.println(mForceDarkForScrim);
+        pw.print(" mForceLightForScrim="); pw.println(mForceLightForScrim);
+        pw.println();
+        pw.print(" mQsCustomizing="); pw.println(mQsCustomizing);
+        pw.print(" mQsExpanded="); pw.println(mQsExpanded);
+        pw.print(" mGlobalActionsVisible="); pw.println(mGlobalActionsVisible);
         pw.print(" mDirectReplying="); pw.println(mDirectReplying);
         pw.print(" mNavbarColorManagedByIme="); pw.println(mNavbarColorManagedByIme);
+        pw.println();
+        pw.println(" Recent Calculation Logs:");
+        pw.print("   "); pw.println(mLastSetScrimStateLog);
+        pw.print("   "); pw.println(mLastNavigationBarAppearanceChangedLog);
 
         pw.println();
 
@@ -344,6 +460,7 @@
         private final DarkIconDispatcher mDarkIconDispatcher;
         private final BatteryController mBatteryController;
         private final NavigationModeController mNavModeController;
+        private final FeatureFlags mFeatureFlags;
         private final DumpManager mDumpManager;
         private final DisplayTracker mDisplayTracker;
 
@@ -352,12 +469,14 @@
                 DarkIconDispatcher darkIconDispatcher,
                 BatteryController batteryController,
                 NavigationModeController navModeController,
+                FeatureFlags featureFlags,
                 DumpManager dumpManager,
                 DisplayTracker displayTracker) {
 
             mDarkIconDispatcher = darkIconDispatcher;
             mBatteryController = batteryController;
             mNavModeController = navModeController;
+            mFeatureFlags = featureFlags;
             mDumpManager = dumpManager;
             mDisplayTracker = displayTracker;
         }
@@ -365,7 +484,7 @@
         /** Create an {@link LightBarController} */
         public LightBarController create(Context context) {
             return new LightBarController(context, mDarkIconDispatcher, mBatteryController,
-                    mNavModeController, mDumpManager, mDisplayTracker);
+                    mNavModeController, mFeatureFlags, mDumpManager, mDisplayTracker);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 006a029d..b9a12e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -306,7 +306,7 @@
     public void applyIconStates() {
         for (int i = 0; i < getChildCount(); i++) {
             View child = getChildAt(i);
-            ViewState childState = mIconStates.get(child);
+            IconState childState = mIconStates.get(child);
             if (childState != null) {
                 childState.applyToView(child);
             }
@@ -339,6 +339,7 @@
             }
         }
         if (child instanceof StatusBarIconView) {
+            ((StatusBarIconView) child).updateIconDimens();
             ((StatusBarIconView) child).setDozing(mDozing, false, 0);
         }
     }
@@ -447,9 +448,14 @@
     @VisibleForTesting
     boolean isOverflowing(boolean isLastChild, float translationX, float layoutEnd,
             float iconSize) {
-        // Layout end, as used here, does not include padding end.
-        final float overflowX = isLastChild ? layoutEnd : layoutEnd - iconSize;
-        return translationX >= overflowX;
+        if (isLastChild) {
+            return translationX + iconSize > layoutEnd;
+        } else {
+            // If the child is not the last child, we need to ensure that we have room for the next
+            // icon and the dot. The dot could be as large as an icon, so verify that we have room
+            // for 2 icons.
+            return translationX + iconSize * 2f > layoutEnd;
+        }
     }
 
     /**
@@ -489,10 +495,7 @@
             // First icon to overflow.
             if (firstOverflowIndex == -1 && isOverflowing) {
                 firstOverflowIndex = i;
-                mVisualOverflowStart = layoutEnd - mIconSize;
-                if (forceOverflow || mIsStaticLayout) {
-                    mVisualOverflowStart = Math.min(translationX, mVisualOverflowStart);
-                }
+                mVisualOverflowStart = translationX;
             }
             final float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
                     ? ((StatusBarIconView) view).getIconScaleIncreased()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 51c56a0..fdb772b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -42,6 +42,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.graphics.ColorUtils;
+import com.android.internal.util.ContrastColorUtil;
 import com.android.internal.util.function.TriConsumer;
 import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -249,6 +250,7 @@
     private final TriConsumer<ScrimState, Float, GradientColors> mScrimStateListener;
     private final LargeScreenShadeInterpolator mLargeScreenShadeInterpolator;
     private final FeatureFlags mFeatureFlags;
+    private final boolean mUseNewLightBarLogic;
     private Consumer<Integer> mScrimVisibleListener;
     private boolean mBlankScreen;
     private boolean mScreenBlankingCallbackCalled;
@@ -306,6 +308,7 @@
         mScrimStateListener = lightBarController::setScrimState;
         mLargeScreenShadeInterpolator = largeScreenShadeInterpolator;
         mFeatureFlags = featureFlags;
+        mUseNewLightBarLogic = featureFlags.isEnabled(Flags.NEW_LIGHT_BAR_LOGIC);
         mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
 
         mKeyguardStateController = keyguardStateController;
@@ -1159,7 +1162,13 @@
         if (mClipsQsScrim && mQsBottomVisible) {
             alpha = mNotificationsAlpha;
         }
-        mScrimStateListener.accept(mState, alpha, mScrimInFront.getColors());
+        if (mUseNewLightBarLogic) {
+            mScrimStateListener.accept(mState, alpha, mColors);
+        } else {
+            // NOTE: This wasn't wrong, but it implied that each scrim might have different colors,
+            //  when in fact they all share the same GradientColors instance, which we own.
+            mScrimStateListener.accept(mState, alpha, mScrimInFront.getColors());
+        }
     }
 
     private void dispatchScrimsVisible() {
@@ -1487,8 +1496,15 @@
         int accent = Utils.getColorAccent(mScrimBehind.getContext()).getDefaultColor();
         mColors.setMainColor(background);
         mColors.setSecondaryColor(accent);
-        mColors.setSupportsDarkText(
-                ColorUtils.calculateContrast(mColors.getMainColor(), Color.WHITE) > 4.5);
+        if (mUseNewLightBarLogic) {
+            final boolean isBackgroundLight = !ContrastColorUtil.isColorDark(background);
+            mColors.setSupportsDarkText(isBackgroundLight);
+        } else {
+            // NOTE: This was totally backward, but LightBarController was flipping it back.
+            // There may be other consumers of this which would struggle though
+            mColors.setSupportsDarkText(
+                    ColorUtils.calculateContrast(mColors.getMainColor(), Color.WHITE) > 4.5);
+        }
         mNeedsDrawableColorUpdate = true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index a8a834f..678873c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -203,8 +203,7 @@
 
         @Override
         protected LayoutParams onCreateLayoutParams() {
-            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
-                    ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
+            LinearLayout.LayoutParams lp = super.onCreateLayoutParams();
             lp.setMargins(mIconHPadding, 0, mIconHPadding, 0);
             return lp;
         }
@@ -370,7 +369,7 @@
         private final MobileIconsViewModel mMobileIconsViewModel;
 
         protected final Context mContext;
-        protected final int mIconSize;
+        protected int mIconSize;
         // Whether or not these icons show up in dumpsys
         protected boolean mShouldLog = false;
         private StatusBarIconController mController;
@@ -395,10 +394,10 @@
             mStatusBarPipelineFlags = statusBarPipelineFlags;
             mMobileContextProvider = mobileContextProvider;
             mContext = group.getContext();
-            mIconSize = mContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.status_bar_icon_size);
             mLocation = location;
 
+            reloadDimens();
+
             if (statusBarPipelineFlags.runNewMobileIconsBackend()) {
                 // This starts the flow for the new pipeline, and will notify us of changes if
                 // {@link StatusBarPipelineFlags#useNewMobileIcons} is also true.
@@ -609,13 +608,9 @@
             mGroup.removeAllViews();
         }
 
-        protected void onDensityOrFontScaleChanged() {
-            for (int i = 0; i < mGroup.getChildCount(); i++) {
-                View child = mGroup.getChildAt(i);
-                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
-                        ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
-                child.setLayoutParams(lp);
-            }
+        protected void reloadDimens() {
+            mIconSize = mContext.getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.status_bar_icon_size);
         }
 
         private void setHeightAndCenter(ImageView imageView, int height) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 3a18423..80d5651 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -109,6 +109,7 @@
         }
 
         group.setController(this);
+        group.reloadDimens();
         mIconGroups.add(group);
         List<Slot> allSlots = mStatusBarIconList.getSlots();
         for (int i = 0; i < allSlots.size(); i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index f7646d7..f2fbd7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -68,6 +68,7 @@
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.navigationbar.TaskbarDelegate;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
@@ -135,7 +136,7 @@
     private final DreamOverlayStateController mDreamOverlayStateController;
     @Nullable
     private final FoldAodAnimationController mFoldAodAnimationController;
-    private KeyguardMessageAreaController<AuthKeyguardMessageArea> mKeyguardMessageAreaController;
+    KeyguardMessageAreaController<AuthKeyguardMessageArea> mKeyguardMessageAreaController;
     private final PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
     private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
     private final AlternateBouncerInteractor mAlternateBouncerInteractor;
@@ -284,6 +285,7 @@
     private boolean mIsBackAnimationEnabled;
     private final boolean mUdfpsNewTouchDetectionEnabled;
     private final UdfpsOverlayInteractor mUdfpsOverlayInteractor;
+    private final ActivityStarter mActivityStarter;
 
     private OnDismissAction mAfterKeyguardGoneAction;
     private Runnable mKeyguardGoneCancelAction;
@@ -339,7 +341,8 @@
             PrimaryBouncerInteractor primaryBouncerInteractor,
             BouncerView primaryBouncerView,
             AlternateBouncerInteractor alternateBouncerInteractor,
-            UdfpsOverlayInteractor udfpsOverlayInteractor
+            UdfpsOverlayInteractor udfpsOverlayInteractor,
+            ActivityStarter activityStarter
     ) {
         mContext = context;
         mViewMediatorCallback = callback;
@@ -367,6 +370,7 @@
                 featureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_BOUNCER_ANIM);
         mUdfpsNewTouchDetectionEnabled = featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION);
         mUdfpsOverlayInteractor = udfpsOverlayInteractor;
+        mActivityStarter = activityStarter;
     }
 
     @Override
@@ -426,6 +430,7 @@
             mDockManager.addListener(mDockEventListener);
             mIsDocked = mDockManager.isDocked();
         }
+        mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
     }
 
     /** Register a callback, to be invoked by the Predictive Back system. */
@@ -1006,7 +1011,13 @@
 
     @Override
     public void dismissAndCollapse() {
-        mCentralSurfaces.executeRunnableDismissingKeyguard(null, null, true, false, true);
+        mActivityStarter.executeRunnableDismissingKeyguard(
+                /* runnable= */ null,
+                /* cancelAction= */ null,
+                /* dismissShade= */ true,
+                /* afterKeyguardGone= */ false,
+                /* deferred= */ true
+        );
     }
 
     /**
@@ -1554,6 +1565,14 @@
                 || mode == KeyguardSecurityModel.SecurityMode.SimPuk;
     }
 
+    private KeyguardStateController.Callback mKeyguardStateControllerCallback =
+            new KeyguardStateController.Callback() {
+        @Override
+        public void onUnlockedChanged() {
+            updateAlternateBouncerShowing(mAlternateBouncerInteractor.maybeHide());
+        }
+    };
+
     /**
      * Delegate used to send show and hide events to an alternate authentication method instead of
      * the regular pin/pattern/password bouncer.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index 26c1767..ddbfd43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -22,6 +22,8 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -72,13 +74,16 @@
     // Any ignored icon will never be added as a child
     private ArrayList<String> mIgnoredSlots = new ArrayList<>();
 
+    private Configuration mConfiguration;
+
     public StatusIconContainer(Context context) {
         this(context, null);
     }
 
     public StatusIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
-        initDimens();
+        mConfiguration = new Configuration(context.getResources().getConfiguration());
+        reloadDimens();
         setWillNotDraw(!DEBUG_OVERFLOW);
     }
 
@@ -95,7 +100,7 @@
         return mShouldRestrictIcons;
     }
 
-    private void initDimens() {
+    private void reloadDimens() {
         // This is the same value that StatusBarIconView uses
         mIconDotFrameWidth = getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.status_bar_icon_size);
@@ -211,6 +216,16 @@
         child.setTag(R.id.status_bar_view_state_tag, null);
     }
 
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        final int configDiff = newConfig.diff(mConfiguration);
+        mConfiguration.setTo(newConfig);
+        if ((configDiff & (ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_FONT_SCALE)) != 0) {
+            reloadDimens();
+        }
+    }
+
     /**
      * Add a name of an icon slot to be ignored. It will not show up nor be measured
      * @param slotName name of the icon as it exists in
@@ -348,13 +363,17 @@
         int totalVisible = mLayoutStates.size();
         int maxVisible = totalVisible <= MAX_ICONS ? MAX_ICONS : MAX_ICONS - 1;
 
-        mUnderflowStart = 0;
+        // Init mUnderflowStart value with the offset to let the dot be placed next to battery icon.
+        // It to prevent if the underflow happens at rightest(totalVisible - 1) child then break the
+        // for loop with mUnderflowStart staying 0(initial value), causing the dot be placed at the
+        // leftest side.
+        mUnderflowStart = (int) Math.max(contentStart, width - getPaddingEnd() - mUnderflowWidth);
         int visible = 0;
         int firstUnderflowIndex = -1;
         for (int i = totalVisible - 1; i >= 0; i--) {
             StatusIconState state = mLayoutStates.get(i);
             // Allow room for underflow if we found we need it in onMeasure
-            if (mNeedsUnderflow && (state.getXTranslation() < (contentStart + mUnderflowWidth))
+            if ((mNeedsUnderflow && (state.getXTranslation() < (contentStart + mUnderflowWidth)))
                     || (mShouldRestrictIcons && (visible >= maxVisible))) {
                 firstUnderflowIndex = i;
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
index 582afb1..a0f1216 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
@@ -19,8 +19,8 @@
 import static com.android.systemui.classifier.FalsingModule.DOUBLE_TAP_TIMEOUT_MS;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.util.ViewController;
@@ -32,7 +32,7 @@
 /**
  * Controller for {@link TapAgainView}.
  */
-@CentralSurfacesComponent.CentralSurfacesScope
+@SysUISingleton
 public class TapAgainViewController extends ViewController<TapAgainView> {
     private final DelayableExecutor mDelayableExecutor;
     private final ConfigurationController mConfigurationController;
@@ -84,7 +84,7 @@
     }
 
     /** Hides the associated view, possibly animating it. */
-    public void hide() {
+    private void hide() {
         mHideCanceler = null;
         mView.animateOut();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index b16d16a..273e783 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -20,8 +20,6 @@
 
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
-import com.android.keyguard.LockIconViewController;
-import com.android.systemui.biometrics.AuthRippleController;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
@@ -45,7 +43,6 @@
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
-import java.util.Set;
 
 import javax.inject.Named;
 import javax.inject.Scope;
@@ -60,7 +57,6 @@
  * outside the component. Should more items be moved *into* this component to avoid so many getters?
  */
 @Subcomponent(modules = {
-        CentralSurfacesStartableModule.class,
         NotificationStackScrollLayoutListContainerModule.class,
         StatusBarViewModule.class,
         StatusBarNotificationActivityStarterModule.class,
@@ -85,14 +81,6 @@
     @interface CentralSurfacesScope {}
 
     /**
-     * Performs initialization logic after {@link CentralSurfacesComponent} has been constructed.
-     */
-    interface Startable {
-        void start();
-        void stop();
-    }
-
-    /**
      * Creates a {@link NotificationShadeWindowView}.
      */
     NotificationShadeWindowView getNotificationShadeWindowView();
@@ -117,11 +105,6 @@
     QuickSettingsController getQuickSettingsController();
 
     /**
-     * Creates a LockIconViewController. Must be init after creation.
-     */
-    LockIconViewController getLockIconViewController();
-
-    /**
      * Creates a StatusBarHeadsUpChangeListener.
      */
     StatusBarHeadsUpChangeListener getStatusBarHeadsUpChangeListener();
@@ -143,11 +126,6 @@
     @Named(STATUS_BAR_FRAGMENT)
     CollapsedStatusBarFragment createCollapsedStatusBarFragment();
 
-    /**
-     * Set of startables to be run after a CentralSurfacesComponent has been constructed.
-     */
-    Set<Startable> getStartables();
-
     NotificationActivityStarter getNotificationActivityStarter();
 
     NotificationPresenter getNotificationPresenter();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 1a943e7..67243b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -16,28 +16,15 @@
 
 package com.android.systemui.statusbar.phone.dagger;
 
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.os.Handler;
 import android.view.LayoutInflater;
-import android.view.ViewStub;
-
-import androidx.constraintlayout.motion.widget.MotionLayout;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.LockIconView;
 import com.android.systemui.R;
-import com.android.systemui.battery.BatteryMeterView;
-import com.android.systemui.battery.BatteryMeterViewController;
 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.statusbar.StatusBarStateController;
-import com.android.systemui.privacy.OngoingPrivacyChip;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.shade.CombinedShadeHeadersConstraintManager;
-import com.android.systemui.shade.CombinedShadeHeadersConstraintManagerImpl;
 import com.android.systemui.shade.NotificationPanelView;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.NotificationShadeWindowView;
@@ -61,18 +48,13 @@
 import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
-import com.android.systemui.statusbar.phone.StatusIconContainer;
 import com.android.systemui.statusbar.phone.SystemBarAttributesListener;
-import com.android.systemui.statusbar.phone.TapAgainView;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
 import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
-import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
-import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.CarrierConfigTracker;
 import com.android.systemui.util.settings.SecureSettings;
 
@@ -93,7 +75,6 @@
         })
 public abstract class StatusBarViewModule {
 
-    public static final String SHADE_HEADER = "large_screen_shade_header";
     public static final String STATUS_BAR_FRAGMENT = "status_bar_fragment";
 
     /** */
@@ -142,92 +123,6 @@
     /** */
     @Provides
     @CentralSurfacesComponent.CentralSurfacesScope
-    public static LockIconView getLockIconView(
-            NotificationShadeWindowView notificationShadeWindowView) {
-        return notificationShadeWindowView.findViewById(R.id.lock_icon_view);
-    }
-
-    /** */
-    @Provides
-    @Named(SHADE_HEADER)
-    @CentralSurfacesComponent.CentralSurfacesScope
-    public static MotionLayout getLargeScreenShadeHeaderBarView(
-            NotificationShadeWindowView notificationShadeWindowView,
-            FeatureFlags featureFlags) {
-        ViewStub stub = notificationShadeWindowView.findViewById(R.id.qs_header_stub);
-        int layoutId = R.layout.combined_qs_header;
-        stub.setLayoutResource(layoutId);
-        MotionLayout v = (MotionLayout) stub.inflate();
-        return v;
-    }
-
-    /** */
-    @Provides
-    @CentralSurfacesComponent.CentralSurfacesScope
-    public static CombinedShadeHeadersConstraintManager
-            provideCombinedShadeHeadersConstraintManager() {
-        return CombinedShadeHeadersConstraintManagerImpl.INSTANCE;
-    }
-
-    /** */
-    @Provides
-    @CentralSurfacesComponent.CentralSurfacesScope
-    public static OngoingPrivacyChip getSplitShadeOngoingPrivacyChip(
-            @Named(SHADE_HEADER) MotionLayout header) {
-        return header.findViewById(R.id.privacy_chip);
-    }
-
-    /** */
-    @Provides
-    @CentralSurfacesComponent.CentralSurfacesScope
-    static StatusIconContainer providesStatusIconContainer(
-            @Named(SHADE_HEADER) MotionLayout header) {
-        return header.findViewById(R.id.statusIcons);
-    }
-
-    /** */
-    @Provides
-    @CentralSurfacesComponent.CentralSurfacesScope
-    @Named(SHADE_HEADER)
-    static BatteryMeterView getBatteryMeterView(@Named(SHADE_HEADER) MotionLayout view) {
-        return view.findViewById(R.id.batteryRemainingIcon);
-    }
-
-    @Provides
-    @CentralSurfacesComponent.CentralSurfacesScope
-    @Named(SHADE_HEADER)
-    static BatteryMeterViewController getBatteryMeterViewController(
-            @Named(SHADE_HEADER) BatteryMeterView batteryMeterView,
-            UserTracker userTracker,
-            ConfigurationController configurationController,
-            TunerService tunerService,
-            @Main Handler mainHandler,
-            ContentResolver contentResolver,
-            FeatureFlags featureFlags,
-            BatteryController batteryController
-    ) {
-        return new BatteryMeterViewController(
-                batteryMeterView,
-                userTracker,
-                configurationController,
-                tunerService,
-                mainHandler,
-                contentResolver,
-                featureFlags,
-                batteryController);
-
-    }
-
-    /** */
-    @Provides
-    @CentralSurfacesComponent.CentralSurfacesScope
-    public static TapAgainView getTapAgainView(NotificationPanelView npv) {
-        return npv.getTapAgainView();
-    }
-
-    /** */
-    @Provides
-    @CentralSurfacesComponent.CentralSurfacesScope
     public static NotificationsQuickSettingsContainer getNotificationsQuickSettingsContainer(
             NotificationShadeWindowView notificationShadeWindowView) {
         return notificationShadeWindowView.findViewById(R.id.notification_container_parent);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
index 98cde2a..abedd3220 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
@@ -28,6 +28,11 @@
     void startCasting(CastDevice device);
     void stopCasting(CastDevice device);
 
+    /**
+     * @return whether we have a connected device.
+     */
+    boolean hasConnectedCastDevice();
+
     public interface Callback {
         void onCastDevicesChanged();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index 7290a1a..f7b601b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -217,6 +217,12 @@
         }
     }
 
+    @Override
+    public boolean hasConnectedCastDevice() {
+        return getCastDevices().stream().anyMatch(
+                castDevice -> castDevice.state == CastDevice.STATE_CONNECTED);
+    }
+
     private void setProjection(MediaProjectionInfo projection, boolean started) {
         boolean changed = false;
         final MediaProjectionInfo oldProjection = mProjection;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt
index aa502bc..f61f3b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerLogger.kt
@@ -34,6 +34,8 @@
     private val halfFoldedStates =
         context.resources.getIntArray(R.array.config_halfFoldedDeviceStates)
     private val unfoldedStates = context.resources.getIntArray(R.array.config_openDeviceStates)
+    private val rearDisplayStates =
+        context.resources.getIntArray(R.array.config_rearDisplayDeviceStates)
 
     fun logListeningChange(listening: Boolean) {
         logBuffer.log(TAG, VERBOSE, { bool1 = listening }, { "setListening: $bool1" })
@@ -122,6 +124,7 @@
             in foldedStates -> "Folded"
             in unfoldedStates -> "Unfolded"
             in halfFoldedStates -> "Half-Folded"
+            in rearDisplayStates -> "Rear display"
             -1 -> "Uninitialized"
             else -> "Unknown"
         }
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
index 412b315..27aaa68 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
@@ -22,7 +22,6 @@
 import android.hardware.BatteryState
 import android.hardware.input.InputManager
 import android.hardware.input.InputSettings
-import android.os.Build
 import android.os.Handler
 import android.util.ArrayMap
 import android.util.Log
@@ -35,6 +34,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.log.DebugLogger.debugLog
 import com.android.systemui.shared.hardware.hasInputDevice
 import com.android.systemui.shared.hardware.isInternalStylusSource
 import java.util.concurrent.CopyOnWriteArrayList
@@ -81,7 +81,7 @@
     fun startListener() {
         handler.post {
             if (hasStarted) return@post
-            logDebug { "Listener has started." }
+            debugLog { "Listener has started." }
 
             hasStarted = true
             isInUsiSession =
@@ -109,7 +109,7 @@
 
         val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
         if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
-        logDebug {
+        debugLog {
             "Stylus InputDevice added: $deviceId ${device.name}, " +
                 "External: ${device.isExternal}"
         }
@@ -134,7 +134,7 @@
 
         val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
         if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
-        logDebug { "Stylus InputDevice changed: $deviceId ${device.name}" }
+        debugLog { "Stylus InputDevice changed: $deviceId ${device.name}" }
 
         val currAddress: String? = device.bluetoothAddress
         val prevAddress: String? = inputDeviceAddressMap[deviceId]
@@ -155,7 +155,7 @@
         if (!hasStarted) return
 
         if (!inputDeviceAddressMap.contains(deviceId)) return
-        logDebug { "Stylus InputDevice removed: $deviceId" }
+        debugLog { "Stylus InputDevice removed: $deviceId" }
 
         unregisterBatteryListener(deviceId)
 
@@ -180,7 +180,7 @@
 
             val isCharging = String(value) == "true"
 
-            logDebug {
+            debugLog {
                 "Charging state metadata changed for device $inputDeviceId " +
                     "${device.address}: $isCharging"
             }
@@ -199,7 +199,7 @@
         handler.post {
             if (!hasStarted) return@post
 
-            logDebug {
+            debugLog {
                 "Battery state changed for $deviceId. " +
                     "batteryState present: ${batteryState.isPresent}, " +
                     "capacity: ${batteryState.capacity}"
@@ -247,7 +247,7 @@
         if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return
         if (InputSettings.isStylusEverUsed(context)) return
 
-        logDebug { "Stylus used for the first time." }
+        debugLog { "Stylus used for the first time." }
         InputSettings.setStylusEverUsed(context, true)
         executeStylusCallbacks { cb -> cb.onStylusFirstUsed() }
     }
@@ -264,7 +264,7 @@
         val hasBtConnection = if (inputDeviceBtSessionIdMap.isEmpty()) 0 else 1
 
         if (batteryStateValid && usiSessionId == null) {
-            logDebug { "USI battery newly present, entering new USI session: $deviceId" }
+            debugLog { "USI battery newly present, entering new USI session: $deviceId" }
             usiSessionId = instanceIdSequence.newInstanceId()
             uiEventLogger.logWithInstanceIdAndPosition(
                 StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_FIRST_DETECTED,
@@ -274,7 +274,7 @@
                 hasBtConnection,
             )
         } else if (!batteryStateValid && usiSessionId != null) {
-            logDebug { "USI battery newly absent, exiting USI session: $deviceId" }
+            debugLog { "USI battery newly absent, exiting USI session: $deviceId" }
             uiEventLogger.logWithInstanceIdAndPosition(
                 StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_REMOVED,
                 0,
@@ -291,7 +291,7 @@
         btAddress: String,
         btConnected: Boolean
     ) {
-        logDebug {
+        debugLog {
             "Bluetooth stylus ${if (btConnected) "connected" else "disconnected"}:" +
                 " $deviceId $btAddress"
         }
@@ -386,9 +386,3 @@
         val TAG = StylusManager::class.simpleName.orEmpty()
     }
 }
-
-private inline fun logDebug(message: () -> String) {
-    if (Build.IS_DEBUGGABLE) {
-        Log.d(StylusManager.TAG, message())
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
index 21b0efa..6eddd9e 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -26,7 +26,6 @@
 import android.content.IntentFilter
 import android.hardware.BatteryState
 import android.hardware.input.InputManager
-import android.os.Build
 import android.os.Bundle
 import android.os.Handler
 import android.os.UserHandle
@@ -40,6 +39,7 @@
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.log.DebugLogger.debugLog
 import com.android.systemui.shared.hardware.hasInputDevice
 import com.android.systemui.shared.hardware.isAnyStylusSource
 import com.android.systemui.util.NotificationChannels
@@ -110,7 +110,7 @@
 
             inputDeviceId = deviceId
             batteryCapacity = batteryState.capacity
-            logDebug {
+            debugLog {
                 "Updating notification battery state to $batteryCapacity " +
                     "for InputDevice $deviceId."
             }
@@ -130,14 +130,14 @@
         handler.post updateSuppressed@{
             if (suppressed == suppress) return@updateSuppressed
 
-            logDebug { "Updating notification suppression to $suppress." }
+            debugLog { "Updating notification suppression to $suppress." }
             suppressed = suppress
             refresh()
         }
     }
 
     private fun hideNotification() {
-        logDebug { "Cancelling USI low battery notification." }
+        debugLog { "Cancelling USI low battery notification." }
         instanceId = null
         notificationManager.cancel(USI_NOTIFICATION_ID)
     }
@@ -160,7 +160,7 @@
                 .setAutoCancel(true)
                 .build()
 
-        logDebug { "Show or update USI low battery notification at $batteryCapacity." }
+        debugLog { "Show or update USI low battery notification at $batteryCapacity." }
         logUiEvent(StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_SHOWN)
         notificationManager.notify(USI_NOTIFICATION_ID, notification)
     }
@@ -188,12 +188,12 @@
             override fun onReceive(context: Context, intent: Intent) {
                 when (intent.action) {
                     ACTION_DISMISSED_LOW_BATTERY -> {
-                        logDebug { "USI low battery notification dismissed." }
+                        debugLog { "USI low battery notification dismissed." }
                         logUiEvent(StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_DISMISSED)
                         updateSuppression(true)
                     }
                     ACTION_CLICKED_LOW_BATTERY -> {
-                        logDebug { "USI low battery notification clicked." }
+                        debugLog { "USI low battery notification clicked." }
                         logUiEvent(StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_CLICKED)
                         updateSuppression(true)
                         if (inputDeviceId == null) return
@@ -263,9 +263,3 @@
         @VisibleForTesting const val KEY_SETTINGS_FRAGMENT_ARGS = ":settings:show_fragment_args"
     }
 }
-
-private inline fun logDebug(message: () -> String) {
-    if (Build.IS_DEBUGGABLE) {
-        Log.d(StylusUsiPowerUI.TAG, message())
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
index 6026d2c..f0fa779 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.systemui.theme
 
 import android.util.Pair
@@ -24,68 +25,73 @@
         @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("outline_variant", MDC.outlineVariant),
-                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_dim", MDC.primaryFixedDim),
-                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_dim", MDC.secondaryFixedDim),
-                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_dim", MDC.tertiaryFixedDim),
-                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("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_dim", MDC.primaryFixedDim()),
+                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_dim", MDC.secondaryFixedDim()),
+                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_dim", MDC.tertiaryFixedDim()),
+                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
+                    MDC.textSecondaryAndTertiaryInverse()
                 ),
-                Pair.create("text_primary_inverse_disable_only", MDC.textPrimaryInverseDisableOnly),
+                Pair.create(
+                    "text_primary_inverse_disable_only",
+                    MDC.textPrimaryInverseDisableOnly()
+                ),
                 Pair.create(
                     "text_secondary_and_tertiary_inverse_disabled",
-                    MDC.textSecondaryAndTertiaryInverseDisabled
+                    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)
+                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/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index faae8df..43d15bc 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.systemui.theme;
 
 import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
@@ -659,9 +660,9 @@
                     && 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)
+                    == MaterialDynamicColors.primaryContainer().getArgb(mDynamicSchemeDark)
                     && res.getColor(android.R.color.system_primary_container_light, theme)
-                    == MaterialDynamicColors.primaryContainer.getArgb(mDynamicSchemeLight))) {
+                    == MaterialDynamicColors.primaryContainer().getArgb(mDynamicSchemeLight))) {
                 return false;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
index 0ec1a21..c2922c4 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
@@ -26,6 +26,7 @@
 import android.content.pm.UserInfo
 import android.graphics.drawable.BitmapDrawable
 import android.graphics.drawable.Drawable
+import android.graphics.drawable.Icon
 import android.os.RemoteException
 import android.os.UserHandle
 import android.os.UserManager
@@ -762,8 +763,18 @@
         }
 
         // TODO(b/246631653): cache the bitmaps to avoid the background work to fetch them.
-        // TODO(b/246631653): downscale the bitmaps to R.dimen.max_avatar_size if requested.
-        val userIcon = withContext(backgroundDispatcher) { manager.getUserIcon(userId) }
+        val userIcon = withContext(backgroundDispatcher) {
+            manager.getUserIcon(userId)
+                ?.let { bitmap ->
+                    val iconSize =
+                        applicationContext
+                            .resources
+                            .getDimensionPixelSize(R.dimen.bouncer_user_switcher_icon_size)
+                    Icon.scaleDownIfNecessary(bitmap, iconSize, iconSize)
+                }
+        }
+
+
         if (userIcon != null) {
             return BitmapDrawable(userIcon)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/util/ColorUtil.kt b/packages/SystemUI/src/com/android/systemui/util/ColorUtil.kt
index 27a53bf..41b3145 100644
--- a/packages/SystemUI/src/com/android/systemui/util/ColorUtil.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/ColorUtil.kt
@@ -19,6 +19,7 @@
 import android.content.res.TypedArray
 import android.graphics.Color
 import android.view.ContextThemeWrapper
+import androidx.annotation.ColorInt
 
 /** Returns an ARGB color version of [color] at the given [alpha]. */
 fun getColorWithAlpha(color: Int, alpha: Float): Int =
@@ -35,8 +36,11 @@
  * otherwise, returns the color from the private attribute {@param privAttrId}.
  */
 fun getPrivateAttrColorIfUnset(
-    ctw: ContextThemeWrapper, attrArray: TypedArray,
-    attrIndex: Int, defColor: Int, privAttrId: Int
+    ctw: ContextThemeWrapper,
+    attrArray: TypedArray,
+    attrIndex: Int,
+    defColor: Int,
+    privAttrId: Int
 ): Int {
     // If the index is specified, use that value
     var a = attrArray
@@ -51,3 +55,8 @@
     a.recycle()
     return color
 }
+
+/** Returns the color as a HTML hex color (or null) */
+fun hexColorString(@ColorInt color: Int?): String = color
+    ?.let { String.format("#%08x", it) }
+    ?: "null"
diff --git a/packages/SystemUI/src/com/android/systemui/util/ListenerSet.kt b/packages/SystemUI/src/com/android/systemui/util/ListenerSet.kt
index 4f20067..a47e614 100644
--- a/packages/SystemUI/src/com/android/systemui/util/ListenerSet.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/ListenerSet.kt
@@ -22,34 +22,27 @@
  * A collection of listeners, observers, callbacks, etc.
  *
  * This container is optimized for infrequent mutation and frequent iteration, with thread safety
- * and reentrant-safety guarantees as well.
+ * and reentrant-safety guarantees as well. Specifically, to ensure that
+ * [ConcurrentModificationException] is never thrown, this iterator will not reflect changes made to
+ * the set after the iterator is constructed.
  */
-class ListenerSet<E> : Iterable<E> {
-    private val listeners: CopyOnWriteArrayList<E> = CopyOnWriteArrayList()
+class ListenerSet<E : Any>
+/** Private constructor takes the internal list so that we can use auto-delegation */
+private constructor(private val listeners: CopyOnWriteArrayList<E>) :
+    Collection<E> by listeners, Set<E> {
+
+    /** Create a new instance */
+    constructor() : this(CopyOnWriteArrayList())
 
     /**
-     * A thread-safe, reentrant-safe method to add a listener.
-     * Does nothing if the listener is already in the set.
+     * A thread-safe, reentrant-safe method to add a listener. Does nothing if the listener is
+     * already in the set.
      */
     fun addIfAbsent(element: E): Boolean = listeners.addIfAbsent(element)
 
-    /**
-     * A thread-safe, reentrant-safe method to remove a listener.
-     */
+    /** A thread-safe, reentrant-safe method to remove a listener. */
     fun remove(element: E): Boolean = listeners.remove(element)
-
-    /**
-     * Determine if the listener set is empty
-     */
-    fun isEmpty(): Boolean = listeners.isEmpty()
-
-    /**
-     * Returns an iterator over the listeners currently in the set.  Note that to ensure
-     * [ConcurrentModificationException] is never thrown, this iterator will not reflect changes
-     * made to the set after the iterator is constructed.
-     */
-    override fun iterator(): Iterator<E> = listeners.iterator()
 }
 
 /** Extension to match Collection which is implemented to only be (easily) accessible in kotlin */
-fun <T> ListenerSet<T>.isNotEmpty(): Boolean = !isEmpty()
+fun <T : Any> ListenerSet<T>.isNotEmpty(): Boolean = !isEmpty()
diff --git a/packages/SystemUI/src/com/android/systemui/util/TraceUtils.kt b/packages/SystemUI/src/com/android/systemui/util/TraceUtils.kt
index 41c6b5d..64234c2 100644
--- a/packages/SystemUI/src/com/android/systemui/util/TraceUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/TraceUtils.kt
@@ -16,22 +16,20 @@
 
 package com.android.systemui.util
 
-import android.os.Handler
+import android.os.Trace
 import android.os.TraceNameSupplier
-import androidx.tracing.Trace
 
 /**
- * Run a block within a [Trace] section. Calls [Trace.beginSection] before and [Trace.endSection]
- * after the passed block. If tracing is disabled, it will run the block directly to avoid using an
- * unnecessary try-finally block.
+ * Run a block within a [Trace] section.
+ * Calls [Trace.beginSection] before and [Trace.endSection] after the passed block.
  */
 inline fun <T> traceSection(tag: String, block: () -> T): T =
-        if (Trace.isEnabled()) {
-            Trace.beginSection(tag)
+        if (Trace.isTagEnabled(Trace.TRACE_TAG_APP)) {
+            Trace.traceBegin(Trace.TRACE_TAG_APP, tag)
             try {
                 block()
             } finally {
-                Trace.endSection()
+                Trace.traceEnd(Trace.TRACE_TAG_APP)
             }
         } else {
             block()
@@ -44,10 +42,8 @@
         }
 
         /**
-         * Helper function for creating a [Runnable] that implements [TraceNameSupplier]. This is
-         * useful when posting to a [Handler] so that the [Runnable] has a meaningful name in the
-         * trace. Otherwise, the class name of the [Runnable] is used, which is often something like
-         * `pkg.MyClass$$ExternalSyntheticLambda0`.
+         * Helper function for creating a Runnable object that implements TraceNameSupplier.
+         * This is useful for posting Runnables to Handlers with meaningful names.
          */
         inline fun namedRunnable(tag: String, crossinline block: () -> Unit): Runnable {
             return object : Runnable, TraceNameSupplier {
diff --git a/packages/SystemUI/src/com/android/systemui/util/ViewController.java b/packages/SystemUI/src/com/android/systemui/util/ViewController.java
index 0dd5788..1f118d1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/ViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/ViewController.java
@@ -109,6 +109,11 @@
         }
     }
 
+    /** Destroy ViewController, removing any listeners. */
+    public void destroy() {
+        mView.removeOnAttachStateChangeListener(mOnAttachStateListener);
+    }
+
     /**
      * Called when the view is attached and a call to {@link #init()} has been made in either order.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/util/wrapper/DisplayUtilsWrapper.kt b/packages/SystemUI/src/com/android/systemui/util/wrapper/DisplayUtilsWrapper.kt
new file mode 100644
index 0000000..cfca7f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/wrapper/DisplayUtilsWrapper.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.wrapper
+
+import android.util.DisplayUtils
+import android.view.Display
+import javax.inject.Inject
+
+/** Injectable wrapper around `DisplayUtils` functions */
+class DisplayUtilsWrapper @Inject constructor() {
+    fun getPhysicalPixelDisplaySizeRatio(
+        physicalWidth: Int,
+        physicalHeight: Int,
+        currentWidth: Int,
+        currentHeight: Int
+    ): Float {
+        return DisplayUtils.getPhysicalPixelDisplaySizeRatio(
+            physicalWidth,
+            physicalHeight,
+            currentWidth,
+            currentHeight
+        )
+    }
+
+    fun getMaximumResolutionDisplayMode(modes: Array<Display.Mode>?): Display.Mode? {
+        return DisplayUtils.getMaximumResolutionDisplayMode(modes)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index b3e7cb0..e60f9b6 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -33,6 +33,7 @@
 import android.graphics.Rect;
 import android.inputmethodservice.InputMethodService;
 import android.os.IBinder;
+import android.view.Display;
 import android.view.KeyEvent;
 
 import androidx.annotation.NonNull;
@@ -347,12 +348,16 @@
     void initDesktopMode(DesktopMode desktopMode) {
         desktopMode.addVisibleTasksListener(
                 new DesktopModeTaskRepository.VisibleTasksListener() {
-            @Override
-            public void onVisibilityChanged(boolean hasFreeformTasks) {
-                mSysUiState.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, hasFreeformTasks)
-                        .commitUpdate(mDisplayTracker.getDefaultDisplayId());
-            }
-        }, mSysUiMainExecutor);
+                    @Override
+                    public void onVisibilityChanged(int displayId, boolean hasFreeformTasks) {
+                        if (displayId == Display.DEFAULT_DISPLAY) {
+                            mSysUiState.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE,
+                                            hasFreeformTasks)
+                                    .commitUpdate(mDisplayTracker.getDefaultDisplayId());
+                        }
+                        // TODO(b/278084491): update sysui state for changes on other displays
+                    }
+                }, mSysUiMainExecutor);
     }
 
     @Override
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index e2b568c..080be6d 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -196,6 +196,17 @@
             android:exported="false"
             android:permission="com.android.systemui.permission.SELF"
             android:excludeFromRecents="true" />
+
+        <activity
+            android:name="com.android.systemui.notetask.LaunchNotesRoleSettingsTrampolineActivity"
+            android:exported="false"
+            android:permission="com.android.systemui.permission.SELF"
+            android:excludeFromRecents="true" >
+            <intent-filter>
+                <action android:name="com.android.systemui.action.MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
     </application>
 
     <instrumentation android:name="android.testing.TestableInstrumentation"
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index f4df26d..8a05a37 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -682,8 +682,7 @@
     }
 
     @Test
-    public void testReinflateViewFlipper_asyncBouncerFlagOn() {
-        when(mFeatureFlags.isEnabled(Flags.ASYNC_INFLATE_BOUNCER)).thenReturn(true);
+    public void testReinflateViewFlipper() {
         KeyguardSecurityViewFlipperController.OnViewInflatedCallback onViewInflatedCallback =
                 controller -> {
                 };
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 2962c14..ddd9a08 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -151,7 +151,9 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
+import org.mockito.InOrder;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.MockitoSession;
 import org.mockito.internal.util.reflection.FieldSetter;
@@ -2737,6 +2739,36 @@
         verifyFingerprintAuthenticateCall();
     }
 
+    @Test
+    public void onTrustChangedCallbacksCalledBeforeOnTrustGrantedForCurrentUserCallback() {
+        // GIVEN device is interactive
+        deviceIsInteractive();
+
+        // GIVEN callback is registered
+        KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
+        mKeyguardUpdateMonitor.registerCallback(callback);
+
+        // WHEN onTrustChanged enabled=true
+        mKeyguardUpdateMonitor.onTrustChanged(
+                true /* enabled */,
+                true /* newlyUnlocked */,
+                getCurrentUser() /* userId */,
+                TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD /* flags */,
+                null /* trustGrantedMessages */);
+
+        // THEN onTrustChanged is called FIRST
+        final InOrder inOrder = Mockito.inOrder(callback);
+        inOrder.verify(callback).onTrustChanged(eq(getCurrentUser()));
+
+        // AND THEN onTrustGrantedForCurrentUser callback called
+        inOrder.verify(callback).onTrustGrantedForCurrentUser(
+                eq(true) /* dismissKeyguard */,
+                eq(true) /* newlyUnlocked */,
+                eq(new TrustGrantFlags(TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD)),
+                eq(null) /* message */
+        );
+    }
+
     private void verifyFingerprintAuthenticateNeverCalled() {
         verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), any());
         verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/SplitShadeTransitionAdapterTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/SplitShadeTransitionAdapterTest.kt
index dea2082..6fe8892 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/SplitShadeTransitionAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/SplitShadeTransitionAdapterTest.kt
@@ -18,6 +18,7 @@
 import android.animation.Animator
 import android.testing.AndroidTestingRunner
 import android.transition.TransitionValues
+import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardStatusViewController.SplitShadeTransitionAdapter
 import com.android.systemui.SysuiTestCase
@@ -44,14 +45,16 @@
 
     @Test
     fun createAnimator_nullStartValues_returnsNull() {
-        val animator = adapter.createAnimator(startValues = null, endValues = TransitionValues())
+        val endValues = createEndValues()
+
+        val animator = adapter.createAnimator(startValues = null, endValues = endValues)
 
         assertThat(animator).isNull()
     }
 
     @Test
     fun createAnimator_nullEndValues_returnsNull() {
-        val animator = adapter.createAnimator(startValues = TransitionValues(), endValues = null)
+        val animator = adapter.createAnimator(startValues = createStartValues(), endValues = null)
 
         assertThat(animator).isNull()
     }
@@ -59,10 +62,22 @@
     @Test
     fun createAnimator_nonNullStartAndEndValues_returnsAnimator() {
         val animator =
-            adapter.createAnimator(startValues = TransitionValues(), endValues = TransitionValues())
+            adapter.createAnimator(startValues = createStartValues(), endValues = createEndValues())
 
         assertThat(animator).isNotNull()
     }
+
+    private fun createStartValues() =
+        TransitionValues().also { values ->
+            values.view = View(context)
+            adapter.captureStartValues(values)
+        }
+
+    private fun createEndValues() =
+        TransitionValues().also { values ->
+            values.view = View(context)
+            adapter.captureEndValues(values)
+        }
 }
 
 private fun SplitShadeTransitionAdapter.createAnimator(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/accessibility/OWNERS
new file mode 100644
index 0000000..a2001e6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/accessibility/OWNERS
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
new file mode 100644
index 0000000..025c88c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.input.InputManager;
+import android.os.RemoteException;
+import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.KeyEvent;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.FakeDisplayTracker;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shade.ShadeController;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+
+import dagger.Lazy;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@TestableLooper.RunWithLooper
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class SystemActionsTest extends SysuiTestCase {
+    @Mock
+    private UserTracker mUserTracker;
+    @Mock
+    private NotificationShadeWindowController mNotificationShadeController;
+    @Mock
+    private ShadeController mShadeController;
+    @Mock
+    private Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
+    @Mock
+    private Optional<Recents> mRecentsOptional;
+    @Mock
+    private TelecomManager mTelecomManager;
+    @Mock
+    private InputManager mInputManager;
+    private final FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
+
+    private SystemActions mSystemActions;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+        mContext.addMockSystemService(TelecomManager.class, mTelecomManager);
+        mContext.addMockSystemService(InputManager.class, mInputManager);
+        mSystemActions = new SystemActions(mContext, mUserTracker, mNotificationShadeController,
+                mShadeController, mCentralSurfacesOptionalLazy, mRecentsOptional, mDisplayTracker);
+    }
+
+    @Test
+    public void handleHeadsetHook_callStateIdle_injectsKeyEvents() {
+        when(mTelecomManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
+        // Use a custom doAnswer captor that copies the KeyEvent before storing it, because the
+        // method under test modifies the event object after injecting it which prevents
+        // reliably asserting on the event properties.
+        final List<KeyEvent> keyEvents = new ArrayList<>();
+        doAnswer(invocation -> {
+            keyEvents.add(new KeyEvent(invocation.getArgument(0)));
+            return null;
+        }).when(mInputManager).injectInputEvent(any(), anyInt());
+
+        mSystemActions.handleHeadsetHook();
+
+        assertThat(keyEvents.size()).isEqualTo(2);
+        assertThat(keyEvents.get(0).getKeyCode()).isEqualTo(KeyEvent.KEYCODE_HEADSETHOOK);
+        assertThat(keyEvents.get(0).getAction()).isEqualTo(KeyEvent.ACTION_DOWN);
+        assertThat(keyEvents.get(1).getKeyCode()).isEqualTo(KeyEvent.KEYCODE_HEADSETHOOK);
+        assertThat(keyEvents.get(1).getAction()).isEqualTo(KeyEvent.ACTION_UP);
+    }
+
+    @Test
+    public void handleHeadsetHook_callStateRinging_answersCall() {
+        when(mTelecomManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_RINGING);
+
+        mSystemActions.handleHeadsetHook();
+
+        verify(mTelecomManager).acceptRingingCall();
+    }
+
+    @Test
+    public void handleHeadsetHook_callStateOffhook_endsCall() {
+        when(mTelecomManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_OFFHOOK);
+
+        mSystemActions.handleHeadsetHook();
+
+        verify(mTelecomManager).endCall();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
index 578e1d4..cc00436 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
@@ -159,22 +159,11 @@
     @Test
     fun doesNotStartIfAnimationIsCancelled() {
         val runner = activityLaunchAnimator.createRunner(controller)
-        runner.onAnimationCancelled(false /* isKeyguardOccluded */)
+        runner.onAnimationCancelled()
         runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback)
 
         waitForIdleSync()
-        verify(controller).onLaunchAnimationCancelled(false /* newKeyguardOccludedState */)
-        verify(controller, never()).onLaunchAnimationStart(anyBoolean())
-    }
-
-    @Test
-    fun passesOccludedStateToLaunchAnimationCancelled_ifTrue() {
-        val runner = activityLaunchAnimator.createRunner(controller)
-        runner.onAnimationCancelled(true /* isKeyguardOccluded */)
-        runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback)
-
-        waitForIdleSync()
-        verify(controller).onLaunchAnimationCancelled(true /* newKeyguardOccludedState */)
+        verify(controller).onLaunchAnimationCancelled()
         verify(controller, never()).onLaunchAnimationStart(anyBoolean())
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
index 02d4ecd..063757a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
@@ -31,6 +31,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
+import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import java.io.File
@@ -64,6 +65,7 @@
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
 class TextInterpolatorTest : SysuiTestCase() {
+    lateinit var typefaceCache: TypefaceVariantCache
 
     private fun makeLayout(
         text: String,
@@ -75,11 +77,16 @@
                 .setTextDirection(dir).build()
     }
 
+    @Before
+    fun setup() {
+        typefaceCache = TypefaceVariantCacheImpl()
+    }
+
     @Test
     fun testStartState() {
         val layout = makeLayout(TEXT, PAINT)
 
-        val interp = TextInterpolator(layout)
+        val interp = TextInterpolator(layout, typefaceCache)
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -98,7 +105,7 @@
     fun testEndState() {
         val layout = makeLayout(TEXT, PAINT)
 
-        val interp = TextInterpolator(layout)
+        val interp = TextInterpolator(layout, typefaceCache)
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -116,7 +123,7 @@
     fun testMiddleState() {
         val layout = makeLayout(TEXT, PAINT)
 
-        val interp = TextInterpolator(layout)
+        val interp = TextInterpolator(layout, typefaceCache)
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -138,7 +145,7 @@
     fun testRebase() {
         val layout = makeLayout(TEXT, PAINT)
 
-        val interp = TextInterpolator(layout)
+        val interp = TextInterpolator(layout, typefaceCache)
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -160,7 +167,7 @@
     fun testBidi_LTR() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.LTR)
 
-        val interp = TextInterpolator(layout)
+        val interp = TextInterpolator(layout, typefaceCache)
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -180,7 +187,7 @@
     fun testBidi_RTL() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout)
+        val interp = TextInterpolator(layout, typefaceCache)
         interp.basePaint.set(START_PAINT)
         interp.onBasePaintModified()
 
@@ -200,7 +207,7 @@
     fun testGlyphCallback_Empty() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout).apply {
+        val interp = TextInterpolator(layout, typefaceCache).apply {
             glyphFilter = { glyph, progress ->
             }
         }
@@ -222,7 +229,7 @@
     fun testGlyphCallback_Xcoordinate() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout).apply {
+        val interp = TextInterpolator(layout, typefaceCache).apply {
             glyphFilter = { glyph, progress ->
                 glyph.x += 30f
             }
@@ -247,7 +254,7 @@
     fun testGlyphCallback_Ycoordinate() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout).apply {
+        val interp = TextInterpolator(layout, typefaceCache).apply {
             glyphFilter = { glyph, progress ->
                 glyph.y += 30f
             }
@@ -272,7 +279,7 @@
     fun testGlyphCallback_TextSize() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout).apply {
+        val interp = TextInterpolator(layout, typefaceCache).apply {
             glyphFilter = { glyph, progress ->
                 glyph.textSize += 10f
             }
@@ -297,7 +304,7 @@
     fun testGlyphCallback_Color() {
         val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
 
-        val interp = TextInterpolator(layout).apply {
+        val interp = TextInterpolator(layout, typefaceCache).apply {
             glyphFilter = { glyph, progress ->
                 glyph.color = Color.RED
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
index f4dacab..213dc87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
@@ -26,6 +26,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
@@ -43,6 +44,7 @@
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
+@RoboPilotTest
 class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
 
     @JvmField
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
index 9f789e4..22ebc7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
@@ -23,6 +23,7 @@
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
@@ -40,6 +41,7 @@
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
+@RoboPilotTest
 class AuthBiometricFingerprintViewTest : SysuiTestCase() {
 
     @JvmField
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 6d4c467..6e37ee7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -40,15 +40,21 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.data.repository.FakePromptRepository
+import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
 import com.android.systemui.biometrics.domain.interactor.FakeCredentialInteractor
 import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
+import com.android.systemui.biometrics.ui.viewmodel.AuthBiometricFingerprintViewModel
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
 import org.junit.After
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -62,6 +68,7 @@
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
 
+@Ignore("b/279650412")
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
@@ -85,13 +92,26 @@
     @Mock
     lateinit var interactionJankMonitor: InteractionJankMonitor
 
+    private val testScope = TestScope(StandardTestDispatcher())
+    private val fakeExecutor = FakeExecutor(FakeSystemClock())
     private val biometricPromptRepository = FakePromptRepository()
+    private val rearDisplayStateRepository = FakeRearDisplayStateRepository()
     private val credentialInteractor = FakeCredentialInteractor()
     private val bpCredentialInteractor = BiometricPromptCredentialInteractor(
         Dispatchers.Main.immediate,
         biometricPromptRepository,
         credentialInteractor
     )
+    private val displayStateInteractor = DisplayStateInteractorImpl(
+        testScope.backgroundScope,
+        mContext,
+        fakeExecutor,
+        rearDisplayStateRepository
+    )
+
+    private val authBiometricFingerprintViewModel = AuthBiometricFingerprintViewModel(
+        displayStateInteractor
+    )
     private val credentialViewModel = CredentialViewModel(mContext, bpCredentialInteractor)
 
     private var authContainer: TestAuthContainerView? = null
@@ -467,9 +487,10 @@
         lockPatternUtils,
         interactionJankMonitor,
         { bpCredentialInteractor },
+        { authBiometricFingerprintViewModel },
         { credentialViewModel },
         Handler(TestableLooper.get(this).looper),
-        FakeExecutor(FakeSystemClock())
+        fakeExecutor
     ) {
         override fun postOnAnimation(runnable: Runnable) {
             runnable.run()
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 0f20ace..a326cc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -89,9 +89,11 @@
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settingslib.udfps.UdfpsUtils;
+import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor;
 import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
+import com.android.systemui.biometrics.ui.viewmodel.AuthBiometricFingerprintViewModel;
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.statusbar.CommandQueue;
@@ -120,6 +122,7 @@
 @RunWith(AndroidJUnit4.class)
 @RunWithLooper
 @SmallTest
+@RoboPilotTest
 public class AuthControllerTest extends SysuiTestCase {
 
     private static final long REQUEST_ID = 22;
@@ -170,6 +173,8 @@
     @Mock
     private BiometricPromptCredentialInteractor mBiometricPromptCredentialInteractor;
     @Mock
+    private AuthBiometricFingerprintViewModel mAuthBiometricFingerprintViewModel;
+    @Mock
     private CredentialViewModel mCredentialViewModel;
     @Mock
     private UdfpsUtils mUdfpsUtils;
@@ -993,8 +998,9 @@
                     () -> mSideFpsController, mDisplayManager, mWakefulnessLifecycle,
                     mPanelInteractionDetector, mUserManager, mLockPatternUtils, mUdfpsLogger,
                     mLogContextInteractor, () -> mBiometricPromptCredentialInteractor,
-                    () -> mCredentialViewModel, mInteractionJankMonitor, mHandler,
-                    mBackgroundExecutor, mVibratorHelper, mUdfpsUtils);
+                    () -> mAuthBiometricFingerprintViewModel, () -> mCredentialViewModel,
+                    mInteractionJankMonitor, mHandler, mBackgroundExecutor, mVibratorHelper,
+                    mUdfpsUtils);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
index 24a13a5..c6315cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
@@ -41,6 +41,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 
 import kotlin.Unit;
@@ -55,6 +56,7 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4.class)
 @RunWithLooper(setAsMainLooper = true)
 public class BiometricDisplayListenerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
index 88b6c39..ad9fc95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
@@ -19,6 +19,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.logging.BiometricMessageDeferralLogger
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import org.junit.Assert.assertEquals
@@ -33,6 +34,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class FaceHelpMessageDeferralTest : SysuiTestCase() {
     val threshold = .75f
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index c554af6..40d9009 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -52,8 +52,12 @@
 import androidx.test.filters.SmallTest
 import com.airbnb.lottie.LottieAnimationView
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.SysuiTestableContext
+import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
@@ -65,7 +69,9 @@
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestCoroutineScope
+import kotlinx.coroutines.test.TestScope
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -89,7 +95,10 @@
 private const val DISPLAY_ID = 2
 private const val SENSOR_ID = 1
 
+private const val REAR_DISPLAY_MODE_DEVICE_STATE = 3
+
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class SideFpsControllerTest : SysuiTestCase() {
@@ -110,7 +119,12 @@
 
     private lateinit var keyguardBouncerRepository: FakeKeyguardBouncerRepository
     private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
+    private lateinit var displayStateInteractor: DisplayStateInteractor
+
     private val executor = FakeExecutor(FakeSystemClock())
+    private val rearDisplayStateRepository = FakeRearDisplayStateRepository()
+    private val testScope = TestScope(StandardTestDispatcher())
+
     private lateinit var overlayController: ISidefpsController
     private lateinit var sideFpsController: SideFpsController
 
@@ -140,6 +154,13 @@
                 FakeDeviceEntryFingerprintAuthRepository(),
                 FakeSystemClock(),
             )
+        displayStateInteractor =
+            DisplayStateInteractorImpl(
+                testScope.backgroundScope,
+                context,
+                executor,
+                rearDisplayStateRepository
+            )
 
         context.addMockSystemService(DisplayManager::class.java, displayManager)
         context.addMockSystemService(WindowManager::class.java, windowManager)
@@ -166,6 +187,7 @@
         isReverseDefaultRotation: Boolean = false,
         initInfo: DisplayInfo.() -> Unit = {},
         windowInsets: WindowInsets = insetsForSmallNavbar(),
+        inRearDisplayMode: Boolean = false,
         block: () -> Unit
     ) {
         this.deviceConfig = deviceConfig
@@ -226,6 +248,13 @@
             isReverseDefaultRotation
         )
 
+        val rearDisplayDeviceStates =
+            if (inRearDisplayMode) intArrayOf(REAR_DISPLAY_MODE_DEVICE_STATE) else intArrayOf()
+        sideFpsControllerContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.array.config_rearDisplayDeviceStates,
+            rearDisplayDeviceStates
+        )
+
         sideFpsController =
             SideFpsController(
                 sideFpsControllerContext,
@@ -235,12 +264,14 @@
                 activityTaskManager,
                 overviewProxyService,
                 displayManager,
+                displayStateInteractor,
                 executor,
                 handler,
                 alternateBouncerInteractor,
                 TestCoroutineScope(),
-                dumpManager,
+                dumpManager
             )
+        rearDisplayStateRepository.setIsInRearDisplayMode(inRearDisplayMode)
 
         overlayController =
             ArgumentCaptor.forClass(ISidefpsController::class.java)
@@ -582,10 +613,62 @@
             verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
         }
 
+    @Test
+    fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_0() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_0 },
+            inRearDisplayMode = true,
+        ) {
+            verifySfpsIndicator_notAdded_InRearDisplayMode()
+        }
+
+    @Test
+    fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_90() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_90 },
+            inRearDisplayMode = true,
+        ) {
+            verifySfpsIndicator_notAdded_InRearDisplayMode()
+        }
+
+    @Test
+    fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_180 },
+            inRearDisplayMode = true,
+        ) {
+            verifySfpsIndicator_notAdded_InRearDisplayMode()
+        }
+
+    @Test
+    fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_270() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_270 },
+            inRearDisplayMode = true,
+        ) {
+            verifySfpsIndicator_notAdded_InRearDisplayMode()
+        }
+
     private fun verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible: Boolean) {
         sideFpsController.overlayOffsets = sensorLocation
     }
 
+    private fun verifySfpsIndicator_notAdded_InRearDisplayMode() {
+        sideFpsController.overlayOffsets = sensorLocation
+        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+        executor.runAllReady()
+
+        verify(windowManager, never()).addView(any(), any())
+    }
+
     fun alternateBouncerVisibility_showAndHideSideFpsUI() = testWithDisplay {
         // WHEN alternate bouncer is visible
         keyguardBouncerRepository.setAlternateVisible(true)
@@ -622,7 +705,7 @@
      * in other rotations have been omitted.
      */
     @Test
-    fun verifiesIndicatorPlacementForXAlignedSensor_0() {
+    fun verifiesIndicatorPlacementForXAlignedSensor_0() =
         testWithDisplay(
             deviceConfig = DeviceConfig.X_ALIGNED,
             isReverseDefaultRotation = false,
@@ -639,7 +722,6 @@
             assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
             assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
         }
-    }
 
     /**
      * {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_270
@@ -648,7 +730,7 @@
      * correctly, tests for indicator placement in other rotations have been omitted.
      */
     @Test
-    fun verifiesIndicatorPlacementForXAlignedSensor_InReverseDefaultRotation_270() {
+    fun verifiesIndicatorPlacementForXAlignedSensor_InReverseDefaultRotation_270() =
         testWithDisplay(
             deviceConfig = DeviceConfig.X_ALIGNED,
             isReverseDefaultRotation = true,
@@ -665,7 +747,6 @@
             assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
             assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
         }
-    }
 
     /**
      * {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_0,
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 1faad80..2747e83 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -40,6 +40,7 @@
 import com.android.settingslib.udfps.UdfpsOverlayParams
 import com.android.settingslib.udfps.UdfpsUtils
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.dump.DumpManager
@@ -80,6 +81,7 @@
 private const val SENSOR_HEIGHT = 60
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 class UdfpsControllerOverlayTest : SysuiTestCase() {
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 8d8b190..da71188 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -76,6 +76,7 @@
 import com.android.settingslib.udfps.UdfpsOverlayParams;
 import com.android.settingslib.udfps.UdfpsUtils;
 import com.android.systemui.R;
+import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.biometrics.udfps.InteractionEvent;
@@ -125,6 +126,7 @@
 import javax.inject.Provider;
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4.class)
 @RunWithLooper(setAsMainLooper = true)
 public class UdfpsControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
index cd9189b..280bfdf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
@@ -27,6 +27,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Test;
@@ -37,6 +38,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
+@RoboPilotTest
 public class UdfpsDialogMeasureAdapterTest extends SysuiTestCase {
     @Test
     public void testUdfpsBottomSpacerHeightForPortrait() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
index 5239966..1afb223 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
@@ -30,6 +30,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.concurrency.FakeExecution;
 
@@ -40,6 +41,7 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4.class)
 @RunWithLooper(setAsMainLooper = true)
 public class UdfpsDisplayModeTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index af3a06b..b5515d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -33,6 +33,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.RoboPilotTest;
 import com.android.systemui.shade.ShadeExpansionListener;
 import com.android.systemui.statusbar.StatusBarState;
 
@@ -40,6 +41,7 @@
 import org.junit.runner.RunWith;
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4.class)
 
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
index fea9d2d5..8bf32cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -55,6 +56,7 @@
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
+@RoboPilotTest
 @TestableLooper.RunWithLooper
 @kotlinx.coroutines.ExperimentalCoroutinesApi
 class UdfpsKeyguardViewControllerWithCoroutinesTest : UdfpsKeyguardViewControllerBaseTest() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
index 8b374ae..6d55254 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
@@ -21,6 +21,7 @@
 import android.view.MotionEvent
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.UdfpsController.UdfpsOverlayController
 import com.android.systemui.statusbar.commandline.CommandRegistry
@@ -39,6 +40,7 @@
 import org.mockito.junit.MockitoJUnit
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class UdfpsShellTest : SysuiTestCase() {
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 f075967..d11c965 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -27,6 +27,7 @@
 import androidx.test.filters.SmallTest
 import com.android.settingslib.udfps.UdfpsOverlayParams
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
@@ -49,6 +50,7 @@
 private const val SENSOR_RADIUS = 10
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class UdfpsViewTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
new file mode 100644
index 0000000..f3a100b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.data.repository
+
+import android.hardware.biometrics.ComponentInfoInternal
+import android.hardware.biometrics.SensorLocationInternal
+import android.hardware.biometrics.SensorProperties
+import android.hardware.fingerprint.FingerprintManager
+import android.hardware.fingerprint.FingerprintSensorProperties
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.shared.model.FingerprintSensorType
+import com.android.systemui.biometrics.shared.model.SensorStrength
+import com.android.systemui.coroutines.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(JUnit4::class)
+class FingerprintRepositoryImplTest : SysuiTestCase() {
+
+    @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
+    private lateinit var testScope: TestScope
+
+    @Mock private lateinit var fingerprintManager: FingerprintManager
+    private lateinit var repository: FingerprintPropertyRepositoryImpl
+
+    @Captor
+    private lateinit var fingerprintAuthenticatorsCaptor:
+        ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback.Stub>
+
+    @Before
+    fun setup() {
+        val dispatcher = StandardTestDispatcher()
+        testScope = TestScope(dispatcher)
+        repository =
+            FingerprintPropertyRepositoryImpl(testScope.backgroundScope, fingerprintManager)
+        testScope.runCurrent()
+
+        verify(fingerprintManager)
+            .addAuthenticatorsRegisteredCallback(fingerprintAuthenticatorsCaptor.capture())
+    }
+
+    @Test
+    fun initializeProperties() =
+        testScope.runTest {
+            val isInitialized = collectLastValue(repository.isInitialized)
+
+            assertDefaultProperties()
+            assertThat(isInitialized()).isFalse()
+
+            val fingerprintProps =
+                listOf(
+                    FingerprintSensorPropertiesInternal(
+                        1 /* sensorId */,
+                        SensorProperties.STRENGTH_STRONG,
+                        5 /* maxEnrollmentsPerUser */,
+                        listOf<ComponentInfoInternal>(
+                            ComponentInfoInternal(
+                                "sensor" /* componentId */,
+                                "vendor/model/revision" /* hardwareVersion */,
+                                "1.01" /* firmwareVersion */,
+                                "00000001" /* serialNumber */,
+                                "" /* softwareVersion */
+                            )
+                        ),
+                        FingerprintSensorProperties.TYPE_REAR,
+                        false /* halControlsIllumination */,
+                        true /* resetLockoutRequiresHardwareAuthToken */,
+                        listOf<SensorLocationInternal>(
+                            SensorLocationInternal(
+                                "" /* displayId */,
+                                540 /* sensorLocationX */,
+                                1636 /* sensorLocationY */,
+                                130 /* sensorRadius */
+                            )
+                        )
+                    )
+                )
+
+            fingerprintAuthenticatorsCaptor.value.onAllAuthenticatorsRegistered(fingerprintProps)
+
+            assertThat(repository.sensorId.value).isEqualTo(1)
+            assertThat(repository.strength.value).isEqualTo(SensorStrength.STRONG)
+            assertThat(repository.sensorType.value).isEqualTo(FingerprintSensorType.REAR)
+            with(repository.sensorLocation.value) {
+                assertThat(displayId).isEqualTo("")
+                assertThat(sensorLocationX).isEqualTo(540)
+                assertThat(sensorLocationY).isEqualTo(1636)
+                assertThat(sensorRadius).isEqualTo(130)
+            }
+            assertThat(isInitialized()).isTrue()
+        }
+
+    private fun assertDefaultProperties() {
+        assertThat(repository.sensorId.value).isEqualTo(-1)
+        assertThat(repository.strength.value).isEqualTo(SensorStrength.CONVENIENCE)
+        assertThat(repository.sensorType.value).isEqualTo(FingerprintSensorType.UNKNOWN)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepositoryTest.kt
new file mode 100644
index 0000000..dfe8d36
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/RearDisplayStateRepositoryTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import android.hardware.devicestate.DeviceStateManager
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.RearDisplayStateRepository
+import com.android.systemui.biometrics.data.repository.RearDisplayStateRepositoryImpl
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+
+private const val NORMAL_DISPLAY_MODE_DEVICE_STATE = 2
+private const val REAR_DISPLAY_MODE_DEVICE_STATE = 3
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class RearDisplayStateRepositoryTest : SysuiTestCase() {
+    @JvmField @Rule var mockitoRule: MockitoRule = MockitoJUnit.rule()
+    @Mock private lateinit var deviceStateManager: DeviceStateManager
+    private lateinit var underTest: RearDisplayStateRepository
+
+    private val testScope = TestScope(StandardTestDispatcher())
+    private val fakeExecutor = FakeExecutor(FakeSystemClock())
+
+    @Captor
+    private lateinit var callbackCaptor: ArgumentCaptor<DeviceStateManager.DeviceStateCallback>
+
+    @Before
+    fun setUp() {
+        val rearDisplayDeviceStates = intArrayOf(REAR_DISPLAY_MODE_DEVICE_STATE)
+        mContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.array.config_rearDisplayDeviceStates,
+            rearDisplayDeviceStates
+        )
+
+        underTest =
+            RearDisplayStateRepositoryImpl(
+                testScope.backgroundScope,
+                mContext,
+                deviceStateManager,
+                fakeExecutor
+            )
+    }
+
+    @Test
+    fun updatesIsInRearDisplayMode_whenRearDisplayStateChanges() =
+        testScope.runTest {
+            val isInRearDisplayMode = collectLastValue(underTest.isInRearDisplayMode)
+            runCurrent()
+
+            val callback = deviceStateManager.captureCallback()
+
+            callback.onStateChanged(NORMAL_DISPLAY_MODE_DEVICE_STATE)
+            assertThat(isInRearDisplayMode()).isFalse()
+
+            callback.onStateChanged(REAR_DISPLAY_MODE_DEVICE_STATE)
+            assertThat(isInRearDisplayMode()).isTrue()
+        }
+}
+
+private fun DeviceStateManager.captureCallback() =
+    withArgCaptor<DeviceStateManager.DeviceStateCallback> {
+        verify(this@captureCallback).registerCallback(any(), capture())
+    }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
new file mode 100644
index 0000000..2217c5c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
@@ -0,0 +1,84 @@
+package com.android.systemui.biometrics.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.unfold.compat.ScreenSizeFoldProvider
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+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.junit.MockitoJUnit
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class DisplayStateInteractorImplTest : SysuiTestCase() {
+
+    @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
+
+    private val fakeExecutor = FakeExecutor(FakeSystemClock())
+    private val testScope = TestScope(StandardTestDispatcher())
+    private val rearDisplayStateRepository = FakeRearDisplayStateRepository()
+
+    @Mock private lateinit var screenSizeFoldProvider: ScreenSizeFoldProvider
+    private lateinit var interactor: DisplayStateInteractorImpl
+
+    @Before
+    fun setup() {
+        interactor =
+            DisplayStateInteractorImpl(
+                testScope.backgroundScope,
+                mContext,
+                fakeExecutor,
+                rearDisplayStateRepository
+            )
+        interactor.setScreenSizeFoldProvider(screenSizeFoldProvider)
+    }
+
+    @Test
+    fun isInRearDisplayModeChanges() =
+        testScope.runTest {
+            val isInRearDisplayMode = collectLastValue(interactor.isInRearDisplayMode)
+
+            rearDisplayStateRepository.setIsInRearDisplayMode(false)
+            assertThat(isInRearDisplayMode()).isFalse()
+
+            rearDisplayStateRepository.setIsInRearDisplayMode(true)
+            assertThat(isInRearDisplayMode()).isTrue()
+        }
+
+    @Test
+    fun isFoldedChanges() =
+        testScope.runTest {
+            val isFolded = collectLastValue(interactor.isFolded)
+            runCurrent()
+            val callback = screenSizeFoldProvider.captureCallback()
+
+            callback.onFoldUpdated(isFolded = true)
+            assertThat(isFolded()).isTrue()
+
+            callback.onFoldUpdated(isFolded = false)
+            assertThat(isFolded()).isFalse()
+        }
+}
+
+private fun FoldProvider.captureCallback() =
+    withArgCaptor<FoldProvider.FoldCallback> {
+        verify(this@captureCallback).registerCallback(capture(), any())
+    }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
index 4b41537..fb3c185 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
@@ -61,7 +61,7 @@
         @JvmStatic
         fun data(): List<TestCase> =
             listOf(
-                    genTestCases(
+                    genPositiveTestCases(
                         innerXs = listOf(SENSOR.left, SENSOR.right, SENSOR.centerX()),
                         innerYs = listOf(SENSOR.top, SENSOR.bottom, SENSOR.centerY()),
                         outerXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
@@ -70,9 +70,7 @@
                         major = 300f,
                         expected = true
                     ),
-                    genTestCases(
-                        innerXs = listOf(SENSOR.left, SENSOR.right),
-                        innerYs = listOf(SENSOR.top, SENSOR.bottom),
+                    genNegativeTestCase(
                         outerXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
                         outerYs = listOf(SENSOR.top - 1, SENSOR.bottom + 1),
                         minor = 100f,
@@ -107,7 +105,7 @@
 
 private val SENSOR = Rect(100 /* left */, 200 /* top */, 300 /* right */, 400 /* bottom */)
 
-private fun genTestCases(
+private fun genPositiveTestCases(
     innerXs: List<Int>,
     innerYs: List<Int>,
     outerXs: List<Int>,
@@ -122,3 +120,15 @@
         }
     }
 }
+
+private fun genNegativeTestCase(
+    outerXs: List<Int>,
+    outerYs: List<Int>,
+    minor: Float,
+    major: Float,
+    expected: Boolean
+): List<EllipseOverlapDetectorTest.TestCase> {
+    return outerXs.flatMap { x ->
+        outerYs.map { y -> EllipseOverlapDetectorTest.TestCase(x, y, minor, major, expected) }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/AuthBiometricFingerprintViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/AuthBiometricFingerprintViewModelTest.kt
new file mode 100644
index 0000000..0c210e5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/AuthBiometricFingerprintViewModelTest.kt
@@ -0,0 +1,69 @@
+package com.android.systemui.biometrics.ui.viewmodel
+
+import android.content.res.Configuration
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class AuthBiometricFingerprintViewModelTest : SysuiTestCase() {
+
+    private val rearDisplayStateRepository = FakeRearDisplayStateRepository()
+    private val testScope = TestScope(StandardTestDispatcher())
+    private val fakeExecutor = FakeExecutor(FakeSystemClock())
+
+    private lateinit var interactor: DisplayStateInteractor
+    private lateinit var viewModel: AuthBiometricFingerprintViewModel
+
+    @Before
+    fun setup() {
+        interactor =
+            DisplayStateInteractorImpl(
+                testScope.backgroundScope,
+                mContext,
+                fakeExecutor,
+                rearDisplayStateRepository
+            )
+        viewModel = AuthBiometricFingerprintViewModel(interactor)
+    }
+
+    @Test
+    fun iconUpdates_onConfigurationChanged() {
+        testScope.runTest {
+            runCurrent()
+            val testConfig = Configuration()
+            val folded = INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP - 1
+            val unfolded = INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP + 1
+            val currentIcon = collectLastValue(viewModel.iconAsset)
+
+            testConfig.smallestScreenWidthDp = folded
+            viewModel.onConfigurationChanged(testConfig)
+            val foldedIcon = currentIcon()
+
+            testConfig.smallestScreenWidthDp = unfolded
+            viewModel.onConfigurationChanged(testConfig)
+            val unfoldedIcon = currentIcon()
+
+            assertThat(foldedIcon).isNotEqualTo(unfoldedIcon)
+        }
+    }
+}
+
+internal const val INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP = 600
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardImageLoaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardImageLoaderTest.kt
new file mode 100644
index 0000000..21516d49
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardImageLoaderTest.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.clipboardoverlay
+
+import android.content.ContentResolver
+import android.content.Context
+import android.net.Uri
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.whenever
+import java.io.IOException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Test
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class ClipboardImageLoaderTest : SysuiTestCase() {
+    @Mock private lateinit var mockContext: Context
+
+    @Mock private lateinit var mockContentResolver: ContentResolver
+
+    private lateinit var clipboardImageLoader: ClipboardImageLoader
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @Test
+    @Throws(IOException::class)
+    fun test_imageLoadSuccess() = runTest {
+        val testDispatcher = StandardTestDispatcher(this.testScheduler)
+        clipboardImageLoader =
+            ClipboardImageLoader(mockContext, testDispatcher, CoroutineScope(testDispatcher))
+        val testUri = Uri.parse("testUri")
+        whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
+        whenever(mockContext.resources).thenReturn(context.resources)
+
+        clipboardImageLoader.load(testUri)
+
+        verify(mockContentResolver).loadThumbnail(eq(testUri), any(), any())
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    @Throws(IOException::class)
+    fun test_imageLoadFailure() = runTest {
+        val testDispatcher = StandardTestDispatcher(this.testScheduler)
+        clipboardImageLoader =
+            ClipboardImageLoader(mockContext, testDispatcher, CoroutineScope(testDispatcher))
+        val testUri = Uri.parse("testUri")
+        whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
+        whenever(mockContext.resources).thenReturn(context.resources)
+
+        val res = clipboardImageLoader.load(testUri)
+
+        verify(mockContentResolver).loadThumbnail(eq(testUri), any(), any())
+        assertNull(res)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
index fe5fa1f..39fb7b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
@@ -25,6 +25,7 @@
 import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SHOWN_EXPANDED;
 import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SHOWN_MINIMIZED;
 import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_SWIPE_DISMISSED;
+import static com.android.systemui.flags.Flags.CLIPBOARD_IMAGE_TIMEOUT;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -90,6 +91,8 @@
     @Mock
     private ClipboardOverlayUtils mClipboardUtils;
     @Mock
+    private ClipboardImageLoader mClipboardImageLoader;
+    @Mock
     private UiEventLogger mUiEventLogger;
     private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
     private FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
@@ -120,6 +123,7 @@
         mSampleClipData = new ClipData("Test", new String[]{"text/plain"},
                 new ClipData.Item("Test Item"));
 
+        mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, true); // turned off for legacy tests
 
         mOverlayController = new ClipboardOverlayController(
                 mContext,
@@ -131,6 +135,7 @@
                 mFeatureFlags,
                 mClipboardUtils,
                 mExecutor,
+                mClipboardImageLoader,
                 mUiEventLogger);
         verify(mClipboardOverlayView).setCallbacks(mOverlayCallbacksCaptor.capture());
         mCallbacks = mOverlayCallbacksCaptor.getValue();
@@ -142,6 +147,69 @@
     }
 
     @Test
+    public void test_setClipData_invalidImageData_legacy() {
+        ClipData clipData = new ClipData("", new String[]{"image/png"},
+                new ClipData.Item(Uri.parse("")));
+        mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
+
+        mOverlayController.setClipData(clipData, "");
+
+        verify(mClipboardOverlayView, times(1)).showDefaultTextPreview();
+        verify(mClipboardOverlayView, times(1)).showShareChip();
+        verify(mClipboardOverlayView, times(1)).getEnterAnimation();
+    }
+
+    @Test
+    public void test_setClipData_nonImageUri_legacy() {
+        ClipData clipData = new ClipData("", new String[]{"resource/png"},
+                new ClipData.Item(Uri.parse("")));
+        mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
+
+        mOverlayController.setClipData(clipData, "");
+
+        verify(mClipboardOverlayView, times(1)).showDefaultTextPreview();
+        verify(mClipboardOverlayView, times(1)).showShareChip();
+        verify(mClipboardOverlayView, times(1)).getEnterAnimation();
+    }
+
+    @Test
+    public void test_setClipData_textData_legacy() {
+        mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
+        mOverlayController.setClipData(mSampleClipData, "abc");
+
+        verify(mClipboardOverlayView, times(1)).showTextPreview("Test Item", false);
+        verify(mUiEventLogger, times(1)).log(CLIPBOARD_OVERLAY_SHOWN_EXPANDED, 0, "abc");
+        verify(mClipboardOverlayView, times(1)).showShareChip();
+        verify(mClipboardOverlayView, times(1)).getEnterAnimation();
+    }
+
+    @Test
+    public void test_setClipData_sensitiveTextData_legacy() {
+        mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
+        ClipDescription description = mSampleClipData.getDescription();
+        PersistableBundle b = new PersistableBundle();
+        b.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true);
+        description.setExtras(b);
+        ClipData data = new ClipData(description, mSampleClipData.getItemAt(0));
+        mOverlayController.setClipData(data, "");
+
+        verify(mClipboardOverlayView, times(1)).showTextPreview("••••••", true);
+        verify(mClipboardOverlayView, times(1)).showShareChip();
+        verify(mClipboardOverlayView, times(1)).getEnterAnimation();
+    }
+
+    @Test
+    public void test_setClipData_repeatedCalls_legacy() {
+        when(mAnimator.isRunning()).thenReturn(true);
+        mFeatureFlags.set(CLIPBOARD_IMAGE_TIMEOUT, false);
+
+        mOverlayController.setClipData(mSampleClipData, "");
+        mOverlayController.setClipData(mSampleClipData, "");
+
+        verify(mClipboardOverlayView, times(1)).getEnterAnimation();
+    }
+
+    @Test
     public void test_setClipData_invalidImageData() {
         ClipData clipData = new ClipData("", new String[]{"image/png"},
                 new ClipData.Item(Uri.parse("")));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/data/repository/ConfigurationRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/common/ui/data/repository/ConfigurationRepositoryImplTest.kt
new file mode 100644
index 0000000..a308c8e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/ui/data/repository/ConfigurationRepositoryImplTest.kt
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.ui.data.repository
+
+import android.content.res.Configuration
+import android.view.Display
+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.statusbar.policy.ConfigurationController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.wrapper.DisplayUtilsWrapper
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ConfigurationRepositoryImplTest : SysuiTestCase() {
+    private var displaySizeRatio = 0f
+    @Mock private lateinit var configurationController: ConfigurationController
+    @Mock private lateinit var displayUtils: DisplayUtilsWrapper
+
+    private lateinit var testScope: TestScope
+    private lateinit var underTest: ConfigurationRepositoryImpl
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        setPhysicalPixelDisplaySizeRatio(displaySizeRatio)
+
+        testScope = TestScope()
+        underTest =
+            ConfigurationRepositoryImpl(
+                configurationController,
+                context,
+                testScope.backgroundScope,
+                displayUtils,
+            )
+    }
+
+    @Test
+    fun onAnyConfigurationChange_updatesOnUiModeChanged() =
+        testScope.runTest {
+            val lastAnyConfigurationChange by collectLastValue(underTest.onAnyConfigurationChange)
+            assertThat(lastAnyConfigurationChange).isNull()
+
+            val configurationCallback = withArgCaptor {
+                verify(configurationController).addCallback(capture())
+            }
+
+            configurationCallback.onUiModeChanged()
+            runCurrent()
+            assertThat(lastAnyConfigurationChange).isNotNull()
+        }
+
+    @Test
+    fun onAnyConfigurationChange_updatesOnThemeChanged() =
+        testScope.runTest {
+            val lastAnyConfigurationChange by collectLastValue(underTest.onAnyConfigurationChange)
+            assertThat(lastAnyConfigurationChange).isNull()
+
+            val configurationCallback = withArgCaptor {
+                verify(configurationController).addCallback(capture())
+            }
+
+            configurationCallback.onThemeChanged()
+            runCurrent()
+            assertThat(lastAnyConfigurationChange).isNotNull()
+        }
+
+    @Test
+    fun onAnyConfigurationChange_updatesOnConfigChanged() =
+        testScope.runTest {
+            val lastAnyConfigurationChange by collectLastValue(underTest.onAnyConfigurationChange)
+            assertThat(lastAnyConfigurationChange).isNull()
+
+            val configurationCallback = withArgCaptor {
+                verify(configurationController).addCallback(capture())
+            }
+
+            configurationCallback.onConfigChanged(mock(Configuration::class.java))
+            runCurrent()
+            assertThat(lastAnyConfigurationChange).isNotNull()
+        }
+
+    @Test
+    fun onResolutionScale_updatesOnConfigurationChange() =
+        testScope.runTest {
+            val scaleForResolution by collectLastValue(underTest.scaleForResolution)
+            assertThat(scaleForResolution).isEqualTo(displaySizeRatio)
+
+            val configurationCallback = withArgCaptor {
+                verify(configurationController).addCallback(capture())
+            }
+
+            setPhysicalPixelDisplaySizeRatio(2f)
+            configurationCallback.onConfigChanged(mock(Configuration::class.java))
+            assertThat(scaleForResolution).isEqualTo(displaySizeRatio)
+
+            setPhysicalPixelDisplaySizeRatio(.21f)
+            configurationCallback.onConfigChanged(mock(Configuration::class.java))
+            assertThat(scaleForResolution).isEqualTo(displaySizeRatio)
+        }
+
+    @Test
+    fun onResolutionScale_nullMaxResolution() =
+        testScope.runTest {
+            val scaleForResolution by collectLastValue(underTest.scaleForResolution)
+            runCurrent()
+
+            givenNullMaxResolutionDisplayMode()
+            val configurationCallback = withArgCaptor {
+                verify(configurationController).addCallback(capture())
+            }
+            configurationCallback.onConfigChanged(mock(Configuration::class.java))
+            assertThat(scaleForResolution).isEqualTo(1f)
+        }
+
+    @Test
+    fun getResolutionScale_nullMaxResolutionDisplayMode() {
+        givenNullMaxResolutionDisplayMode()
+        assertThat(underTest.getResolutionScale()).isEqualTo(1f)
+    }
+
+    @Test
+    fun getResolutionScale_infiniteDisplayRatios() {
+        setPhysicalPixelDisplaySizeRatio(Float.POSITIVE_INFINITY)
+        assertThat(underTest.getResolutionScale()).isEqualTo(1f)
+    }
+
+    @Test
+    fun getResolutionScale_differentDisplayRatios() {
+        setPhysicalPixelDisplaySizeRatio(.5f)
+        assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio)
+
+        setPhysicalPixelDisplaySizeRatio(.283f)
+        assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio)
+
+        setPhysicalPixelDisplaySizeRatio(3.58f)
+        assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio)
+
+        setPhysicalPixelDisplaySizeRatio(0f)
+        assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio)
+
+        setPhysicalPixelDisplaySizeRatio(1f)
+        assertThat(underTest.getResolutionScale()).isEqualTo(displaySizeRatio)
+    }
+
+    private fun givenNullMaxResolutionDisplayMode() {
+        whenever(displayUtils.getMaximumResolutionDisplayMode(any())).thenReturn(null)
+    }
+
+    private fun setPhysicalPixelDisplaySizeRatio(ratio: Float) {
+        displaySizeRatio = ratio
+        whenever(displayUtils.getMaximumResolutionDisplayMode(any()))
+            .thenReturn(Display.Mode(0, 0, 0, 90f))
+        whenever(
+                displayUtils.getPhysicalPixelDisplaySizeRatio(
+                    anyInt(),
+                    anyInt(),
+                    anyInt(),
+                    anyInt()
+                )
+            )
+            .thenReturn(ratio)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt
new file mode 100644
index 0000000..b2a1668
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.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.systemui.common.ui.data.repository
+
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.receiveAsFlow
+
+class FakeConfigurationRepository : ConfigurationRepository {
+    private val onAnyConfigurationChangeChannel = Channel<Unit>()
+    override val onAnyConfigurationChange: Flow<Unit> =
+        onAnyConfigurationChangeChannel.receiveAsFlow()
+
+    private val _scaleForResolution = MutableStateFlow(1f)
+    override val scaleForResolution: Flow<Float> = _scaleForResolution.asStateFlow()
+
+    suspend fun onAnyConfigurationChange() {
+        onAnyConfigurationChangeChannel.send(Unit)
+    }
+
+    fun setScaleForResolution(scale: Float) {
+        _scaleForResolution.value = scale
+    }
+
+    override fun getResolutionScale(): Float {
+        return _scaleForResolution.value
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
index ebbe096..26cbd77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
@@ -41,11 +41,11 @@
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -378,7 +378,13 @@
     executor: DelayableExecutor,
     lazyController: Lazy<ControlsController>,
     userTracker: UserTracker
-) : ControlsBindingControllerImpl(context, executor, lazyController, userTracker) {
+) : ControlsBindingControllerImpl(
+    context,
+    executor,
+    lazyController,
+    mock(PackageUpdateMonitor.Factory::class.java),
+    userTracker
+) {
 
     companion object {
         val providers = mutableListOf<ControlsProviderLifecycleManager>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
index da548f7..b5d3476 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
@@ -30,6 +30,10 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.time.FakeSystemClock
 import org.junit.After
 import org.junit.Assert.assertEquals
@@ -39,17 +43,17 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers
-import org.mockito.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.anyString
-import org.mockito.ArgumentMatchers.eq
 import org.mockito.Captor
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.mock
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.never
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -62,16 +66,21 @@
     private lateinit var subscriberService: IControlsSubscriber.Stub
     @Mock
     private lateinit var service: IControlsProvider.Stub
-
+    @Mock
+    private lateinit var packageUpdateMonitor: PackageUpdateMonitor
     @Captor
     private lateinit var wrapperCaptor: ArgumentCaptor<ControlActionWrapper>
 
+    private lateinit var packageUpdateMonitorFactory: FakePackageUpdateMonitorFactory
+
     private val componentName = ComponentName("test.pkg", "test.cls")
     private lateinit var manager: ControlsProviderLifecycleManager
     private lateinit var executor: FakeExecutor
+    private lateinit var fakeSystemClock: FakeSystemClock
 
     companion object {
         fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
+        private val USER = UserHandle.of(0)
     }
 
     @Before
@@ -79,16 +88,20 @@
         MockitoAnnotations.initMocks(this)
 
         context.addMockService(componentName, service)
-        executor = FakeExecutor(FakeSystemClock())
+        fakeSystemClock = FakeSystemClock()
+        executor = FakeExecutor(fakeSystemClock)
         `when`(service.asBinder()).thenCallRealMethod()
-        `when`(service.queryLocalInterface(ArgumentMatchers.anyString())).thenReturn(service)
+        `when`(service.queryLocalInterface(anyString())).thenReturn(service)
+
+        packageUpdateMonitorFactory = FakePackageUpdateMonitorFactory(packageUpdateMonitor)
 
         manager = ControlsProviderLifecycleManager(
                 context,
                 executor,
                 actionCallbackService,
-                UserHandle.of(0),
-                componentName
+                USER,
+                componentName,
+                packageUpdateMonitorFactory,
         )
     }
 
@@ -122,7 +135,7 @@
 
     @Test
     fun testNullBinding() {
-        val mockContext = mock(Context::class.java)
+        val mockContext = mock<Context>()
         lateinit var serviceConnection: ServiceConnection
         `when`(mockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer {
             val component = (it.arguments[0] as Intent).component
@@ -139,8 +152,9 @@
                 mockContext,
                 executor,
                 actionCallbackService,
-                UserHandle.of(0),
-                componentName
+                USER,
+                componentName,
+                packageUpdateMonitorFactory,
         )
 
         nullManager.bindService()
@@ -229,14 +243,15 @@
 
     @Test
     fun testFalseBindCallsUnbind() {
-        val falseContext = mock(Context::class.java)
+        val falseContext = mock<Context>()
         `when`(falseContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(false)
         val manager = ControlsProviderLifecycleManager(
             falseContext,
             executor,
             actionCallbackService,
-            UserHandle.of(0),
-            componentName
+            USER,
+            componentName,
+            packageUpdateMonitorFactory,
         )
         manager.bindService()
         executor.runAllReady()
@@ -247,4 +262,150 @@
         verify(falseContext).bindServiceAsUser(any(), captor.capture(), anyInt(), any())
         verify(falseContext).unbindService(captor.value)
     }
+
+    @Test
+    fun testPackageUpdateMonitor_createdWithCorrectValues() {
+        assertEquals(USER, packageUpdateMonitorFactory.lastUser)
+        assertEquals(componentName.packageName, packageUpdateMonitorFactory.lastPackage)
+    }
+
+    @Test
+    fun testBound_packageMonitorStartsMonitoring() {
+        manager.bindService()
+        executor.runAllReady()
+
+        // Service will connect and monitoring should start
+        verify(packageUpdateMonitor).startMonitoring()
+    }
+
+    @Test
+    fun testOnPackageUpdateWhileBound_unbound_thenBindAgain() {
+        val mockContext = mock<Context> {
+            `when`(bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true)
+        }
+
+        val manager = ControlsProviderLifecycleManager(
+            mockContext,
+            executor,
+            actionCallbackService,
+            USER,
+            componentName,
+            packageUpdateMonitorFactory,
+        )
+
+        manager.bindService()
+        executor.runAllReady()
+        clearInvocations(mockContext)
+
+        packageUpdateMonitorFactory.lastCallback?.run()
+        executor.runAllReady()
+
+        val inOrder = inOrder(mockContext)
+        inOrder.verify(mockContext).unbindService(any())
+        inOrder.verify(mockContext).bindServiceAsUser(any(), any(), anyInt(), any())
+    }
+
+    @Test
+    fun testOnPackageUpdateWhenNotBound_nothingHappens() {
+        val mockContext = mock<Context> {
+            `when`(bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true)
+        }
+
+        ControlsProviderLifecycleManager(
+            mockContext,
+            executor,
+            actionCallbackService,
+            USER,
+            componentName,
+            packageUpdateMonitorFactory,
+        )
+
+        packageUpdateMonitorFactory.lastCallback?.run()
+        verifyNoMoreInteractions(mockContext)
+    }
+
+    @Test
+    fun testUnbindService_stopsTracking() {
+        manager.bindService()
+        manager.unbindService()
+        executor.runAllReady()
+
+        verify(packageUpdateMonitor).stopMonitoring()
+    }
+
+    @Test
+    fun testRebindForPanelWithSameFlags() {
+        val mockContext = mock<Context> {
+            `when`(bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true)
+        }
+
+        val manager = ControlsProviderLifecycleManager(
+            mockContext,
+            executor,
+            actionCallbackService,
+            USER,
+            componentName,
+            packageUpdateMonitorFactory,
+        )
+
+        manager.bindServiceForPanel()
+        executor.runAllReady()
+
+        val flagsCaptor = argumentCaptor<Int>()
+        verify(mockContext).bindServiceAsUser(any(), any(), capture(flagsCaptor), any())
+        clearInvocations(mockContext)
+
+        packageUpdateMonitorFactory.lastCallback?.run()
+        executor.runAllReady()
+
+        verify(mockContext).bindServiceAsUser(any(), any(), eq(flagsCaptor.value), any())
+    }
+
+    @Test
+    fun testBindAfterSecurityExceptionWorks() {
+        val mockContext = mock<Context> {
+            `when`(bindServiceAsUser(any(), any(), anyInt(), any()))
+                .thenThrow(SecurityException("exception"))
+        }
+
+        val manager = ControlsProviderLifecycleManager(
+            mockContext,
+            executor,
+            actionCallbackService,
+            USER,
+            componentName,
+            packageUpdateMonitorFactory,
+        )
+
+        manager.bindServiceForPanel()
+        executor.runAllReady()
+
+        `when`(mockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true)
+
+        manager.bindServiceForPanel()
+        executor.runAllReady()
+
+        verify(mockContext, times(2)).bindServiceAsUser(any(), any(), anyInt(), any())
+    }
+
+    private class FakePackageUpdateMonitorFactory(
+        private val monitor: PackageUpdateMonitor
+    ) : PackageUpdateMonitor.Factory {
+
+        var lastUser: UserHandle? = null
+        var lastPackage: String? = null
+        var lastCallback: Runnable? = null
+
+        override fun create(
+            user: UserHandle,
+            packageName: String,
+            callback: Runnable
+        ): PackageUpdateMonitor {
+            lastUser = user
+            lastPackage = packageName
+            lastCallback = callback
+            return monitor
+        }
+    }
 }
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt
new file mode 100644
index 0000000..6954710
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.controls.controller
+
+import android.content.Context
+import android.os.Handler
+import android.os.UserHandle
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+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.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class PackageUpdateMonitorTest : SysuiTestCase() {
+
+    @Mock private lateinit var context: Context
+    @Mock private lateinit var bgHandler: Handler
+
+    private lateinit var underTest: PackageUpdateMonitor
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @Test
+    fun startMonitoring_registerOnlyOnce() {
+        underTest = PackageUpdateMonitor(USER, PACKAGE, {}, bgHandler, context)
+
+        underTest.startMonitoring()
+        // There are two receivers registered
+        verify(context, times(2))
+            .registerReceiverAsUser(any(), eq(USER), any(), eq(null), eq(bgHandler))
+
+        underTest.startMonitoring()
+        verifyNoMoreInteractions(context)
+    }
+
+    @Test
+    fun stopMonitoring_unregistersOnlyOnce() {
+        underTest = PackageUpdateMonitor(USER, PACKAGE, {}, bgHandler, context)
+
+        underTest.startMonitoring()
+        clearInvocations(context)
+
+        underTest.stopMonitoring()
+        verify(context).unregisterReceiver(any())
+
+        underTest.stopMonitoring()
+        verifyNoMoreInteractions(context)
+    }
+
+    @Test
+    fun onPackageUpdated_correctPackageAndUser_callbackRuns() {
+        val callback = mock<Runnable>()
+
+        underTest = PackageUpdateMonitor(USER, PACKAGE, callback, bgHandler, context)
+
+        underTest.onPackageUpdateFinished(PACKAGE, UserHandle.getUid(USER.identifier, 10000))
+        verify(callback).run()
+    }
+
+    @Test
+    fun onPackageUpdated_correctPackage_wrongUser_callbackDoesntRun() {
+        val callback = mock<Runnable>()
+
+        underTest = PackageUpdateMonitor(USER, PACKAGE, callback, bgHandler, context)
+
+        underTest.onPackageUpdateFinished(PACKAGE, UserHandle.getUid(USER.identifier + 1, 10000))
+        verify(callback, never()).run()
+    }
+
+    @Test
+    fun onPackageUpdated_wrongPackage_correctUser_callbackDoesntRun() {
+        val callback = mock<Runnable>()
+
+        underTest = PackageUpdateMonitor(USER, PACKAGE, callback, bgHandler, context)
+
+        underTest.onPackageUpdateFinished("bad", UserHandle.getUid(USER.identifier + 1, 10000))
+        verify(callback, never()).run()
+    }
+
+    companion object {
+        private val USER = UserHandle.of(0)
+        private val PACKAGE = "pkg"
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
index c3506e8..5414259 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.controls.ui
 
+import android.app.ActivityOptions
 import android.app.PendingIntent
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
@@ -24,7 +25,10 @@
 import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
 import com.android.wm.shell.taskview.TaskView
+import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -69,6 +73,25 @@
         verify(taskView).startActivity(eq(pendingIntent), any(), any(), any())
     }
 
+    @Test
+    fun testActivityOptionsAllowBal() {
+        // GIVEN the dialog is created with a PendingIntent
+        val dialog = createDialog(pendingIntent)
+
+        // WHEN the TaskView is initialized
+        dialog.stateCallback.onInitialized()
+
+        val optionsCaptor = argumentCaptor<ActivityOptions>()
+
+        // THEN the ActivityOptions have the correct flags
+        verify(taskView).startActivity(any(), any(), capture(optionsCaptor), any())
+
+        assertThat(optionsCaptor.value.pendingIntentBackgroundActivityStartMode)
+            .isEqualTo(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+        assertThat(optionsCaptor.value.isPendingIntentBackgroundActivityLaunchAllowedByPermission)
+            .isTrue()
+    }
+
     private fun createDialog(pendingIntent: PendingIntent): DetailDialog {
         return DetailDialog(
             mContext,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
index f7c8cca..7840525 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
@@ -19,6 +19,7 @@
 
 import android.app.ActivityOptions
 import android.app.PendingIntent
+import android.content.ComponentName
 import android.content.Context
 import android.content.Intent
 import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
@@ -90,6 +91,11 @@
     }
 
     @Test
+    fun testTaskViewStartsWithAlpha0() {
+        verify(taskView).alpha = 0f
+    }
+
+    @Test
     fun testLaunchTaskViewAttachedListener() {
         underTest.launchTaskView()
         verify(taskView).setListener(eq(uiExecutor), any())
@@ -120,6 +126,16 @@
     }
 
     @Test
+    fun testOnTaskCreated_taskViewAlpha1() {
+        underTest.launchTaskView()
+        verify(taskView).setListener(any(), capture(listenerCaptor))
+
+        listenerCaptor.value.onTaskCreated(1, ComponentName("Test", "TEST"))
+
+        verify(taskView).alpha = 1f
+    }
+
+    @Test
     fun testHideRunnableCalledWhenBackOnRoot() {
         underTest.launchTaskView()
         verify(taskView).setListener(any(), capture(listenerCaptor))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
index b7c6246..039682c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
@@ -24,6 +24,7 @@
 import org.mockito.ArgumentCaptor
 import org.mockito.Mock
 import org.mockito.Mockito.anyLong
+import org.mockito.Mockito.atLeastOnce
 import org.mockito.Mockito.eq
 import org.mockito.Mockito.never
 import org.mockito.Mockito.times
@@ -49,6 +50,7 @@
     @Mock private lateinit var stateController: DreamOverlayStateController
     @Mock private lateinit var configController: ConfigurationController
     @Mock private lateinit var transitionViewModel: DreamingToLockscreenTransitionViewModel
+    @Mock private lateinit var logger: DreamLogger
     private lateinit var controller: DreamOverlayAnimationsController
 
     @Before
@@ -67,6 +69,7 @@
                 DREAM_IN_COMPLICATIONS_ANIMATION_DURATION,
                 DREAM_IN_TRANSLATION_Y_DISTANCE,
                 DREAM_IN_TRANSLATION_Y_DURATION,
+                logger
             )
 
         val mockView: View = mock()
@@ -82,9 +85,9 @@
         verify(stateController).setExitAnimationsRunning(true)
 
         val captor = argumentCaptor<Animator.AnimatorListener>()
-        verify(mockAnimator).addListener(captor.capture())
+        verify(mockAnimator, atLeastOnce()).addListener(captor.capture())
 
-        captor.value.onAnimationEnd(mockAnimator)
+        captor.allValues.forEach { it.onAnimationEnd(mockAnimator) }
         verify(stateController).setExitAnimationsRunning(false)
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index f143c467..7b41605 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -376,6 +376,34 @@
         }
     }
 
+    @Test
+    public void testHomeControlsDoNotShowIfNotAvailable_featureEnabled() {
+        when(mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)).thenReturn(true);
+
+        final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+        stateController.setShouldShowComplications(true);
+
+        final Complication homeControlsComplication = Mockito.mock(Complication.class);
+        when(homeControlsComplication.getRequiredTypeAvailability())
+                .thenReturn(Complication.COMPLICATION_TYPE_HOME_CONTROLS);
+
+        stateController.addComplication(homeControlsComplication);
+
+        final DreamOverlayStateController.Callback callback =
+                Mockito.mock(DreamOverlayStateController.Callback.class);
+
+        stateController.addCallback(callback);
+        mExecutor.runAllReady();
+
+        // No home controls since it is not available.
+        assertThat(stateController.getComplications()).doesNotContain(homeControlsComplication);
+
+        stateController.setAvailableComplicationTypes(Complication.COMPLICATION_TYPE_HOME_CONTROLS
+                | Complication.COMPLICATION_TYPE_WEATHER);
+        mExecutor.runAllReady();
+        assertThat(stateController.getComplications()).contains(homeControlsComplication);
+    }
+
     private DreamOverlayStateController getDreamOverlayStateController(boolean overlayEnabled) {
         return new DreamOverlayStateController(mExecutor, overlayEnabled, mFeatureFlags);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
index 58eb7d4..e1c54976 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
@@ -18,7 +18,6 @@
 
 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.clearInvocations;
 import static org.mockito.Mockito.never;
@@ -26,13 +25,13 @@
 import static org.mockito.Mockito.when;
 
 import android.app.DreamManager;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
 import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.shared.condition.Condition;
 
@@ -55,6 +54,9 @@
     @Mock
     DreamManager mDreamManager;
 
+    @Mock
+    KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
@@ -66,7 +68,7 @@
     @Test
     public void testInitialDreamingState() {
         when(mDreamManager.isDreaming()).thenReturn(true);
-        final DreamCondition condition = new DreamCondition(mContext, mDreamManager);
+        final DreamCondition condition = new DreamCondition(mDreamManager, mKeyguardUpdateMonitor);
         condition.addCallback(mCallback);
 
         verify(mCallback).onConditionChanged(eq(condition));
@@ -79,7 +81,7 @@
     @Test
     public void testInitialNonDreamingState() {
         when(mDreamManager.isDreaming()).thenReturn(false);
-        final DreamCondition condition = new DreamCondition(mContext, mDreamManager);
+        final DreamCondition condition = new DreamCondition(mDreamManager, mKeyguardUpdateMonitor);
         condition.addCallback(mCallback);
 
         verify(mCallback, never()).onConditionChanged(eq(condition));
@@ -91,15 +93,21 @@
      */
     @Test
     public void testChange() {
-        final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
+        final ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCaptor =
+                ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
         when(mDreamManager.isDreaming()).thenReturn(true);
-        final DreamCondition condition = new DreamCondition(mContext, mDreamManager);
+        final DreamCondition condition = new DreamCondition(mDreamManager, mKeyguardUpdateMonitor);
         condition.addCallback(mCallback);
-        verify(mContext).registerReceiver(receiverCaptor.capture(), any());
+        verify(mKeyguardUpdateMonitor).registerCallback(callbackCaptor.capture());
+
         clearInvocations(mCallback);
-        receiverCaptor.getValue().onReceive(mContext, new Intent(Intent.ACTION_DREAMING_STOPPED));
+        callbackCaptor.getValue().onDreamingStateChanged(false);
         verify(mCallback).onConditionChanged(eq(condition));
         assertThat(condition.isConditionMet()).isFalse();
+
+        clearInvocations(mCallback);
+        callbackCaptor.getValue().onDreamingStateChanged(true);
+        verify(mCallback).onConditionChanged(eq(condition));
+        assertThat(condition.isConditionMet()).isTrue();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
index 8795ac0..c9ee1e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -70,6 +70,7 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.telephony.TelephonyListenerManager;
@@ -115,6 +116,7 @@
     @Mock private MetricsLogger mMetricsLogger;
     @Mock private SysuiColorExtractor mColorExtractor;
     @Mock private IStatusBarService mStatusBarService;
+    @Mock private LightBarController mLightBarController;
     @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
     @Mock private IWindowManager mWindowManager;
     @Mock private Executor mBackgroundExecutor;
@@ -166,6 +168,7 @@
                 mMetricsLogger,
                 mColorExtractor,
                 mStatusBarService,
+                mLightBarController,
                 mNotificationShadeWindowController,
                 mWindowManager,
                 mBackgroundExecutor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
index 6f9dedf..fae6375 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
@@ -18,9 +18,12 @@
 package com.android.systemui.keyboard.data.repository
 
 import android.hardware.input.InputManager
+import android.hardware.input.InputManager.KeyboardBacklightListener
+import android.hardware.input.KeyboardBacklightState
 import android.view.InputDevice
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.FlowValue
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
@@ -29,9 +32,11 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -50,6 +55,7 @@
 
     @Captor
     private lateinit var deviceListenerCaptor: ArgumentCaptor<InputManager.InputDeviceListener>
+    @Captor private lateinit var backlightListenerCaptor: ArgumentCaptor<KeyboardBacklightListener>
     @Mock private lateinit var inputManager: InputManager
 
     private lateinit var underTest: KeyboardRepository
@@ -174,7 +180,71 @@
 
     @Test
     fun passesKeyboardBacklightValues_fromBacklightListener() {
-        // TODO(b/268645734): implement when implementing backlight listener
+        testScope.runTest {
+            // we want to capture backlight listener but this can only be done after Flow is
+            // subscribed to and listener is actually registered in inputManager
+            val backlight by collectLastValueImmediately(underTest.backlight)
+
+            verify(inputManager)
+                .registerKeyboardBacklightListener(any(), backlightListenerCaptor.capture())
+
+            backlightListenerCaptor.value.onBacklightChanged(current = 1, max = 5)
+
+            assertThat(backlight?.level).isEqualTo(1)
+            assertThat(backlight?.maxLevel).isEqualTo(5)
+        }
+    }
+
+    private fun <T> TestScope.collectLastValueImmediately(flow: Flow<T>): FlowValue<T?> {
+        val lastValue = collectLastValue(flow)
+        // runCurrent() makes us wait for collect that happens in collectLastValue and ensures
+        // Flow is initialized
+        runCurrent()
+        return lastValue
+    }
+
+    @Test
+    fun keyboardBacklightValuesNotPassed_fromBacklightListener_whenNotTriggeredByKeyPress() {
+        testScope.runTest() {
+            val backlight by collectLastValueImmediately(underTest.backlight)
+            verify(inputManager)
+                .registerKeyboardBacklightListener(any(), backlightListenerCaptor.capture())
+
+            backlightListenerCaptor.value.onBacklightChanged(
+                current = 1,
+                max = 5,
+                triggeredByKeyPress = false
+            )
+            assertThat(backlight).isNull()
+        }
+    }
+
+    @Test
+    fun passesKeyboardBacklightValues_fromBacklightListener_whenTriggeredByKeyPress() {
+        testScope.runTest() {
+            val backlight by collectLastValueImmediately(underTest.backlight)
+            verify(inputManager)
+                .registerKeyboardBacklightListener(any(), backlightListenerCaptor.capture())
+
+            backlightListenerCaptor.value.onBacklightChanged(
+                current = 1,
+                max = 5,
+                triggeredByKeyPress = true
+            )
+            assertThat(backlight).isNotNull()
+        }
+    }
+
+    private fun KeyboardBacklightListener.onBacklightChanged(
+        current: Int,
+        max: Int,
+        triggeredByKeyPress: Boolean = true
+    ) {
+        onKeyboardBacklightChanged(
+            /* deviceId= */ 0,
+            TestBacklightState(current, max),
+            triggeredByKeyPress
+        )
     }
 
     private companion object {
@@ -199,4 +269,12 @@
                 whenever(it.isFullKeyboard).thenReturn(fullKeyboard)
             }
     }
+
+    private class TestBacklightState(
+        private val brightnessLevel: Int,
+        private val maxBrightnessLevel: Int
+    ) : KeyboardBacklightState() {
+        override fun getBrightnessLevel() = brightnessLevel
+        override fun getMaxBrightnessLevel() = maxBrightnessLevel
+    }
 }
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 c3b0e5226..d934f76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
@@ -23,9 +23,11 @@
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
 
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
@@ -88,6 +90,54 @@
     }
 
     @Test
+    public void onViewDetached_removesStatusBarStateListener() {
+        mController.onViewDetached();
+        verify(mStatusBarStateController).removeCallback(mStatusBarStateListener);
+    }
+
+    @Test
+    public void onViewDetached_removesAllScheduledIndications() {
+        // GIVEN show next indication runnable is set
+        final KeyguardIndicationRotateTextViewController.ShowNextIndication mockShowNextIndication =
+                mock(KeyguardIndicationRotateTextViewController.ShowNextIndication.class);
+        mController.mShowNextIndicationRunnable = mockShowNextIndication;
+
+        // WHEN the view is detached
+        mController.onViewDetached();
+
+        // THEN delayed execution is cancelled & runnable set to null
+        verify(mockShowNextIndication).cancelDelayedExecution();
+        assertNull(mController.mShowNextIndicationRunnable);
+    }
+
+    @Test
+    public void destroy_removesStatusBarStateListener() {
+        mController.destroy();
+        verify(mStatusBarStateController).removeCallback(mStatusBarStateListener);
+    }
+
+    @Test
+    public void destroy_removesOnAttachStateChangeListener() {
+        mController.destroy();
+        verify(mView).removeOnAttachStateChangeListener(any());
+    }
+
+    @Test
+    public void destroy_removesAllScheduledIndications() {
+        // GIVEN show next indication runnable is set
+        final KeyguardIndicationRotateTextViewController.ShowNextIndication mockShowNextIndication =
+                mock(KeyguardIndicationRotateTextViewController.ShowNextIndication.class);
+        mController.mShowNextIndicationRunnable = mockShowNextIndication;
+
+        // WHEN the controller is destroyed
+        mController.destroy();
+
+        // THEN delayed execution is cancelled & runnable set to null
+        verify(mockShowNextIndication).cancelDelayedExecution();
+        assertNull(mController.mShowNextIndicationRunnable);
+    }
+
+    @Test
     public void testInitialState_noIndication() {
         assertFalse(mController.hasIndications());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
index b9cfc65..e981d62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java
@@ -25,13 +25,11 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.IActivityTaskManager;
 import android.app.IApplicationThread;
 import android.app.ProfilerInfo;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
@@ -59,13 +57,14 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class WorkLockActivityControllerTest extends SysuiTestCase {
-    private static final int USER_ID = 333;
+    private static final int TASK_USER_ID = 333;
+    private static final int PROFILE_USER_ID = 555;
     private static final int TASK_ID = 444;
     private static final ActivityManager.RunningTaskInfo TASK_INFO =
             new ActivityManager.RunningTaskInfo();
 
     static {
-        TASK_INFO.userId = USER_ID;
+        TASK_INFO.userId = TASK_USER_ID;
         TASK_INFO.taskId = TASK_ID;
     }
 
@@ -101,10 +100,10 @@
         setActivityStartCode(TASK_ID, true /*taskOverlay*/, ActivityManager.START_SUCCESS);
 
         // And the controller receives a message saying the profile is locked,
-        mTaskStackListener.onTaskProfileLocked(TASK_INFO);
+        mTaskStackListener.onTaskProfileLocked(TASK_INFO, PROFILE_USER_ID);
 
         // The overlay should start and the task the activity started in should not be removed.
-        verifyStartActivity(TASK_ID, true /*taskOverlay*/);
+        verifyStartActivity(TASK_ID, true /*taskOverlay*/, PROFILE_USER_ID);
         verify(mIActivityTaskManager, never()).removeTask(anyInt() /*taskId*/);
     }
 
@@ -114,11 +113,11 @@
         setActivityStartCode(TASK_ID, true /*taskOverlay*/, ActivityManager.START_CLASS_NOT_FOUND);
 
         // And the controller receives a message saying the profile is locked,
-        mTaskStackListener.onTaskProfileLocked(TASK_INFO);
+        mTaskStackListener.onTaskProfileLocked(TASK_INFO, PROFILE_USER_ID);
 
         // The task the activity started in should be removed to prevent the locked task from
         // being shown.
-        verifyStartActivity(TASK_ID, true /*taskOverlay*/);
+        verifyStartActivity(TASK_ID, true /*taskOverlay*/, PROFILE_USER_ID);
         verify(mIActivityTaskManager).removeTask(TASK_ID);
     }
 
@@ -141,12 +140,13 @@
                 eq(ActivityManager.getCurrentUser()));
     }
 
-    private void verifyStartActivity(int taskId, boolean taskOverlay) throws Exception {
+    private void verifyStartActivity(int taskId, boolean taskOverlay, int profileUserId)
+            throws Exception {
         verify(mIActivityTaskManager).startActivityAsUser(
                 eq((IApplicationThread) null),
                 eq((String) null),
                 eq((String) null),
-                any(Intent.class),
+                argThat(hasUserId(profileUserId)),
                 eq((String) null),
                 eq((IBinder) null),
                 eq((String) null),
@@ -157,24 +157,15 @@
                 eq(ActivityManager.getCurrentUser()));
     }
 
-    private static ArgumentMatcher<Intent> hasComponent(final Context context,
-            final Class<? extends Activity> activityClass) {
-        return new ArgumentMatcher<Intent>() {
-            @Override
-            public boolean matches(Intent intent) {
-                return new ComponentName(context, activityClass).equals(intent.getComponent());
-            }
-        };
+    private static ArgumentMatcher<Intent> hasUserId(int userId) {
+        return intent -> intent.getIntExtra(Intent.EXTRA_USER_ID, -1) == userId;
     }
 
     private static ArgumentMatcher<Bundle> hasOptions(final int taskId, final boolean overlay) {
-        return new ArgumentMatcher<Bundle>() {
-            @Override
-            public boolean matches(Bundle item) {
-                final ActivityOptions options = ActivityOptions.fromBundle(item);
-                return (options.getLaunchTaskId() == taskId)
-                        && (options.getTaskOverlay() == overlay);
-            }
+        return item -> {
+            final ActivityOptions options = ActivityOptions.fromBundle(item);
+            return (options.getLaunchTaskId() == taskId)
+                    && (options.getTaskOverlay() == overlay);
         };
     }
 }
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 e20d3af..cfee3b8 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
@@ -23,6 +23,7 @@
 import android.content.pm.PackageManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.camera.CameraGestureHelper
 import com.android.systemui.settings.UserTracker
@@ -42,6 +43,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class CameraQuickAffordanceConfigTest : SysuiTestCase() {
 
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 c326a86..d84a4f7 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
@@ -26,6 +26,7 @@
 import androidx.test.filters.SmallTest
 import com.android.settingslib.notification.EnableZenModeDialog
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.ContentDescription
@@ -60,6 +61,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
index 0fb181d..13d1e64 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
@@ -17,6 +17,7 @@
 
 package com.android.systemui.keyguard.data.quickaffordance
 
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.animation.Expandable
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
 import kotlinx.coroutines.flow.Flow
@@ -24,6 +25,7 @@
 import kotlinx.coroutines.yield
 
 /** Fake implementation of a quick affordance data source. */
+@RoboPilotTest
 class FakeKeyguardQuickAffordanceConfig(
     override val key: String,
     override val pickerName: String = key,
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 292d067..b6dffff 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
@@ -21,6 +21,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
 import com.android.systemui.statusbar.policy.FlashlightController
@@ -41,6 +42,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class FlashlightQuickAffordanceConfigTest : LeakCheckedTest() {
 
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 26f0cdb..2fd4947 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
@@ -20,6 +20,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Expandable
 import com.android.systemui.controls.controller.ControlsController
@@ -40,6 +41,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
 
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 9a18ba8..9200d72 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
@@ -23,6 +23,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
@@ -48,6 +49,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceLegacySettingSyncerTest : SysuiTestCase() {
 
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 6989f44..bad4b36 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
@@ -23,6 +23,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.settings.UserFileManager
@@ -51,6 +52,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceLocalUserSelectionManagerTest : SysuiTestCase() {
 
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 a1c9f87..0797d07 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
@@ -21,6 +21,7 @@
 import android.os.UserHandle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
@@ -43,6 +44,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
index c38827a..d8c0341 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
@@ -19,7 +19,9 @@
 
 import android.content.Context
 import android.media.AudioManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
@@ -37,7 +39,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.times
 import org.mockito.Mockito.verify
@@ -45,7 +46,8 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RoboPilotTest
+@RunWith(AndroidJUnit4::class)
 class MuteQuickAffordanceConfigTest : SysuiTestCase() {
 
     private lateinit var underTest: MuteQuickAffordanceConfig
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 faf18d3..26c0ea4 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
@@ -20,6 +20,7 @@
 import android.content.Intent
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController
@@ -39,6 +40,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
 
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 952882d..111b8e8 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
@@ -23,6 +23,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.animation.Expandable
@@ -48,6 +49,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
 
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 a9b9c90..1414bac 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
@@ -21,6 +21,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.ActivityIntentHelper
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.camera.CameraIntentsWrapper
 import com.android.systemui.coroutines.collectLastValue
@@ -44,6 +45,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() {
 
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 726728a..1bab817 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
@@ -24,8 +24,8 @@
 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.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
@@ -33,6 +33,7 @@
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.coroutines.collectLastValue
@@ -69,8 +70,9 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class BiometricSettingsRepositoryTest : SysuiTestCase() {
     private lateinit var underTest: BiometricSettingsRepository
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index fa40fc4..d73c2c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -29,6 +29,7 @@
 import android.hardware.face.FaceSensorProperties
 import android.hardware.face.FaceSensorPropertiesInternal
 import android.os.CancellationSignal
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId.fakeInstanceId
 import com.android.internal.logging.UiEventLogger
@@ -36,6 +37,7 @@
 import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN
 import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.FlowValue
 import com.android.systemui.coroutines.collectLastValue
@@ -52,6 +54,7 @@
 import com.android.systemui.keyguard.shared.model.HelpAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.SuccessAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.keyguard.shared.model.WakeSleepReason
 import com.android.systemui.keyguard.shared.model.WakefulnessModel
@@ -65,6 +68,7 @@
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.util.mockito.KotlinArgumentCaptor
 import com.android.systemui.util.mockito.captureMany
+import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.systemui.util.time.SystemClock
@@ -81,7 +85,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.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.eq
@@ -98,7 +101,8 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RoboPilotTest
+@RunWith(AndroidJUnit4::class)
 class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
     private lateinit var underTest: DeviceEntryFaceAuthRepositoryImpl
 
@@ -191,8 +195,24 @@
         bypassControllerOverride: KeyguardBypassController? = bypassController
     ): DeviceEntryFaceAuthRepositoryImpl {
         val systemClock = FakeSystemClock()
-        val faceAuthBuffer = TableLogBuffer(10, "face auth", systemClock)
-        val faceDetectBuffer = TableLogBuffer(10, "face detect", systemClock)
+        val faceAuthBuffer =
+            TableLogBuffer(
+                10,
+                "face auth",
+                systemClock,
+                mock(),
+                testDispatcher,
+                testScope.backgroundScope
+            )
+        val faceDetectBuffer =
+            TableLogBuffer(
+                10,
+                "face detect",
+                systemClock,
+                mock(),
+                testDispatcher,
+                testScope.backgroundScope
+            )
         keyguardTransitionRepository = FakeKeyguardTransitionRepository()
         val keyguardTransitionInteractor =
             KeyguardTransitionInteractor(keyguardTransitionRepository)
@@ -215,6 +235,7 @@
             faceDetectBuffer,
             faceAuthBuffer,
             keyguardTransitionInteractor,
+            featureFlags,
             dumpManager,
         )
     }
@@ -593,6 +614,7 @@
             authStatus()
             detectStatus()
             authRunning()
+            bypassEnabled()
             lockedOut()
             canFaceAuthRun()
             authenticated()
@@ -828,7 +850,11 @@
     fun schedulesFaceManagerWatchdogWhenKeyguardIsGoneFromDozing() =
         testScope.runTest {
             keyguardTransitionRepository.sendTransitionStep(
-                TransitionStep(from = KeyguardState.DOZING, to = KeyguardState.GONE)
+                TransitionStep(
+                    from = KeyguardState.DOZING,
+                    to = KeyguardState.GONE,
+                    transitionState = TransitionState.FINISHED
+                )
             )
 
             runCurrent()
@@ -839,7 +865,11 @@
     fun schedulesFaceManagerWatchdogWhenKeyguardIsGoneFromAod() =
         testScope.runTest {
             keyguardTransitionRepository.sendTransitionStep(
-                TransitionStep(from = KeyguardState.AOD, to = KeyguardState.GONE)
+                TransitionStep(
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.GONE,
+                    transitionState = TransitionState.FINISHED
+                )
             )
 
             runCurrent()
@@ -850,7 +880,11 @@
     fun schedulesFaceManagerWatchdogWhenKeyguardIsGoneFromLockscreen() =
         testScope.runTest {
             keyguardTransitionRepository.sendTransitionStep(
-                TransitionStep(from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE)
+                TransitionStep(
+                    from = KeyguardState.LOCKSCREEN,
+                    to = KeyguardState.GONE,
+                    transitionState = TransitionState.FINISHED
+                )
             )
 
             runCurrent()
@@ -861,7 +895,11 @@
     fun schedulesFaceManagerWatchdogWhenKeyguardIsGoneFromBouncer() =
         testScope.runTest {
             keyguardTransitionRepository.sendTransitionStep(
-                TransitionStep(from = KeyguardState.PRIMARY_BOUNCER, to = KeyguardState.GONE)
+                TransitionStep(
+                    from = KeyguardState.PRIMARY_BOUNCER,
+                    to = KeyguardState.GONE,
+                    transitionState = TransitionState.FINISHED
+                )
             )
 
             runCurrent()
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 e57b044..264328b 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
@@ -18,9 +18,11 @@
 
 import android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT
 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
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.coroutines.collectLastValue
@@ -34,7 +36,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
@@ -44,7 +45,8 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RoboPilotTest
+@RunWith(AndroidJUnit4::class)
 class DeviceEntryFingerprintAuthRepositoryTest : SysuiTestCase() {
     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
     @Mock private lateinit var dumpManager: DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
index bd6b7a8..7eb8a26 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
@@ -16,7 +16,9 @@
 
 package com.android.systemui.keyguard.data.repository
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.shared.model.DevicePosture
@@ -29,7 +31,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
@@ -38,7 +39,8 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RoboPilotTest
+@RunWith(AndroidJUnit4::class)
 class DevicePostureRepositoryTest : SysuiTestCase() {
     private lateinit var underTest: DevicePostureRepository
     private lateinit var testScope: TestScope
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 12b8261..8dc04bd 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
@@ -22,6 +22,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
@@ -54,6 +55,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
 
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 b53a434..4b4c7e9 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
@@ -22,6 +22,7 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.common.shared.model.Position
@@ -63,6 +64,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardRepositoryImplTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
index 9daf3f3..f974577 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
@@ -17,7 +17,9 @@
 package com.android.systemui.keyguard.data.repository
 
 import android.graphics.Point
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
 import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
@@ -31,11 +33,11 @@
 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)
+@RoboPilotTest
+@RunWith(AndroidJUnit4::class)
 class LightRevealScrimRepositoryTest : SysuiTestCase() {
     private lateinit var fakeKeyguardRepository: FakeKeyguardRepository
     private lateinit var underTest: LightRevealScrimRepositoryImpl
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 a181137..bf3c73a 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
@@ -21,6 +21,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.logging.TrustRepositoryLogger
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.plugins.log.LogBuffer
@@ -43,6 +44,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class TrustRepositoryTest : SysuiTestCase() {
     @Mock private lateinit var trustManager: TrustManager
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 e7e5969..2180a8f 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
@@ -19,6 +19,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.ViewMediatorCallback
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
@@ -43,6 +44,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class AlternateBouncerInteractorTest : SysuiTestCase() {
     private lateinit var underTest: AlternateBouncerInteractor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt
new file mode 100644
index 0000000..069a486
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.doze.util.BurnInHelperWrapper
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertEquals
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+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.Mock
+import org.mockito.MockitoAnnotations
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BurnInInteractorTest : SysuiTestCase() {
+    private val burnInOffset = 7
+    private var burnInProgress = 0f
+
+    @Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper
+
+    private lateinit var configurationRepository: FakeConfigurationRepository
+    private lateinit var systemClock: FakeSystemClock
+    private lateinit var testScope: TestScope
+    private lateinit var underTest: BurnInInteractor
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        configurationRepository = FakeConfigurationRepository()
+        systemClock = FakeSystemClock()
+
+        whenever(burnInHelperWrapper.burnInOffset(anyInt(), anyBoolean())).thenReturn(burnInOffset)
+        setBurnInProgress(.65f)
+
+        testScope = TestScope()
+        underTest =
+            BurnInInteractor(
+                context,
+                burnInHelperWrapper,
+                testScope.backgroundScope,
+                configurationRepository,
+                systemClock,
+            )
+    }
+
+    @Test
+    fun dozeTimeTick_updatesOnDozeTimeTick() =
+        testScope.runTest {
+            // Initial state set to 0
+            val lastDozeTimeTick by collectLastValue(underTest.dozeTimeTick)
+            assertEquals(0L, lastDozeTimeTick)
+
+            // WHEN dozeTimeTick updated
+            incrementUptimeMillis()
+            underTest.dozeTimeTick()
+
+            // THEN listeners were updated to the latest uptime millis
+            assertThat(systemClock.uptimeMillis()).isEqualTo(lastDozeTimeTick)
+        }
+
+    @Test
+    fun udfpsBurnInOffset_updatesOnResolutionScaleChange() =
+        testScope.runTest {
+            val udfpsBurnInOffsetX by collectLastValue(underTest.udfpsBurnInXOffset)
+            val udfpsBurnInOffsetY by collectLastValue(underTest.udfpsBurnInYOffset)
+            assertThat(udfpsBurnInOffsetX).isEqualTo(burnInOffset)
+            assertThat(udfpsBurnInOffsetY).isEqualTo(burnInOffset)
+
+            configurationRepository.setScaleForResolution(3f)
+            assertThat(udfpsBurnInOffsetX).isEqualTo(burnInOffset * 3)
+            assertThat(udfpsBurnInOffsetY).isEqualTo(burnInOffset * 3)
+
+            configurationRepository.setScaleForResolution(.5f)
+            assertThat(udfpsBurnInOffsetX).isEqualTo(burnInOffset / 2)
+            assertThat(udfpsBurnInOffsetY).isEqualTo(burnInOffset / 2)
+        }
+
+    @Test
+    fun udfpsBurnInProgress_updatesOnDozeTimeTick() =
+        testScope.runTest {
+            val udfpsBurnInProgress by collectLastValue(underTest.udfpsBurnInProgress)
+            assertThat(udfpsBurnInProgress).isEqualTo(burnInProgress)
+
+            setBurnInProgress(.88f)
+            incrementUptimeMillis()
+            underTest.dozeTimeTick()
+            assertThat(udfpsBurnInProgress).isEqualTo(burnInProgress)
+
+            setBurnInProgress(.92f)
+            incrementUptimeMillis()
+            underTest.dozeTimeTick()
+            assertThat(udfpsBurnInProgress).isEqualTo(burnInProgress)
+
+            setBurnInProgress(.32f)
+            incrementUptimeMillis()
+            underTest.dozeTimeTick()
+            assertThat(udfpsBurnInProgress).isEqualTo(burnInProgress)
+        }
+
+    private fun incrementUptimeMillis() {
+        systemClock.setUptimeMillis(systemClock.uptimeMillis() + 5)
+    }
+
+    private fun setBurnInProgress(progress: Float) {
+        burnInProgress = progress
+        whenever(burnInHelperWrapper.burnInProgressOffset()).thenReturn(burnInProgress)
+    }
+}
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 68d694a..0d695aa 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
@@ -20,6 +20,7 @@
 import android.app.StatusBarManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.FakeFeatureFlags
@@ -39,6 +40,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardInteractorTest : SysuiTestCase() {
     private lateinit var commandQueue: FakeCommandQueue
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 8a0cf4f..dfef947 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
@@ -21,6 +21,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.FakeFeatureFlags
@@ -48,6 +49,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardLongPressInteractorTest : SysuiTestCase() {
 
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 23f0523..6e21c00 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
@@ -23,6 +23,7 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.R
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.common.shared.model.ContentDescription
@@ -71,6 +72,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
 
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 503687d..d66e420 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 com.android.systemui.RoboPilotTest
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -38,6 +39,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 @kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardTransitionInteractorTest : SysuiTestCase() {
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 fe65236..344df0ac 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
@@ -180,7 +180,7 @@
     }
 
     @Test
-    fun DREAMINGtoLOCKSCREEN() =
+    fun dreamingToLockscreen() =
         testScope.runTest {
             // GIVEN a device is dreaming
             keyguardRepository.setDreamingWithOverlay(true)
@@ -215,7 +215,7 @@
         }
 
     @Test
-    fun LOCKSCREENtoPRIMARY_BOUNCERviaBouncerShowingCall() =
+    fun lockscreenToPrimaryBouncerViaBouncerShowingCall() =
         testScope.runTest {
             // GIVEN a device that has at least woken up
             keyguardRepository.setWakefulnessModel(startingToWake())
@@ -242,7 +242,7 @@
         }
 
     @Test
-    fun OCCLUDEDtoDOZING() =
+    fun occludedToDozing() =
         testScope.runTest {
             // GIVEN a device with AOD not available
             keyguardRepository.setAodAvailable(false)
@@ -269,7 +269,7 @@
         }
 
     @Test
-    fun OCCLUDEDtoAOD() =
+    fun occludedToAod() =
         testScope.runTest {
             // GIVEN a device with AOD available
             keyguardRepository.setAodAvailable(true)
@@ -296,7 +296,7 @@
         }
 
     @Test
-    fun LOCKSCREENtoDREAMING() =
+    fun lockscreenToDreaming() =
         testScope.runTest {
             // GIVEN a device that is not dreaming or dozing
             keyguardRepository.setDreamingWithOverlay(false)
@@ -327,7 +327,7 @@
         }
 
     @Test
-    fun LOCKSCREENtoDOZING() =
+    fun lockscreenToDozing() =
         testScope.runTest {
             // GIVEN a device with AOD not available
             keyguardRepository.setAodAvailable(false)
@@ -354,7 +354,7 @@
         }
 
     @Test
-    fun LOCKSCREENtoAOD() =
+    fun lockscreenToAod() =
         testScope.runTest {
             // GIVEN a device with AOD available
             keyguardRepository.setAodAvailable(true)
@@ -381,7 +381,7 @@
         }
 
     @Test
-    fun DOZINGtoLOCKSCREEN() =
+    fun dozingToLockscreen() =
         testScope.runTest {
             // GIVEN a prior transition has run to DOZING
             runTransition(KeyguardState.LOCKSCREEN, KeyguardState.DOZING)
@@ -404,7 +404,7 @@
         }
 
     @Test
-    fun DOZINGtoLOCKSCREENcannotBeInterrupedByDREAMING() =
+    fun dozingToLockscreenCannotBeInterruptedByDreaming() =
         testScope.runTest {
             // GIVEN a prior transition has started to LOCKSCREEN
             transitionRepository.sendTransitionStep(
@@ -430,7 +430,7 @@
         }
 
     @Test
-    fun DOZINGtoGONE() =
+    fun dozingToGone() =
         testScope.runTest {
             // GIVEN a prior transition has run to DOZING
             runTransition(KeyguardState.LOCKSCREEN, KeyguardState.DOZING)
@@ -453,7 +453,7 @@
         }
 
     @Test
-    fun GONEtoDOZING() =
+    fun goneToDozing() =
         testScope.runTest {
             // GIVEN a device with AOD not available
             keyguardRepository.setAodAvailable(false)
@@ -480,7 +480,7 @@
         }
 
     @Test
-    fun GONEtoAOD() =
+    fun goneToAod() =
         testScope.runTest {
             // GIVEN a device with AOD available
             keyguardRepository.setAodAvailable(true)
@@ -507,7 +507,7 @@
         }
 
     @Test
-    fun GONEtoLOCKSREEN() =
+    fun goneToLockscreen() =
         testScope.runTest {
             // GIVEN a prior transition has run to GONE
             runTransition(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
@@ -530,7 +530,7 @@
         }
 
     @Test
-    fun GONEtoDREAMING() =
+    fun goneToDreaming() =
         testScope.runTest {
             // GIVEN a device that is not dreaming or dozing
             keyguardRepository.setDreamingWithOverlay(false)
@@ -561,7 +561,7 @@
         }
 
     @Test
-    fun ALTERNATE_BOUNCERtoPRIMARY_BOUNCER() =
+    fun alternateBouncerToPrimaryBouncer() =
         testScope.runTest {
             // GIVEN a prior transition has run to ALTERNATE_BOUNCER
             runTransition(KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER)
@@ -584,7 +584,7 @@
         }
 
     @Test
-    fun ALTERNATE_BOUNCERtoAOD() =
+    fun alternateBoucnerToAod() =
         testScope.runTest {
             // GIVEN a prior transition has run to ALTERNATE_BOUNCER
             bouncerRepository.setAlternateVisible(true)
@@ -613,7 +613,7 @@
         }
 
     @Test
-    fun ALTERNATE_BOUNCERtoDOZING() =
+    fun alternateBouncerToDozing() =
         testScope.runTest {
             // GIVEN a prior transition has run to ALTERNATE_BOUNCER
             bouncerRepository.setAlternateVisible(true)
@@ -643,7 +643,7 @@
         }
 
     @Test
-    fun ALTERNATE_BOUNCERtoLOCKSCREEN() =
+    fun alternateBouncerToLockscreen() =
         testScope.runTest {
             // GIVEN a prior transition has run to ALTERNATE_BOUNCER
             bouncerRepository.setAlternateVisible(true)
@@ -671,7 +671,7 @@
         }
 
     @Test
-    fun PRIMARY_BOUNCERtoAOD() =
+    fun primaryBouncerToAod() =
         testScope.runTest {
             // GIVEN a prior transition has run to PRIMARY_BOUNCER
             bouncerRepository.setPrimaryShow(true)
@@ -699,7 +699,7 @@
         }
 
     @Test
-    fun PRIMARY_BOUNCERtoDOZING() =
+    fun primaryBouncerToDozing() =
         testScope.runTest {
             // GIVEN a prior transition has run to PRIMARY_BOUNCER
             bouncerRepository.setPrimaryShow(true)
@@ -727,7 +727,7 @@
         }
 
     @Test
-    fun PRIMARY_BOUNCERtoLOCKSCREEN() =
+    fun primaryBouncerToLockscreen() =
         testScope.runTest {
             // GIVEN a prior transition has run to PRIMARY_BOUNCER
             bouncerRepository.setPrimaryShow(true)
@@ -754,7 +754,7 @@
         }
 
     @Test
-    fun OCCLUDEDtoGONE() =
+    fun occludedToGone() =
         testScope.runTest {
             // GIVEN a device on lockscreen
             keyguardRepository.setKeyguardShowing(true)
@@ -785,7 +785,7 @@
         }
 
     @Test
-    fun OCCLUDEDtoLOCKSCREEN() =
+    fun occludedToLockscreen() =
         testScope.runTest {
             // GIVEN a device on lockscreen
             keyguardRepository.setKeyguardShowing(true)
@@ -813,6 +813,61 @@
             coroutineContext.cancelChildren()
         }
 
+    @Test
+    fun occludedToAlternateBouncer() =
+        testScope.runTest {
+
+            // GIVEN a prior transition has run to OCCLUDED
+            runTransition(KeyguardState.LOCKSCREEN, KeyguardState.OCCLUDED)
+            keyguardRepository.setKeyguardOccluded(true)
+            runCurrent()
+
+            // WHEN alternate bouncer shows
+            bouncerRepository.setAlternateVisible(true)
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
+                }
+            // THEN a transition to AlternateBouncer should occur
+            assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.OCCLUDED)
+            assertThat(info.to).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun primaryBouncerToOccluded() =
+        testScope.runTest {
+            // GIVEN device not sleeping
+            keyguardRepository.setWakefulnessModel(startingToWake())
+
+            // GIVEN a prior transition has run to PRIMARY_BOUNCER
+            runTransition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER)
+            bouncerRepository.setPrimaryShow(true)
+            runCurrent()
+
+            // WHEN the keyguard is occluded and primary bouncer stops showing
+            keyguardRepository.setKeyguardOccluded(true)
+            bouncerRepository.setPrimaryShow(false)
+            runCurrent()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
+                }
+            // THEN a transition to AlternateBouncer should occur
+            assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+            assertThat(info.to).isEqualTo(KeyguardState.OCCLUDED)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
     private fun startingToWake() =
         WakefulnessModel(
             WakefulnessState.STARTING_TO_WAKE,
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 359854b..4440946 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
@@ -18,6 +18,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.FakeLightRevealScrimRepository
@@ -37,6 +38,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class LightRevealScrimInteractorTest : SysuiTestCase() {
     private val fakeKeyguardTransitionRepository = FakeKeyguardTransitionRepository()
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 f86ac79..2b135cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
@@ -19,6 +19,7 @@
 import android.view.View
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Before
 import org.junit.Test
@@ -28,6 +29,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerCallbackInteractorTest : SysuiTestCase() {
     private val mPrimaryBouncerCallbackInteractor = PrimaryBouncerCallbackInteractor()
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 edac468..e35e971 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
@@ -21,6 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.coroutines.collectLastValue
@@ -39,6 +40,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() {
     private lateinit var repository: FakeKeyguardBouncerRepository
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 706154e..cdd06ac 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
@@ -18,6 +18,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -36,6 +37,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: DreamingToLockscreenTransitionViewModel
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 b15ce10..40511a0 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
@@ -18,6 +18,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -35,6 +36,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class GoneToDreamingTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: GoneToDreamingTransitionViewModel
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 9cd2220..0e9c99e 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
@@ -21,6 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.keyguard.DismissCallbackRegistry
@@ -44,6 +45,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 @kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardBouncerViewModelTest : SysuiTestCase() {
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 d94c108..c98058d 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
@@ -18,6 +18,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -35,6 +36,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class LockscreenToDreamingTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: LockscreenToDreamingTransitionViewModel
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 12ec24d..031b7fb 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
@@ -18,6 +18,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -35,6 +36,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class LockscreenToOccludedTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: LockscreenToOccludedTransitionViewModel
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 efa5f0c..c7ff882 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
@@ -18,6 +18,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -35,6 +36,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: OccludedToLockscreenTransitionViewModel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
index 98794fd..db251a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
@@ -18,6 +18,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -41,6 +42,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RoboPilotTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: PrimaryBouncerToGoneTransitionViewModel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/FakeLogProxy.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/FakeLogProxy.kt
new file mode 100644
index 0000000..471c461
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/FakeLogProxy.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.log.table
+
+/**
+ * Fake [LogProxy] that collects all lines sent to it. Mimics the ADB logcat format without the
+ * timestamp. [FakeLogProxy.d] will write a log like so:
+ * ```
+ * logger.d("TAG", "message here")
+ * // writes this to the [logs] field
+ * "D TAG: message here"
+ * ```
+ *
+ * Logs sent to this class are collected as a list of strings for simple test assertions.
+ */
+class FakeLogProxy : LogProxy {
+    val logs: MutableList<String> = mutableListOf()
+
+    override fun v(tag: String, message: String) {
+        logs.add("V $tag: $message")
+    }
+
+    override fun d(tag: String, message: String) {
+        logs.add("D $tag: $message")
+    }
+
+    override fun i(tag: String, message: String) {
+        logs.add("I $tag: $message")
+    }
+
+    override fun w(tag: String, message: String) {
+        logs.add("W $tag: $message")
+    }
+
+    override fun e(tag: String, message: String) {
+        logs.add("E $tag: $message")
+    }
+
+    override fun wtf(tag: String, message: String) {
+        logs.add("WTF $tag: $message")
+    }
+}
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 c49337a..1d182cf 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
@@ -19,6 +19,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableChange.Companion.IS_INITIAL_PREFIX
+import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import java.io.PrintWriter
@@ -39,7 +40,8 @@
 @OptIn(ExperimentalCoroutinesApi::class)
 class LogDiffsForTableTest : SysuiTestCase() {
 
-    private val testScope = TestScope(UnconfinedTestDispatcher())
+    private val testDispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
 
     private lateinit var systemClock: FakeSystemClock
     private lateinit var tableLogBuffer: TableLogBuffer
@@ -47,7 +49,15 @@
     @Before
     fun setUp() {
         systemClock = FakeSystemClock()
-        tableLogBuffer = TableLogBuffer(MAX_SIZE, BUFFER_NAME, systemClock)
+        tableLogBuffer =
+            TableLogBuffer(
+                MAX_SIZE,
+                BUFFER_NAME,
+                systemClock,
+                mock(),
+                testDispatcher,
+                testScope.backgroundScope,
+            )
     }
 
     // ---- Flow<Boolean> tests ----
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 a003e1d..43e430f 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
@@ -19,7 +19,9 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableChange.Companion.IS_INITIAL_PREFIX
+import com.android.systemui.log.table.TableChange.Companion.MAX_STRING_LENGTH
 import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertTrue
 import org.junit.Test
 
 @SmallTest
@@ -326,4 +328,152 @@
 
         assertThat(underTest.getVal()).doesNotContain(IS_INITIAL_PREFIX)
     }
+
+    @Test
+    fun constructor_columnAndValueTooLong_truncated() {
+        val underTest =
+            TableChange(
+                columnPrefix = "P".repeat(MAX_STRING_LENGTH + 10),
+                columnName = "N".repeat(MAX_STRING_LENGTH + 10),
+                type = TableChange.DataType.STRING,
+                str = "V".repeat(MAX_STRING_LENGTH + 10),
+            )
+
+        assertThat(underTest.getName()).contains("P".repeat(MAX_STRING_LENGTH))
+        assertThat(underTest.getName()).doesNotContain("P".repeat(MAX_STRING_LENGTH + 1))
+        assertThat(underTest.getName()).contains("N".repeat(MAX_STRING_LENGTH))
+        assertThat(underTest.getName()).doesNotContain("N".repeat(MAX_STRING_LENGTH + 1))
+        assertThat(underTest.getVal()).isEqualTo("V".repeat(MAX_STRING_LENGTH))
+    }
+
+    @Test
+    fun constructor_columnNameNotTooLong_noReallocation() {
+        val inputColumnName = "fakeName"
+        val inputValue = "fakeValue"
+        val underTest =
+            TableChange(
+                columnPrefix = "",
+                columnName = inputColumnName,
+                type = TableChange.DataType.STRING,
+                str = inputValue,
+            )
+
+        // Use referential equality to verify we didn't reallocate a new string when the string is
+        // *not* too long.
+        assertTrue(underTest.getColumnName() === inputColumnName)
+    }
+
+    @Test
+    fun reset_columnPrefixTooLong_truncated() {
+        val underTest = TableChange()
+
+        underTest.reset(
+            timestamp = 1L,
+            columnPrefix = "P".repeat(MAX_STRING_LENGTH + 10),
+            columnName = "name",
+            isInitial = false,
+        )
+
+        assertThat(underTest.getName()).contains("P".repeat(MAX_STRING_LENGTH))
+        assertThat(underTest.getName()).doesNotContain("P".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
+    fun reset_columnNameTooLong_truncated() {
+        val underTest = TableChange()
+
+        underTest.reset(
+            timestamp = 1L,
+            columnPrefix = "prefix",
+            columnName = "N".repeat(MAX_STRING_LENGTH + 10),
+            isInitial = false,
+        )
+
+        assertThat(underTest.getName()).contains("N".repeat(MAX_STRING_LENGTH))
+        assertThat(underTest.getName()).doesNotContain("N".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
+    fun reset_columnNameNotTooLong_noReallocation() {
+        val underTest = TableChange()
+        val shortColumnName = "shortColumnName"
+
+        underTest.reset(
+            timestamp = 1L,
+            columnPrefix = "prefix",
+            columnName = shortColumnName,
+            isInitial = false,
+        )
+
+        // Use referential equality to verify we didn't reallocate a new string when the string is
+        // *not* too long.
+        assertTrue(underTest.getColumnName() === shortColumnName)
+    }
+
+    @Test
+    fun setString_valueTooLong_truncated() {
+        val underTest = TableChange()
+
+        underTest.set("V".repeat(MAX_STRING_LENGTH + 1))
+
+        assertThat(underTest.getVal()).isEqualTo("V".repeat(MAX_STRING_LENGTH))
+    }
+
+    @Test
+    fun updateTo_newColumnPrefixTooLong_truncated() {
+        val underTest = TableChange(columnPrefix = "fakePrefix", columnName = "fakeName")
+        underTest.set(42)
+
+        val new =
+            TableChange(
+                columnPrefix = "P".repeat(MAX_STRING_LENGTH + 10),
+                columnName = "name",
+            )
+        underTest.updateTo(new)
+
+        assertThat(underTest.getName()).contains("P".repeat(MAX_STRING_LENGTH))
+        assertThat(underTest.getName()).doesNotContain("P".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
+    fun updateTo_newColumnNameTooLong_truncated() {
+        val underTest = TableChange(columnPrefix = "fakePrefix", columnName = "fakeName")
+        underTest.set(42)
+
+        val new =
+            TableChange(
+                columnPrefix = "prefix",
+                columnName = "N".repeat(MAX_STRING_LENGTH + 10),
+            )
+        underTest.updateTo(new)
+
+        assertThat(underTest.getName()).contains("N".repeat(MAX_STRING_LENGTH))
+        assertThat(underTest.getName()).doesNotContain("N".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
+    fun updateTo_columnNameNotTooLong_noReallocation() {
+        val underTest = TableChange()
+        val shortColumnName = "shortColumnName"
+        val new = TableChange(columnPrefix = "prefix", columnName = shortColumnName)
+
+        underTest.updateTo(new)
+
+        // Use referential equality to verify we didn't reallocate a new string when the string is
+        // *not* too long.
+        assertTrue(underTest.getColumnName() === shortColumnName)
+    }
+
+    @Test
+    fun updateTo_newValTooLong_truncated() {
+        val underTest = TableChange(columnPrefix = "fakePrefix", columnName = "fakeName")
+        underTest.set("value")
+
+        val new = TableChange()
+        new.set("V".repeat(MAX_STRING_LENGTH + 10))
+
+        underTest.updateTo(new)
+
+        assertThat(underTest.getVal()).isEqualTo("V".repeat(MAX_STRING_LENGTH))
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
index af83a56..8ba7643 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
@@ -22,13 +22,20 @@
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import org.junit.Test
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class TableLogBufferFactoryTest : SysuiTestCase() {
     private val dumpManager: DumpManager = mock()
     private val systemClock = FakeSystemClock()
-    private val underTest = TableLogBufferFactory(dumpManager, systemClock)
+    private val testDispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
+    private val underTest =
+        TableLogBufferFactory(dumpManager, systemClock, mock(), testDispatcher, testScope)
 
     @Test
     fun create_alwaysCreatesNewInstance() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt
index aed830a..f867fc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt
@@ -19,31 +19,67 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableChange.Companion.IS_INITIAL_PREFIX
+import com.android.systemui.log.table.TableChange.Companion.MAX_STRING_LENGTH
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.plugins.log.LogcatEchoTracker
+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.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import org.junit.Before
 import org.junit.Test
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class TableLogBufferTest : SysuiTestCase() {
     private lateinit var underTest: TableLogBuffer
 
     private lateinit var systemClock: FakeSystemClock
     private lateinit var outputWriter: StringWriter
+    private lateinit var logcatEchoTracker: LogcatEchoTracker
+    private lateinit var localLogcat: FakeLogProxy
+
+    private val testDispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
 
     @Before
     fun setup() {
+        localLogcat = FakeLogProxy()
+        logcatEchoTracker = mock()
         systemClock = FakeSystemClock()
         outputWriter = StringWriter()
 
-        underTest = TableLogBuffer(MAX_SIZE, NAME, systemClock)
+        underTest =
+            TableLogBuffer(
+                MAX_SIZE,
+                NAME,
+                systemClock,
+                logcatEchoTracker,
+                testDispatcher,
+                testScope.backgroundScope,
+                localLogcat = localLogcat,
+            )
+        underTest.init()
     }
 
     @Test(expected = IllegalArgumentException::class)
     fun maxSizeZero_throwsException() {
-        TableLogBuffer(maxSize = 0, "name", systemClock)
+        TableLogBuffer(
+            maxSize = 0,
+            "name",
+            systemClock,
+            logcatEchoTracker,
+            testDispatcher,
+            testScope.backgroundScope,
+            localLogcat = localLogcat,
+        )
     }
 
     @Test
@@ -541,6 +577,112 @@
     }
 
     @Test
+    fun dumpChanges_tooLongColumnPrefix_viaLogChange_truncated() {
+        underTest.logChange(
+            prefix = "P".repeat(MAX_STRING_LENGTH + 10),
+            columnName = "name",
+            value = true,
+        )
+
+        val dumpedString = dumpChanges()
+
+        assertThat(dumpedString).contains("P".repeat(MAX_STRING_LENGTH))
+        assertThat(dumpedString).doesNotContain("P".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
+    fun dumpChanges_tooLongColumnPrefix_viaLogDiffs_truncated() {
+        val prevDiffable = object : TestDiffable() {}
+        val nextDiffable =
+            object : TestDiffable() {
+                override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) {
+                    row.logChange("status", "value")
+                }
+            }
+
+        // WHEN the column prefix is too large
+        underTest.logDiffs(
+            columnPrefix = "P".repeat(MAX_STRING_LENGTH + 10),
+            prevDiffable,
+            nextDiffable,
+        )
+
+        val dumpedString = dumpChanges()
+
+        // THEN it's truncated to the max length
+        assertThat(dumpedString).contains("P".repeat(MAX_STRING_LENGTH))
+        assertThat(dumpedString).doesNotContain("P".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
+    fun dumpChanges_tooLongColumnName_viaLogChange_truncated() {
+        underTest.logChange(
+            prefix = "prefix",
+            columnName = "N".repeat(MAX_STRING_LENGTH + 10),
+            value = 10,
+        )
+
+        val dumpedString = dumpChanges()
+
+        assertThat(dumpedString).contains("N".repeat(MAX_STRING_LENGTH))
+        assertThat(dumpedString).doesNotContain("N".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
+    fun dumpChanges_tooLongColumnName_viaLogDiffs_truncated() {
+        val prevDiffable = object : TestDiffable() {}
+        val nextDiffable =
+            object : TestDiffable() {
+                override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) {
+                    // WHEN the column name is too large
+                    row.logChange(columnName = "N".repeat(MAX_STRING_LENGTH + 10), "value")
+                }
+            }
+
+        underTest.logDiffs(columnPrefix = "prefix", prevDiffable, nextDiffable)
+
+        val dumpedString = dumpChanges()
+
+        // THEN it's truncated to the max length
+        assertThat(dumpedString).contains("N".repeat(MAX_STRING_LENGTH))
+        assertThat(dumpedString).doesNotContain("N".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
+    fun dumpChanges_tooLongValue_viaLogChange_truncated() {
+        underTest.logChange(
+            prefix = "prefix",
+            columnName = "name",
+            value = "V".repeat(MAX_STRING_LENGTH + 10),
+        )
+
+        val dumpedString = dumpChanges()
+
+        assertThat(dumpedString).contains("V".repeat(MAX_STRING_LENGTH))
+        assertThat(dumpedString).doesNotContain("V".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
+    fun dumpChanges_tooLongValue_viaLogDiffs_truncated() {
+        val prevDiffable = object : TestDiffable() {}
+        val nextDiffable =
+            object : TestDiffable() {
+                override fun logDiffs(prevVal: TestDiffable, row: TableRowLogger) {
+                    // WHEN the value is too large
+                    row.logChange("columnName", value = "V".repeat(MAX_STRING_LENGTH + 10))
+                }
+            }
+
+        underTest.logDiffs(columnPrefix = "prefix", prevDiffable, nextDiffable)
+
+        val dumpedString = dumpChanges()
+
+        // THEN it's truncated to the max length
+        assertThat(dumpedString).contains("V".repeat(MAX_STRING_LENGTH))
+        assertThat(dumpedString).doesNotContain("V".repeat(MAX_STRING_LENGTH + 1))
+    }
+
+    @Test
     fun dumpChanges_rotatesIfBufferIsFull() {
         lateinit var valToDump: String
 
@@ -791,6 +933,112 @@
         assertThat(dumpedString).contains(evictedColumnLog3)
     }
 
+    @Test
+    fun logcat_bufferNotLoggable_tagNotLoggable_noEcho() {
+        whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(false)
+        whenever(logcatEchoTracker.isTagLoggable(eq("columnName"), any())).thenReturn(false)
+
+        underTest.logChange("prefix", "columnName", true)
+
+        assertThat(localLogcat.logs).isEmpty()
+    }
+
+    @Test
+    fun logcat_bufferIsLoggable_tagNotLoggable_echoes() {
+        whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(true)
+        whenever(logcatEchoTracker.isTagLoggable(eq("columnName"), any())).thenReturn(false)
+
+        underTest.logChange("prefix", "columnName", true)
+
+        assertThat(localLogcat.logs).hasSize(1)
+    }
+
+    @Test
+    fun logcat_bufferNotLoggable_tagIsLoggable_echoes() {
+        whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(false)
+        whenever(logcatEchoTracker.isTagLoggable(eq("columnName"), any())).thenReturn(true)
+
+        underTest.logChange("prefix", "columnName", true)
+
+        assertThat(localLogcat.logs).hasSize(1)
+    }
+
+    @Test
+    fun logcat_echoesDebugLogs_debugDisabled_noEcho() {
+        // Allow any log other than debug
+        whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenAnswer { invocation ->
+            (invocation.getArgument(1) as LogLevel) != LogLevel.DEBUG
+        }
+
+        underTest.logChange("prefix", "columnName", true)
+
+        assertThat(localLogcat.logs).isEmpty()
+    }
+
+    @Test
+    fun logcat_echoesDebugLogs_debugEnabled_echoes() {
+        // Only allow debug logs
+        whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), eq(LogLevel.DEBUG))).thenReturn(true)
+
+        underTest.logChange("prefix", "columnName", true)
+
+        assertThat(localLogcat.logs).hasSize(1)
+    }
+
+    @Test
+    fun logcat_bufferNotLoggable_tagIsLoggable_usesColNameForTagCheck() {
+        systemClock.setCurrentTimeMillis(1000L)
+
+        val nonLoggingTag = "nonLoggingColName"
+        val loggingTag = "loggingColName"
+
+        whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(false)
+        whenever(logcatEchoTracker.isTagLoggable(eq(loggingTag), eq(LogLevel.DEBUG)))
+            .thenReturn(true)
+        whenever(logcatEchoTracker.isTagLoggable(eq(nonLoggingTag), eq(LogLevel.DEBUG)))
+            .thenReturn(false)
+
+        underTest.logChange("", nonLoggingTag, true)
+        underTest.logChange("", loggingTag, true)
+
+        assertThat(localLogcat.logs).hasSize(1)
+
+        val timestamp = TABLE_LOG_DATE_FORMAT.format(1000L)
+        val expectedMessage = "${timestamp}${SEPARATOR}${loggingTag}${SEPARATOR}true"
+        val expectedLine = "D $NAME: $expectedMessage"
+
+        assertThat(localLogcat.logs[0]).isEqualTo(expectedLine)
+    }
+
+    @Test
+    fun logcat_bufferLoggable_multipleMessagesAreEchoed() {
+        systemClock.setCurrentTimeMillis(1000L)
+        whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(true)
+
+        val col1 = "column1"
+        val col2 = "column2"
+
+        // Log a couple of columns that flip bits
+        underTest.logChange("", col1, true)
+        underTest.logChange("", col2, false)
+        underTest.logChange("", col1, false)
+        underTest.logChange("", col2, true)
+
+        assertThat(localLogcat.logs).hasSize(4)
+
+        val timestamp = TABLE_LOG_DATE_FORMAT.format(1000L)
+        val msg1 = "${timestamp}${SEPARATOR}${col1}${SEPARATOR}true"
+        val msg2 = "${timestamp}${SEPARATOR}${col2}${SEPARATOR}false"
+        val msg3 = "${timestamp}${SEPARATOR}${col1}${SEPARATOR}false"
+        val msg4 = "${timestamp}${SEPARATOR}${col2}${SEPARATOR}true"
+        val expected = listOf(msg1, msg2, msg3, msg4).map { "D $NAME: $it" }
+
+        // Logs use the same bg dispatcher for writing to logcat, they should be in order
+        for ((msg, logLine) in expected zip localLogcat.logs) {
+            assertThat(logLine).isEqualTo(msg)
+        }
+    }
+
     private fun dumpChanges(): String {
         underTest.dump(PrintWriter(outputWriter), arrayOf())
         return outputWriter.toString()
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 0a1db60..d428db7b 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,7 +40,6 @@
 import androidx.media.utils.MediaConstants
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
-import com.android.internal.statusbar.IStatusBarService
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.InstanceIdSequenceFake
 import com.android.systemui.R
@@ -131,7 +130,6 @@
     @Mock lateinit var activityStarter: ActivityStarter
     @Mock lateinit var smartspaceManager: SmartspaceManager
     @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
-    @Mock lateinit var statusBarService: IStatusBarService
     lateinit var smartspaceMediaDataProvider: SmartspaceMediaDataProvider
     @Mock lateinit var mediaSmartspaceTarget: SmartspaceTarget
     @Mock private lateinit var mediaRecommendationItem: SmartspaceAction
@@ -194,8 +192,7 @@
                 mediaFlags = mediaFlags,
                 logger = logger,
                 smartspaceManager = smartspaceManager,
-                keyguardUpdateMonitor = keyguardUpdateMonitor,
-                statusBarService = statusBarService,
+                keyguardUpdateMonitor = keyguardUpdateMonitor
             )
         verify(tunerService)
             .addTunable(capture(tunableCaptor), eq(Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION))
@@ -520,136 +517,19 @@
     }
 
     @Test
-    fun testOnNotificationAdded_emptyTitle_notLoaded() {
-        // GIVEN that the manager has a notification with an empty title.
+    fun testOnNotificationRemoved_emptyTitle_notConverted() {
+        // GIVEN that the manager has a notification with a resume action and empty title.
         whenever(controller.metadata)
             .thenReturn(
                 metadataBuilder
                     .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_EMPTY_TITLE)
                     .build()
             )
-        mediaDataManager.onNotificationAdded(KEY, mediaNotification)
-
-        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
-        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
-        verify(statusBarService)
-            .onNotificationError(
-                eq(PACKAGE_NAME),
-                eq(mediaNotification.tag),
-                eq(mediaNotification.id),
-                eq(mediaNotification.uid),
-                eq(mediaNotification.initialPid),
-                eq(MEDIA_TITLE_ERROR_MESSAGE),
-                eq(mediaNotification.user.identifier)
-            )
-        verify(listener, never())
-            .onMediaDataLoaded(
-                eq(KEY),
-                eq(null),
-                capture(mediaDataCaptor),
-                eq(true),
-                eq(0),
-                eq(false)
-            )
-        verify(logger, never()).logResumeMediaAdded(anyInt(), eq(PACKAGE_NAME), any())
-        verify(logger, never()).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), any())
-    }
-
-    @Test
-    fun testOnNotificationAdded_blankTitle_notLoaded() {
-        // GIVEN that the manager has a notification with a blank title.
-        whenever(controller.metadata)
-            .thenReturn(
-                metadataBuilder
-                    .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_BLANK_TITLE)
-                    .build()
-            )
-        mediaDataManager.onNotificationAdded(KEY, mediaNotification)
-
-        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
-        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
-        verify(statusBarService)
-            .onNotificationError(
-                eq(PACKAGE_NAME),
-                eq(mediaNotification.tag),
-                eq(mediaNotification.id),
-                eq(mediaNotification.uid),
-                eq(mediaNotification.initialPid),
-                eq(MEDIA_TITLE_ERROR_MESSAGE),
-                eq(mediaNotification.user.identifier)
-            )
-        verify(listener, never())
-            .onMediaDataLoaded(
-                eq(KEY),
-                eq(null),
-                capture(mediaDataCaptor),
-                eq(true),
-                eq(0),
-                eq(false)
-            )
-        verify(logger, never()).logResumeMediaAdded(anyInt(), eq(PACKAGE_NAME), any())
-        verify(logger, never()).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), any())
-    }
-
-    @Test
-    fun testOnNotificationUpdated_invalidTitle_logMediaRemoved() {
-        addNotificationAndLoad()
-        val data = mediaDataCaptor.value
-
-        verify(listener)
-            .onMediaDataLoaded(
-                eq(KEY),
-                eq(null),
-                capture(mediaDataCaptor),
-                eq(true),
-                eq(0),
-                eq(false)
-            )
-
-        reset(listener)
-        whenever(controller.metadata)
-            .thenReturn(
-                metadataBuilder
-                    .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_BLANK_TITLE)
-                    .build()
-            )
-        mediaDataManager.onNotificationAdded(KEY, mediaNotification)
-        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
-        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
-        verify(statusBarService)
-            .onNotificationError(
-                eq(PACKAGE_NAME),
-                eq(mediaNotification.tag),
-                eq(mediaNotification.id),
-                eq(mediaNotification.uid),
-                eq(mediaNotification.initialPid),
-                eq(MEDIA_TITLE_ERROR_MESSAGE),
-                eq(mediaNotification.user.identifier)
-            )
-        verify(listener, never())
-            .onMediaDataLoaded(
-                eq(KEY),
-                eq(null),
-                capture(mediaDataCaptor),
-                eq(true),
-                eq(0),
-                eq(false)
-            )
-        verify(logger).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), eq(data.instanceId))
-    }
-
-    @Test
-    fun testOnNotificationRemoved_emptyTitle_notConverted() {
-        // GIVEN that the manager has a notification with a resume action and empty title.
         addNotificationAndLoad()
         val data = mediaDataCaptor.value
         val instanceId = data.instanceId
         assertThat(data.resumption).isFalse()
-        mediaDataManager.onMediaDataLoaded(
-            KEY,
-            null,
-            data.copy(song = SESSION_EMPTY_TITLE, resumeAction = Runnable {})
-        )
+        mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
 
         // WHEN the notification is removed
         reset(listener)
@@ -674,15 +554,17 @@
     @Test
     fun testOnNotificationRemoved_blankTitle_notConverted() {
         // GIVEN that the manager has a notification with a resume action and blank title.
+        whenever(controller.metadata)
+            .thenReturn(
+                metadataBuilder
+                    .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_BLANK_TITLE)
+                    .build()
+            )
         addNotificationAndLoad()
         val data = mediaDataCaptor.value
         val instanceId = data.instanceId
         assertThat(data.resumption).isFalse()
-        mediaDataManager.onMediaDataLoaded(
-            KEY,
-            null,
-            data.copy(song = SESSION_BLANK_TITLE, resumeAction = Runnable {})
-        )
+        mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
 
         // WHEN the notification is removed
         reset(listener)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt
index a45e9d9..0c57e7b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt
@@ -468,7 +468,7 @@
     }
 
     @Test
-    fun audioInfoChanged() {
+    fun audioInfoPlaybackTypeChanged() {
         whenever(playbackInfo.getPlaybackType()).thenReturn(PlaybackInfo.PLAYBACK_TYPE_LOCAL)
         whenever(controller.getPlaybackInfo()).thenReturn(playbackInfo)
         // GIVEN a controller with local playback type
@@ -486,6 +486,25 @@
     }
 
     @Test
+    fun audioInfoVolumeControlIdChanged() {
+        whenever(playbackInfo.getPlaybackType()).thenReturn(PlaybackInfo.PLAYBACK_TYPE_LOCAL)
+        whenever(playbackInfo.getVolumeControlId()).thenReturn(null)
+        whenever(controller.getPlaybackInfo()).thenReturn(playbackInfo)
+        // GIVEN a controller with local playback type
+        manager.onMediaDataLoaded(KEY, null, mediaData)
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+        reset(mr2)
+        // WHEN onAudioInfoChanged fires with a volume control id change
+        whenever(playbackInfo.getVolumeControlId()).thenReturn("placeholder id")
+        val captor = ArgumentCaptor.forClass(MediaController.Callback::class.java)
+        verify(controller).registerCallback(captor.capture())
+        captor.value.onAudioInfoChanged(playbackInfo)
+        // THEN the route is checked
+        verify(mr2).getRoutingSessionForMediaController(eq(controller))
+    }
+
+    @Test
     fun audioInfoHasntChanged() {
         whenever(playbackInfo.getPlaybackType()).thenReturn(PlaybackInfo.PLAYBACK_TYPE_REMOTE)
         whenever(controller.getPlaybackInfo()).thenReturn(playbackInfo)
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 a72634b..07f7c15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
@@ -17,7 +17,9 @@
 package com.android.systemui.media.controls.ui
 
 import android.app.PendingIntent
+import android.content.res.ColorStateList
 import android.content.res.Configuration
+import android.os.LocaleList
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.util.MathUtils.abs
@@ -26,6 +28,7 @@
 import com.android.internal.logging.InstanceId
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.qualifiers.Main
@@ -50,9 +53,11 @@
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
+import java.util.Locale
 import javax.inject.Provider
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
@@ -68,6 +73,7 @@
 import org.mockito.Mock
 import org.mockito.Mockito.floatThat
 import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
@@ -77,6 +83,8 @@
 private val DATA = MediaTestUtils.emptyMediaData
 
 private val SMARTSPACE_KEY = "smartspace"
+private const val PAUSED_LOCAL = "paused local"
+private const val PLAYING_LOCAL = "playing local"
 
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -110,6 +118,7 @@
     lateinit var configListener: ArgumentCaptor<ConfigurationController.ConfigurationListener>
     @Captor lateinit var visualStabilityCallback: ArgumentCaptor<OnReorderingAllowedListener>
     @Captor lateinit var keyguardCallback: ArgumentCaptor<KeyguardUpdateMonitorCallback>
+    @Captor lateinit var hostStateCallback: ArgumentCaptor<MediaHostStatesManager.Callback>
 
     private val clock = FakeSystemClock()
     private lateinit var mediaCarouselController: MediaCarouselController
@@ -117,6 +126,7 @@
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
+        context.resources.configuration.locales = LocaleList(Locale.US, Locale.UK)
         transitionRepository = FakeKeyguardTransitionRepository()
         mediaCarouselController =
             MediaCarouselController(
@@ -143,6 +153,7 @@
         verify(visualStabilityProvider)
             .addPersistentReorderingAllowedListener(capture(visualStabilityCallback))
         verify(keyguardUpdateMonitor).registerCallback(capture(keyguardCallback))
+        verify(mediaHostStatesManager).addCallback(capture(hostStateCallback))
         whenever(mediaControlPanelFactory.get()).thenReturn(panel)
         whenever(panel.mediaViewController).thenReturn(mediaViewController)
         whenever(mediaDataManager.smartspaceMediaData).thenReturn(smartspaceMediaData)
@@ -155,7 +166,7 @@
         // Test values: key, data, last active time
         val playingLocal =
             Triple(
-                "playing local",
+                PLAYING_LOCAL,
                 DATA.copy(
                     active = true,
                     isPlaying = true,
@@ -179,7 +190,7 @@
 
         val pausedLocal =
             Triple(
-                "paused local",
+                PAUSED_LOCAL,
                 DATA.copy(
                     active = true,
                     isPlaying = false,
@@ -382,8 +393,8 @@
         testPlayerOrdering()
         // playing paused player
         listener.value.onMediaDataLoaded(
-            "paused local",
-            "paused local",
+            PAUSED_LOCAL,
+            PAUSED_LOCAL,
             DATA.copy(
                 active = true,
                 isPlaying = true,
@@ -392,8 +403,8 @@
             )
         )
         listener.value.onMediaDataLoaded(
-            "playing local",
-            "playing local",
+            PLAYING_LOCAL,
+            PLAYING_LOCAL,
             DATA.copy(
                 active = true,
                 isPlaying = false,
@@ -403,7 +414,7 @@
         )
 
         assertEquals(
-            MediaPlayerData.getMediaPlayerIndex("paused local"),
+            MediaPlayerData.getMediaPlayerIndex(PAUSED_LOCAL),
             mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
         )
         // paused player order should stays the same in visibleMediaPLayer map.
@@ -484,7 +495,7 @@
     @Test
     fun testMediaLoaded_ScrollToActivePlayer() {
         listener.value.onMediaDataLoaded(
-            "playing local",
+            PLAYING_LOCAL,
             null,
             DATA.copy(
                 active = true,
@@ -494,7 +505,7 @@
             )
         )
         listener.value.onMediaDataLoaded(
-            "paused local",
+            PAUSED_LOCAL,
             null,
             DATA.copy(
                 active = true,
@@ -512,8 +523,8 @@
         mediaCarouselController.shouldScrollToKey = true
         // switching between media players.
         listener.value.onMediaDataLoaded(
-            "playing local",
-            "playing local",
+            PLAYING_LOCAL,
+            PLAYING_LOCAL,
             DATA.copy(
                 active = true,
                 isPlaying = false,
@@ -522,8 +533,8 @@
             )
         )
         listener.value.onMediaDataLoaded(
-            "paused local",
-            "paused local",
+            PAUSED_LOCAL,
+            PAUSED_LOCAL,
             DATA.copy(
                 active = true,
                 isPlaying = true,
@@ -533,7 +544,7 @@
         )
 
         assertEquals(
-            MediaPlayerData.getMediaPlayerIndex("paused local"),
+            MediaPlayerData.getMediaPlayerIndex(PAUSED_LOCAL),
             mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
         )
     }
@@ -546,7 +557,7 @@
             false
         )
         listener.value.onMediaDataLoaded(
-            "playing local",
+            PLAYING_LOCAL,
             null,
             DATA.copy(
                 active = true,
@@ -556,7 +567,7 @@
             )
         )
 
-        var playerIndex = MediaPlayerData.getMediaPlayerIndex("playing local")
+        var playerIndex = MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL)
         assertEquals(
             playerIndex,
             mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
@@ -567,7 +578,7 @@
         // And check that the card stays in its position.
         mediaCarouselController.shouldScrollToKey = true
         listener.value.onMediaDataLoaded(
-            "playing local",
+            PLAYING_LOCAL,
             null,
             DATA.copy(
                 active = true,
@@ -577,7 +588,7 @@
                 packageName = "PACKAGE_NAME"
             )
         )
-        playerIndex = MediaPlayerData.getMediaPlayerIndex("playing local")
+        playerIndex = MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL)
         assertEquals(playerIndex, 0)
     }
 
@@ -674,36 +685,52 @@
 
     @Test
     fun testOnConfigChanged_playersAreAddedBack() {
-        listener.value.onMediaDataLoaded(
-            "playing local",
-            null,
-            DATA.copy(
-                active = true,
-                isPlaying = true,
-                playbackLocation = MediaData.PLAYBACK_LOCAL,
-                resumption = false
-            )
-        )
-        listener.value.onMediaDataLoaded(
-            "paused local",
-            null,
-            DATA.copy(
-                active = true,
-                isPlaying = false,
-                playbackLocation = MediaData.PLAYBACK_LOCAL,
-                resumption = false
-            )
-        )
+        testConfigurationChange { configListener.value.onConfigChanged(Configuration()) }
+    }
 
-        val playersSize = MediaPlayerData.players().size
+    @Test
+    fun testOnUiModeChanged_playersAreAddedBack() {
+        testConfigurationChange(configListener.value::onUiModeChanged)
 
-        configListener.value.onConfigChanged(Configuration())
+        verify(pageIndicator).tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+        verify(pageIndicator, times(2)).setNumPages(any())
+    }
 
-        assertEquals(playersSize, MediaPlayerData.players().size)
-        assertEquals(
-            MediaPlayerData.getMediaPlayerIndex("playing local"),
-            mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
-        )
+    @Test
+    fun testOnDensityOrFontScaleChanged_playersAreAddedBack() {
+        testConfigurationChange(configListener.value::onDensityOrFontScaleChanged)
+
+        verify(pageIndicator).tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+        // when recreateMedia is set to true, page indicator is updated on removal and addition.
+        verify(pageIndicator, times(4)).setNumPages(any())
+    }
+
+    @Test
+    fun testOnThemeChanged_playersAreAddedBack() {
+        testConfigurationChange(configListener.value::onThemeChanged)
+
+        verify(pageIndicator).tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+        verify(pageIndicator, times(2)).setNumPages(any())
+    }
+
+    @Test
+    fun testOnLocaleListChanged_playersAreAddedBack() {
+        context.resources.configuration.locales = LocaleList(Locale.US, Locale.UK, Locale.CANADA)
+        testConfigurationChange(configListener.value::onLocaleListChanged)
+
+        verify(pageIndicator, never()).tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+
+        context.resources.configuration.locales = LocaleList(Locale.UK, Locale.US, Locale.CANADA)
+        testConfigurationChange(configListener.value::onLocaleListChanged)
+
+        verify(pageIndicator).tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+        // When recreateMedia is set to true, page indicator is updated on removal and addition.
+        verify(pageIndicator, times(4)).setNumPages(any())
     }
 
     @Test
@@ -832,4 +859,55 @@
         // Verify that seekbar listening attribute in media control panel is set to false.
         verify(panel, times(MediaPlayerData.players().size)).listening = false
     }
+
+    @Test
+    fun testOnHostStateChanged_updateVisibility() {
+        var stateUpdated = false
+        mediaCarouselController.updateUserVisibility = { stateUpdated = true }
+
+        // When the host state updates
+        hostStateCallback.value!!.onHostStateChanged(LOCATION_QS, mediaHostState)
+
+        // Then the carousel visibility is updated
+        assertTrue(stateUpdated)
+    }
+
+    /**
+     * Helper method when a configuration change occurs.
+     *
+     * @param function called when a certain configuration change occurs.
+     */
+    private fun testConfigurationChange(function: () -> Unit) {
+        mediaCarouselController.pageIndicator = pageIndicator
+        listener.value.onMediaDataLoaded(
+            PLAYING_LOCAL,
+            null,
+            DATA.copy(
+                active = true,
+                isPlaying = true,
+                playbackLocation = MediaData.PLAYBACK_LOCAL,
+                resumption = false
+            )
+        )
+        listener.value.onMediaDataLoaded(
+            PAUSED_LOCAL,
+            null,
+            DATA.copy(
+                active = true,
+                isPlaying = false,
+                playbackLocation = MediaData.PLAYBACK_LOCAL,
+                resumption = false
+            )
+        )
+
+        val playersSize = MediaPlayerData.players().size
+        reset(pageIndicator)
+        function()
+
+        assertEquals(playersSize, MediaPlayerData.players().size)
+        assertEquals(
+            MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL),
+            mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
+        )
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
index eb78ded..2ce236d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
@@ -470,6 +470,21 @@
             )
     }
 
+    @Test
+    fun testQsExpandedChanged_noQqsMedia() {
+        // When we are looking at QQS with active media
+        whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
+        whenever(statusBarStateController.isExpanded).thenReturn(true)
+
+        // When there is no longer any active media
+        whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(false)
+        mediaHierarchyManager.qsExpanded = false
+
+        // Then the carousel is set to not visible
+        verify(mediaCarouselScrollHandler).visibleToUser = false
+        assertThat(mediaCarouselScrollHandler.visibleToUser).isFalse()
+    }
+
     private fun enableSplitShade() {
         context
             .getOrCreateTestableResources()
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 0bdcaf4..299303d 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
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -33,7 +34,12 @@
 
 import android.app.KeyguardManager;
 import android.app.Notification;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.media.AudioDeviceAttributes;
 import android.media.AudioManager;
@@ -44,6 +50,7 @@
 import android.media.RoutingSessionInfo;
 import android.media.session.MediaController;
 import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
 import android.os.PowerExemptionManager;
 import android.os.RemoteException;
 import android.service.notification.StatusBarNotification;
@@ -74,6 +81,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -93,29 +103,54 @@
     private static final String TEST_SONG = "test_song";
     private static final String TEST_SESSION_ID = "test_session_id";
     private static final String TEST_SESSION_NAME = "test_session_name";
-    private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
-    private final ActivityLaunchAnimator.Controller mActivityLaunchAnimatorController = mock(
-            ActivityLaunchAnimator.Controller.class);
-    private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
-            NearbyMediaDevicesManager.class);
+    @Mock
+    private DialogLaunchAnimator mDialogLaunchAnimator;
+    @Mock
+    private ActivityLaunchAnimator.Controller mActivityLaunchAnimatorController;
+    @Mock
+    private NearbyMediaDevicesManager mNearbyMediaDevicesManager;
     // Mock
-    private MediaController mMediaController = mock(MediaController.class);
-    private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
-    private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager =
-            mock(CachedBluetoothDeviceManager.class);
-    private LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
-    private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
-    private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
-    private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
-    private NearbyDevice mNearbyDevice1 = mock(NearbyDevice.class);
-    private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
-    private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
-    private RoutingSessionInfo mRemoteSessionInfo = mock(RoutingSessionInfo.class);
-    private ActivityStarter mStarter = mock(ActivityStarter.class);
-    private AudioManager mAudioManager = mock(AudioManager.class);
-    private KeyguardManager mKeyguardManager = mock(KeyguardManager.class);
-    private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class);
-    private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class);
+    @Mock
+    private MediaController mMediaController;
+    @Mock
+    private MediaSessionManager mMediaSessionManager;
+    @Mock
+    private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager;
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+    @Mock
+    private MediaOutputController.Callback mCb;
+    @Mock
+    private MediaDevice mMediaDevice1;
+    @Mock
+    private MediaDevice mMediaDevice2;
+    @Mock
+    private NearbyDevice mNearbyDevice1;
+    @Mock
+    private NearbyDevice mNearbyDevice2;
+    @Mock
+    private MediaMetadata mMediaMetadata;
+    @Mock
+    private RoutingSessionInfo mRemoteSessionInfo;
+    @Mock
+    private ActivityStarter mStarter;
+    @Mock
+    private AudioManager mAudioManager;
+    @Mock
+    private KeyguardManager mKeyguardManager;
+    @Mock
+    private ActivityLaunchAnimator.Controller mController;
+    @Mock
+    private PowerExemptionManager mPowerExemptionManager;
+    @Mock
+    private CommonNotifCollection mNotifCollection;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private Drawable mDrawable;
+    @Mock
+    private PlaybackState mPlaybackState;
+
     private FeatureFlags mFlags = mock(FeatureFlags.class);
     private View mDialogLaunchView = mock(View.class);
     private MediaOutputController.Callback mCallback = mock(MediaOutputController.Callback.class);
@@ -131,8 +166,11 @@
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext.setMockPackageManager(mPackageManager);
         mSpyContext = spy(mContext);
         when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
         mMediaControllers.add(mMediaController);
         when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
         doReturn(mMediaSessionManager).when(mSpyContext).getSystemService(
@@ -258,6 +296,34 @@
     }
 
     @Test
+    public void tryToLaunchMediaApplication_intentNotNull_startActivity() {
+        when(mDialogLaunchAnimator.createActivityLaunchController(any(View.class))).thenReturn(
+                mController);
+        Intent intent = new Intent(TEST_PACKAGE_NAME);
+        doReturn(intent).when(mPackageManager).getLaunchIntentForPackage(TEST_PACKAGE_NAME);
+        mMediaOutputController.start(mCallback);
+
+        mMediaOutputController.tryToLaunchMediaApplication(mDialogLaunchView);
+
+        verify(mStarter).startActivity(any(Intent.class), anyBoolean(),
+                Mockito.eq(mController));
+    }
+
+    @Test
+    public void tryToLaunchInAppRoutingIntent_componentNameNotNull_startActivity() {
+        when(mDialogLaunchAnimator.createActivityLaunchController(any(View.class))).thenReturn(
+                mController);
+        mMediaOutputController.start(mCallback);
+        when(mLocalMediaManager.getLinkedItemComponentName()).thenReturn(
+                new ComponentName(TEST_PACKAGE_NAME, ""));
+
+        mMediaOutputController.tryToLaunchInAppRoutingIntent(TEST_DEVICE_1_ID, mDialogLaunchView);
+
+        verify(mStarter).startActivity(any(Intent.class), anyBoolean(),
+                Mockito.eq(mController));
+    }
+
+    @Test
     public void onDevicesUpdated_unregistersNearbyDevicesCallback() throws RemoteException {
         mMediaOutputController.start(mCb);
 
@@ -342,6 +408,30 @@
     }
 
     @Test
+    public void advanced_onDeviceListUpdateWithConnectedDeviceRemote_verifyItemSize() {
+        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+        when(mMediaDevice1.getFeatures()).thenReturn(
+                ImmutableList.of(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK));
+        when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice1);
+        mMediaOutputController.start(mCb);
+        reset(mCb);
+
+        mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+        final List<MediaDevice> devices = new ArrayList<>();
+        for (MediaItem item : mMediaOutputController.getMediaItemList()) {
+            if (item.getMediaDevice().isPresent()) {
+                devices.add(item.getMediaDevice().get());
+            }
+        }
+
+        assertThat(devices.containsAll(mMediaDevices)).isTrue();
+        assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+        assertThat(mMediaOutputController.getMediaItemList().size()).isEqualTo(
+                mMediaDevices.size() + 1);
+        verify(mCb).onDeviceListChanged();
+    }
+
+    @Test
     public void advanced_categorizeMediaItems_withSuggestedDevice_verifyDeviceListSize() {
         when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
         when(mMediaDevice1.isSuggestedDevice()).thenReturn(true);
@@ -582,6 +672,17 @@
     }
 
     @Test
+    public void isAnyDeviceTransferring_advancedLayoutSupport() {
+        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+        when(mMediaDevice1.getState()).thenReturn(
+                LocalMediaManager.MediaDeviceState.STATE_CONNECTING);
+        mMediaOutputController.start(mCb);
+        mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+
+        assertThat(mMediaOutputController.isAnyDeviceTransferring()).isTrue();
+    }
+
+    @Test
     public void isPlaying_stateIsNull() {
         when(mMediaController.getPlaybackState()).thenReturn(null);
 
@@ -661,22 +762,6 @@
     }
 
     @Test
-    public void connectDevice_verifyConnect() {
-        when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice2);
-
-        mMediaOutputController.connectDevice(mMediaDevice1);
-
-        // Wait for background thread execution
-        try {
-            Thread.sleep(100);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-
-        verify(mLocalMediaManager).connectDevice(mMediaDevice1);
-    }
-
-    @Test
     public void getActiveRemoteMediaDevice_isSystemSession_returnSession() {
         when(mRemoteSessionInfo.getId()).thenReturn(TEST_SESSION_ID);
         when(mRemoteSessionInfo.getName()).thenReturn(TEST_SESSION_NAME);
@@ -883,6 +968,56 @@
     }
 
     @Test
+    public void getDeviceIconCompat_deviceIconIsNotNull_returnsIcon() {
+        when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice2);
+        when(mMediaDevice1.getIcon()).thenReturn(mDrawable);
+
+        assertThat(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).isInstanceOf(
+                IconCompat.class);
+    }
+
+    @Test
+    public void getDeviceIconCompat_deviceIconIsNull_returnsIcon() {
+        when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice2);
+        when(mMediaDevice1.getIcon()).thenReturn(null);
+
+        assertThat(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).isInstanceOf(
+                IconCompat.class);
+    }
+
+    @Test
+    public void setColorFilter_setColorFilterToDrawable() {
+        mMediaOutputController.setColorFilter(mDrawable, true);
+
+        verify(mDrawable).setColorFilter(any(PorterDuffColorFilter.class));
+    }
+
+    @Test
+    public void resetGroupMediaDevices_clearGroupDevices() {
+        final MediaDevice selectedMediaDevice1 = mock(MediaDevice.class);
+        final MediaDevice selectedMediaDevice2 = mock(MediaDevice.class);
+        final MediaDevice selectableMediaDevice1 = mock(MediaDevice.class);
+        final MediaDevice selectableMediaDevice2 = mock(MediaDevice.class);
+        final List<MediaDevice> selectedMediaDevices = new ArrayList<>();
+        final List<MediaDevice> selectableMediaDevices = new ArrayList<>();
+        when(selectedMediaDevice1.getId()).thenReturn(TEST_DEVICE_1_ID);
+        when(selectedMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
+        when(selectableMediaDevice1.getId()).thenReturn(TEST_DEVICE_3_ID);
+        when(selectableMediaDevice2.getId()).thenReturn(TEST_DEVICE_4_ID);
+        selectedMediaDevices.add(selectedMediaDevice1);
+        selectedMediaDevices.add(selectedMediaDevice2);
+        selectableMediaDevices.add(selectableMediaDevice1);
+        selectableMediaDevices.add(selectableMediaDevice2);
+        doReturn(selectedMediaDevices).when(mLocalMediaManager).getSelectedMediaDevice();
+        doReturn(selectableMediaDevices).when(mLocalMediaManager).getSelectableMediaDevice();
+        assertThat(mMediaOutputController.getGroupMediaDevices().isEmpty()).isFalse();
+
+        mMediaOutputController.resetGroupMediaDevices();
+
+        assertThat(mMediaOutputController.mGroupMediaDevices.isEmpty()).isTrue();
+    }
+
+    @Test
     public void isVolumeControlEnabled_isCastWithVolumeFixed_returnsFalse() {
         when(mMediaDevice1.getDeviceType()).thenReturn(
                 MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
@@ -919,6 +1054,42 @@
     }
 
     @Test
+    public void setTemporaryAllowListExceptionIfNeeded_packageNameIsNull_NoAction() {
+        MediaOutputController testMediaOutputController = new MediaOutputController(mSpyContext,
+                null,
+                mMediaSessionManager, mLocalBluetoothManager, mStarter,
+                mNotifCollection, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
+                mKeyguardManager, mFlags);
+
+        testMediaOutputController.setTemporaryAllowListExceptionIfNeeded(mMediaDevice2);
+
+        verify(mPowerExemptionManager, never()).addToTemporaryAllowList(anyString(), anyInt(),
+                anyString(),
+                anyLong());
+    }
+
+    @Test
+    public void onMetadataChanged_triggersOnMetadataChanged() {
+        mMediaOutputController.mCallback = this.mCallback;
+
+        mMediaOutputController.mCb.onMetadataChanged(mMediaMetadata);
+
+        verify(mMediaOutputController.mCallback).onMediaChanged();
+    }
+
+    @Test
+    public void onPlaybackStateChanged_updateWithNullState_onMediaStoppedOrPaused() {
+        when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+        mMediaOutputController.mCallback = this.mCallback;
+        mMediaOutputController.start(mCb);
+
+        mMediaOutputController.mCb.onPlaybackStateChanged(null);
+
+        verify(mMediaOutputController.mCallback).onMediaStoppedOrPaused();
+    }
+
+    @Test
     public void launchBluetoothPairing_isKeyguardLocked_dismissDialog() {
         when(mDialogLaunchAnimator.createActivityLaunchController(mDialogLaunchView)).thenReturn(
                 mActivityLaunchAnimatorController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/DynamicColorTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/DynamicColorTest.java
index fb5197e..4ce32d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/DynamicColorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/DynamicColorTest.java
@@ -17,18 +17,16 @@
 package com.android.systemui.monet;
 
 import static com.android.systemui.monet.utils.ArgbSubject.assertThat;
-
 import static org.junit.Assert.assertTrue;
 
-
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.SysuiTestCase;
 import com.android.systemui.monet.contrast.Contrast;
 import com.android.systemui.monet.dynamiccolor.DynamicColor;
 import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors;
 import com.android.systemui.monet.dynamiccolor.ToneDeltaConstraint;
 import com.android.systemui.monet.dynamiccolor.TonePolarity;
+import com.android.systemui.SysuiTestCase;
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.DynamicScheme;
 import com.android.systemui.monet.scheme.SchemeContent;
@@ -36,182 +34,174 @@
 import com.android.systemui.monet.scheme.SchemeMonochrome;
 import com.android.systemui.monet.scheme.SchemeTonalSpot;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
-public final class DynamicColorTest extends SysuiTestCase {
+public final class DynamicColorTest extends SysuiTestCase{
 
-    @Test
-    public void fromArgbNoBackground_doesntChangeForContrast() {
-        final int blueArgb = 0xff0000ff;
-        final DynamicColor dynamicColor = DynamicColor.fromArgb(blueArgb);
+  private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
 
-        final SchemeTonalSpot standardContrast = new SchemeTonalSpot(Hct.fromInt(blueArgb), false,
-                0.0);
-        assertThat(dynamicColor.getArgb(standardContrast)).isSameColorAs(blueArgb);
+  @Test
+  public void fromArgbNoBackground_doesntChangeForContrast() {
+    final int blueArgb = 0xff0000ff;
+    final DynamicColor dynamicColor = DynamicColor.fromArgb(blueArgb);
 
-        final SchemeTonalSpot minContrast = new SchemeTonalSpot(Hct.fromInt(blueArgb), false, -1.0);
-        assertThat(dynamicColor.getArgb(minContrast)).isSameColorAs(blueArgb);
+    final SchemeTonalSpot standardContrast = new SchemeTonalSpot(Hct.fromInt(blueArgb), false, 0.0);
+    assertThat(dynamicColor.getArgb(standardContrast)).isSameColorAs(blueArgb);
 
-        final SchemeTonalSpot maxContrast = new SchemeTonalSpot(Hct.fromInt(blueArgb), false, 1.0);
-        assertThat(dynamicColor.getArgb(maxContrast)).isSameColorAs(blueArgb);
-    }
+    final SchemeTonalSpot minContrast = new SchemeTonalSpot(Hct.fromInt(blueArgb), false, -1.0);
+    assertThat(dynamicColor.getArgb(minContrast)).isSameColorAs(blueArgb);
 
-    @Test
-    public void toneDeltaConstraintNoPreference_evaluatesCorrectly() {
-        final int blueArgb = 0xff0000ff;
-        final int redArgb = 0xffff0000;
-        final DynamicColor otherDynamicColor = DynamicColor.fromArgb(redArgb);
-        final DynamicColor dynamicColor =
-                DynamicColor.fromArgb(
-                        blueArgb,
-                        (s) -> 30.0,
-                        null,
-                        (s) -> new ToneDeltaConstraint(30, otherDynamicColor,
-                                TonePolarity.NO_PREFERENCE));
-        final SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(blueArgb), false, 0.0);
-        assertThat(dynamicColor.getArgb(scheme)).isSameColorAs(0xff0000ef);
-    }
+    final SchemeTonalSpot maxContrast = new SchemeTonalSpot(Hct.fromInt(blueArgb), false, 1.0);
+    assertThat(dynamicColor.getArgb(maxContrast)).isSameColorAs(blueArgb);
+  }
 
-    @Test
-    public void dynamicColor_withOpacity() {
-        final DynamicColor dynamicColor =
-                new DynamicColor(
-                        s -> 0.0,
-                        s -> 0.0,
-                        s -> s.isDark ? 100.0 : 0.0,
-                        s -> s.isDark ? 0.20 : 0.12,
-                        null,
-                        scheme ->
-                                DynamicColor.toneMinContrastDefault(
-                                        (s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
-                        scheme ->
-                                DynamicColor.toneMaxContrastDefault(
-                                        (s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
-                        null);
-        final SchemeTonalSpot lightScheme = new SchemeTonalSpot(Hct.fromInt(0xff4285f4), false,
-                0.0);
-        assertThat(dynamicColor.getArgb(lightScheme)).isSameColorAs(0x1f000000);
+  @Test
+  public void toneDeltaConstraintNoPreference_evaluatesCorrectly() {
+    final int blueArgb = 0xff0000ff;
+    final int redArgb = 0xffff0000;
+    final DynamicColor otherDynamicColor = DynamicColor.fromArgb(redArgb);
+    final DynamicColor dynamicColor =
+        DynamicColor.fromArgb(
+            blueArgb,
+            (s) -> 30.0,
+            null,
+            (s) -> new ToneDeltaConstraint(30, otherDynamicColor, TonePolarity.NO_PREFERENCE));
+    final SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(blueArgb), false, 0.0);
+    assertThat(dynamicColor.getArgb(scheme)).isSameColorAs(0xff0000ef);
+  }
 
-        final SchemeTonalSpot darkScheme = new SchemeTonalSpot(Hct.fromInt(0xff4285f4), true, 0.0);
-        assertThat(dynamicColor.getArgb(darkScheme)).isSameColorAs(0x33ffffff);
-    }
+  @Test
+  public void dynamicColor_withOpacity() {
+    final DynamicColor dynamicColor =
+        new DynamicColor(
+            s -> 0.0,
+            s -> 0.0,
+            s -> s.isDark ? 100.0 : 0.0,
+            s -> s.isDark ? 0.20 : 0.12,
+            null,
+            scheme ->
+                DynamicColor.toneMinContrastDefault(
+                    (s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
+            scheme ->
+                DynamicColor.toneMaxContrastDefault(
+                    (s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
+            null);
+    final SchemeTonalSpot lightScheme = new SchemeTonalSpot(Hct.fromInt(0xff4285f4), false, 0.0);
+    assertThat(dynamicColor.getArgb(lightScheme)).isSameColorAs(0x1f000000);
 
-    @Test
-    public void respectsContrast() {
-        final Hct[] seedColors =
-                new Hct[]{
-                        Hct.fromInt(0xFFFF0000),
-                        Hct.fromInt(0xFFFFFF00),
-                        Hct.fromInt(0xFF00FF00),
-                        Hct.fromInt(0xFF0000FF)
-                };
+    final SchemeTonalSpot darkScheme = new SchemeTonalSpot(Hct.fromInt(0xff4285f4), true, 0.0);
+    assertThat(dynamicColor.getArgb(darkScheme)).isSameColorAs(0x33ffffff);
+  }
 
-        final double[] contrastLevels = {-1.0, -0.5, 0.0, 0.5, 1.0};
+  @Test
+  public void respectsContrast() {
+    final Hct[] seedColors =
+        new Hct[] {
+          Hct.fromInt(0xFFFF0000),
+          Hct.fromInt(0xFFFFFF00),
+          Hct.fromInt(0xFF00FF00),
+          Hct.fromInt(0xFF0000FF)
+        };
 
-        for (Hct seedColor : seedColors) {
-            for (double contrastLevel : contrastLevels) {
-                for (boolean isDark : new boolean[]{false, true}) {
-                    final DynamicScheme[] schemes =
-                            new DynamicScheme[]{
-                                    new SchemeContent(seedColor, isDark, contrastLevel),
-                                    new SchemeMonochrome(seedColor, isDark, contrastLevel),
-                                    new SchemeTonalSpot(seedColor, isDark, contrastLevel),
-                                    new SchemeFidelity(seedColor, isDark, contrastLevel)
-                            };
-                    for (final DynamicScheme scheme : schemes) {
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme, MaterialDynamicColors.onPrimary,
-                                        MaterialDynamicColors.primary));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme,
-                                        MaterialDynamicColors.onPrimaryContainer,
-                                        MaterialDynamicColors.primaryContainer));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme, MaterialDynamicColors.onSecondary,
-                                        MaterialDynamicColors.secondary));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme,
-                                        MaterialDynamicColors.onSecondaryContainer,
-                                        MaterialDynamicColors.secondaryContainer));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme, MaterialDynamicColors.onTertiary,
-                                        MaterialDynamicColors.tertiary));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme,
-                                        MaterialDynamicColors.onTertiaryContainer,
-                                        MaterialDynamicColors.tertiaryContainer));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme, MaterialDynamicColors.onError,
-                                        MaterialDynamicColors.error));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme,
-                                        MaterialDynamicColors.onErrorContainer,
-                                        MaterialDynamicColors.errorContainer));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme, MaterialDynamicColors.onBackground,
-                                        MaterialDynamicColors.background));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme,
-                                        MaterialDynamicColors.onSurfaceVariant,
-                                        MaterialDynamicColors.surfaceVariant));
-                        assertTrue(
-                                pairSatisfiesContrast(
-                                        scheme,
-                                        MaterialDynamicColors.onSurfaceInverse,
-                                        MaterialDynamicColors.surfaceInverse));
-                    }
-                }
-            }
+    final double[] contrastLevels = {-1.0, -0.5, 0.0, 0.5, 1.0};
+
+    for (Hct seedColor : seedColors) {
+      for (double contrastLevel : contrastLevels) {
+        for (boolean isDark : new boolean[] {false, true}) {
+          final DynamicScheme[] schemes =
+              new DynamicScheme[] {
+                new SchemeContent(seedColor, isDark, contrastLevel),
+                new SchemeMonochrome(seedColor, isDark, contrastLevel),
+                new SchemeTonalSpot(seedColor, isDark, contrastLevel),
+                new SchemeFidelity(seedColor, isDark, contrastLevel)
+              };
+          for (final DynamicScheme scheme : schemes) {
+            assertTrue(
+                pairSatisfiesContrast(scheme, dynamicColors.onPrimary(), dynamicColors.primary()));
+            assertTrue(
+                pairSatisfiesContrast(
+                    scheme, dynamicColors.onPrimaryContainer(), dynamicColors.primaryContainer()));
+            assertTrue(
+                pairSatisfiesContrast(
+                    scheme, dynamicColors.onSecondary(), dynamicColors.secondary()));
+            assertTrue(
+                pairSatisfiesContrast(
+                    scheme,
+                    dynamicColors.onSecondaryContainer(),
+                    dynamicColors.secondaryContainer()));
+            assertTrue(
+                pairSatisfiesContrast(
+                    scheme, dynamicColors.onTertiary(), dynamicColors.tertiary()));
+            assertTrue(
+                pairSatisfiesContrast(
+                    scheme,
+                    dynamicColors.onTertiaryContainer(),
+                    dynamicColors.tertiaryContainer()));
+            assertTrue(
+                pairSatisfiesContrast(scheme, dynamicColors.onError(), dynamicColors.error()));
+            assertTrue(
+                pairSatisfiesContrast(
+                    scheme, dynamicColors.onErrorContainer(), dynamicColors.errorContainer()));
+            assertTrue(
+                pairSatisfiesContrast(
+                    scheme, dynamicColors.onBackground(), dynamicColors.background()));
+            assertTrue(
+                pairSatisfiesContrast(
+                    scheme, dynamicColors.onSurfaceVariant(), dynamicColors.surfaceVariant()));
+            assertTrue(
+                pairSatisfiesContrast(
+                    scheme, dynamicColors.inverseOnSurface(), dynamicColors.inverseSurface()));
+          }
         }
+      }
     }
+  }
 
-    @Test
-    public void valuesAreCorrect() {
-        // Checks that the values of certain dynamic colors match Dart results.
-        assertThat(
-                MaterialDynamicColors.onPrimaryContainer.getArgb(
-                        new SchemeFidelity(Hct.fromInt(0xFFFF0000), false, 0.5)))
-                .isSameColorAs(0xFFFFE5E1);
-        assertThat(
-                MaterialDynamicColors.onSecondaryContainer.getArgb(
-                        new SchemeContent(Hct.fromInt(0xFF0000FF), false, 0.5)))
-                .isSameColorAs(0xFFFFFCFF);
-        assertThat(
-                MaterialDynamicColors.onTertiaryContainer.getArgb(
-                        new SchemeContent(Hct.fromInt(0xFFFFFF00), true, -0.5)))
-                .isSameColorAs(0xFF616600);
-        assertThat(
-                MaterialDynamicColors.surfaceInverse.getArgb(
-                        new SchemeContent(Hct.fromInt(0xFF0000FF), false, 0.0)))
-                .isSameColorAs(0xFF464652);
-        assertThat(
-                MaterialDynamicColors.primaryInverse.getArgb(
-                        new SchemeContent(Hct.fromInt(0xFFFF0000), false, -0.5)))
-                .isSameColorAs(0xFFFF8C7A);
-        assertThat(
-                MaterialDynamicColors.outlineVariant.getArgb(
-                        new SchemeContent(Hct.fromInt(0xFFFFFF00), true, 0.0)))
-                .isSameColorAs(0xFF484831);
-    }
+  @Test
+  public void valuesAreCorrect() {
+    // Checks that the values of certain dynamic colors match Dart results.
+    assertThat(
+            dynamicColors
+                .onPrimaryContainer()
+                .getArgb(new SchemeFidelity(Hct.fromInt(0xFFFF0000), false, 0.5)))
+        .isSameColorAs(0xFFFFE5E1);
+    assertThat(
+            dynamicColors
+                .onSecondaryContainer()
+                .getArgb(new SchemeContent(Hct.fromInt(0xFF0000FF), false, 0.5)))
+        .isSameColorAs(0xFFFFFCFF);
+    assertThat(
+            dynamicColors
+                .onTertiaryContainer()
+                .getArgb(new SchemeContent(Hct.fromInt(0xFFFFFF00), true, -0.5)))
+        .isSameColorAs(0xFF616600);
+    assertThat(
+            dynamicColors
+                .inverseSurface()
+                .getArgb(new SchemeContent(Hct.fromInt(0xFF0000FF), false, 0.0)))
+        .isSameColorAs(0xFF2F2F3B);
+    assertThat(
+            dynamicColors
+                .inversePrimary()
+                .getArgb(new SchemeContent(Hct.fromInt(0xFFFF0000), false, -0.5)))
+        .isSameColorAs(0xFFFF907F);
+    assertThat(
+            dynamicColors
+                .outlineVariant()
+                .getArgb(new SchemeContent(Hct.fromInt(0xFFFFFF00), true, 0.0)))
+        .isSameColorAs(0xFF484831);
+  }
 
-    private boolean pairSatisfiesContrast(DynamicScheme scheme, DynamicColor fg, DynamicColor bg) {
-        double fgTone = fg.getHct(scheme).getTone();
-        double bgTone = bg.getHct(scheme).getTone();
-        double minimumRequirement = scheme.contrastLevel >= 0.0 ? 4.5 : 3.0;
-        return Contrast.ratioOfTones(fgTone, bgTone) >= minimumRequirement;
-    }
+  private boolean pairSatisfiesContrast(DynamicScheme scheme, DynamicColor fg, DynamicColor bg) {
+    double fgTone = fg.getHct(scheme).getTone();
+    double bgTone = bg.getHct(scheme).getTone();
+    double minimumRequirement = scheme.contrastLevel >= 0.0 ? 4.5 : 3.0;
+    return Contrast.ratioOfTones(fgTone, bgTone) >= minimumRequirement;
+  }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeContentTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeContentTest.java
index 1ddfc4d..704aed8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeContentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeContentTest.java
@@ -25,246 +25,229 @@
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.SchemeContent;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
 public final class SchemeContentTest extends SysuiTestCase {
 
+    private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
+
     @Test
     public void testKeyColors() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xff0000ff), false, 0.0);
 
-        assertThat(MaterialDynamicColors.primaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.primaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff080CFF);
-        assertThat(MaterialDynamicColors.secondaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.secondaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff656DD3);
-        assertThat(MaterialDynamicColors.tertiaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.tertiaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff81009F);
-        assertThat(MaterialDynamicColors.neutralPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff767684);
-        assertThat(MaterialDynamicColors.neutralVariantPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralVariantPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff757589);
     }
 
     @Test
     public void lightTheme_minContrast_primary() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xFF1218FF);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xFF1218FF);
     }
 
     @Test
     public void lightTheme_standardContrast_primary() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xFF0001C3);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xFF0001C3);
     }
 
     @Test
     public void lightTheme_maxContrast_primary() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xFF000181);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xFF000181);
     }
 
     @Test
     public void lightTheme_minContrast_primaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF5660FF);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xFF5660FF);
     }
 
     @Test
     public void lightTheme_standardContrast_primaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF2D36FF);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xFF2D36FF);
     }
 
     @Test
     public void lightTheme_maxContrast_primaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF0000E3);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xFF0000E3);
     }
 
     @Test
     public void lightTheme_minContrast_tertiaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFB042CC);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xFFB042CC);
     }
 
     @Test
     public void lightTheme_standardContrast_tertiaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF9221AF);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xFF9221AF);
     }
 
     @Test
     public void lightTheme_maxContrast_tertiaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF73008E);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xFF73008E);
     }
 
     @Test
     public void lightTheme_minContrast_objectionableTertiaryContainerLightens() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF850096), false, -1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFD03A71);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xFFD03A71);
     }
 
     @Test
     public void lightTheme_standardContrast_objectionableTertiaryContainerLightens() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF850096), false, 0.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFAC1B57);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xFFAC1B57);
     }
 
     @Test
     public void lightTheme_maxContrast_objectionableTertiaryContainerDarkens() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF850096), false, 1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF870040);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xFF870040);
     }
 
     @Test
     public void lightTheme_minContrast_onPrimaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFCBCDFF);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xFFCBCDFF);
     }
 
     @Test
     public void lightTheme_standardContrast_onPrimaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFCECFFF);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xFFCECFFF);
     }
 
     @Test
     public void lightTheme_maxContrast_onPrimaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFD6D6FF);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xFFD6D6FF);
     }
 
     @Test
     public void lightTheme_minContrast_surface() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, -1);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xFFFBF8FF);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xFFFBF8FF);
     }
 
     @Test
     public void lightTheme_standardContrast_surface() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xFFFBF8FF);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xFFFBF8FF);
     }
 
     @Test
     public void lightTheme_maxContrast_surface() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xFFFBF8FF);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xFFFBF8FF);
     }
 
     @Test
     public void darkTheme_minContrast_primary() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xFF5660FF);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xFF5660FF);
     }
 
     @Test
     public void darkTheme_standardContrast_primary() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xFFBEC2FF);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xFFBEC2FF);
     }
 
     @Test
     public void darkTheme_maxContrast_primary() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xFFF6F4FF);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xFFF6F4FF);
     }
 
     @Test
     public void darkTheme_minContrast_primaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF0000E6);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xFF0000E6);
     }
 
     @Test
     public void darkTheme_standardContrast_primaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF0000E6);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xFF0000E6);
     }
 
     @Test
     public void darkTheme_maxContrast_primaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFC4C6FF);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xFFC4C6FF);
     }
 
     @Test
     public void darkTheme_minContrast_onPrimaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF7A83FF);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xFF7A83FF);
     }
 
     @Test
     public void darkTheme_standardContrast_onPrimaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFA4AAFF);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xFFA4AAFF);
     }
 
     @Test
     public void darkTheme_maxContrast_onPrimaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF0001C6);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xFF0001C6);
     }
 
     @Test
     public void darkTheme_minContrast_onTertiaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFCF60EA);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xFFCF60EA);
     }
 
     @Test
     public void darkTheme_standardContrast_onTertiaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFFEB8CFF);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xFFEB8CFF);
     }
 
     @Test
     public void darkTheme_maxContrast_onTertiaryContainer() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xFF63007B);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xFF63007B);
     }
 
     @Test
     public void darkTheme_minContrast_surface() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xFF12121D);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xFF12121D);
     }
 
     @Test
     public void darkTheme_standardContrast_surface() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xFF12121D);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xFF12121D);
     }
 
     @Test
     public void darkTheme_maxContrast_surface() {
         SchemeContent scheme = new SchemeContent(Hct.fromInt(0xFF0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xFF12121D);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xFF12121D);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeExpressiveTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeExpressiveTest.java
index 31e8711..32a589d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeExpressiveTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeExpressiveTest.java
@@ -25,183 +25,175 @@
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.SchemeExpressive;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
 public final class SchemeExpressiveTest extends SysuiTestCase {
 
+    private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
+
     @Test
     public void testKeyColors() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, 0.0);
 
-        assertThat(MaterialDynamicColors.primaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.primaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff35855F);
-        assertThat(MaterialDynamicColors.secondaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.secondaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff8C6D8C);
-        assertThat(MaterialDynamicColors.tertiaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.tertiaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff806EA1);
-        assertThat(MaterialDynamicColors.neutralPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff79757F);
-        assertThat(MaterialDynamicColors.neutralVariantPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralVariantPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff7A7585);
     }
 
     @Test
     public void lightTheme_minContrast_primary() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff32835D);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffad603c);
     }
 
     @Test
     public void lightTheme_standardContrast_primary() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff146C48);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff924b28);
     }
 
     @Test
     public void lightTheme_maxContrast_primary() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff002818);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff401400);
     }
 
     @Test
     public void lightTheme_minContrast_primaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffA2F4C6);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffffdbcc);
     }
 
     @Test
     public void lightTheme_standardContrast_primaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffA2F4C6);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffffdbcc);
     }
 
     @Test
     public void lightTheme_maxContrast_primaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff004D31);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff6f3010);
     }
 
     @Test
     public void lightTheme_minContrast_onPrimaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff1e724e);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff99512e);
     }
 
     @Test
     public void lightTheme_standardContrast_onPrimaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff002112);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff351000);
     }
 
     @Test
     public void lightTheme_maxContrast_onPrimaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff9aebbe);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffffd0bc);
     }
 
     @Test
     public void lightTheme_minContrast_surface() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffdf7ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_standardContrast_surface() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffdf7ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_maxContrast_surface() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffdf7ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void darkTheme_minContrast_primary() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff32835d);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffad603c);
     }
 
     @Test
     public void darkTheme_standardContrast_primary() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff87d7ab);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffffb595);
     }
 
     @Test
     public void darkTheme_maxContrast_primary() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xffd5ffe4);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xfffff3ee);
     }
 
     @Test
     public void darkTheme_minContrast_primaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff005234);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff743413);
     }
 
     @Test
     public void darkTheme_standardContrast_primaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff005234);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff743413);
     }
 
     @Test
     public void darkTheme_maxContrast_primaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff8bdbaf);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffffbb9e);
     }
 
     @Test
     public void darkTheme_minContrast_onPrimaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff76c59b);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xfff99f75);
     }
 
     @Test
     public void darkTheme_standardContrast_onPrimaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffa2f4c6);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffffdbcc);
     }
 
     @Test
     public void darkTheme_maxContrast_onPrimaryContainer() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff004229);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff622706);
     }
 
     @Test
     public void darkTheme_minContrast_surface() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff14121a);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12131a);
     }
 
     @Test
     public void darkTheme_standardContrast_surface() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff14121a);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12131a);
     }
 
     @Test
     public void darkTheme_maxContrast_surface() {
         SchemeExpressive scheme = new SchemeExpressive(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff14121a);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12131a);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeFidelityTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeFidelityTest.java
index 511f83b..6844a92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeFidelityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeFidelityTest.java
@@ -25,245 +25,230 @@
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.SchemeFidelity;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
 public final class SchemeFidelityTest extends SysuiTestCase {
+
+    private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
+
     @Test
     public void testKeyColors() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 0.0);
 
-        assertThat(MaterialDynamicColors.primaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.primaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff080CFF);
-        assertThat(MaterialDynamicColors.secondaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.secondaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff656DD3);
-        assertThat(MaterialDynamicColors.tertiaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.tertiaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff9D0002);
-        assertThat(MaterialDynamicColors.neutralPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff767684);
-        assertThat(MaterialDynamicColors.neutralVariantPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralVariantPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff757589);
     }
 
     @Test
     public void lightTheme_minContrast_primary() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff1218ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff1218ff);
     }
 
     @Test
     public void lightTheme_standardContrast_primary() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff0001c3);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff0001c3);
     }
 
     @Test
     public void lightTheme_maxContrast_primary() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff000181);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff000181);
     }
 
     @Test
     public void lightTheme_minContrast_primaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff5660ff);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff5660ff);
     }
 
     @Test
     public void lightTheme_standardContrast_primaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff2d36ff);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff2d36ff);
     }
 
     @Test
     public void lightTheme_maxContrast_primaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff0000e3);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff0000e3);
     }
 
     @Test
     public void lightTheme_minContrast_tertiaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffd93628);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xffd93628);
     }
 
     @Test
     public void lightTheme_standardContrast_tertiaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffb31910);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xffb31910);
     }
 
     @Test
     public void lightTheme_maxContrast_tertiaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff8c0002);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xff8c0002);
     }
 
     @Test
     public void lightTheme_minContrast_objectionableTertiaryContainerLightens() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff850096), false, -1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffbcac5a);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xffbcac5a);
     }
 
     @Test
     public void lightTheme_standardContrast_objectionableTertiaryContainerLightens() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff850096), false, 0.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffbcac5a);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xffbcac5a);
     }
 
     @Test
     public void lightTheme_maxContrast_objectionableTertiaryContainerDarkens() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff850096), false, 1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff4d4300);
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(0xff4d4300);
     }
 
     @Test
     public void lightTheme_minContrast_onPrimaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffcbcdff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffcbcdff);
     }
 
     @Test
     public void lightTheme_standardContrast_onPrimaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffcecfff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffcecfff);
     }
 
     @Test
     public void lightTheme_maxContrast_onPrimaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffd6d6ff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffd6d6ff);
     }
 
     @Test
     public void lightTheme_minContrast_surface() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffbf8ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_standardContrast_surface() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffbf8ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_maxContrast_surface() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffbf8ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void darkTheme_minContrast_primary() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff5660ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff5660ff);
     }
 
     @Test
     public void darkTheme_standardContrast_primary() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xffbec2ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffbec2ff);
     }
 
     @Test
     public void darkTheme_maxContrast_primary() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xfff6f4ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xfff6f4ff);
     }
 
     @Test
     public void darkTheme_minContrast_primaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff0000e6);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff0000e6);
     }
 
     @Test
     public void darkTheme_standardContrast_primaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff0000e6);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff0000e6);
     }
 
     @Test
     public void darkTheme_maxContrast_primaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffc4c6ff);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffc4c6ff);
     }
 
     @Test
     public void darkTheme_minContrast_onPrimaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff7a83ff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff7a83ff);
     }
 
     @Test
     public void darkTheme_standardContrast_onPrimaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffa4aaff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffa4aaff);
     }
 
     @Test
     public void darkTheme_maxContrast_onPrimaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff0001c6);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff0001c6);
     }
 
     @Test
     public void darkTheme_minContrast_onTertiaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xfffe513e);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xfffe513e);
     }
 
     @Test
     public void darkTheme_standardContrast_onTertiaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffFF9181);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xffFF9181);
     }
 
     @Test
     public void darkTheme_maxContrast_onTertiaryContainer() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff790001);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xff790001);
     }
 
     @Test
     public void darkTheme_minContrast_surface() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff12121d);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12121d);
     }
 
     @Test
     public void darkTheme_standardContrast_surface() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff12121d);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12121d);
     }
 
     @Test
     public void darkTheme_maxContrast_surface() {
         SchemeFidelity scheme = new SchemeFidelity(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff12121d);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12121d);
     }
+
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeFruitSaladTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeFruitSaladTest.java
index 4cf14d5..4bca2c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeFruitSaladTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeFruitSaladTest.java
@@ -25,226 +25,230 @@
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.SchemeFruitSalad;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
 public final class SchemeFruitSaladTest extends SysuiTestCase {
 
+    private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
+
     @Test
     public void testKeyColors() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 0.0);
 
-        assertThat(MaterialDynamicColors.primaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.primaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff0091C0);
-        assertThat(MaterialDynamicColors.secondaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.secondaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff3A7E9E);
-        assertThat(MaterialDynamicColors.tertiaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.tertiaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff6E72AC);
-        assertThat(MaterialDynamicColors.neutralPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff777682);
-        assertThat(MaterialDynamicColors.neutralVariantPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralVariantPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff75758B);
     }
 
     @Test
     public void lightTheme_minContrast_primary() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff007ea7);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff007ea7);
     }
 
     @Test
     public void lightTheme_standardContrast_primary() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff006688);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff006688);
     }
 
     @Test
     public void lightTheme_maxContrast_primary() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff002635);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff002635);
     }
 
     @Test
     public void lightTheme_minContrast_primaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffC2E8FF);
     }
 
     @Test
     public void lightTheme_standardContrast_primaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffC2E8FF);
     }
 
     @Test
     public void lightTheme_maxContrast_primaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff004862);
     }
 
     @Test
     public void lightTheme_minContrast_tertiaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffE0E0FF);
     }
 
     @Test
     public void lightTheme_standardContrast_tertiaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffE0E0FF);
     }
 
     @Test
     public void lightTheme_maxContrast_tertiaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xFF3A3E74);
     }
 
     @Test
     public void lightTheme_minContrast_onPrimaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff006C90);
     }
 
     @Test
     public void lightTheme_standardContrast_onPrimaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff001E2B);
     }
 
     @Test
     public void lightTheme_maxContrast_onPrimaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffACE1FF);
     }
 
     @Test
     public void lightTheme_minContrast_surface() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffbf8ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_standardContrast_surface() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffbf8ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_maxContrast_surface() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffbf8ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void darkTheme_minContrast_primary() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff007EA7);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff007EA7);
     }
 
     @Test
     public void darkTheme_standardContrast_primary() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xFF76D1FF);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xFF76D1FF);
     }
 
     @Test
     public void darkTheme_maxContrast_primary() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xFFECF7FF);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xFFECF7FF);
     }
 
     @Test
     public void darkTheme_minContrast_primaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xFF004D67);
     }
 
     @Test
     public void darkTheme_standardContrast_primaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xFF004D67);
     }
 
     @Test
     public void darkTheme_maxContrast_primaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xFF83D5FF);
     }
 
     @Test
     public void darkTheme_minContrast_onPrimaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff55C0F2);
     }
 
     @Test
     public void darkTheme_standardContrast_onPrimaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffC2E8FF);
     }
 
     @Test
     public void darkTheme_maxContrast_onPrimaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff003E54);
     }
 
     @Test
     public void darkTheme_minContrast_onTertiaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffADB0EF);
     }
 
     @Test
     public void darkTheme_standardContrast_onTertiaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffe0e0ff);
     }
 
     @Test
     public void darkTheme_maxContrast_onTertiaryContainer() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff30346A);
     }
 
     @Test
     public void darkTheme_minContrast_surface() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff12131c);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12131c);
     }
 
     @Test
     public void darkTheme_standardContrast_surface() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff12131c);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12131c);
     }
 
     @Test
     public void darkTheme_maxContrast_surface() {
         SchemeFruitSalad scheme = new SchemeFruitSalad(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff12131c);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12131c);
     }
 
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeMonochromeTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeMonochromeTest.java
index 3eca4dc..d511422 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeMonochromeTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeMonochromeTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.monet;
 
+import static com.google.common.truth.Truth.assertThat;
 import static com.android.systemui.monet.utils.ArgbSubject.assertThat;
 
 import androidx.test.filters.SmallTest;
@@ -25,204 +26,227 @@
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.SchemeMonochrome;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
 public final class SchemeMonochromeTest extends SysuiTestCase {
 
+    private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
+
     @Test
     public void testKeyColors() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 0.0);
 
-        assertThat(MaterialDynamicColors.primaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.primaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff070707);
-        assertThat(MaterialDynamicColors.secondaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.secondaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff070707);
-        assertThat(MaterialDynamicColors.tertiaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.tertiaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff070707);
-        assertThat(MaterialDynamicColors.neutralPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff070707);
-        assertThat(MaterialDynamicColors.neutralVariantPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralVariantPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff070707);
     }
 
     @Test
     public void lightTheme_minContrast_primary() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff747474);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, -1);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff3c3c3c);
     }
 
     @Test
     public void lightTheme_standardContrast_primary() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff5e5e5e);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff000000);
     }
 
     @Test
     public void lightTheme_maxContrast_primary() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff222222);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 1);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff000000);
     }
 
     @Test
     public void lightTheme_minContrast_primaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe2e2e2);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, -1);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff5f5f5f);
     }
 
     @Test
     public void lightTheme_standardContrast_primaryContainer() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe2e2e2);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff3b3b3b);
     }
 
     @Test
     public void lightTheme_maxContrast_primaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff434343);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 1);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff3a3a3a);
     }
 
     @Test
     public void lightTheme_minContrast_onPrimaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff646464);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, -1);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffd9d9d9);
     }
 
     @Test
     public void lightTheme_standardContrast_onPrimaryContainer() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff1b1b1b);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffffffff);
     }
 
     @Test
     public void lightTheme_maxContrast_onPrimaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffdadada);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 1);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffcdcdcd);
     }
 
     @Test
     public void lightTheme_minContrast_surface() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfff9f9f9);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, -1);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfff9f9f9);
     }
 
     @Test
     public void lightTheme_standardContrast_surface() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfff9f9f9);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfff9f9f9);
     }
 
     @Test
     public void lightTheme_maxContrast_surface() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfff9f9f9);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 1);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfff9f9f9);
     }
 
     @Test
     public void darkTheme_minContrast_primary() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff747474);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffcccccc);
     }
 
     @Test
     public void darkTheme_standardContrast_primary() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xffc6c6c6);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffffffff);
     }
 
     @Test
     public void darkTheme_maxContrast_primary() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xfff5f5f5);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffffffff);
     }
 
     @Test
     public void darkTheme_minContrast_primaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff474747);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffa3a3a3);
     }
 
     @Test
     public void darkTheme_standardContrast_primaryContainer() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff474747);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffd4d4d4);
     }
 
     @Test
     public void darkTheme_maxContrast_primaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffcbcbcb);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffd5d5d5);
     }
 
     @Test
     public void darkTheme_minContrast_onPrimaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffb5b5b5);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff393939);
     }
 
     @Test
     public void darkTheme_standardContrast_onPrimaryContainer() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe2e2e2);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff000000);
     }
 
     @Test
     public void darkTheme_maxContrast_onPrimaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff393939);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff404040);
     }
 
     @Test
     public void darkTheme_minContrast_onTertiaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffb5b5b5);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xffd1d1d1);
     }
 
     @Test
     public void darkTheme_standardContrast_onTertiaryContainer() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe2e2e2);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xff000000);
     }
 
     @Test
     public void darkTheme_maxContrast_onTertiaryContainer() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff393939);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xff393939);
     }
 
     @Test
     public void darkTheme_minContrast_surface() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131313);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, -1);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131313);
     }
 
     @Test
     public void darkTheme_standardContrast_surface() {
         SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131313);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131313);
     }
 
     @Test
     public void darkTheme_maxContrast_surface() {
-        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131313);
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 1);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131313);
+    }
+
+    @Test
+    public void darkTheme_monochromeSpec() {
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), true, 0.0);
+        assertThat(dynamicColors.primary().getHct(scheme).getTone()).isWithin(1).of(100);
+        assertThat(dynamicColors.onPrimary().getHct(scheme).getTone()).isWithin(1).of(10);
+        assertThat(dynamicColors.primaryContainer().getHct(scheme).getTone()).isWithin(1).of(85);
+        assertThat(dynamicColors.onPrimaryContainer().getHct(scheme).getTone()).isWithin(1).of(0);
+        assertThat(dynamicColors.secondary().getHct(scheme).getTone()).isWithin(1).of(80);
+        assertThat(dynamicColors.onSecondary().getHct(scheme).getTone()).isWithin(1).of(10);
+        assertThat(dynamicColors.secondaryContainer().getHct(scheme).getTone()).isWithin(1).of(30);
+        assertThat(dynamicColors.onSecondaryContainer().getHct(scheme).getTone()).isWithin(1).of(90);
+        assertThat(dynamicColors.tertiary().getHct(scheme).getTone()).isWithin(1).of(90);
+        assertThat(dynamicColors.onTertiary().getHct(scheme).getTone()).isWithin(1).of(10);
+        assertThat(dynamicColors.tertiaryContainer().getHct(scheme).getTone()).isWithin(1).of(60);
+        assertThat(dynamicColors.onTertiaryContainer().getHct(scheme).getTone()).isWithin(1).of(0);
+    }
+
+    @Test
+    public void lightTheme_monochromeSpec() {
+        SchemeMonochrome scheme = new SchemeMonochrome(Hct.fromInt(0xff0000ff), false, 0.0);
+        assertThat(dynamicColors.primary().getHct(scheme).getTone()).isWithin(1).of(0);
+        assertThat(dynamicColors.onPrimary().getHct(scheme).getTone()).isWithin(1).of(90);
+        assertThat(dynamicColors.primaryContainer().getHct(scheme).getTone()).isWithin(1).of(25);
+        assertThat(dynamicColors.onPrimaryContainer().getHct(scheme).getTone()).isWithin(1).of(100);
+        assertThat(dynamicColors.secondary().getHct(scheme).getTone()).isWithin(1).of(40);
+        assertThat(dynamicColors.onSecondary().getHct(scheme).getTone()).isWithin(1).of(100);
+        assertThat(dynamicColors.secondaryContainer().getHct(scheme).getTone()).isWithin(1).of(85);
+        assertThat(dynamicColors.onSecondaryContainer().getHct(scheme).getTone()).isWithin(1).of(10);
+        assertThat(dynamicColors.tertiary().getHct(scheme).getTone()).isWithin(1).of(25);
+        assertThat(dynamicColors.onTertiary().getHct(scheme).getTone()).isWithin(1).of(90);
+        assertThat(dynamicColors.tertiaryContainer().getHct(scheme).getTone()).isWithin(1).of(49);
+        assertThat(dynamicColors.onTertiaryContainer().getHct(scheme).getTone()).isWithin(1).of(100);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeNeutralTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeNeutralTest.java
index 71e9f4d..4f3fc7d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeNeutralTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeNeutralTest.java
@@ -25,204 +25,193 @@
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.SchemeNeutral;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
 public final class SchemeNeutralTest extends SysuiTestCase {
 
+    private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
+
     @Test
     public void testKeyColors() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, 0.0);
 
-        assertThat(MaterialDynamicColors.primaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.primaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff767685);
-        assertThat(MaterialDynamicColors.secondaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.secondaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff777680);
-        assertThat(MaterialDynamicColors.tertiaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.tertiaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff75758B);
-        assertThat(MaterialDynamicColors.neutralPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff787678);
-        assertThat(MaterialDynamicColors.neutralVariantPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralVariantPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff787678);
     }
 
     @Test
     public void lightTheme_minContrast_primary() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff737383);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff737383);
     }
 
     @Test
     public void lightTheme_standardContrast_primary() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff5d5d6c);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff5d5d6c);
     }
 
     @Test
     public void lightTheme_maxContrast_primary() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff21212e);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff21212e);
     }
 
     @Test
     public void lightTheme_minContrast_primaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe2e1f3);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffe2e1f3);
     }
 
     @Test
     public void lightTheme_standardContrast_primaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe2e1f3);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffe2e1f3);
     }
 
     @Test
     public void lightTheme_maxContrast_primaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff414250);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff414250);
     }
 
     @Test
     public void lightTheme_minContrast_onPrimaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff636372);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff636372);
     }
 
     @Test
     public void lightTheme_standardContrast_onPrimaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff1a1b27);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff1a1b27);
     }
 
     @Test
     public void lightTheme_maxContrast_onPrimaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffd9d8ea);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffd9d8ea);
     }
 
     @Test
     public void lightTheme_minContrast_surface() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffcf8fa);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffcf8fa);
     }
 
     @Test
     public void lightTheme_standardContrast_surface() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffcf8fa);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffcf8fa);
     }
 
     @Test
     public void lightTheme_maxContrast_surface() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffcf8fa);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffcf8fa);
     }
 
     @Test
     public void darkTheme_minContrast_primary() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff737383);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff737383);
     }
 
     @Test
     public void darkTheme_standardContrast_primary() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xffc6c5d6);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffc6c5d6);
     }
 
     @Test
     public void darkTheme_maxContrast_primary() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xfff6f4ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xfff6f4ff);
     }
 
     @Test
     public void darkTheme_minContrast_primaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff454654);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff454654);
     }
 
     @Test
     public void darkTheme_standardContrast_primaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff454654);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff454654);
     }
 
     @Test
     public void darkTheme_maxContrast_primaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffcac9da);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffcac9da);
     }
 
     @Test
     public void darkTheme_minContrast_onPrimaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffb5b3c4);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffb5b3c4);
     }
 
     @Test
     public void darkTheme_standardContrast_onPrimaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe2e1f3);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffe2e1f3);
     }
 
     @Test
     public void darkTheme_maxContrast_onPrimaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff373846);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff373846);
     }
 
     @Test
     public void darkTheme_minContrast_onTertiaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffb3b3cb);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xffb3b3cb);
     }
 
     @Test
     public void darkTheme_standardContrast_onTertiaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe1e0f9);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xffe1e0f9);
     }
 
     @Test
     public void darkTheme_maxContrast_onTertiaryContainer() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff37374b);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xff37374b);
     }
 
     @Test
     public void darkTheme_minContrast_surface() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131315);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131315);
     }
 
     @Test
     public void darkTheme_standardContrast_surface() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131315);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131315);
     }
 
     @Test
     public void darkTheme_maxContrast_surface() {
         SchemeNeutral scheme = new SchemeNeutral(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131315);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131315);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeRainbowTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeRainbowTest.java
index cc6f044..ece3f9a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeRainbowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeRainbowTest.java
@@ -25,225 +25,229 @@
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.SchemeRainbow;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
 public final class SchemeRainbowTest extends SysuiTestCase {
 
+    private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
+
     @Test
     public void testKeyColors() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 0.0);
 
-        assertThat(MaterialDynamicColors.primaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.primaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff696FC4);
-        assertThat(MaterialDynamicColors.secondaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.secondaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff75758B);
-        assertThat(MaterialDynamicColors.tertiaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.tertiaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff936B84);
-        assertThat(MaterialDynamicColors.neutralPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff070707);
-        assertThat(MaterialDynamicColors.neutralVariantPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralVariantPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff070707);
     }
 
     @Test
     public void lightTheme_minContrast_primary() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff676DC1);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff676DC1);
     }
 
     @Test
     public void lightTheme_standardContrast_primary() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff5056A9);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff5056A9);
     }
 
     @Test
     public void lightTheme_maxContrast_primary() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff0F136A);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff0F136A);
     }
 
     @Test
     public void lightTheme_minContrast_primaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffE0E0FF);
     }
 
     @Test
     public void lightTheme_standardContrast_primaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffE0E0FF);
     }
 
     @Test
     public void lightTheme_maxContrast_primaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff34398B);
     }
 
     @Test
     public void lightTheme_minContrast_tertiaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffffd8ee);
     }
 
     @Test
     public void lightTheme_standardContrast_tertiaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffffd8ee);
     }
 
     @Test
     public void lightTheme_maxContrast_tertiaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.tertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.tertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff5A384E);
     }
 
     @Test
     public void lightTheme_minContrast_onPrimaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff565CB0);
     }
 
     @Test
     public void lightTheme_standardContrast_onPrimaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff050865);
     }
 
     @Test
     public void lightTheme_maxContrast_onPrimaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffd6d6ff);
     }
 
     @Test
     public void lightTheme_minContrast_surface() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfff9f9f9);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfff9f9f9);
     }
 
     @Test
     public void lightTheme_standardContrast_surface() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfff9f9f9);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfff9f9f9);
     }
 
     @Test
     public void lightTheme_maxContrast_surface() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfff9f9f9);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfff9f9f9);
     }
 
     @Test
     public void darkTheme_minContrast_primary() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff676DC1);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff676DC1);
     }
 
     @Test
     public void darkTheme_standardContrast_primary() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xffbec2ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffbec2ff);
     }
 
     @Test
     public void darkTheme_maxContrast_primary() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xfff6f4ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xfff6f4ff);
     }
 
     @Test
     public void darkTheme_minContrast_primaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff383E8F);
     }
 
     @Test
     public void darkTheme_standardContrast_primaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff383E8F);
     }
 
     @Test
     public void darkTheme_maxContrast_primaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffc4c6ff);
     }
 
     @Test
     public void darkTheme_minContrast_onPrimaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffa9afff);
     }
 
     @Test
     public void darkTheme_standardContrast_onPrimaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffe0e0ff);
     }
 
     @Test
     public void darkTheme_maxContrast_onPrimaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff292f81);
     }
 
     @Test
     public void darkTheme_minContrast_onTertiaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffd5a8c3);
     }
 
     @Test
     public void darkTheme_standardContrast_onTertiaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xffffd8ee);
     }
 
     @Test
     public void darkTheme_maxContrast_onTertiaryContainer() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(
                 0xff4f2e44);
     }
 
     @Test
     public void darkTheme_minContrast_surface() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131313);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131313);
     }
 
     @Test
     public void darkTheme_standardContrast_surface() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131313);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131313);
     }
 
     @Test
     public void darkTheme_maxContrast_surface() {
         SchemeRainbow scheme = new SchemeRainbow(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131313);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131313);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeTonalSpotTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeTonalSpotTest.java
index e4880d9..01d199b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeTonalSpotTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeTonalSpotTest.java
@@ -25,348 +25,338 @@
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.SchemeTonalSpot;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
 public final class SchemeTonalSpotTest extends SysuiTestCase {
 
+    private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
+
     @Test
     public void testKeyColors() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 0.0);
 
-        assertThat(MaterialDynamicColors.primaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.primaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff6E72AC);
-        assertThat(MaterialDynamicColors.secondaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.secondaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff75758B);
-        assertThat(MaterialDynamicColors.tertiaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.tertiaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff936B84);
-        assertThat(MaterialDynamicColors.neutralPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff78767A);
-        assertThat(MaterialDynamicColors.neutralVariantPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralVariantPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff777680);
     }
 
+
     @Test
     public void lightTheme_minContrast_primary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff6c70aa);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff6a6fb1);
     }
 
     @Test
     public void lightTheme_standardContrast_primary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff555992);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff545999);
     }
 
     @Test
     public void lightTheme_maxContrast_primary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff181c51);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff161a59);
     }
 
     @Test
     public void lightTheme_minContrast_primaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe0e0ff);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffe0e0ff);
     }
 
     @Test
     public void lightTheme_standardContrast_primaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe0e0ff);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffe0e0ff);
     }
 
     @Test
     public void lightTheme_maxContrast_primaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff3a3e74);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff383c7c);
     }
 
     @Test
     public void lightTheme_minContrast_onPrimaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff5C5F98);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff5a5fa0);
     }
 
     @Test
     public void lightTheme_standardContrast_onPrimaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff11144B);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff0e1253);
     }
 
     @Test
     public void lightTheme_maxContrast_onPrimaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffd6d6ff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffd6d6ff);
     }
 
     @Test
     public void lightTheme_minContrast_surface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xffFCF8FD);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_standardContrast_surface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xffFCF8FD);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_maxContrast_surface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xffFCF8FD);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_minContrast_onSurface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onSurface.getArgb(scheme)).isSameColorAs(0xff605E62);
+        assertThat(dynamicColors.onSurface().getArgb(scheme)).isSameColorAs(0xff5f5e65);
     }
 
     @Test
     public void lightTheme_standardContrast_onSurface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onSurface.getArgb(scheme)).isSameColorAs(0xff1B1B1F);
+        assertThat(dynamicColors.onSurface().getArgb(scheme)).isSameColorAs(0xff1b1b21);
     }
 
     @Test
     public void lightTheme_maxContrast_onSurface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onSurface.getArgb(scheme)).isSameColorAs(0xff1B1A1E);
+        assertThat(dynamicColors.onSurface().getArgb(scheme)).isSameColorAs(0xff1a1a20);
     }
 
     @Test
     public void lightTheme_minContrast_onSecondary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onSecondary.getArgb(scheme)).isSameColorAs(0xffcfcfe7);
+        assertThat(dynamicColors.onSecondary().getArgb(scheme)).isSameColorAs(0xffcfcfe7);
     }
 
     @Test
     public void lightTheme_standardContrast_onSecondary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onSecondary.getArgb(scheme)).isSameColorAs(0xffffffff);
+        assertThat(dynamicColors.onSecondary().getArgb(scheme)).isSameColorAs(0xffffffff);
     }
 
     @Test
     public void lightTheme_maxContrast_onSecondary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onSecondary.getArgb(scheme)).isSameColorAs(0xffababc3);
+        assertThat(dynamicColors.onSecondary().getArgb(scheme)).isSameColorAs(0xffababc3);
     }
 
     @Test
     public void lightTheme_minContrast_onTertiary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onTertiary.getArgb(scheme)).isSameColorAs(0xfff3c3df);
+        assertThat(dynamicColors.onTertiary().getArgb(scheme)).isSameColorAs(0xfff3c3df);
     }
 
     @Test
     public void lightTheme_standardContrast_onTertiary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onTertiary.getArgb(scheme)).isSameColorAs(0xffffffff);
+        assertThat(dynamicColors.onTertiary().getArgb(scheme)).isSameColorAs(0xffffffff);
     }
 
     @Test
     public void lightTheme_maxContrast_onTertiary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onTertiary.getArgb(scheme)).isSameColorAs(0xffcda0bb);
+        assertThat(dynamicColors.onTertiary().getArgb(scheme)).isSameColorAs(0xffcda0bb);
     }
 
     @Test
     public void lightTheme_minContrast_onError() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onError.getArgb(scheme)).isSameColorAs(0xffffc2bb);
+        assertThat(dynamicColors.onError().getArgb(scheme)).isSameColorAs(0xffffc2bb);
     }
 
     @Test
     public void lightTheme_standardContrast_onError() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onError.getArgb(scheme)).isSameColorAs(0xffffffff);
+        assertThat(dynamicColors.onError().getArgb(scheme)).isSameColorAs(0xffffffff);
     }
 
     @Test
     public void lightTheme_maxContrast_onError() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onError.getArgb(scheme)).isSameColorAs(0xffff8d80);
+        assertThat(dynamicColors.onError().getArgb(scheme)).isSameColorAs(0xffff8d80);
     }
 
     @Test
     public void darkTheme_minContrast_primary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff6C70AA);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff6a6fb1);
     }
 
     @Test
     public void darkTheme_standardContrast_primary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xffbec2ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffbec2ff);
     }
 
     @Test
     public void darkTheme_maxContrast_primary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xfff6f4ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xfff6f4ff);
     }
 
     @Test
     public void darkTheme_minContrast_primaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff3E4278);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff3c4180);
     }
 
     @Test
     public void darkTheme_standardContrast_primaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff3E4278);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff3c4180);
     }
 
     @Test
     public void darkTheme_maxContrast_primaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffc4c6ff);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffc4c6ff);
     }
 
     @Test
     public void darkTheme_minContrast_onPrimaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffadb0ef);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffabaff7);
     }
 
     @Test
     public void darkTheme_standardContrast_onPrimaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe0e0ff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffe0e0ff);
     }
 
     @Test
     public void darkTheme_maxContrast_onPrimaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff30346A);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff2e3271);
     }
 
     @Test
     public void darkTheme_minContrast_onTertiaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffd5a8c3);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xffd5a8c3);
     }
 
     @Test
     public void darkTheme_standardContrast_onTertiaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffffd8ee);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xffffd8ee);
     }
 
     @Test
     public void darkTheme_maxContrast_onTertiaryContainer() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff4f2e44);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xff4f2e44);
     }
 
     @Test
     public void darkTheme_minContrast_onSecondary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onSecondary.getArgb(scheme)).isSameColorAs(0xfffffbff);
+        assertThat(dynamicColors.onSecondary().getArgb(scheme)).isSameColorAs(0xfffffbff);
     }
 
     @Test
     public void darkTheme_standardContrast_onSecondary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onSecondary.getArgb(scheme)).isSameColorAs(0xff2e2f42);
+        assertThat(dynamicColors.onSecondary().getArgb(scheme)).isSameColorAs(0xff2e2f42);
     }
 
     @Test
     public void darkTheme_maxContrast_onSecondary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onSecondary.getArgb(scheme)).isSameColorAs(0xff505165);
+        assertThat(dynamicColors.onSecondary().getArgb(scheme)).isSameColorAs(0xff505165);
     }
 
     @Test
     public void darkTheme_minContrast_onTertiary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onTertiary.getArgb(scheme)).isSameColorAs(0xfffffbff);
+        assertThat(dynamicColors.onTertiary().getArgb(scheme)).isSameColorAs(0xfffffbff);
     }
 
     @Test
     public void darkTheme_standardContrast_onTertiary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onTertiary.getArgb(scheme)).isSameColorAs(0xff46263b);
+        assertThat(dynamicColors.onTertiary().getArgb(scheme)).isSameColorAs(0xff46263b);
     }
 
     @Test
     public void darkTheme_maxContrast_onTertiary() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onTertiary.getArgb(scheme)).isSameColorAs(0xff6b485f);
+        assertThat(dynamicColors.onTertiary().getArgb(scheme)).isSameColorAs(0xff6b485f);
     }
 
     @Test
     public void darkTheme_minContrast_onError() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onError.getArgb(scheme)).isSameColorAs(0xfffffbff);
+        assertThat(dynamicColors.onError().getArgb(scheme)).isSameColorAs(0xfffffbff);
     }
 
     @Test
     public void darkTheme_standardContrast_onError() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onError.getArgb(scheme)).isSameColorAs(0xff690005);
+        assertThat(dynamicColors.onError().getArgb(scheme)).isSameColorAs(0xff690005);
     }
 
     @Test
     public void darkTheme_maxContrast_onError() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onError.getArgb(scheme)).isSameColorAs(0xffa80710);
+        assertThat(dynamicColors.onError().getArgb(scheme)).isSameColorAs(0xffa80710);
     }
 
     @Test
     public void darkTheme_minContrast_surface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131316);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131318);
     }
 
     @Test
     public void darkTheme_standardContrast_surface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131316);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131318);
     }
 
     @Test
     public void darkTheme_maxContrast_surface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff131316);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff131318);
     }
 
     @Test
     public void darkTheme_minContrast_onSurface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onSurface.getArgb(scheme)).isSameColorAs(0xffa4a2a6);
+        assertThat(dynamicColors.onSurface().getArgb(scheme)).isSameColorAs(0xffa4a2a9);
     }
 
     @Test
     public void darkTheme_standardContrast_onSurface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onSurface.getArgb(scheme)).isSameColorAs(0xffe5e1e6);
+        assertThat(dynamicColors.onSurface().getArgb(scheme)).isSameColorAs(0xffe4e1e9);
     }
 
     @Test
     public void darkTheme_maxContrast_onSurface() {
         SchemeTonalSpot scheme = new SchemeTonalSpot(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onSurface.getArgb(scheme)).isSameColorAs(0xffe6e2e7);
+        assertThat(dynamicColors.onSurface().getArgb(scheme)).isSameColorAs(0xffe5e2ea);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeVibrantTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeVibrantTest.java
index e5963a2..0fb53eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeVibrantTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/SchemeVibrantTest.java
@@ -25,204 +25,193 @@
 import com.android.systemui.monet.hct.Hct;
 import com.android.systemui.monet.scheme.SchemeVibrant;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+@Ignore("b/279581953")
 @SmallTest
 @RunWith(JUnit4.class)
 public final class SchemeVibrantTest extends SysuiTestCase {
 
+    private final MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
+
     @Test
     public void testKeyColors() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, 0.0);
 
-        assertThat(MaterialDynamicColors.primaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.primaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff080CFF);
-        assertThat(MaterialDynamicColors.secondaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.secondaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff7B7296);
-        assertThat(MaterialDynamicColors.tertiaryPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.tertiaryPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff886C9D);
-        assertThat(MaterialDynamicColors.neutralPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff777682);
-        assertThat(MaterialDynamicColors.neutralVariantPaletteKeyColor.getArgb(scheme))
+        assertThat(dynamicColors.neutralVariantPaletteKeyColor().getArgb(scheme))
                 .isSameColorAs(0xff767685);
     }
 
     @Test
     public void lightTheme_minContrast_primary() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff5660ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff5660ff);
     }
 
     @Test
     public void lightTheme_standardContrast_primary() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff343dff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff343dff);
     }
 
     @Test
     public void lightTheme_maxContrast_primary() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff000181);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff000181);
     }
 
     @Test
     public void lightTheme_minContrast_primaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe0e0ff);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffe0e0ff);
     }
 
     @Test
     public void lightTheme_standardContrast_primaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe0e0ff);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffe0e0ff);
     }
 
     @Test
     public void lightTheme_maxContrast_primaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff0000e3);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff0000e3);
     }
 
     @Test
     public void lightTheme_minContrast_onPrimaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff3e47ff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff3e47ff);
     }
 
     @Test
     public void lightTheme_standardContrast_onPrimaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff00006e);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff00006e);
     }
 
     @Test
     public void lightTheme_maxContrast_onPrimaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffd6d6ff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffd6d6ff);
     }
 
     @Test
     public void lightTheme_minContrast_surface() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffbf8ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_standardContrast_surface() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffbf8ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void lightTheme_maxContrast_surface() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), false, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xfffbf8ff);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xfffbf8ff);
     }
 
     @Test
     public void darkTheme_minContrast_primary() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xff5660ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xff5660ff);
     }
 
     @Test
     public void darkTheme_standardContrast_primary() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xffbec2ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xffbec2ff);
     }
 
     @Test
     public void darkTheme_maxContrast_primary() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primary.getArgb(scheme)).isSameColorAs(0xfff6f4ff);
+        assertThat(dynamicColors.primary().getArgb(scheme)).isSameColorAs(0xfff6f4ff);
     }
 
     @Test
     public void darkTheme_minContrast_primaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff0000ef);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff0000ef);
     }
 
     @Test
     public void darkTheme_standardContrast_primaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff0000ef);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xff0000ef);
     }
 
     @Test
     public void darkTheme_maxContrast_primaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.primaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffc4c6ff);
+        assertThat(dynamicColors.primaryContainer().getArgb(scheme)).isSameColorAs(0xffc4c6ff);
     }
 
     @Test
     public void darkTheme_minContrast_onPrimaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffa9afff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffa9afff);
     }
 
     @Test
     public void darkTheme_standardContrast_onPrimaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffe0e0ff);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xffe0e0ff);
     }
 
     @Test
     public void darkTheme_maxContrast_onPrimaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onPrimaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff0001c6);
+        assertThat(dynamicColors.onPrimaryContainer().getArgb(scheme)).isSameColorAs(0xff0001c6);
     }
 
     @Test
     public void darkTheme_minContrast_onTertiaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xffc9a9df);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xffc9a9df);
     }
 
     @Test
     public void darkTheme_standardContrast_onTertiaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xfff2daff);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xfff2daff);
     }
 
     @Test
     public void darkTheme_maxContrast_onTertiaryContainer() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.onTertiaryContainer.getArgb(scheme)).isSameColorAs(
-                0xff472e5b);
+        assertThat(dynamicColors.onTertiaryContainer().getArgb(scheme)).isSameColorAs(0xff472e5b);
     }
 
     @Test
     public void darkTheme_minContrast_surface() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, -1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff12131C);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12131a);
     }
 
     @Test
     public void darkTheme_standardContrast_surface() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 0.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff12131C);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12131a);
     }
 
     @Test
     public void darkTheme_maxContrast_surface() {
         SchemeVibrant scheme = new SchemeVibrant(Hct.fromInt(0xff0000ff), true, 1.0);
-        assertThat(MaterialDynamicColors.surface.getArgb(scheme)).isSameColorAs(0xff12131C);
+        assertThat(dynamicColors.surface().getArgb(scheme)).isSameColorAs(0xff12131a);
     }
 }
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
index d9428f8..611c5b9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt
@@ -104,6 +104,9 @@
         continueTouch(START_X + touchSlop.toFloat() + 1)
         // Move again to cross the back trigger threshold
         continueTouch(START_X + touchSlop + triggerThreshold + 1)
+        // Wait threshold duration and hold touch past trigger threshold
+        Thread.sleep((MAX_DURATION_ENTRY_BEFORE_ACTIVE_ANIMATION + 1).toLong())
+        continueTouch(START_X + touchSlop + triggerThreshold + 1)
 
         assertThat(mBackPanelController.currentState)
             .isEqualTo(BackPanelController.GestureState.ACTIVE)
@@ -114,14 +117,22 @@
 
         finishTouchActionUp(START_X + touchSlop + triggerThreshold + 1)
         assertThat(mBackPanelController.currentState)
-            .isEqualTo(BackPanelController.GestureState.FLUNG)
+            .isEqualTo(BackPanelController.GestureState.COMMITTED)
         verify(backCallback).triggerBack()
     }
 
     @Test
     fun handlesBackCancelled() {
         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 -
+                mBackPanelController.params.deactivationTriggerThreshold
+        )
+        // Wait threshold duration and hold touch before trigger threshold
+        Thread.sleep((MAX_DURATION_ENTRY_BEFORE_ACTIVE_ANIMATION + 1).toLong())
         continueTouch(
             START_X + touchSlop + triggerThreshold -
                 mBackPanelController.params.deactivationTriggerThreshold
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt
new file mode 100644
index 0000000..36b913f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.notetask
+
+import android.content.Context
+import android.content.Intent
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import androidx.test.rule.ActivityTestRule
+import androidx.test.runner.intercepting.SingleActivityFactory
+import com.android.dx.mockito.inline.extended.ExtendedMockito.verify
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.notetask.LaunchNotesRoleSettingsTrampolineActivity.Companion.ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE
+import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+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
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@TestableLooper.RunWithLooper
+class LaunchNotesRoleSettingsTrampolineActivityTest : SysuiTestCase() {
+
+    @Mock lateinit var noteTaskController: NoteTaskController
+
+    @Rule
+    @JvmField
+    val activityRule =
+        ActivityTestRule<LaunchNotesRoleSettingsTrampolineActivity>(
+            /* activityFactory= */ object :
+                SingleActivityFactory<LaunchNotesRoleSettingsTrampolineActivity>(
+                    LaunchNotesRoleSettingsTrampolineActivity::class.java
+                ) {
+                override fun create(intent: Intent?) =
+                    LaunchNotesRoleSettingsTrampolineActivity(noteTaskController)
+            },
+            /* initialTouchMode= */ false,
+            /* launchActivity= */ false,
+        )
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @After
+    fun tearDown() {
+        activityRule.finishActivity()
+    }
+
+    @Test
+    fun startActivity_noAction_shouldLaunchNotesRoleSettingTaskWithNullEntryPoint() {
+        activityRule.launchActivity(/* startIntent= */ null)
+
+        verify(noteTaskController).startNotesRoleSetting(any(Context::class.java), eq(null))
+    }
+
+    @Test
+    fun startActivity_quickAffordanceAction_shouldLaunchNotesRoleSettingTaskWithQuickAffordanceEntryPoint() { // ktlint-disable max-line-length
+        activityRule.launchActivity(Intent(ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE))
+
+        verify(noteTaskController)
+            .startNotesRoleSetting(any(Context::class.java), eq(QUICK_AFFORDANCE))
+    }
+}
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 7dc622b..5f89705 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -45,8 +45,11 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.notetask.NoteTaskController.Companion.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
+import com.android.systemui.notetask.NoteTaskController.Companion.SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT
 import com.android.systemui.notetask.NoteTaskController.Companion.SHORTCUT_ID
-import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
+import com.android.systemui.notetask.NoteTaskEntryPoint.APP_CLIPS
+import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
+import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
 import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
 import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity
 import com.android.systemui.settings.FakeUserTracker
@@ -423,8 +426,8 @@
                 eq(COMPONENT_ENABLED_STATE_ENABLED),
                 eq(PackageManager.DONT_KILL_APP),
             )
-        assertThat(argument.value.className)
-            .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+
+        assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
     }
 
     @Test
@@ -438,8 +441,7 @@
                 eq(COMPONENT_ENABLED_STATE_DISABLED),
                 eq(PackageManager.DONT_KILL_APP),
             )
-        assertThat(argument.value.className)
-            .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+        assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
     }
 
     @Test
@@ -458,8 +460,7 @@
                 eq(COMPONENT_ENABLED_STATE_ENABLED),
                 eq(PackageManager.DONT_KILL_APP),
             )
-        assertThat(argument.value.className)
-            .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+        assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
     }
 
     @Test
@@ -479,8 +480,7 @@
                 eq(COMPONENT_ENABLED_STATE_DISABLED),
                 eq(PackageManager.DONT_KILL_APP),
             )
-        assertThat(argument.value.className)
-            .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+        assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
     }
     // endregion
 
@@ -496,7 +496,7 @@
             )
             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
 
-        createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
+        createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
 
         verifyZeroInteractions(context, bubbles, eventLogger)
     }
@@ -512,7 +512,7 @@
             )
             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
 
-        createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
+        createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
 
         verifyZeroInteractions(context, bubbles, eventLogger)
     }
@@ -528,7 +528,7 @@
             )
             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
 
-        createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
+        createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
 
         verifyNoteTaskOpenInBubbleInUser(userTracker.userHandle)
     }
@@ -544,7 +544,7 @@
             )
             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
 
-        createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
+        createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
 
         verifyNoteTaskOpenInBubbleInUser(userTracker.userHandle)
     }
@@ -556,7 +556,7 @@
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(listOf(mainUserInfo), mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
-        createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
+        createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
 
         verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
     }
@@ -566,7 +566,7 @@
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
-        createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
+        createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
 
         verifyNoteTaskOpenInBubbleInUser(workUserInfo.userHandle)
     }
@@ -620,6 +620,38 @@
         }
     }
 
+    // region onRoleHoldersChanged
+    @Test
+    fun onRoleHoldersChanged_notNotesRole_doNothing() {
+        val user = UserHandle.of(0)
+
+        createNoteTaskController(isEnabled = true).onRoleHoldersChanged("NOT_NOTES", user)
+
+        verifyZeroInteractions(context)
+    }
+
+    @Test
+    fun onRoleHoldersChanged_notesRole_sameUser_shouldUpdateShortcuts() {
+        val user = userTracker.userHandle
+        val controller = spy(createNoteTaskController())
+        doNothing().whenever(controller).updateNoteTaskAsUser(any())
+
+        controller.onRoleHoldersChanged(ROLE_NOTES, user)
+
+        verify(controller).updateNoteTaskAsUser(user)
+    }
+
+    @Test
+    fun onRoleHoldersChanged_notesRole_differentUser_shouldUpdateShortcutsInUserProcess() {
+        // FakeUserTracker will default to UserHandle.SYSTEM.
+        val user = UserHandle.CURRENT
+
+        createNoteTaskController(isEnabled = true).onRoleHoldersChanged(ROLE_NOTES, user)
+
+        verify(context).startServiceAsUser(any(), eq(user))
+    }
+    // endregion
+
     // region updateNoteTaskAsUser
     @Test
     fun updateNoteTaskAsUser_withNotesRole_withShortcuts_shouldUpdateShortcuts() {
@@ -632,8 +664,7 @@
                 eq(COMPONENT_ENABLED_STATE_ENABLED),
                 eq(PackageManager.DONT_KILL_APP),
             )
-        assertThat(actualComponent.value.className)
-            .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+        assertThat(actualComponent.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
         verify(shortcutManager, never()).disableShortcuts(any())
         verify(shortcutManager).enableShortcuts(listOf(SHORTCUT_ID))
         val actualShortcuts = argumentCaptor<List<ShortcutInfo>>()
@@ -664,8 +695,7 @@
                 eq(COMPONENT_ENABLED_STATE_DISABLED),
                 eq(PackageManager.DONT_KILL_APP),
             )
-        assertThat(argument.value.className)
-            .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+        assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
         verify(shortcutManager).disableShortcuts(listOf(SHORTCUT_ID))
         verify(shortcutManager, never()).enableShortcuts(any())
         verify(shortcutManager, never()).updateShortcuts(any())
@@ -682,8 +712,7 @@
                 eq(COMPONENT_ENABLED_STATE_DISABLED),
                 eq(PackageManager.DONT_KILL_APP),
             )
-        assertThat(argument.value.className)
-            .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+        assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
         verify(shortcutManager).disableShortcuts(listOf(SHORTCUT_ID))
         verify(shortcutManager, never()).enableShortcuts(any())
         verify(shortcutManager, never()).updateShortcuts(any())
@@ -708,6 +737,129 @@
     }
     // endregion
 
+    // region getUserForHandlingNotesTaking
+    @Test
+    fun getUserForHandlingNotesTaking_cope_quickAffordance_shouldReturnWorkProfileUser() {
+        whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        val user = createNoteTaskController().getUserForHandlingNotesTaking(QUICK_AFFORDANCE)
+
+        assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id))
+    }
+
+    @Test
+    fun getUserForHandlingNotesTaking_cope_tailButton_shouldReturnWorkProfileUser() {
+        whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        val user = createNoteTaskController().getUserForHandlingNotesTaking(TAIL_BUTTON)
+
+        assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id))
+    }
+
+    @Test
+    fun getUserForHandlingNotesTaking_cope_appClip_shouldReturnCurrentUser() {
+        whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        val user = createNoteTaskController().getUserForHandlingNotesTaking(APP_CLIPS)
+
+        assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
+    }
+
+    @Test
+    fun getUserForHandlingNotesTaking_noManagement_quickAffordance_shouldReturnCurrentUser() {
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        val user = createNoteTaskController().getUserForHandlingNotesTaking(QUICK_AFFORDANCE)
+
+        assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
+    }
+
+    @Test
+    fun getUserForHandlingNotesTaking_noManagement_tailButton_shouldReturnCurrentUser() {
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        val user = createNoteTaskController().getUserForHandlingNotesTaking(TAIL_BUTTON)
+
+        assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
+    }
+
+    @Test
+    fun getUserForHandlingNotesTaking_noManagement_appClip_shouldReturnCurrentUser() {
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        val user = createNoteTaskController().getUserForHandlingNotesTaking(APP_CLIPS)
+
+        assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
+    }
+    // endregion
+
+    // startregion startNotesRoleSetting
+    @Test
+    fun startNotesRoleSetting_cope_quickAffordance_shouldStartNoteRoleIntentWithWorkProfileUser() {
+        whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        createNoteTaskController().startNotesRoleSetting(context, QUICK_AFFORDANCE)
+
+        val intentCaptor = argumentCaptor<Intent>()
+        val userCaptor = argumentCaptor<UserHandle>()
+        verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+        intentCaptor.value.let { intent ->
+            assertThat(intent).hasAction(Intent.ACTION_MANAGE_DEFAULT_APP)
+        }
+        assertThat(userCaptor.value).isEqualTo(UserHandle.of(workUserInfo.id))
+    }
+
+    @Test
+    fun startNotesRoleSetting_cope_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() {
+        whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        createNoteTaskController().startNotesRoleSetting(context, entryPoint = null)
+
+        val intentCaptor = argumentCaptor<Intent>()
+        val userCaptor = argumentCaptor<UserHandle>()
+        verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+        intentCaptor.value.let { intent ->
+            assertThat(intent).hasAction(Intent.ACTION_MANAGE_DEFAULT_APP)
+        }
+        assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
+    }
+
+    @Test
+    fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        createNoteTaskController().startNotesRoleSetting(context, QUICK_AFFORDANCE)
+
+        val intentCaptor = argumentCaptor<Intent>()
+        val userCaptor = argumentCaptor<UserHandle>()
+        verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+        intentCaptor.value.let { intent ->
+            assertThat(intent).hasAction(Intent.ACTION_MANAGE_DEFAULT_APP)
+        }
+        assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
+    }
+
+    @Test
+    fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        createNoteTaskController().startNotesRoleSetting(context, entryPoint = null)
+
+        val intentCaptor = argumentCaptor<Intent>()
+        val userCaptor = argumentCaptor<UserHandle>()
+        verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+        intentCaptor.value.let { intent ->
+            assertThat(intent).hasAction(Intent.ACTION_MANAGE_DEFAULT_APP)
+        }
+        assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
+    }
+    // endregion
+
     private companion object {
         const val NOTE_TASK_SHORT_LABEL = "Notetaking"
         const val NOTE_TASK_ACTIVITY_NAME = "NoteTaskActivity"
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 42ef2b5..4526580 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
@@ -18,7 +18,12 @@
 
 package com.android.systemui.notetask.quickaffordance
 
+import android.app.role.RoleManager
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.content.pm.PackageManager.ApplicationInfoFlags
 import android.hardware.input.InputSettings
+import android.os.UserHandle
 import android.os.UserManager
 import android.test.suitebuilder.annotation.SmallTest
 import android.testing.AndroidTestingRunner
@@ -31,11 +36,18 @@
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.LockScreenState
 import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
+import com.android.systemui.notetask.LaunchNotesRoleSettingsTrampolineActivity.Companion.ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE
 import com.android.systemui.notetask.NoteTaskController
 import com.android.systemui.notetask.NoteTaskEntryPoint
+import com.android.systemui.notetask.NoteTaskInfoResolver
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract.LockScreenQuickAffordances.AffordanceTable.COMPONENT_NAME_SEPARATOR
 import com.android.systemui.stylus.StylusManager
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -45,6 +57,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.anyString
 import org.mockito.Mockito.verify
 import org.mockito.MockitoSession
 import org.mockito.quality.Strictness
@@ -58,6 +71,8 @@
     @Mock lateinit var stylusManager: StylusManager
     @Mock lateinit var repository: KeyguardQuickAffordanceRepository
     @Mock lateinit var userManager: UserManager
+    @Mock lateinit var roleManager: RoleManager
+    @Mock lateinit var packageManager: PackageManager
 
     private lateinit var mockitoSession: MockitoSession
 
@@ -69,6 +84,23 @@
                 .mockStatic(InputSettings::class.java)
                 .strictness(Strictness.LENIENT)
                 .startMocking()
+
+        whenever(
+                packageManager.getApplicationInfoAsUser(
+                    anyString(),
+                    any(ApplicationInfoFlags::class.java),
+                    any(UserHandle::class.java)
+                )
+            )
+            .thenReturn(ApplicationInfo())
+        whenever(controller.getUserForHandlingNotesTaking(any())).thenReturn(UserHandle.SYSTEM)
+        whenever(
+                roleManager.getRoleHoldersAsUser(
+                    eq(RoleManager.ROLE_NOTES),
+                    any(UserHandle::class.java)
+                )
+            )
+            .thenReturn(listOf("com.google.test.notes"))
     }
 
     @After
@@ -85,6 +117,9 @@
             keyguardMonitor = mock(),
             lazyRepository = { repository },
             isEnabled = isEnabled,
+            backgroundExecutor = FakeExecutor(FakeSystemClock()),
+            roleManager = roleManager,
+            noteTaskInfoResolver = NoteTaskInfoResolver(roleManager, packageManager)
         )
 
     private fun createLockScreenStateVisible(): LockScreenState =
@@ -112,6 +147,27 @@
     }
 
     @Test
+    fun lockScreenState_stylusUsed_userUnlocked_isSelected_noDefaultNotesAppSet_shouldEmitHidden() =
+        runTest {
+            TestConfig()
+                .setStylusEverUsed(true)
+                .setUserUnlocked(true)
+                .setConfigSelections(mock<NoteTaskQuickAffordanceConfig>())
+            whenever(
+                    roleManager.getRoleHoldersAsUser(
+                        eq(RoleManager.ROLE_NOTES),
+                        any(UserHandle::class.java)
+                    )
+                )
+                .thenReturn(emptyList())
+
+            val underTest = createUnderTest()
+            val actual by collectLastValue(underTest.lockScreenState)
+
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
+
+    @Test
     fun lockScreenState_stylusUnused_userUnlocked_isSelected_shouldEmitHidden() = runTest {
         TestConfig()
             .setStylusEverUsed(false)
@@ -217,6 +273,39 @@
         verify(controller).showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
     }
 
+    // region getPickerScreenState
+    @Test
+    fun getPickerScreenState_defaultNoteAppSet_shouldReturnDefault() = runTest {
+        val underTest = createUnderTest(isEnabled = true)
+
+        assertThat(underTest.getPickerScreenState())
+            .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
+    }
+
+    @Test
+    fun getPickerScreenState_nodefaultNoteAppSet_shouldReturnDisable() = runTest {
+        val underTest = createUnderTest(isEnabled = true)
+        whenever(
+                roleManager.getRoleHoldersAsUser(
+                    eq(RoleManager.ROLE_NOTES),
+                    any(UserHandle::class.java)
+                )
+            )
+            .thenReturn(emptyList())
+
+        assertThat(underTest.getPickerScreenState())
+            .isEqualTo(
+                KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
+                    listOf("Select a default notes app to use the notetaking shortcut"),
+                    actionText = "Select app",
+                    actionComponentName =
+                        "${context.packageName}$COMPONENT_NAME_SEPARATOR" +
+                            "$ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE"
+                )
+            )
+    }
+    // endregion
+
     private inner class TestConfig {
 
         fun setStylusEverUsed(value: Boolean) = also {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 0ab0e2b..87ca9df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -106,6 +106,7 @@
     @Mock private QSSquishinessController mSquishinessController;
     @Mock private FooterActionsViewModel mFooterActionsViewModel;
     @Mock private FooterActionsViewModel.Factory mFooterActionsViewModelFactory;
+    @Mock private FooterActionsViewBinder mFooterActionsViewBinder;
     @Mock private LargeScreenShadeInterpolator mLargeScreenShadeInterpolator;
     @Mock private FeatureFlags mFeatureFlags;
     private View mQsFragmentView;
@@ -558,6 +559,7 @@
                 mock(QSLogger.class),
                 mock(FooterActionsController.class),
                 mFooterActionsViewModelFactory,
+                mFooterActionsViewBinder,
                 mLargeScreenShadeInterpolator,
                 mFeatureFlags);
     }
@@ -584,7 +586,7 @@
         when(mQsFragmentView.findViewById(R.id.header)).thenReturn(mHeader);
         when(mQsFragmentView.findViewById(android.R.id.edit)).thenReturn(new View(mContext));
         when(mQsFragmentView.findViewById(R.id.qs_footer_actions)).thenAnswer(
-                invocation -> FooterActionsViewBinder.create(mContext));
+                invocation -> new FooterActionsViewBinder().create(mContext));
     }
 
     private void setUpInflater() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index 88d7e9c..2dc78a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -587,14 +587,14 @@
         assertEquals(addLink(mContext.getString(R.string.monitoring_description_two_named_vpns,
                                  VPN_PACKAGE, VPN_PACKAGE_2)),
                 mFooterUtils.getVpnMessage(false, true, VPN_PACKAGE, VPN_PACKAGE_2));
-        assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn,
-                                 VPN_PACKAGE)),
+        assertEquals(addLink(mContext.getString(
+                R.string.monitoring_description_managed_device_named_vpn, VPN_PACKAGE)),
                 mFooterUtils.getVpnMessage(true, false, VPN_PACKAGE, null));
         assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn,
                                  VPN_PACKAGE)),
                 mFooterUtils.getVpnMessage(false, false, VPN_PACKAGE, null));
-        assertEquals(addLink(mContext.getString(R.string.monitoring_description_named_vpn,
-                                 VPN_PACKAGE_2)),
+        assertEquals(addLink(mContext.getString(
+                R.string.monitoring_description_managed_device_named_vpn, VPN_PACKAGE_2)),
                 mFooterUtils.getVpnMessage(true, true, null, VPN_PACKAGE_2));
         assertEquals(addLink(mContext.getString(
                                  R.string.monitoring_description_managed_profile_named_vpn,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt
index 59f0d96..2cc6709 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt
@@ -376,13 +376,13 @@
     @Test
     fun isVisible() {
         val underTest = utils.footerActionsViewModel()
-        assertThat(underTest.isVisible.value).isTrue()
-
-        underTest.onVisibilityChangeRequested(visible = false)
         assertThat(underTest.isVisible.value).isFalse()
 
         underTest.onVisibilityChangeRequested(visible = true)
         assertThat(underTest.isVisible.value).isTrue()
+
+        underTest.onVisibilityChangeRequested(visible = false)
+        assertThat(underTest.isVisible.value).isFalse()
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
index e106741..41545fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
@@ -30,6 +30,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.testing.TestableResources;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
@@ -94,14 +95,18 @@
     private RotationLockController mController;
     private TestableLooper mTestableLooper;
     private RotationLockTile mLockTile;
+    private TestableResources mTestableResources;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mTestableLooper = TestableLooper.get(this);
+        mTestableResources = mContext.getOrCreateTestableResources();
 
         when(mHost.getContext()).thenReturn(mContext);
         when(mHost.getUserContext()).thenReturn(mContext);
+        mTestableResources.addOverride(com.android.internal.R.bool.config_allowRotationResolver,
+                true);
 
         mController = new RotationLockControllerImpl(mRotationPolicyWrapper,
                 mDeviceStateRotationLockSettingController, DEFAULT_SETTINGS);
@@ -208,6 +213,32 @@
     }
 
     @Test
+    public void testSecondaryString_rotationResolverDisabled_isEmpty() {
+        mTestableResources.addOverride(com.android.internal.R.bool.config_allowRotationResolver,
+                false);
+        mLockTile = new RotationLockTile(
+                mHost,
+                mUiEventLogger,
+                mTestableLooper.getLooper(),
+                new Handler(mTestableLooper.getLooper()),
+                new FalsingManagerFake(),
+                mMetricsLogger,
+                mStatusBarStateController,
+                mActivityStarter,
+                mQSLogger,
+                mController,
+                mPrivacyManager,
+                mBatteryController,
+                new FakeSettings()
+        );
+
+        mLockTile.refreshState();
+        mTestableLooper.processAllMessages();
+
+        assertEquals("", mLockTile.getState().secondaryLabel.toString());
+    }
+
+    @Test
     public void testIcon_whenDisabled_isOffState() {
         QSTile.BooleanState state = new QSTile.BooleanState();
         disableAutoRotation();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
index a1d78cb..7c30843b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -18,7 +18,6 @@
 
 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.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -94,6 +93,7 @@
         doReturn(mContext.getUserId()).when(mRecordingService).getUserId();
         doReturn(mContext.getPackageName()).when(mRecordingService).getPackageName();
         doReturn(mContext.getContentResolver()).when(mRecordingService).getContentResolver();
+        doReturn(mContext.getResources()).when(mRecordingService).getResources();
 
         // Mock notifications
         doNothing().when(mRecordingService).createRecordingNotification();
@@ -101,7 +101,7 @@
         doReturn(mNotification).when(mRecordingService).createSaveNotification(any());
         doNothing().when(mRecordingService).createErrorNotification();
         doNothing().when(mRecordingService).showErrorToast(anyInt());
-        doNothing().when(mRecordingService).stopForeground(anyBoolean());
+        doNothing().when(mRecordingService).stopForeground(anyInt());
 
         doNothing().when(mRecordingService).startForeground(anyInt(), any());
         doReturn(mScreenMediaRecorder).when(mRecordingService).getRecorder();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java
index 7d58325..9ea30d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java
@@ -39,9 +39,9 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.settings.FakeDisplayTracker;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -50,22 +50,20 @@
 import org.mockito.MockitoAnnotations;
 import org.mockito.stubbing.Answer;
 
-import java.util.Optional;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
 public class ActionProxyReceiverTest extends SysuiTestCase {
-
-    @Mock
-    private CentralSurfaces mMockCentralSurfaces;
     @Mock
     private ActivityManagerWrapper mMockActivityManagerWrapper;
     @Mock
     private ScreenshotSmartActions mMockScreenshotSmartActions;
     @Mock
     private PendingIntent mMockPendingIntent;
+    @Mock
+    private ActivityStarter mActivityStarter;
 
     private Intent mIntent;
     private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
@@ -78,32 +76,19 @@
     }
 
     @Test
-    public void testPendingIntentSentWithoutStatusBar() throws PendingIntent.CanceledException {
-        ActionProxyReceiver actionProxyReceiver = constructActionProxyReceiver(false);
-
-        actionProxyReceiver.onReceive(mContext, mIntent);
-
-        verify(mMockActivityManagerWrapper).closeSystemWindows(SYSTEM_DIALOG_REASON_SCREENSHOT);
-        verify(mMockCentralSurfaces, never()).executeRunnableDismissingKeyguard(
-                any(Runnable.class), any(Runnable.class), anyBoolean(), anyBoolean(), anyBoolean());
-        verify(mMockPendingIntent).send(
-                eq(mContext), anyInt(), isNull(), isNull(), isNull(), isNull(), any(Bundle.class));
-    }
-
-    @Test
     public void testPendingIntentSentWithStatusBar() throws PendingIntent.CanceledException {
-        ActionProxyReceiver actionProxyReceiver = constructActionProxyReceiver(true);
+        ActionProxyReceiver actionProxyReceiver = constructActionProxyReceiver();
         // ensure that the pending intent call is passed through
         doAnswer((Answer<Object>) invocation -> {
             ((Runnable) invocation.getArgument(0)).run();
             return null;
-        }).when(mMockCentralSurfaces).executeRunnableDismissingKeyguard(
+        }).when(mActivityStarter).executeRunnableDismissingKeyguard(
                 any(Runnable.class), isNull(), anyBoolean(), anyBoolean(), anyBoolean());
 
         actionProxyReceiver.onReceive(mContext, mIntent);
 
         verify(mMockActivityManagerWrapper).closeSystemWindows(SYSTEM_DIALOG_REASON_SCREENSHOT);
-        verify(mMockCentralSurfaces).executeRunnableDismissingKeyguard(
+        verify(mActivityStarter).executeRunnableDismissingKeyguard(
                 any(Runnable.class), isNull(), eq(true), eq(true), eq(true));
         verify(mMockPendingIntent).send(
                 eq(mContext), anyInt(), isNull(), isNull(), isNull(), isNull(), any(Bundle.class));
@@ -111,7 +96,7 @@
 
     @Test
     public void testSmartActionsNotNotifiedByDefault() {
-        ActionProxyReceiver actionProxyReceiver = constructActionProxyReceiver(true);
+        ActionProxyReceiver actionProxyReceiver = constructActionProxyReceiver();
 
         actionProxyReceiver.onReceive(mContext, mIntent);
 
@@ -122,7 +107,7 @@
 
     @Test
     public void testSmartActionsNotifiedIfEnabled() {
-        ActionProxyReceiver actionProxyReceiver = constructActionProxyReceiver(true);
+        ActionProxyReceiver actionProxyReceiver = constructActionProxyReceiver();
         mIntent.putExtra(EXTRA_SMART_ACTIONS_ENABLED, true);
         String testId = "testID";
         mIntent.putExtra(EXTRA_ID, testId);
@@ -133,15 +118,12 @@
                 testId, ACTION_TYPE_SHARE, false, null);
     }
 
-    private ActionProxyReceiver constructActionProxyReceiver(boolean withStatusBar) {
-        if (withStatusBar) {
-            return new ActionProxyReceiver(
-                    Optional.of(mMockCentralSurfaces), mMockActivityManagerWrapper,
-                    mMockScreenshotSmartActions, mDisplayTracker);
-        } else {
-            return new ActionProxyReceiver(
-                    Optional.empty(), mMockActivityManagerWrapper, mMockScreenshotSmartActions,
-                    mDisplayTracker);
-        }
+    private ActionProxyReceiver constructActionProxyReceiver() {
+        return new ActionProxyReceiver(
+                mMockActivityManagerWrapper,
+                mMockScreenshotSmartActions,
+                mDisplayTracker,
+                mActivityStarter
+        );
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
index db6fc13..38a666e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
@@ -37,6 +37,7 @@
 import org.mockito.ArgumentCaptor
 import org.mockito.Captor
 import org.mockito.Mock
+import org.mockito.Mockito.atLeastOnce
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
@@ -54,10 +55,12 @@
 
     @Mock private lateinit var parent: ViewGroup
 
+    @Mock private lateinit var splitShadeStatusBar: ViewGroup
+
     @Mock private lateinit var statusBarStateController: StatusBarStateController
 
     private lateinit var underTest: NotificationPanelUnfoldAnimationController
-    private lateinit var progressListener: TransitionProgressListener
+    private lateinit var progressListeners: List<TransitionProgressListener>
     private var xTranslationMax = 0f
 
     @Before
@@ -73,10 +76,13 @@
                 statusBarStateController,
                 progressProvider
             )
+        whenever(parent.findViewById<ViewGroup>(R.id.split_shade_status_bar)).thenReturn(
+            splitShadeStatusBar
+        )
         underTest.setup(parent)
 
-        verify(progressProvider).addCallback(capture(progressListenerCaptor))
-        progressListener = progressListenerCaptor.value
+        verify(progressProvider, atLeastOnce()).addCallback(capture(progressListenerCaptor))
+        progressListeners = progressListenerCaptor.allValues
     }
 
     @Test
@@ -86,16 +92,16 @@
         val view = View(context)
         whenever(parent.findViewById<View>(R.id.quick_settings_panel)).thenReturn(view)
 
-        progressListener.onTransitionStarted()
+        onTransitionStarted()
         assertThat(view.translationX).isZero()
 
-        progressListener.onTransitionProgress(0f)
+        onTransitionProgress(0f)
         assertThat(view.translationX).isZero()
 
-        progressListener.onTransitionProgress(0.5f)
+        onTransitionProgress(0.5f)
         assertThat(view.translationX).isZero()
 
-        progressListener.onTransitionFinished()
+        onTransitionFinished()
         assertThat(view.translationX).isZero()
     }
 
@@ -106,16 +112,16 @@
         val view = View(context)
         whenever(parent.findViewById<View>(R.id.quick_settings_panel)).thenReturn(view)
 
-        progressListener.onTransitionStarted()
+        onTransitionStarted()
         assertThat(view.translationX).isZero()
 
-        progressListener.onTransitionProgress(0f)
+        onTransitionProgress(0f)
         assertThat(view.translationX).isEqualTo(xTranslationMax)
 
-        progressListener.onTransitionProgress(0.5f)
+        onTransitionProgress(0.5f)
         assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
 
-        progressListener.onTransitionFinished()
+        onTransitionFinished()
         assertThat(view.translationX).isZero()
     }
 
@@ -126,16 +132,88 @@
         val view = View(context)
         whenever(parent.findViewById<View>(R.id.quick_settings_panel)).thenReturn(view)
 
-        progressListener.onTransitionStarted()
+        onTransitionStarted()
         assertThat(view.translationX).isZero()
 
-        progressListener.onTransitionProgress(0f)
+        onTransitionProgress(0f)
         assertThat(view.translationX).isEqualTo(xTranslationMax)
 
-        progressListener.onTransitionProgress(0.5f)
+        onTransitionProgress(0.5f)
         assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
 
-        progressListener.onTransitionFinished()
+        onTransitionFinished()
         assertThat(view.translationX).isZero()
     }
+
+    @Test
+    fun whenInKeyguardState_statusBarViewDoesNotMove() {
+        whenever(statusBarStateController.getState()).thenReturn(KEYGUARD)
+
+        val view = View(context)
+        whenever(splitShadeStatusBar.findViewById<View>(R.id.date)).thenReturn(view)
+
+        onTransitionStarted()
+        assertThat(view.translationX).isZero()
+
+        onTransitionProgress(0f)
+        assertThat(view.translationX).isZero()
+
+        onTransitionProgress(0.5f)
+        assertThat(view.translationX).isZero()
+
+        onTransitionFinished()
+        assertThat(view.translationX).isZero()
+    }
+
+    @Test
+    fun whenInShadeState_statusBarViewDoesMove() {
+        whenever(statusBarStateController.getState()).thenReturn(SHADE)
+
+        val view = View(context)
+        whenever(splitShadeStatusBar.findViewById<View>(R.id.date)).thenReturn(view)
+
+        onTransitionStarted()
+        assertThat(view.translationX).isZero()
+
+        onTransitionProgress(0f)
+        assertThat(view.translationX).isEqualTo(xTranslationMax)
+
+        onTransitionProgress(0.5f)
+        assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
+
+        onTransitionFinished()
+        assertThat(view.translationX).isZero()
+    }
+
+    @Test
+    fun whenInShadeLockedState_statusBarViewDoesMove() {
+        whenever(statusBarStateController.getState()).thenReturn(SHADE_LOCKED)
+
+        val view = View(context)
+        whenever(splitShadeStatusBar.findViewById<View>(R.id.date)).thenReturn(view)
+        onTransitionStarted()
+        assertThat(view.translationX).isZero()
+
+        onTransitionProgress(0f)
+        assertThat(view.translationX).isEqualTo(xTranslationMax)
+
+        onTransitionProgress(0.5f)
+        assertThat(view.translationX).isEqualTo(0.5f * xTranslationMax)
+
+        onTransitionFinished()
+        assertThat(view.translationX).isZero()
+    }
+
+    private fun onTransitionStarted() {
+        progressListeners.forEach { it.onTransitionStarted() }
+    }
+
+    private fun onTransitionProgress(progress: Float) {
+        progressListeners.forEach { it.onTransitionProgress(progress) }
+    }
+
+    private fun onTransitionFinished() {
+        progressListeners.forEach { it.onTransitionFinished() }
+    }
+
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 068d933..9a8ec88 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -115,6 +115,7 @@
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.data.repository.ShadeRepository;
 import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -150,6 +151,7 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
 import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
+import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.ScrimController;
@@ -157,6 +159,7 @@
 import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
 import com.android.systemui.statusbar.phone.TapAgainViewController;
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
+import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -238,6 +241,7 @@
     @Mock protected KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
     @Mock protected KeyguardClockSwitchController mKeyguardClockSwitchController;
     @Mock protected KeyguardStatusBarViewController mKeyguardStatusBarViewController;
+    @Mock protected LightBarController mLightBarController;
     @Mock protected NotificationStackScrollLayoutController
             mNotificationStackScrollLayoutController;
     @Mock protected NotificationShadeDepthController mNotificationShadeDepthController;
@@ -304,7 +308,10 @@
             mEmptySpaceClickListenerCaptor;
     @Mock protected ActivityStarter mActivityStarter;
     @Mock protected KeyguardFaceAuthInteractor mKeyguardFaceAuthInteractor;
+    @Mock protected ShadeRepository mShadeRepository;
+    @Mock private CastController mCastController;
 
+    protected final int mMaxUdfpsBurnInOffsetY = 5;
     protected KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
     protected KeyguardInteractor mKeyguardInteractor;
     protected NotificationPanelViewController.TouchHandler mTouchHandler;
@@ -365,6 +372,8 @@
         when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
         mDisplayMetrics.density = 100;
         when(mResources.getBoolean(R.bool.config_enableNotificationShadeDrag)).thenReturn(true);
+        when(mResources.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y))
+                .thenReturn(mMaxUdfpsBurnInOffsetY);
         when(mResources.getDimensionPixelSize(R.dimen.notifications_top_padding_split_shade))
                 .thenReturn(NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE);
         when(mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_horizontal))
@@ -648,6 +657,7 @@
                 mNotificationRemoteInputManager,
                 mShadeExpansionStateManager,
                 mStatusBarKeyguardViewManager,
+                mLightBarController,
                 mNotificationStackScrollLayoutController,
                 mLockscreenShadeTransitionController,
                 mNotificationShadeDepthController,
@@ -669,7 +679,9 @@
                 mFeatureFlags,
                 mInteractionJankMonitor,
                 mShadeLog,
-                mKeyguardFaceAuthInteractor
+                mKeyguardFaceAuthInteractor,
+                mShadeRepository,
+                mCastController
         );
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 600fb5c..48e0b53 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -29,6 +29,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -44,6 +45,7 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
+import android.graphics.Point;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.MotionEvent;
@@ -61,6 +63,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.phone.KeyguardClockPositionAlgorithm;
 
 import org.junit.Before;
 import org.junit.Ignore;
@@ -251,6 +254,43 @@
     }
 
     @Test
+    public void testOnDozeAmountChanged_positionClockAndNotificationsUsesUdfpsLocation() {
+        // GIVEN UDFPS is enrolled and we're on the keyguard
+        final Point udfpsLocationCenter = new Point(0, 100);
+        final float udfpsRadius = 10f;
+        when(mUpdateMonitor.isUdfpsEnrolled()).thenReturn(true);
+        when(mAuthController.getUdfpsLocation()).thenReturn(udfpsLocationCenter);
+        when(mAuthController.getUdfpsRadius()).thenReturn(udfpsRadius);
+        mNotificationPanelViewController.getStatusBarStateListener().onStateChanged(KEYGUARD);
+
+        // WHEN the doze amount changes
+        mNotificationPanelViewController.mClockPositionAlgorithm = mock(
+                KeyguardClockPositionAlgorithm.class);
+        mNotificationPanelViewController.getStatusBarStateListener().onDozeAmountChanged(1f, 1f);
+
+        // THEN the clock positions accounts for the UDFPS location & its worst case burn in
+        final float udfpsTop = udfpsLocationCenter.y - udfpsRadius - mMaxUdfpsBurnInOffsetY;
+        verify(mNotificationPanelViewController.mClockPositionAlgorithm).setup(
+                anyInt(),
+                anyFloat(),
+                anyInt(),
+                anyInt(),
+                anyInt(),
+                /* darkAmount */ eq(1f),
+                anyFloat(),
+                anyBoolean(),
+                anyInt(),
+                anyFloat(),
+                anyInt(),
+                anyBoolean(),
+                /* udfpsTop */ eq(udfpsTop),
+                anyFloat(),
+                anyBoolean()
+        );
+    }
+
+
+    @Test
     public void testSetExpandedHeight() {
         mNotificationPanelViewController.setExpandedHeight(200);
         assertThat((int) mNotificationPanelViewController.getExpandedHeight()).isEqualTo(200);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
index 908f7cb..1cf3873 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
@@ -69,6 +69,7 @@
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.data.repository.ShadeRepository;
 import com.android.systemui.shade.transition.ShadeTransitionController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -82,12 +83,16 @@
 import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
+import dagger.Lazy;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -98,8 +103,6 @@
 
 import java.util.List;
 
-import dagger.Lazy;
-
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -131,6 +134,7 @@
     @Mock private PulseExpansionHandler mPulseExpansionHandler;
     @Mock private NotificationRemoteInputManager mNotificationRemoteInputManager;
     @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    @Mock private LightBarController mLightBarController;
     @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
     @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
     @Mock private NotificationShadeDepthController mNotificationShadeDepthController;
@@ -154,6 +158,7 @@
     @Mock private ShadeLogger mShadeLogger;
     @Mock private DumpManager mDumpManager;
     @Mock private UiEventLogger mUiEventLogger;
+    @Mock private CastController mCastController;
 
     private SysuiStatusBarStateController mStatusBarStateController;
 
@@ -220,6 +225,7 @@
                 mNotificationRemoteInputManager,
                 mShadeExpansionStateManager,
                 mStatusBarKeyguardViewManager,
+                mLightBarController,
                 mNotificationStackScrollLayoutController,
                 mLockscreenShadeTransitionController,
                 mNotificationShadeDepthController,
@@ -241,7 +247,9 @@
                 mFeatureFlags,
                 mInteractionJankMonitor,
                 mShadeLogger,
-                mock(KeyguardFaceAuthInteractor.class)
+                mock(KeyguardFaceAuthInteractor.class),
+                mock(ShadeRepository.class),
+                mCastController
         );
 
         mFragmentListener = mQsController.getQsFragmentListener();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
new file mode 100644
index 0000000..8f2c93b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
@@ -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.systemui.shade.data.repository
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.RoboPilotTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.shade.ShadeExpansionChangeEvent
+import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.shade.domain.model.ShadeModel
+import com.android.systemui.util.mockito.withArgCaptor
+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.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RoboPilotTest
+@RunWith(AndroidJUnit4::class)
+class ShadeRepositoryImplTest : SysuiTestCase() {
+
+    @Mock private lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
+    private val testDispatcher = StandardTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
+
+    private lateinit var underTest: ShadeRepositoryImpl
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        underTest = ShadeRepositoryImpl(shadeExpansionStateManager)
+    }
+
+    @Test
+    fun shadeExpansionChangeEvent() =
+        testScope.runTest {
+            var latest: ShadeModel? = null
+            val job = underTest.shadeModel.onEach { latest = it }.launchIn(this)
+            runCurrent()
+            assertThat(latest?.expansionAmount).isEqualTo(0f)
+            assertThat(latest?.isExpanded).isEqualTo(false)
+            assertThat(latest?.isUserDragging).isEqualTo(false)
+
+            val captor = withArgCaptor {
+                verify(shadeExpansionStateManager).addExpansionListener(capture())
+            }
+
+            captor.onPanelExpansionChanged(
+                ShadeExpansionChangeEvent(
+                    fraction = 1f,
+                    expanded = true,
+                    tracking = false,
+                    dragDownPxAmount = 0f,
+                )
+            )
+            runCurrent()
+            assertThat(latest?.expansionAmount).isEqualTo(1f)
+            assertThat(latest?.isExpanded).isEqualTo(true)
+            assertThat(latest?.isUserDragging).isEqualTo(false)
+
+            captor.onPanelExpansionChanged(
+                ShadeExpansionChangeEvent(
+                    fraction = .67f,
+                    expanded = false,
+                    tracking = true,
+                    dragDownPxAmount = 0f,
+                )
+            )
+            runCurrent()
+            assertThat(latest?.expansionAmount).isEqualTo(.67f)
+            assertThat(latest?.isExpanded).isEqualTo(false)
+            assertThat(latest?.isUserDragging).isEqualTo(true)
+
+            job.cancel()
+        }
+
+    @Test
+    fun updateQsExpansion() =
+        testScope.runTest {
+            assertThat(underTest.qsExpansion.value).isEqualTo(0f)
+
+            underTest.setQsExpansion(.5f)
+            assertThat(underTest.qsExpansion.value).isEqualTo(.5f)
+
+            underTest.setQsExpansion(.82f)
+            assertThat(underTest.qsExpansion.value).isEqualTo(.82f)
+
+            underTest.setQsExpansion(1f)
+            assertThat(underTest.qsExpansion.value).isEqualTo(1f)
+        }
+
+    @Test
+    fun updateUdfpsTransitionToFullShadeProgress() =
+        testScope.runTest {
+            assertThat(underTest.udfpsTransitionToFullShadeProgress.value).isEqualTo(0f)
+
+            underTest.setUdfpsTransitionToFullShadeProgress(.5f)
+            assertThat(underTest.udfpsTransitionToFullShadeProgress.value).isEqualTo(.5f)
+
+            underTest.setUdfpsTransitionToFullShadeProgress(.82f)
+            assertThat(underTest.udfpsTransitionToFullShadeProgress.value).isEqualTo(.82f)
+
+            underTest.setUdfpsTransitionToFullShadeProgress(1f)
+            assertThat(underTest.udfpsTransitionToFullShadeProgress.value).isEqualTo(1f)
+        }
+}
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 78f5bf2..eef4470 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
@@ -43,6 +43,8 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
@@ -172,7 +174,7 @@
     }
 
     @Test
-    fun clockIdConflict_ErrorWithoutCrash() {
+    fun clockIdConflict_ErrorWithoutCrash_unloadDuplicate() {
         val mockPluginLifecycle1 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
         val plugin1 = FakeClockPlugin()
             .addClock("clock_1", "clock 1", { mockClock }, { mockThumbnail })
@@ -199,6 +201,8 @@
         assertEquals(registry.createExampleClock("clock_2"), mockClock)
         assertEquals(registry.getClockThumbnail("clock_1"), mockThumbnail)
         assertEquals(registry.getClockThumbnail("clock_2"), mockThumbnail)
+        verify(mockPluginLifecycle1, never()).unloadPlugin()
+        verify(mockPluginLifecycle2, times(2)).unloadPlugin()
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 4438b98..f7fcab1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -325,6 +325,21 @@
     }
 
     @Test
+    public void createController_setIndicationAreaAgain_destroysPreviousRotateTextViewController() {
+        // GIVEN a controller with a mocked rotate text view controlller
+        final KeyguardIndicationRotateTextViewController mockedRotateTextViewController =
+                mock(KeyguardIndicationRotateTextViewController.class);
+        createController();
+        mController.mRotateTextViewController = mockedRotateTextViewController;
+
+        // WHEN a new indication area is set
+        mController.setIndicationArea(mIndicationArea);
+
+        // THEN the previous rotateTextViewController is destroyed
+        verify(mockedRotateTextViewController).destroy();
+    }
+
+    @Test
     public void createController_addsAlignmentListener() {
         createController();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index d017ffd..2351f760 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -11,9 +11,11 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.media.controls.ui.MediaHierarchyManager
+import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.QS
 import com.android.systemui.shade.ShadeViewController
+import com.android.systemui.shade.data.repository.FakeShadeRepository
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.statusbar.notification.stack.AmbientState
@@ -79,6 +81,7 @@
     @Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller
     @Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller
     @Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController
+    @Mock lateinit var activityStarter: ActivityStarter
     @Mock lateinit var transitionControllerCallback: LockscreenShadeTransitionController.Callback
     @JvmField @Rule val mockito = MockitoJUnit.rule()
 
@@ -124,6 +127,8 @@
                         dumpManager)
                 },
                 qsTransitionControllerFactory = { qsTransitionController },
+                activityStarter = activityStarter,
+                shadeRepository = FakeShadeRepository(),
             )
         transitionController.addCallback(transitionControllerCallback)
         whenever(nsslController.view).thenReturn(stackscroller)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 8ee1ea8..39accfb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -49,6 +49,8 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.settings.UserTracker;
@@ -110,6 +112,7 @@
     private NotificationEntry mCurrentUserNotif;
     private NotificationEntry mSecondaryUserNotif;
     private NotificationEntry mWorkProfileNotif;
+    private final FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags();
 
     @Before
     public void setUp() {
@@ -291,7 +294,16 @@
     }
 
     @Test
+    public void testUserSwitchedCallsOnUserSwitching() {
+        mFakeFeatureFlags.set(Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE, true);
+        mLockscreenUserManager.getUserTrackerCallbackForTest().onUserChanging(mSecondaryUser.id,
+                mContext);
+        verify(mPresenter, times(1)).onUserSwitched(mSecondaryUser.id);
+    }
+
+    @Test
     public void testUserSwitchedCallsOnUserSwitched() {
+        mFakeFeatureFlags.set(Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE, false);
         mLockscreenUserManager.getUserTrackerCallbackForTest().onUserChanged(mSecondaryUser.id,
                 mContext);
         verify(mPresenter, times(1)).onUserSwitched(mSecondaryUser.id);
@@ -356,7 +368,8 @@
                     mKeyguardStateController,
                     mSettings,
                     mock(DumpManager.class),
-                    mock(LockPatternUtils.class));
+                    mock(LockPatternUtils.class),
+                    mFakeFeatureFlags);
         }
 
         public BroadcastReceiver getBaseBroadcastReceiverForTest() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index beaf300..c49f179 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -356,6 +356,7 @@
     @Test
     fun ignoreShadeBlurUntilHidden_schedulesFrame() {
         notificationShadeDepthController.blursDisabledForAppLaunch = true
+        verify(blurUtils).prepareBlur(any(), anyInt())
         verify(choreographer)
             .postFrameCallback(eq(notificationShadeDepthController.updateBlurCallback))
     }
@@ -419,6 +420,7 @@
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
         verify(notificationShadeWindowController).setBackgroundBlurRadius(eq(0))
         verify(wallpaperController).setNotificationShadeZoom(eq(1f))
+        verify(blurUtils).prepareBlur(any(), eq(0))
         verify(blurUtils).applyBlur(eq(viewRootImpl), eq(0), eq(false))
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
index 70266e4..655bd72 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener
+import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl
 import com.android.systemui.statusbar.notification.collection.render.NotifStackController
 import com.android.systemui.statusbar.notification.collection.render.NotifStats
 import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
@@ -49,6 +50,7 @@
     private lateinit var entry: NotificationEntry
 
     @Mock private lateinit var pipeline: NotifPipeline
+    @Mock private lateinit var groupExpansionManagerImpl: GroupExpansionManagerImpl
     @Mock private lateinit var notificationIconAreaController: NotificationIconAreaController
     @Mock private lateinit var stackController: NotifStackController
     @Mock private lateinit var section: NotifSection
@@ -56,7 +58,7 @@
     @Before
     fun setUp() {
         initMocks(this)
-        coordinator = StackCoordinator(notificationIconAreaController)
+        coordinator = StackCoordinator(groupExpansionManagerImpl, notificationIconAreaController)
         coordinator.attach(pipeline)
         afterRenderListListener = withArgCaptor {
             verify(pipeline).addOnAfterRenderListListener(capture())
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 9186c35..4c83194 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
@@ -617,24 +617,9 @@
     }
 
     @Test
-    public void applyRoundnessAndInv_should_be_immediately_applied_on_childrenContainer_legacy()
-            throws Exception {
-        ExpandableNotificationRow group = mNotificationTestHelper.createGroup();
-        group.useRoundnessSourceTypes(false);
-        Assert.assertEquals(0f, group.getBottomRoundness(), 0.001f);
-        Assert.assertEquals(0f, group.getChildrenContainer().getBottomRoundness(), 0.001f);
-
-        group.requestBottomRoundness(1f, SourceType.from(""), false);
-
-        Assert.assertEquals(1f, group.getBottomRoundness(), 0.001f);
-        Assert.assertEquals(1f, group.getChildrenContainer().getBottomRoundness(), 0.001f);
-    }
-
-    @Test
     public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_childrenContainer()
             throws Exception {
         ExpandableNotificationRow group = mNotificationTestHelper.createGroup();
-        group.useRoundnessSourceTypes(true);
         Assert.assertEquals(0f, group.getBottomRoundness(), 0.001f);
         Assert.assertEquals(0f, group.getChildrenContainer().getBottomRoundness(), 0.001f);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 4bb2c87..3cefc99 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -67,6 +67,7 @@
 import com.android.internal.logging.testing.UiEventLoggerFake;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.settings.UserContextProvider;
@@ -80,7 +81,6 @@
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.wmshell.BubblesManager;
@@ -120,7 +120,6 @@
     @Mock private NotificationListContainer mNotificationListContainer;
     @Mock private OnSettingsClickListener mOnSettingsClickListener;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
-    @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private AccessibilityManager mAccessibilityManager;
     @Mock private HighPriorityProvider mHighPriorityProvider;
     @Mock private INotificationManager mINotificationManager;
@@ -136,6 +135,7 @@
     @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
     @Mock private StatusBarStateController mStatusBarStateController;
     @Mock private HeadsUpManagerPhone mHeadsUpManagerPhone;
+    @Mock private ActivityStarter mActivityStarter;
 
     @Before
     public void setUp() {
@@ -145,8 +145,8 @@
         mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this));
         when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
 
-        mGutsManager = new NotificationGutsManager(mContext,
-                () -> Optional.of(mCentralSurfaces), mHandler, mHandler, mAccessibilityManager,
+        mGutsManager = new NotificationGutsManager(mContext, mHandler, mHandler,
+                mAccessibilityManager,
                 mHighPriorityProvider, mINotificationManager,
                 mPeopleSpaceWidgetManager, mLauncherApps, mShortcutManager,
                 mChannelEditorDialogController, mContextTracker, mAssistantFeedbackController,
@@ -156,7 +156,7 @@
                 mStatusBarStateController,
                 mDeviceProvisionedController,
                 mMetricsLogger,
-                mHeadsUpManagerPhone);
+                mHeadsUpManagerPhone, mActivityStarter);
         mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
                 mOnSettingsClickListener);
         mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
index e41929f..be976a1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
@@ -25,7 +25,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.notification.LegacySourceType;
 import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
@@ -158,55 +157,7 @@
     }
 
     @Test
-    public void addNotification_shouldResetOnScrollRoundness() throws Exception {
-        ExpandableNotificationRow row = mNotificationTestHelper.createRowWithRoundness(
-                /* topRoundness = */ 1f,
-                /* bottomRoundness = */ 1f,
-                /* sourceType = */ LegacySourceType.OnScroll);
-
-        mChildrenContainer.addNotification(row, 0);
-
-        Assert.assertEquals(0f, row.getTopRoundness(), /* delta = */ 0f);
-        Assert.assertEquals(0f, row.getBottomRoundness(), /* delta = */ 0f);
-    }
-
-    @Test
-    public void addNotification_shouldNotResetOtherRoundness() throws Exception {
-        ExpandableNotificationRow row1 = mNotificationTestHelper.createRowWithRoundness(
-                /* topRoundness = */ 1f,
-                /* bottomRoundness = */ 1f,
-                /* sourceType = */ LegacySourceType.DefaultValue);
-        ExpandableNotificationRow row2 = mNotificationTestHelper.createRowWithRoundness(
-                /* topRoundness = */ 1f,
-                /* bottomRoundness = */ 1f,
-                /* sourceType = */ LegacySourceType.OnDismissAnimation);
-
-        mChildrenContainer.addNotification(row1, 0);
-        mChildrenContainer.addNotification(row2, 0);
-
-        Assert.assertEquals(1f, row1.getTopRoundness(), /* delta = */ 0f);
-        Assert.assertEquals(1f, row1.getBottomRoundness(), /* delta = */ 0f);
-        Assert.assertEquals(1f, row2.getTopRoundness(), /* delta = */ 0f);
-        Assert.assertEquals(1f, row2.getBottomRoundness(), /* delta = */ 0f);
-    }
-
-    @Test
-    public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_last_child_legacy() {
-        mChildrenContainer.useRoundnessSourceTypes(false);
-        List<ExpandableNotificationRow> children = mChildrenContainer.getAttachedChildren();
-        ExpandableNotificationRow notificationRow = children.get(children.size() - 1);
-        Assert.assertEquals(0f, mChildrenContainer.getBottomRoundness(), 0.001f);
-        Assert.assertEquals(0f, notificationRow.getBottomRoundness(), 0.001f);
-
-        mChildrenContainer.requestBottomRoundness(1f, SourceType.from(""), false);
-
-        Assert.assertEquals(1f, mChildrenContainer.getBottomRoundness(), 0.001f);
-        Assert.assertEquals(1f, notificationRow.getBottomRoundness(), 0.001f);
-    }
-
-    @Test
     public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_last_child() {
-        mChildrenContainer.useRoundnessSourceTypes(true);
         List<ExpandableNotificationRow> children = mChildrenContainer.getAttachedChildren();
         ExpandableNotificationRow notificationRow = children.get(children.size() - 1);
         Assert.assertEquals(0f, mChildrenContainer.getBottomRoundness(), 0.001f);
@@ -220,8 +171,6 @@
 
     @Test
     public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_header() {
-        mChildrenContainer.useRoundnessSourceTypes(true);
-
         NotificationHeaderViewWrapper header = mChildrenContainer.getNotificationHeaderWrapper();
         Assert.assertEquals(0f, header.getTopRoundness(), 0.001f);
 
@@ -232,7 +181,6 @@
 
     @Test
     public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_headerLowPriority() {
-        mChildrenContainer.useRoundnessSourceTypes(true);
         mChildrenContainer.setIsLowPriority(true);
 
         NotificationHeaderViewWrapper header = mChildrenContainer.getNotificationHeaderWrapper();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
deleted file mode 100644
index bd0a556..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.stack;
-
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.res.Resources;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.logging.NotificationRoundnessLogger;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.ExpandableView;
-import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
-import com.android.systemui.util.DeviceConfigProxy;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-import java.util.HashSet;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-public class NotificationRoundnessManagerTest extends SysuiTestCase {
-
-    private NotificationRoundnessManager mRoundnessManager;
-    private HashSet<ExpandableView> mAnimatedChildren = new HashSet<>();
-    private Runnable mRoundnessCallback = mock(Runnable.class);
-    private ExpandableNotificationRow mFirst;
-    private ExpandableNotificationRow mSecond;
-    private NotificationRoundnessLogger mLogger = mock(NotificationRoundnessLogger.class);
-    private float mSmallRadiusRatio;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        final Resources resources = mContext.getResources();
-        mSmallRadiusRatio = resources.getDimension(R.dimen.notification_corner_radius_small)
-                / resources.getDimension(R.dimen.notification_corner_radius);
-        mRoundnessManager = new NotificationRoundnessManager(
-                new NotificationSectionsFeatureManager(new DeviceConfigProxy(), mContext),
-                mLogger,
-                mock(DumpManager.class),
-                mock(FeatureFlags.class));
-        allowTestableLooperAsMainThread();
-        NotificationTestHelper testHelper = new NotificationTestHelper(
-                mContext,
-                mDependency,
-                TestableLooper.get(this));
-        mFirst = testHelper.createRow();
-        mFirst.setHeadsUpAnimatingAwayListener(animatingAway
-                -> mRoundnessManager.updateView(mFirst, false));
-        mSecond = testHelper.createRow();
-        mSecond.setHeadsUpAnimatingAwayListener(animatingAway
-                -> mRoundnessManager.updateView(mSecond, false));
-        mRoundnessManager.setOnRoundingChangedCallback(mRoundnessCallback);
-        mRoundnessManager.setAnimatedChildren(mAnimatedChildren);
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, mFirst),
-                createSection(null, null)
-        });
-        mRoundnessManager.setExpanded(1.0f, 1.0f);
-        mRoundnessManager.setShouldRoundPulsingViews(true);
-        reset(mRoundnessCallback);
-    }
-
-    @Test
-    public void testCallbackCalledWhenSecondChanged() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, mSecond),
-                createSection(null, null)
-        });
-        verify(mRoundnessCallback, atLeast(1)).run();
-    }
-
-    @Test
-    public void testCallbackCalledWhenFirstChanged() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mFirst),
-                createSection(null, null)
-        });
-        verify(mRoundnessCallback, atLeast(1)).run();
-    }
-
-    @Test
-    public void testCallbackCalledWhenSecondSectionFirstChanged() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, mFirst),
-                createSection(mSecond, null)
-        });
-        verify(mRoundnessCallback, atLeast(1)).run();
-    }
-
-    @Test
-    public void testCallbackCalledWhenSecondSectionLastChanged() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, mFirst),
-                createSection(null, mSecond)
-        });
-        verify(mRoundnessCallback, atLeast(1)).run();
-    }
-
-    @Test
-    public void testCallbackNotCalledWhenFirstChangesSections() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(null, mFirst),
-                createSection(mFirst, null)
-        });
-        verify(mRoundnessCallback, never()).run();
-    }
-
-    @Test
-    public void testRoundnessSetOnLast() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, mSecond),
-                createSection(null, null)
-        });
-        Assert.assertEquals(1.0f, mSecond.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(mSmallRadiusRatio, mSecond.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testRoundnessPulsing() throws Exception {
-        // Let's create a notification that's neither the first or last item of the stack,
-        // this way we'll ensure that it won't have any rounded corners by default.
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, mSecond),
-                createSection(null, null)
-        });
-        NotificationTestHelper testHelper = new NotificationTestHelper(
-                mContext,
-                mDependency,
-                TestableLooper.get(this));
-        ExpandableNotificationRow row = testHelper.createRow();
-        NotificationEntry entry = mock(NotificationEntry.class);
-        when(entry.getRow()).thenReturn(row);
-
-        when(testHelper.getStatusBarStateController().isDozing()).thenReturn(true);
-        row.setHeadsUp(true);
-        mRoundnessManager.updateView(entry.getRow(), false);
-        Assert.assertEquals(1f, row.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(1f, row.getTopRoundness(), 0.0f);
-
-        row.setHeadsUp(false);
-        mRoundnessManager.updateView(entry.getRow(), false);
-        Assert.assertEquals(mSmallRadiusRatio, row.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(mSmallRadiusRatio, row.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testRoundnessSetOnSecondSectionLast() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, mFirst),
-                createSection(null, mSecond)
-        });
-        Assert.assertEquals(1.0f, mSecond.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(mSmallRadiusRatio, mSecond.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testRoundnessSetOnSecondSectionFirst() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, mFirst),
-                createSection(mSecond, null)
-        });
-        Assert.assertEquals(mSmallRadiusRatio, mSecond.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(1.0f, mSecond.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testRoundnessSetOnNew() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, null),
-                createSection(null, null)
-        });
-        Assert.assertEquals(mSmallRadiusRatio, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(1.0f, mFirst.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testCompleteReplacement() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mSecond),
-                createSection(null, null)
-        });
-        Assert.assertEquals(mSmallRadiusRatio, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(mSmallRadiusRatio, mFirst.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testNotCalledWhenRemoved() {
-        mFirst.setRemoved();
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mSecond),
-                createSection(null, null)
-        });
-        Assert.assertEquals(1.0f, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(1.0f, mFirst.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testRoundedWhenPinnedAndCollapsed() {
-        mFirst.setPinned(true);
-        mRoundnessManager.setExpanded(0.0f /* expandedHeight */, 0.0f /* appearFraction */);
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mSecond),
-                createSection(null, null)
-        });
-        Assert.assertEquals(1.0f, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(1.0f, mFirst.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testRoundedWhenGoingAwayAndCollapsed() {
-        mFirst.setHeadsUpAnimatingAway(true);
-        mRoundnessManager.setExpanded(0.0f /* expandedHeight */, 0.0f /* appearFraction */);
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mSecond),
-                createSection(null, null)
-        });
-        Assert.assertEquals(1.0f, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(1.0f, mFirst.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testRoundedNormalRoundingWhenExpanded() {
-        mFirst.setHeadsUpAnimatingAway(true);
-        mRoundnessManager.setExpanded(1.0f /* expandedHeight */, 0.0f /* appearFraction */);
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mSecond),
-                createSection(null, null)
-        });
-        Assert.assertEquals(mSmallRadiusRatio, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(mSmallRadiusRatio, mFirst.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testTrackingHeadsUpRoundedIfPushingUp() {
-        mRoundnessManager.setExpanded(1.0f /* expandedHeight */, -0.5f /* appearFraction */);
-        mRoundnessManager.setTrackingHeadsUp(mFirst);
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mSecond),
-                createSection(null, null)
-        });
-        Assert.assertEquals(1.0f, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(1.0f, mFirst.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testTrackingHeadsUpPartiallyRoundedIfPushingDown() {
-        mRoundnessManager.setExpanded(1.0f /* expandedHeight */, 0.5f /* appearFraction */);
-        mRoundnessManager.setTrackingHeadsUp(mFirst);
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mSecond),
-                createSection(null, null)
-        });
-        Assert.assertEquals(0.5f, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(0.5f, mFirst.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testRoundingUpdatedWhenAnimatingAwayTrue() {
-        mRoundnessManager.setExpanded(0.0f, 0.0f);
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mSecond),
-                createSection(null, null)
-        });
-        mFirst.setHeadsUpAnimatingAway(true);
-        Assert.assertEquals(1.0f, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(1.0f, mFirst.getTopRoundness(), 0.0f);
-    }
-
-
-    @Test
-    public void testRoundingUpdatedWhenAnimatingAwayFalse() {
-        mRoundnessManager.setExpanded(0.0f, 0.0f);
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mSecond, mSecond),
-                createSection(null, null)
-        });
-        mFirst.setHeadsUpAnimatingAway(true);
-        mFirst.setHeadsUpAnimatingAway(false);
-        Assert.assertEquals(mSmallRadiusRatio, mFirst.getBottomRoundness(), 0.0f);
-        Assert.assertEquals(mSmallRadiusRatio, mFirst.getTopRoundness(), 0.0f);
-    }
-
-    @Test
-    public void testNoViewsFirstOrLastInSectionWhenSecondSectionEmpty() {
-        Assert.assertTrue(mFirst.isFirstInSection());
-        Assert.assertTrue(mFirst.isLastInSection());
-    }
-
-    @Test
-    public void testNoViewsFirstOrLastInSectionWhenFirstSectionEmpty() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(null, null),
-                createSection(mSecond, mSecond)
-        });
-        Assert.assertTrue(mSecond.isFirstInSection());
-        Assert.assertTrue(mSecond.isLastInSection());
-    }
-
-    @Test
-    public void testFirstAndLastViewsInSectionSetWhenBothSectionsNonEmpty() {
-        mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
-                createSection(mFirst, mFirst),
-                createSection(mSecond, mSecond)
-        });
-        Assert.assertTrue(mFirst.isFirstInSection());
-        Assert.assertTrue(mFirst.isLastInSection());
-        Assert.assertTrue(mSecond.isFirstInSection());
-        Assert.assertTrue(mSecond.isLastInSection());
-    }
-
-    @Test
-    public void testLoggingOnRoundingUpdate() {
-        NotificationSection[] sections = new NotificationSection[]{
-                createSection(mFirst, mSecond),
-                createSection(null, null)
-        };
-        mRoundnessManager.updateRoundedChildren(sections);
-        verify(mLogger).onSectionCornersUpdated(sections, /*anyChanged=*/ true);
-        verify(mLogger, atLeast(1)).onCornersUpdated(eq(mFirst), anyBoolean(),
-                anyBoolean(), anyBoolean(), anyBoolean());
-        verify(mLogger, atLeast(1)).onCornersUpdated(eq(mSecond), anyBoolean(),
-                anyBoolean(), anyBoolean(), anyBoolean());
-    }
-
-    private NotificationSection createSection(ExpandableNotificationRow first,
-            ExpandableNotificationRow last) {
-        NotificationSection section = mock(NotificationSection.class);
-        when(section.getFirstVisibleChild()).thenReturn(first);
-        when(section.getLastVisibleChild()).thenReturn(last);
-        return section;
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 30da08e..f38881c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -96,8 +96,7 @@
                         mIncomingHeaderController,
                         mPeopleHeaderController,
                         mAlertingHeaderController,
-                        mSilentHeaderController,
-                        mFeatureFlag
+                        mSilentHeaderController
                 );
         // Required in order for the header inflation to work properly
         when(mNssl.generateLayoutParams(any(AttributeSet.class)))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
index b1d3daa..05b70eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
@@ -12,7 +12,6 @@
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator
 import com.android.systemui.statusbar.NotificationShelf
 import com.android.systemui.statusbar.StatusBarIconView
-import com.android.systemui.statusbar.notification.LegacySourceType
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
@@ -359,39 +358,6 @@
         )
     }
 
-    @Test
-    fun resetOnScrollRoundness_shouldSetOnScrollTo0() {
-        val row: ExpandableNotificationRow = notificationTestHelper.createRowWithRoundness(
-                /* topRoundness = */ 1f,
-                /* bottomRoundness = */ 1f,
-                /* sourceType = */ LegacySourceType.OnScroll)
-
-        NotificationShelf.resetLegacyOnScrollRoundness(row)
-
-        assertEquals(0f, row.topRoundness)
-        assertEquals(0f, row.bottomRoundness)
-    }
-
-    @Test
-    fun resetOnScrollRoundness_shouldNotResetOtherRoundness() {
-        val row1: ExpandableNotificationRow = notificationTestHelper.createRowWithRoundness(
-                /* topRoundness = */ 1f,
-                /* bottomRoundness = */ 1f,
-                /* sourceType = */ LegacySourceType.DefaultValue)
-        val row2: ExpandableNotificationRow = notificationTestHelper.createRowWithRoundness(
-                /* topRoundness = */ 1f,
-                /* bottomRoundness = */ 1f,
-                /* sourceType = */ LegacySourceType.OnDismissAnimation)
-
-        NotificationShelf.resetLegacyOnScrollRoundness(row1)
-        NotificationShelf.resetLegacyOnScrollRoundness(row2)
-
-        assertEquals(1f, row1.topRoundness)
-        assertEquals(1f, row1.bottomRoundness)
-        assertEquals(1f, row2.topRoundness)
-        assertEquals(1f, row2.bottomRoundness)
-    }
-
     private fun setFractionToShade(fraction: Float) {
         whenever(ambientState.fractionToShade).thenReturn(fraction)
     }
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 420c7ae..6a0e3c6 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
@@ -48,6 +48,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.media.controls.ui.KeyguardMediaController;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -143,6 +144,7 @@
     @Mock private NotificationTargetsHelper mNotificationTargetsHelper;
     @Mock private SecureSettings mSecureSettings;
     @Mock private NotificationIconAreaController mIconAreaController;
+    @Mock private ActivityStarter mActivityStarter;
 
     @Captor
     private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor;
@@ -491,7 +493,8 @@
                 mFeatureFlags,
                 mNotificationTargetsHelper,
                 mSecureSettings,
-                mock(NotificationDismissibilityProvider.class)
+                mock(NotificationDismissibilityProvider.class),
+                mActivityStarter
         );
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 7153e59..f771606 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -801,6 +801,34 @@
     }
 
     @Test
+    public void onShadeClosesWithAnimationWillResetSwipeState() {
+        // GIVEN shade is expanded
+        mStackScroller.setIsExpanded(true);
+        clearInvocations(mNotificationSwipeHelper);
+
+        // WHEN closing the shade with the animations
+        mStackScroller.onExpansionStarted();
+        mStackScroller.setIsExpanded(false);
+        mStackScroller.onExpansionStopped();
+
+        // VERIFY swipe is reset
+        verify(mNotificationSwipeHelper).resetSwipeState();
+    }
+
+    @Test
+    public void onShadeClosesWithoutAnimationWillResetSwipeState() {
+        // GIVEN shade is expanded
+        mStackScroller.setIsExpanded(true);
+        clearInvocations(mNotificationSwipeHelper);
+
+        // WHEN closing the shade without the animation
+        mStackScroller.setIsExpanded(false);
+
+        // VERIFY swipe is reset
+        verify(mNotificationSwipeHelper).resetSwipeState();
+    }
+
+    @Test
     public void testSplitShade_hasTopOverscroll() {
         mTestableResources
                 .addOverride(R.bool.config_use_split_notification_shade, /* value= */ true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt
index 81a3f12..45725ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelperTest.kt
@@ -6,7 +6,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.util.mockito.mock
 import junit.framework.Assert.assertEquals
@@ -30,14 +29,7 @@
             NotificationTestHelper(mContext, mDependency, TestableLooper.get(this))
     }
 
-    private fun notificationTargetsHelper(
-        notificationGroupCorner: Boolean = true,
-    ) =
-        NotificationTargetsHelper(
-            FakeFeatureFlags().apply {
-                set(Flags.USE_ROUNDNESS_SOURCETYPES, notificationGroupCorner)
-            }
-        )
+    private fun notificationTargetsHelper() = NotificationTargetsHelper(FakeFeatureFlags())
 
     @Test
     fun targetsForFirstNotificationInGroup() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
new file mode 100644
index 0000000..b6b28c9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.os.RemoteException
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.ActivityIntentHelper
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.assist.AssistManager
+import com.android.systemui.keyguard.KeyguardViewMediator
+import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.shade.ShadeController
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.statusbar.window.StatusBarWindowController
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import dagger.Lazy
+import java.util.Optional
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ActivityStarterImplTest : SysuiTestCase() {
+    @Mock private lateinit var centralSurfaces: CentralSurfaces
+    @Mock private lateinit var assistManager: AssistManager
+    @Mock private lateinit var dozeServiceHost: DozeServiceHost
+    @Mock private lateinit var biometricUnlockController: BiometricUnlockController
+    @Mock private lateinit var keyguardViewMediator: KeyguardViewMediator
+    @Mock private lateinit var shadeController: ShadeController
+    @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+    @Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
+    @Mock private lateinit var lockScreenUserManager: NotificationLockscreenUserManager
+    @Mock private lateinit var statusBarWindowController: StatusBarWindowController
+    @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
+    @Mock private lateinit var keyguardStateController: KeyguardStateController
+    @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
+    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController
+    @Mock private lateinit var userTracker: UserTracker
+    @Mock private lateinit var activityIntentHelper: ActivityIntentHelper
+    private lateinit var underTest: ActivityStarterImpl
+    private val mainExecutor = FakeExecutor(FakeSystemClock())
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        underTest =
+            ActivityStarterImpl(
+                Lazy { Optional.of(centralSurfaces) },
+                Lazy { assistManager },
+                Lazy { dozeServiceHost },
+                Lazy { biometricUnlockController },
+                Lazy { keyguardViewMediator },
+                Lazy { shadeController },
+                Lazy { statusBarKeyguardViewManager },
+                activityLaunchAnimator,
+                context,
+                lockScreenUserManager,
+                statusBarWindowController,
+                wakefulnessLifecycle,
+                keyguardStateController,
+                statusBarStateController,
+                keyguardUpdateMonitor,
+                deviceProvisionedController,
+                userTracker,
+                activityIntentHelper,
+                mainExecutor,
+            )
+    }
+
+    @Test
+    fun startPendingIntentDismissingKeyguard_keyguardShowing_dismissWithAction() {
+        val pendingIntent = mock(PendingIntent::class.java)
+        whenever(keyguardStateController.isShowing).thenReturn(true)
+        whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+
+        underTest.startPendingIntentDismissingKeyguard(pendingIntent)
+
+        verify(statusBarKeyguardViewManager)
+            .dismissWithAction(any(OnDismissAction::class.java), eq(null), anyBoolean(), eq(null))
+    }
+
+    @Test
+    fun startPendingIntentDismissingKeyguard_associatedView_getAnimatorController() {
+        val pendingIntent = mock(PendingIntent::class.java)
+        val associatedView = mock(ExpandableNotificationRow::class.java)
+
+        underTest.startPendingIntentDismissingKeyguard(
+            intent = pendingIntent,
+            intentSentUiThreadCallback = null,
+            associatedView = associatedView,
+        )
+
+        verify(centralSurfaces).getAnimatorControllerFromNotification(associatedView)
+    }
+
+    @Test
+    fun startActivity_noUserHandleProvided_getUserHandle() {
+        val intent = mock(Intent::class.java)
+
+        underTest.startActivity(intent, false)
+
+        verify(userTracker).userHandle
+    }
+
+    @Test
+    fun postStartActivityDismissingKeyguard_pendingIntent_postsOnMain() {
+        val intent = mock(PendingIntent::class.java)
+
+        underTest.postStartActivityDismissingKeyguard(intent)
+
+        assertThat(mainExecutor.numPending()).isEqualTo(1)
+    }
+
+    @Test
+    fun postStartActivityDismissingKeyguard_intent_postsOnMain() {
+        val intent = mock(Intent::class.java)
+
+        underTest.postStartActivityDismissingKeyguard(intent, 0)
+
+        assertThat(mainExecutor.numPending()).isEqualTo(1)
+    }
+
+    @Test
+    fun dismissKeyguardThenExecute_startWakeAndUnlock() {
+        whenever(wakefulnessLifecycle.wakefulness)
+            .thenReturn(WakefulnessLifecycle.WAKEFULNESS_ASLEEP)
+        whenever(keyguardStateController.canDismissLockScreen()).thenReturn(true)
+        whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false)
+        whenever(dozeServiceHost.isPulsing).thenReturn(true)
+
+        underTest.dismissKeyguardThenExecute({ true }, {}, false)
+
+        verify(biometricUnlockController)
+            .startWakeAndUnlock(BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING)
+    }
+
+    @Test
+    fun dismissKeyguardThenExecute_keyguardIsShowing_dismissWithAction() {
+        val customMessage = "Enter your pin."
+        whenever(keyguardStateController.isShowing).thenReturn(true)
+
+        underTest.dismissKeyguardThenExecute({ true }, {}, false, customMessage)
+
+        verify(statusBarKeyguardViewManager)
+            .dismissWithAction(
+                any(OnDismissAction::class.java),
+                any(Runnable::class.java),
+                eq(false),
+                eq(customMessage)
+            )
+    }
+
+    @Test
+    fun dismissKeyguardThenExecute_awakeDreams() {
+        val customMessage = "Enter your pin."
+        var dismissActionExecuted = false
+        whenever(keyguardStateController.isShowing).thenReturn(false)
+        whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true)
+
+        underTest.dismissKeyguardThenExecute(
+            {
+                dismissActionExecuted = true
+                true
+            },
+            {},
+            false,
+            customMessage
+        )
+
+        verify(centralSurfaces).awakenDreams()
+        assertThat(dismissActionExecuted).isTrue()
+    }
+
+    @Test
+    @Throws(RemoteException::class)
+    fun executeRunnableDismissingKeyguard_dreaming_notShowing_awakenDreams() {
+        whenever(keyguardStateController.isShowing).thenReturn(false)
+        whenever(keyguardStateController.isOccluded).thenReturn(false)
+        whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true)
+
+        underTest.executeRunnableDismissingKeyguard(
+            runnable = {},
+            cancelAction = null,
+            dismissShade = false,
+            afterKeyguardGone = false,
+            deferred = false
+        )
+
+        verify(centralSurfaces, times(1)).awakenDreams()
+    }
+
+    @Test
+    @Throws(RemoteException::class)
+    fun executeRunnableDismissingKeyguard_notDreaming_notShowing_doNotAwakenDreams() {
+        whenever(keyguardStateController.isShowing).thenReturn(false)
+        whenever(keyguardStateController.isOccluded).thenReturn(false)
+        whenever(keyguardUpdateMonitor.isDreaming).thenReturn(false)
+
+        underTest.executeRunnableDismissingKeyguard(
+            runnable = {},
+            cancelAction = null,
+            dismissShade = false,
+            afterKeyguardGone = false,
+            deferred = false
+        )
+
+        verify(centralSurfaces, never()).awakenDreams()
+    }
+
+    @Test
+    fun postQSRunnableDismissingKeyguard_leaveOpenStatusBarState() {
+        underTest.postQSRunnableDismissingKeyguard {}
+
+        assertThat(mainExecutor.numPending()).isEqualTo(1)
+        mainExecutor.runAllReady()
+        verify(statusBarStateController).setLeaveOpenOnKeyguardHide(true)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index 872c560..3870d99 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -43,6 +43,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.CameraLauncher;
@@ -96,6 +97,7 @@
     @Mock private Lazy<CameraLauncher> mCameraLauncherLazy;
     @Mock private UserTracker mUserTracker;
     @Mock private QSHost mQSHost;
+    @Mock private ActivityStarter mActivityStarter;
 
     CentralSurfacesCommandQueueCallbacks mSbcqCallbacks;
 
@@ -131,7 +133,8 @@
                 mSystemBarAttributesListener,
                 mCameraLauncherLazy,
                 mUserTracker,
-                mQSHost);
+                mQSHost,
+                mActivityStarter);
 
         when(mUserTracker.getUserHandle()).thenReturn(
                 UserHandle.of(ActivityManager.getCurrentUser()));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 2831d2f..163369f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -41,6 +41,7 @@
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.keyguard.domain.interactor.BurnInInteractor;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.shade.ShadeViewController;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -92,6 +93,7 @@
     @Mock private BiometricUnlockController mBiometricUnlockController;
     @Mock private AuthController mAuthController;
     @Mock private DozeHost.Callback mCallback;
+    @Mock private BurnInInteractor mBurnInInteractor;
 
     @Before
     public void setup() {
@@ -102,7 +104,8 @@
                 () -> mAssistManager, mDozeScrimController,
                 mKeyguardUpdateMonitor, mPulseExpansionHandler,
                 mNotificationShadeWindowController, mNotificationWakeUpCoordinator,
-                mAuthController, mNotificationIconAreaController);
+                mAuthController, mNotificationIconAreaController,
+                mBurnInInteractor);
 
         mDozeServiceHost.initialize(
                 mCentralSurfaces,
@@ -213,4 +216,12 @@
         assertFalse(mDozeServiceHost.isPulsePending());
         verify(mDozeScrimController).pulseOutNow();
     }
+    @Test
+    public void dozeTimeTickSentTBurnInInteractor() {
+        // WHEN dozeTimeTick
+        mDozeServiceHost.dozeTimeTick();
+
+        // THEN burnInInteractor's dozeTimeTick is updated
+        verify(mBurnInInteractor).dozeTimeTick();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 205cebd..2f1e372 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -34,8 +34,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.ShadeHeadsUpTracker;
@@ -82,7 +80,6 @@
     private KeyguardStateController mKeyguardStateController;
     private CommandQueue mCommandQueue;
     private NotificationRoundnessManager mNotificationRoundnessManager;
-    private FeatureFlags mFeatureFlag;
 
     @Before
     public void setUp() throws Exception {
@@ -103,9 +100,7 @@
         mKeyguardStateController = mock(KeyguardStateController.class);
         mCommandQueue = mock(CommandQueue.class);
         mNotificationRoundnessManager = mock(NotificationRoundnessManager.class);
-        mFeatureFlag = mock(FeatureFlags.class);
         when(mShadeViewController.getShadeHeadsUpTracker()).thenReturn(mShadeHeadsUpTracker);
-        when(mFeatureFlag.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES)).thenReturn(true);
         mHeadsUpAppearanceController = new HeadsUpAppearanceController(
                 mock(NotificationIconAreaController.class),
                 mHeadsUpManager,
@@ -118,7 +113,6 @@
                 mStackScrollerController,
                 mShadeViewController,
                 mNotificationRoundnessManager,
-                mFeatureFlag,
                 mHeadsUpStatusBarView,
                 new Clock(mContext, null),
                 Optional.of(mOperatorNameView));
@@ -202,7 +196,6 @@
                 mStackScrollerController,
                 mShadeViewController,
                 mNotificationRoundnessManager,
-                mFeatureFlag,
                 mHeadsUpStatusBarView,
                 new Clock(mContext, null),
                 Optional.empty());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 780e0c5..6fda56c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -116,7 +116,6 @@
                 .thenReturn(TEST_AUTO_DISMISS_TIME);
         when(mVSProvider.isReorderingAllowed()).thenReturn(true);
         mDependency.injectMockDependency(NotificationShadeWindowController.class);
-        mDependency.injectMockDependency(ConfigurationController.class);
         super.setUp();
 
         mHeadsUpManager = new TestableHeadsUpManagerPhone(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
index 529519a..a501556 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
@@ -22,21 +22,31 @@
 
 import static junit.framework.Assert.assertTrue;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import androidx.annotation.ColorInt;
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.util.ContrastColorUtil;
 import com.android.internal.view.AppearanceRegion;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.settings.FakeDisplayTracker;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -53,13 +63,25 @@
 @TestableLooper.RunWithLooper
 public class LightBarControllerTest extends SysuiTestCase {
 
+    private static final GradientColors COLORS_LIGHT = makeColors(Color.WHITE);
+    private static final GradientColors COLORS_DARK = makeColors(Color.BLACK);
+    private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
     private LightBarTransitionsController mLightBarTransitionsController;
+    private LightBarTransitionsController mNavBarController;
     private SysuiDarkIconDispatcher mStatusBarIconController;
     private LightBarController mLightBarController;
 
+    /** Allow testing with NEW_LIGHT_BAR_LOGIC flag in different states */
+    protected boolean testNewLightBarLogic() {
+        return false;
+    }
+
     @Before
     public void setup() {
+        mFeatureFlags.set(Flags.NEW_LIGHT_BAR_LOGIC, testNewLightBarLogic());
         mStatusBarIconController = mock(SysuiDarkIconDispatcher.class);
+        mNavBarController = mock(LightBarTransitionsController.class);
+        when(mNavBarController.supportsIconTintForNavMode(anyInt())).thenReturn(true);
         mLightBarTransitionsController = mock(LightBarTransitionsController.class);
         when(mStatusBarIconController.getTransitionsController()).thenReturn(
                 mLightBarTransitionsController);
@@ -68,10 +90,19 @@
                 mStatusBarIconController,
                 mock(BatteryController.class),
                 mock(NavigationModeController.class),
+                mFeatureFlags,
                 mock(DumpManager.class),
                 new FakeDisplayTracker(mContext));
     }
 
+    private static GradientColors makeColors(@ColorInt int bgColor) {
+        GradientColors colors = new GradientColors();
+        colors.setMainColor(bgColor);
+        colors.setSecondaryColor(bgColor);
+        colors.setSupportsDarkText(!ContrastColorUtil.isColorDark(bgColor));
+        return colors;
+    }
+
     @Test
     public void testOnStatusBarAppearanceChanged_multipleStacks_allStacksLight() {
         final Rect firstBounds = new Rect(0, 0, 1, 1);
@@ -177,4 +208,54 @@
                 false /* navbarColorManagedByIme */);
         verify(mLightBarTransitionsController).setIconsDark(eq(false), anyBoolean());
     }
+
+    @Test
+    public void validateNavBarChangesUpdateIcons() {
+        assumeTrue(testNewLightBarLogic());  // Only run in the new suite
+
+        // On the launcher in dark mode buttons are light
+        mLightBarController.setScrimState(ScrimState.UNLOCKED, 0f, COLORS_DARK);
+        mLightBarController.onNavigationBarAppearanceChanged(
+                0, /* nbModeChanged = */ true,
+                MODE_TRANSPARENT, /* navbarColorManagedByIme = */ false);
+        verifyNavBarIconsUnchanged(); // no changes yet; not attached
+
+        // Initial state is set when controller is set
+        mLightBarController.setNavigationBar(mNavBarController);
+        verifyNavBarIconsDarkSetTo(false);
+
+        // Changing the color of the transparent scrim has no effect
+        mLightBarController.setScrimState(ScrimState.UNLOCKED, 0f, COLORS_LIGHT);
+        verifyNavBarIconsUnchanged(); // still light
+
+        // Showing the notification shade with white scrim requires dark icons
+        mLightBarController.setScrimState(ScrimState.UNLOCKED, 1f, COLORS_LIGHT);
+        verifyNavBarIconsDarkSetTo(true);
+
+        // Expanded QS always provides a black background, so icons become light again
+        mLightBarController.setQsExpanded(true);
+        verifyNavBarIconsDarkSetTo(false);
+
+        // Tapping the QS tile to change to dark theme has no effect in this state
+        mLightBarController.setScrimState(ScrimState.UNLOCKED, 1f, COLORS_DARK);
+        verifyNavBarIconsUnchanged(); // still light
+
+        // collapsing QS in dark mode doesn't affect button color
+        mLightBarController.setQsExpanded(false);
+        verifyNavBarIconsUnchanged(); // still light
+
+        // Closing the shade has no affect
+        mLightBarController.setScrimState(ScrimState.UNLOCKED, 0f, COLORS_DARK);
+        verifyNavBarIconsUnchanged(); // still light
+    }
+
+    private void verifyNavBarIconsUnchanged() {
+        verify(mNavBarController, never()).setIconsDark(anyBoolean(), anyBoolean());
+    }
+
+    private void verifyNavBarIconsDarkSetTo(boolean iconsDark) {
+        verify(mNavBarController).setIconsDark(eq(iconsDark), anyBoolean());
+        verify(mNavBarController, never()).setIconsDark(eq(!iconsDark), anyBoolean());
+        clearInvocations(mNavBarController);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerWithNewLogicTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerWithNewLogicTest.kt
new file mode 100644
index 0000000..d9c2cfa
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerWithNewLogicTest.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.phone
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.flags.Flags.NEW_LIGHT_BAR_LOGIC
+
+/**
+ * This file only needs to live as long as [NEW_LIGHT_BAR_LOGIC] does. When we delete that flag, we
+ * can roll this back into the old test.
+ */
+@SmallTest
+class LightBarControllerWithNewLogicTest : LightBarControllerTest() {
+    override fun testNewLightBarLogic(): Boolean = true
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
index b80b825..c282c1e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
@@ -21,6 +21,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
+import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
@@ -49,7 +51,7 @@
     fun calculateWidthFor_oneIcon_widthForOneIcon() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 1f),
                 /* actual= */ 30f)
@@ -59,7 +61,7 @@
     fun calculateWidthFor_fourIcons_widthForFourIcons() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 4f),
                 /* actual= */ 60f)
@@ -69,7 +71,7 @@
     fun calculateWidthFor_fiveIcons_widthForFourIcons() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
         assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 5f),
                 /* actual= */ 60f)
     }
@@ -78,7 +80,7 @@
     fun calculateIconXTranslations_shortShelfOneIcon_atCorrectXWithoutOverflowDot() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         val icon = mockStatusBarIcon()
         iconContainer.addView(icon)
@@ -99,7 +101,7 @@
     fun calculateIconXTranslations_shortShelfFourIcons_atCorrectXWithoutOverflowDot() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         val iconOne = mockStatusBarIcon()
         val iconTwo = mockStatusBarIcon()
@@ -128,7 +130,7 @@
     fun calculateIconXTranslations_shortShelfFiveIcons_atCorrectXWithOverflowDot() {
         iconContainer.setActualPaddingStart(10f)
         iconContainer.setActualPaddingEnd(10f)
-        iconContainer.setIconSize(10);
+        iconContainer.setIconSize(10)
 
         val iconOne = mockStatusBarIcon()
         val iconTwo = mockStatusBarIcon()
@@ -154,6 +156,55 @@
     }
 
     @Test
+    fun calculateIconXTranslations_givenWidthEnoughForThreeIcons_atCorrectXWithoutOverflowDot() {
+        iconContainer.setActualPaddingStart(0f)
+        iconContainer.setActualPaddingEnd(0f)
+        iconContainer.setActualLayoutWidth(30)
+        iconContainer.setIconSize(10)
+
+        val iconOne = mockStatusBarIcon()
+        val iconTwo = mockStatusBarIcon()
+        val iconThree = mockStatusBarIcon()
+
+        iconContainer.addView(iconOne)
+        iconContainer.addView(iconTwo)
+        iconContainer.addView(iconThree)
+        assertEquals(3, iconContainer.childCount)
+
+        iconContainer.calculateIconXTranslations()
+        assertEquals(0f, iconContainer.getIconState(iconOne).xTranslation)
+        assertEquals(10f, iconContainer.getIconState(iconTwo).xTranslation)
+        assertEquals(20f, iconContainer.getIconState(iconThree).xTranslation)
+        assertFalse(iconContainer.areIconsOverflowing())
+    }
+
+    @Test
+    fun calculateIconXTranslations_givenWidthNotEnoughForFourIcons_atCorrectXWithOverflowDot() {
+        iconContainer.setActualPaddingStart(0f)
+        iconContainer.setActualPaddingEnd(0f)
+        iconContainer.setActualLayoutWidth(35)
+        iconContainer.setIconSize(10)
+
+        val iconOne = mockStatusBarIcon()
+        val iconTwo = mockStatusBarIcon()
+        val iconThree = mockStatusBarIcon()
+        val iconFour = mockStatusBarIcon()
+
+        iconContainer.addView(iconOne)
+        iconContainer.addView(iconTwo)
+        iconContainer.addView(iconThree)
+        iconContainer.addView(iconFour)
+        assertEquals(4, iconContainer.childCount)
+
+        iconContainer.calculateIconXTranslations()
+        assertEquals(0f, iconContainer.getIconState(iconOne).xTranslation)
+        assertEquals(10f, iconContainer.getIconState(iconTwo).xTranslation)
+        assertEquals(STATE_DOT, iconContainer.getIconState(iconThree).visibleState)
+        assertEquals(STATE_HIDDEN, iconContainer.getIconState(iconFour).visibleState)
+        assertTrue(iconContainer.areIconsOverflowing())
+    }
+
+    @Test
     fun shouldForceOverflow_appearingAboveSpeedBump_true() {
         val forceOverflow = iconContainer.shouldForceOverflow(
                 /* i= */ 1,
@@ -161,7 +212,7 @@
                 /* iconAppearAmount= */ 1f,
                 /* maxVisibleIcons= */ 5
         )
-        assertTrue(forceOverflow);
+        assertTrue(forceOverflow)
     }
 
     @Test
@@ -172,7 +223,7 @@
                 /* iconAppearAmount= */ 0f,
                 /* maxVisibleIcons= */ 5
         )
-        assertTrue(forceOverflow);
+        assertTrue(forceOverflow)
     }
 
     @Test
@@ -183,7 +234,7 @@
                 /* iconAppearAmount= */ 0f,
                 /* maxVisibleIcons= */ 5
         )
-        assertFalse(forceOverflow);
+        assertFalse(forceOverflow)
     }
 
     @Test
@@ -210,6 +261,17 @@
     }
 
     @Test
+    fun isOverflowing_lastChildXGreaterThanDotX_true() {
+        val isOverflowing = iconContainer.isOverflowing(
+                /* isLastChild= */ true,
+                /* translationX= */ 9f,
+                /* layoutEnd= */ 10f,
+                /* iconSize= */ 2f,
+        )
+        assertTrue(isOverflowing)
+    }
+
+    @Test
     fun isOverflowing_lastChildXGreaterThanLayoutEnd_true() {
         val isOverflowing = iconContainer.isOverflowing(
                 /* isLastChild= */ true,
@@ -253,7 +315,7 @@
         assertTrue(isOverflowing)
     }
 
-    private fun mockStatusBarIcon() : StatusBarIconView {
+    private fun mockStatusBarIcon(): StatusBarIconView {
         val iconView = mock(StatusBarIconView::class.java)
         whenever(iconView.width).thenReturn(10)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 4ff225c..e56f0d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -72,6 +72,7 @@
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.navigationbar.TaskbarDelegate;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.ShadeController;
@@ -83,6 +84,7 @@
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.unfold.SysUIUnfoldComponent;
 
 import com.google.common.truth.Truth;
@@ -129,6 +131,7 @@
     @Mock private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
     @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
     @Mock private UdfpsOverlayInteractor mUdfpsOverlayInteractor;
+    @Mock private ActivityStarter mActivityStarter;
     @Mock private BouncerView mBouncerView;
     @Mock private BouncerViewDelegate mBouncerViewDelegate;
     @Mock private OnBackAnimationCallback mBouncerViewDelegateBackCallback;
@@ -149,13 +152,15 @@
     private WindowOnBackInvokedDispatcher mOnBackInvokedDispatcher;
     @Captor
     private ArgumentCaptor<OnBackInvokedCallback> mBackCallbackCaptor;
+    @Captor
+    private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallback;
 
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mContainer.findViewById(anyInt())).thenReturn(mKeyguardMessageArea);
-        when(mKeyguardMessageAreaFactory.create(any(KeyguardMessageArea.class)))
+        when(mKeyguardMessageAreaFactory.create(any()))
                 .thenReturn(mKeyguardMessageAreaController);
         when(mBouncerView.getDelegate()).thenReturn(mBouncerViewDelegate);
         when(mBouncerViewDelegate.getBackCallback()).thenReturn(mBouncerViewDelegateBackCallback);
@@ -192,7 +197,8 @@
                         mPrimaryBouncerInteractor,
                         mBouncerView,
                         mAlternateBouncerInteractor,
-                        mUdfpsOverlayInteractor) {
+                        mUdfpsOverlayInteractor,
+                        mActivityStarter) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
@@ -680,7 +686,8 @@
                         mPrimaryBouncerInteractor,
                         mBouncerView,
                         mAlternateBouncerInteractor,
-                        mUdfpsOverlayInteractor) {
+                        mUdfpsOverlayInteractor,
+                        mActivityStarter) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
@@ -905,4 +912,26 @@
         // THEN the alternateBouncer doesn't hide
         verify(mAlternateBouncerInteractor, never()).hide();
     }
+
+    @Test
+    public void onDeviceUnlocked_hideAlternateBouncerAndClearMessageArea() {
+        reset(mKeyguardUpdateMonitor);
+        reset(mKeyguardMessageAreaController);
+
+        // GIVEN keyguard state controller callback is registered
+        verify(mKeyguardStateController).addCallback(mKeyguardStateControllerCallback.capture());
+
+        // GIVEN alternate bouncer state = not visible
+        when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
+
+        // WHEN the device is unlocked
+        mKeyguardStateControllerCallback.getValue().onUnlockedChanged();
+
+        // THEN the false visibility state is propagated to the keyguardUpdateMonitor
+        verify(mKeyguardUpdateMonitor).setAlternateBouncerShowing(eq(false));
+
+        // THEN message area visibility updated to FALSE with empty message
+        verify(mKeyguardMessageAreaController).setIsVisible(eq(false));
+        verify(mKeyguardMessageAreaController).setMessage(eq(""));
+    }
 }
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 3ec9690..bde05b9 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
@@ -53,6 +53,7 @@
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
@@ -92,13 +93,15 @@
     private val mobileMappings = FakeMobileMappingsProxy()
     private val subscriptionManagerProxy = FakeSubscriptionManagerProxy()
 
+    private val testDispatcher = UnconfinedTestDispatcher()
     private val scope = CoroutineScope(IMMEDIATE)
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
-        logFactory = TableLogBufferFactory(dumpManager, FakeSystemClock())
+        logFactory =
+            TableLogBufferFactory(dumpManager, FakeSystemClock(), mock(), testDispatcher, scope)
 
         // Never start in demo mode
         whenever(demoModeController.isInDemoMode).thenReturn(false)
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 37fac34..7573b28 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
@@ -61,11 +61,18 @@
 internal class DemoMobileConnectionParameterizedTest(private val testCase: TestCase) :
     SysuiTestCase() {
 
-    private val logFactory = TableLogBufferFactory(mock(), FakeSystemClock())
-
     private val testDispatcher = UnconfinedTestDispatcher()
     private val testScope = TestScope(testDispatcher)
 
+    private val logFactory =
+        TableLogBufferFactory(
+            mock(),
+            FakeSystemClock(),
+            mock(),
+            testDispatcher,
+            testScope.backgroundScope,
+        )
+
     private val fakeNetworkEventFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
     private val fakeWifiEventFlow = MutableStateFlow<FakeWifiEventModel?>(null)
 
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 1251dfa..efaf152 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
@@ -54,13 +54,20 @@
 @SmallTest
 class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
     private val dumpManager: DumpManager = mock()
-    private val logFactory = TableLogBufferFactory(dumpManager, FakeSystemClock())
 
     private val testDispatcher = UnconfinedTestDispatcher()
     private val testScope = TestScope(testDispatcher)
 
     private val fakeNetworkEventFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
     private val fakeWifiEventFlow = MutableStateFlow<FakeWifiEventModel?>(null)
+    private val logFactory =
+        TableLogBufferFactory(
+            dumpManager,
+            FakeSystemClock(),
+            mock(),
+            testDispatcher,
+            testScope.backgroundScope,
+        )
 
     private lateinit var underTest: DemoMobileConnectionsRepository
     private lateinit var mobileDataSource: DemoModeMobileConnectionDataSource
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 9f77744..b701fbd 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
@@ -66,7 +66,15 @@
     private val systemClock = FakeSystemClock()
     private val testDispatcher = UnconfinedTestDispatcher()
     private val testScope = TestScope(testDispatcher)
-    private val tableLogBuffer = TableLogBuffer(maxSize = 100, name = "TestName", systemClock)
+    private val tableLogBuffer =
+        TableLogBuffer(
+            maxSize = 100,
+            name = "TestName",
+            systemClock,
+            mock(),
+            testDispatcher,
+            testScope.backgroundScope,
+        )
     private val mobileFactory = mock<MobileConnectionRepositoryImpl.Factory>()
     private val carrierMergedFactory = mock<CarrierMergedConnectionRepository.Factory>()
 
@@ -294,7 +302,14 @@
     @Test
     fun factory_reusesLogBuffersForSameConnection() =
         testScope.runTest {
-            val realLoggerFactory = TableLogBufferFactory(mock(), FakeSystemClock())
+            val realLoggerFactory =
+                TableLogBufferFactory(
+                    mock(),
+                    FakeSystemClock(),
+                    mock(),
+                    testDispatcher,
+                    testScope.backgroundScope,
+                )
 
             val factory =
                 FullMobileConnectionRepository.Factory(
@@ -329,7 +344,14 @@
     @Test
     fun factory_reusesLogBuffersForSameSubIDevenIfCarrierMerged() =
         testScope.runTest {
-            val realLoggerFactory = TableLogBufferFactory(mock(), FakeSystemClock())
+            val realLoggerFactory =
+                TableLogBufferFactory(
+                    mock(),
+                    FakeSystemClock(),
+                    mock(),
+                    testDispatcher,
+                    testScope.backgroundScope,
+                )
 
             val factory =
                 FullMobileConnectionRepository.Factory(
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 c84c9c0..6e1ab58 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
@@ -61,6 +61,16 @@
     private val testDispatcher = UnconfinedTestDispatcher()
     private val testScope = TestScope(testDispatcher)
 
+    private val tableLogBuffer =
+        TableLogBuffer(
+            8,
+            "MobileIconsInteractorTest",
+            FakeSystemClock(),
+            mock(),
+            testDispatcher,
+            testScope.backgroundScope,
+        )
+
     @Mock private lateinit var carrierConfigTracker: CarrierConfigTracker
 
     @Before
@@ -687,16 +697,14 @@
     }
 
     companion object {
-        private val tableLogBuffer =
-            TableLogBuffer(8, "MobileIconsInteractorTest", FakeSystemClock())
 
         private const val SUB_1_ID = 1
         private val SUB_1 = SubscriptionModel(subscriptionId = SUB_1_ID)
-        private val CONNECTION_1 = FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer)
+        private val CONNECTION_1 = FakeMobileConnectionRepository(SUB_1_ID, mock())
 
         private const val SUB_2_ID = 2
         private val SUB_2 = SubscriptionModel(subscriptionId = SUB_2_ID)
-        private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID, tableLogBuffer)
+        private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID, mock())
 
         private const val SUB_3_ID = 3
         private val SUB_3_OPP =
@@ -705,7 +713,7 @@
                 isOpportunistic = true,
                 groupUuid = ParcelUuid(UUID.randomUUID()),
             )
-        private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID, tableLogBuffer)
+        private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID, mock())
 
         private const val SUB_4_ID = 4
         private val SUB_4_OPP =
@@ -714,6 +722,6 @@
                 isOpportunistic = true,
                 groupUuid = ParcelUuid(UUID.randomUUID()),
             )
-        private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID, tableLogBuffer)
+        private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID, mock())
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
index db50163..b8e4306 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
@@ -1,6 +1,7 @@
 package com.android.systemui.statusbar.policy;
 
 
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -125,4 +126,20 @@
             fail("Concurrent modification exception");
         }
     }
+
+    @Test
+    public void hasConnectedCastDevice_connected() {
+        CastController.CastDevice castDevice = new CastController.CastDevice();
+        castDevice.state = CastController.CastDevice.STATE_CONNECTED;
+        mController.startCasting(castDevice);
+        assertTrue(mController.hasConnectedCastDevice());
+    }
+
+    @Test
+    public void hasConnectedCastDevice_notConnected() {
+        CastController.CastDevice castDevice = new CastController.CastDevice();
+        castDevice.state = CastController.CastDevice.STATE_CONNECTING;
+        mController.startCasting(castDevice);
+        assertTrue(mController.hasConnectedCastDevice());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
index 71ac7c4..683136d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
@@ -45,6 +45,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.Map;
 import java.util.function.Consumer;
@@ -53,16 +55,18 @@
 @SmallTest
 public class ExtensionControllerImplTest extends SysuiTestCase {
 
+    @Mock
+    private ConfigurationController mConfigurationController;
+
     private PluginManager mPluginManager;
     private TunerService mTunerService;
     private ExtensionController mExtensionController;
-    private ConfigurationController mConfigurationController;
 
     @Before
     public void setup() {
+        MockitoAnnotations.initMocks(this);
         mPluginManager = mDependency.injectMockDependency(PluginManager.class);
         mTunerService = mDependency.injectMockDependency(TunerService.class);
-        mConfigurationController = mDependency.injectMockDependency(ConfigurationController.class);
         mExtensionController = new ExtensionControllerImpl(
                 mContext,
                 mock(LeakDetector.class),
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 1510ee8..47a86b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -380,7 +380,7 @@
                 mPositioner,
                 mock(DisplayController.class),
                 mOneHandedOptional,
-                mock(DragAndDropController.class),
+                Optional.of(mock(DragAndDropController.class)),
                 syncExecutor,
                 mock(Handler.class),
                 mTaskViewTransitions,
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 c3bb771..14c3f3c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
@@ -69,7 +69,7 @@
             BubblePositioner positioner,
             DisplayController displayController,
             Optional<OneHandedController> oneHandedOptional,
-            DragAndDropController dragAndDropController,
+            Optional<DragAndDropController> dragAndDropController,
             ShellExecutor shellMainExecutor,
             Handler shellMainHandler,
             TaskViewTransitions taskViewTransitions,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/RoboPilotTest.java b/packages/SystemUI/tests/utils/src/com/android/systemui/RoboPilotTest.java
new file mode 100644
index 0000000..3fff136
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/RoboPilotTest.java
@@ -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;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Mark as tests for Robolectric pilot projects. The filter can better help grouping test results
+ * that runs on CI
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RoboPilotTest {
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFingerprintPropertyRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFingerprintPropertyRepository.kt
new file mode 100644
index 0000000..d9012a5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFingerprintPropertyRepository.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.data.repository
+
+import android.hardware.biometrics.SensorLocationInternal
+import com.android.systemui.biometrics.shared.model.FingerprintSensorType
+import com.android.systemui.biometrics.shared.model.SensorStrength
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class FakeFingerprintPropertyRepository : FingerprintPropertyRepository {
+
+    private val _isInitialized: MutableStateFlow<Boolean> = MutableStateFlow(false)
+    override val isInitialized = _isInitialized.asStateFlow()
+
+    private val _sensorId: MutableStateFlow<Int> = MutableStateFlow(-1)
+    override val sensorId: StateFlow<Int> = _sensorId.asStateFlow()
+
+    private val _strength: MutableStateFlow<SensorStrength> =
+        MutableStateFlow(SensorStrength.CONVENIENCE)
+    override val strength = _strength.asStateFlow()
+
+    private val _sensorType: MutableStateFlow<FingerprintSensorType> =
+        MutableStateFlow(FingerprintSensorType.UNKNOWN)
+    override val sensorType: StateFlow<FingerprintSensorType> = _sensorType.asStateFlow()
+
+    private val _sensorLocation: MutableStateFlow<SensorLocationInternal> =
+        MutableStateFlow(SensorLocationInternal.DEFAULT)
+    override val sensorLocation = _sensorLocation.asStateFlow()
+
+    fun setProperties(
+        sensorId: Int,
+        strength: SensorStrength,
+        sensorType: FingerprintSensorType,
+        sensorLocation: SensorLocationInternal
+    ) {
+        _sensorId.value = sensorId
+        _strength.value = strength
+        _sensorType.value = sensorType
+        _sensorLocation.value = sensorLocation
+        _isInitialized.value = true
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeRearDisplayStateRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeRearDisplayStateRepository.kt
new file mode 100644
index 0000000..fd91391
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeRearDisplayStateRepository.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.biometrics.data.repository
+
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class FakeRearDisplayStateRepository : RearDisplayStateRepository {
+    private val _isInRearDisplayMode = MutableStateFlow<Boolean>(false)
+    override val isInRearDisplayMode: StateFlow<Boolean> = _isInRearDisplayMode.asStateFlow()
+
+    fun setIsInRearDisplayMode(isInRearDisplayMode: Boolean) {
+        _isInRearDisplayMode.value = isInRearDisplayMode
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
index 2c0a8fd..492e542 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
@@ -21,13 +21,27 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 
-/** Fake implementation of [KeyguardRepository] */
+/** Fake implementation of [ShadeRepository] */
 class FakeShadeRepository : ShadeRepository {
 
     private val _shadeModel = MutableStateFlow(ShadeModel())
     override val shadeModel: Flow<ShadeModel> = _shadeModel
 
+    private val _qsExpansion = MutableStateFlow(0f)
+    override val qsExpansion = _qsExpansion
+
+    private val _udfpsTransitionToFullShadeProgress = MutableStateFlow(0f)
+    override val udfpsTransitionToFullShadeProgress = _udfpsTransitionToFullShadeProgress
+
     fun setShadeModel(model: ShadeModel) {
         _shadeModel.value = model
     }
+
+    override fun setQsExpansion(qsExpansion: Float) {
+        _qsExpansion.value = qsExpansion
+    }
+
+    override fun setUdfpsTransitionToFullShadeProgress(progress: Float) {
+        _udfpsTransitionToFullShadeProgress.value = progress
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java
index f6b24da..84ace7c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java
@@ -51,4 +51,9 @@
     public void stopCasting(CastDevice device) {
 
     }
+
+    @Override
+    public boolean hasConnectedCastDevice() {
+        return false;
+    }
 }
diff --git a/packages/VpnDialogs/res/values-zh-rHK/strings.xml b/packages/VpnDialogs/res/values-zh-rHK/strings.xml
index f3abf3c..f4d06e2 100644
--- a/packages/VpnDialogs/res/values-zh-rHK/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rHK/strings.xml
@@ -17,8 +17,8 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="3183836924226407828">"連線要求"</string>
-    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> 要求設定 VPN 連線以監控網絡流量。除非您信任要求來源,否則請勿隨意接受要求。&lt;br /&gt; &lt;br /&gt;VPN 啟用時,畫面頂端會顯示 &lt;img src=vpn_icon /&gt;。"</string>
-    <string name="warning" product="tv" msgid="5188957997628124947">"「<xliff:g id="APP">%s</xliff:g>」要求設定 VPN 連線以監控網絡流量。除非您信任要求來源,否則請勿隨意接受要求。VPN 啟用時,畫面會顯示 &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt;。"</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> 要求設定 VPN 連線以監控網絡流量。除非你信任要求來源,否則請勿隨意接受要求。&lt;br /&gt; &lt;br /&gt;VPN 啟用時,畫面頂端會顯示 &lt;img src=vpn_icon /&gt;。"</string>
+    <string name="warning" product="tv" msgid="5188957997628124947">"「<xliff:g id="APP">%s</xliff:g>」要求設定 VPN 連線以監控網絡流量。除非你信任要求來源,否則請勿隨意接受要求。VPN 啟用時,畫面會顯示 &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt;。"</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN 已連線"</string>
     <string name="session" msgid="6470628549473641030">"時段:"</string>
     <string name="duration" msgid="3584782459928719435">"持續時間︰"</string>
@@ -26,8 +26,8 @@
     <string name="data_received" msgid="4062776929376067820">"已接收:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> 位元組 / <xliff:g id="NUMBER_1">%2$s</xliff:g> 封包"</string>
     <string name="always_on_disconnected_title" msgid="1906740176262776166">"無法連線至保持開啟的 VPN"</string>
-    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> 已設定為隨時保持連線,但目前無法連線。在重新連線至 <xliff:g id="VPN_APP_1">%1$s</xliff:g> 前,您的手機將會使用公共網絡。"</string>
-    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> 已設定為隨時保持連線,但目前無法連線。在重新連線至 VPN 前,您將無法連線至網絡。"</string>
+    <string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> 已設定為隨時保持連線,但目前無法連線。在重新連線至 <xliff:g id="VPN_APP_1">%1$s</xliff:g> 前,你的手機將會使用公共網絡。"</string>
+    <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> 已設定為隨時保持連線,但目前無法連線。在重新連線至 VPN 前,你將無法連線至網絡。"</string>
     <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
     <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"變更 VPN 設定"</string>
     <string name="configure" msgid="4905518375574791375">"設定"</string>
diff --git a/packages/overlays/NoCutoutOverlay/res/values-mk/strings.xml b/packages/overlays/NoCutoutOverlay/res/values-mk/strings.xml
index 505c205..0c821f2 100644
--- a/packages/overlays/NoCutoutOverlay/res/values-mk/strings.xml
+++ b/packages/overlays/NoCutoutOverlay/res/values-mk/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"Сокриј"</string>
+    <string name="display_cutout_emulation_overlay" msgid="9031691255599853162">"Скриј"</string>
 </resources>
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index a3b4a0f..d36c959 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1012,8 +1012,7 @@
                                 + Binder.getCallingPid() + " for device id " + deviceId
                                 + " with package names " + Arrays.toString(client.mPackageNames));
                     }
-                    return IntPair.of(mProxyManager.getStateLocked(deviceId,
-                                    mUiAutomationManager.isUiAutomationRunningLocked()),
+                    return IntPair.of(mProxyManager.getStateLocked(deviceId),
                             client.mLastSentRelevantEventTypes);
                 }
                 mGlobalClients.register(callback, client);
@@ -1028,8 +1027,7 @@
                                 + Binder.getCallingPid() + " for device id " + deviceId
                                 + " with package names " + Arrays.toString(client.mPackageNames));
                     }
-                    return IntPair.of(mProxyManager.getStateLocked(deviceId,
-                                    mUiAutomationManager.isUiAutomationRunningLocked()),
+                    return IntPair.of(mProxyManager.getStateLocked(deviceId),
                             client.mLastSentRelevantEventTypes);
                 }
                 userState.mUserClients.register(callback, client);
@@ -4024,9 +4022,8 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            mProxyManager.registerProxy(client, displayId, mContext,
-                    sIdCounter++, mMainHandler, mSecurityPolicy, this, getTraceManager(),
-                    mWindowManagerService);
+            mProxyManager.registerProxy(client, displayId, sIdCounter++, mSecurityPolicy,
+                    this, getTraceManager(), mWindowManagerService);
 
             synchronized (mLock) {
                 notifyClearAccessibilityCacheLocked();
diff --git a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
index d417197..6dc8fb3 100644
--- a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
@@ -61,7 +61,6 @@
  * proxy connection will belong to a separate user state.
  *
  * TODO(241117292): Remove or cut down during simultaneous user refactoring.
- * TODO(262244375): Add unit tests.
  */
 public class ProxyManager {
     private static final boolean DEBUG = false;
@@ -128,7 +127,7 @@
         RemoteCallbackList<IAccessibilityManagerClient> getCurrentUserClientsLocked();
     }
 
-    ProxyManager(Object lock, AccessibilityWindowManager awm,
+    public ProxyManager(Object lock, AccessibilityWindowManager awm,
             Context context, Handler mainHandler, UiAutomationManager uiAutomationManager,
             SystemSupport systemSupport) {
         mLock = lock;
@@ -144,9 +143,7 @@
      * Creates the service connection.
      */
     public void registerProxy(IAccessibilityServiceClient client, int displayId,
-            Context context,
-            int id, Handler mainHandler,
-            AccessibilitySecurityPolicy securityPolicy,
+            int id, AccessibilitySecurityPolicy securityPolicy,
             AbstractAccessibilityServiceConnection.SystemSupport systemSupport,
             AccessibilityTrace trace,
             WindowManagerInternal windowManagerInternal) throws RemoteException {
@@ -169,8 +166,8 @@
         info.setComponentName(new ComponentName(PROXY_COMPONENT_PACKAGE_NAME,
                 componentClassDisplayName));
         ProxyAccessibilityServiceConnection connection =
-                new ProxyAccessibilityServiceConnection(context, info.getComponentName(), info,
-                        id, mainHandler, mLock, securityPolicy, systemSupport, trace,
+                new ProxyAccessibilityServiceConnection(mContext, info.getComponentName(), info,
+                        id, mMainHandler, mLock, securityPolicy, systemSupport, trace,
                         windowManagerInternal,
                         mA11yWindowManager, displayId, deviceId);
 
@@ -263,7 +260,7 @@
      * When the connection is removed from tracking in ProxyManager, propagate changes to other a11y
      * system components like the input filter and IAccessibilityManagerClients.
      */
-    public void updateStateForRemovedDisplay(int displayId, int deviceId) {
+    private void updateStateForRemovedDisplay(int displayId, int deviceId) {
         mA11yWindowManager.stopTrackingDisplayProxy(displayId);
         // A11yInputFilter isn't thread-safe, so post on the system thread.
         mMainHandler.post(
@@ -360,8 +357,9 @@
     /**
      * If there is at least one proxy, accessibility is enabled.
      */
-    public int getStateLocked(int deviceId, boolean automationRunning) {
+    public int getStateLocked(int deviceId) {
         int clientState = 0;
+        final boolean automationRunning = mUiAutomationManager.isUiAutomationRunningLocked();
         if (automationRunning) {
             clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
         }
@@ -387,7 +385,7 @@
     /**
      * If there is at least one proxy, accessibility is enabled.
      */
-    public int getStateForDisplayIdLocked(ProxyAccessibilityServiceConnection proxy) {
+    private int getStateForDisplayIdLocked(ProxyAccessibilityServiceConnection proxy) {
         int clientState = 0;
         if (proxy != null) {
             clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
@@ -409,14 +407,14 @@
     /**
      * Gets the last state for a device.
      */
-    public int getLastSentStateLocked(int deviceId) {
+    private int getLastSentStateLocked(int deviceId) {
         return mLastStates.get(deviceId, 0);
     }
 
     /**
      * Sets the last state for a device.
      */
-    public void setLastStateLocked(int deviceId, int proxyState) {
+    private void setLastStateLocked(int deviceId, int proxyState) {
         mLastStates.put(deviceId, proxyState);
     }
 
@@ -429,7 +427,7 @@
      * Virtual Device, the app clients will get the aggregated event types for all proxy-ed displays
      * belonging to a VirtualDevice.
      */
-    public void updateRelevantEventTypesLocked(int deviceId) {
+    private void updateRelevantEventTypesLocked(int deviceId) {
         if (!isProxyedDeviceId(deviceId)) {
             return;
         }
@@ -452,7 +450,7 @@
     /**
      * Returns the relevant event types for a Client.
      */
-    int computeRelevantEventTypesLocked(AccessibilityManagerService.Client client) {
+    public int computeRelevantEventTypesLocked(AccessibilityManagerService.Client client) {
         int relevantEventTypes = 0;
         for (int i = 0; i < mProxyA11yServiceConnections.size(); i++) {
             final ProxyAccessibilityServiceConnection proxy =
@@ -578,9 +576,8 @@
     /**
      * Updates the states of the app AccessibilityManagers.
      */
-    public void scheduleUpdateProxyClientsIfNeededLocked(int deviceId) {
-        final int proxyState = getStateLocked(deviceId,
-                mUiAutomationManager.isUiAutomationRunningLocked());
+    private void scheduleUpdateProxyClientsIfNeededLocked(int deviceId) {
+        final int proxyState = getStateLocked(deviceId);
         if (DEBUG) {
             Slog.v(LOG_TAG, "State for device id " + deviceId + " is " + proxyState);
             Slog.v(LOG_TAG, "Last state for device id " + deviceId + " is "
@@ -606,7 +603,7 @@
      *
      * @see AccessibilityManager.AccessibilityServicesStateChangeListener
      */
-    public void scheduleNotifyProxyClientsOfServicesStateChangeLocked(int deviceId) {
+    private void scheduleNotifyProxyClientsOfServicesStateChangeLocked(int deviceId) {
         if (DEBUG) {
             Slog.v(LOG_TAG, "Notify services state change at device id " + deviceId);
         }
@@ -625,7 +622,7 @@
     /**
      * Updates the focus appearance of AccessibilityManagerClients.
      */
-    public void updateFocusAppearanceLocked(int deviceId) {
+    private void updateFocusAppearanceLocked(int deviceId) {
         if (DEBUG) {
             Slog.v(LOG_TAG, "Update proxy focus appearance at device id " + deviceId);
         }
@@ -764,7 +761,7 @@
     /**
      * Sets a Client device id if the app uid belongs to the virtual device.
      */
-    public void updateDeviceIdsIfNeededLocked(int deviceId) {
+    private void updateDeviceIdsIfNeededLocked(int deviceId) {
         final RemoteCallbackList<IAccessibilityManagerClient> userClients =
                 mSystemSupport.getCurrentUserClientsLocked();
         final RemoteCallbackList<IAccessibilityManagerClient> globalClients =
@@ -777,7 +774,7 @@
     /**
      * Updates the device ids of IAccessibilityManagerClients if needed.
      */
-    public void updateDeviceIdsIfNeededLocked(int deviceId,
+    private void updateDeviceIdsIfNeededLocked(int deviceId,
             @NonNull RemoteCallbackList<IAccessibilityManagerClient> clients) {
         final VirtualDeviceManagerInternal localVdm = getLocalVdm();
         if (localVdm == null) {
@@ -809,14 +806,17 @@
         }
     }
 
-    void setAccessibilityInputFilter(AccessibilityInputFilter filter) {
+    /**
+     * Sets the input filter for enabling and disabling features for proxy displays.
+     */
+    public void setAccessibilityInputFilter(AccessibilityInputFilter filter) {
         if (DEBUG) {
             Slog.v(LOG_TAG, "Set proxy input filter to " + filter);
         }
         mA11yInputFilter = filter;
     }
 
-    VirtualDeviceManagerInternal getLocalVdm() {
+    private VirtualDeviceManagerInternal getLocalVdm() {
         if (mLocalVdm == null) {
             mLocalVdm =  LocalServices.getService(VirtualDeviceManagerInternal.class);
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
index a13df47..9747579 100644
--- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
@@ -36,6 +36,7 @@
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 import com.android.internal.R;
+import com.android.internal.accessibility.util.AccessibilityUtils;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ScreenshotHelper;
@@ -302,8 +303,10 @@
                 case AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT:
                     return takeScreenshot();
                 case AccessibilityService.GLOBAL_ACTION_KEYCODE_HEADSETHOOK:
-                    sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK,
-                            InputDevice.SOURCE_KEYBOARD);
+                    if (!AccessibilityUtils.interceptHeadsetHookForActiveCall(mContext)) {
+                        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK,
+                                InputDevice.SOURCE_KEYBOARD);
+                    }
                     return true;
                 case AccessibilityService.GLOBAL_ACTION_DPAD_UP:
                     sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_UP,
diff --git a/services/autofill/java/com/android/server/autofill/ClientSuggestionsSession.java b/services/autofill/java/com/android/server/autofill/ClientSuggestionsSession.java
deleted file mode 100644
index 715697d..0000000
--- a/services/autofill/java/com/android/server/autofill/ClientSuggestionsSession.java
+++ /dev/null
@@ -1,293 +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.autofill;
-
-import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
-
-import static com.android.server.autofill.Helper.sVerbose;
-
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
-import android.app.AppGlobals;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.ICancellationSignal;
-import android.os.RemoteException;
-import android.service.autofill.Dataset;
-import android.service.autofill.FillResponse;
-import android.service.autofill.IFillCallback;
-import android.service.autofill.SaveInfo;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.Slog;
-import android.view.autofill.AutofillId;
-import android.view.autofill.IAutoFillManagerClient;
-import android.view.inputmethod.InlineSuggestionsRequest;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.infra.AndroidFuture;
-
-import java.util.List;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Maintains a client suggestions session with the
- * {@link android.view.autofill.AutofillRequestCallback} through the {@link IAutoFillManagerClient}.
- *
- */
-final class ClientSuggestionsSession {
-
-    private static final String TAG = "ClientSuggestionsSession";
-    private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 15 * DateUtils.SECOND_IN_MILLIS;
-
-    private final int mSessionId;
-    private final IAutoFillManagerClient mClient;
-    private final Handler mHandler;
-    private final ComponentName mComponentName;
-
-    private final RemoteFillService.FillServiceCallbacks mCallbacks;
-
-    private final Object mLock = new Object();
-    @GuardedBy("mLock")
-    private AndroidFuture<FillResponse> mPendingFillRequest;
-    @GuardedBy("mLock")
-    private int mPendingFillRequestId = INVALID_REQUEST_ID;
-
-    ClientSuggestionsSession(int sessionId, IAutoFillManagerClient client, Handler handler,
-            ComponentName componentName, RemoteFillService.FillServiceCallbacks callbacks) {
-        mSessionId = sessionId;
-        mClient = client;
-        mHandler = handler;
-        mComponentName = componentName;
-        mCallbacks = callbacks;
-    }
-
-    void onFillRequest(int requestId, InlineSuggestionsRequest inlineRequest, int flags) {
-        final AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
-        final AtomicReference<AndroidFuture<FillResponse>> futureRef = new AtomicReference<>();
-        final AndroidFuture<FillResponse> fillRequest = new AndroidFuture<>();
-
-        mHandler.post(() -> {
-            if (sVerbose) {
-                Slog.v(TAG, "calling onFillRequest() for id=" + requestId);
-            }
-
-            try {
-                mClient.requestFillFromClient(requestId, inlineRequest,
-                        new FillCallbackImpl(fillRequest, futureRef, cancellationSink));
-            } catch (RemoteException e) {
-                fillRequest.completeExceptionally(e);
-            }
-        });
-
-        fillRequest.orTimeout(TIMEOUT_REMOTE_REQUEST_MILLIS, TimeUnit.MILLISECONDS);
-        futureRef.set(fillRequest);
-
-        synchronized (mLock) {
-            mPendingFillRequest = fillRequest;
-            mPendingFillRequestId = requestId;
-        }
-
-        fillRequest.whenComplete((res, err) -> mHandler.post(() -> {
-            synchronized (mLock) {
-                mPendingFillRequest = null;
-                mPendingFillRequestId = INVALID_REQUEST_ID;
-            }
-            if (err == null) {
-                processAutofillId(res);
-                mCallbacks.onFillRequestSuccess(requestId, res,
-                        mComponentName.getPackageName(), flags);
-            } else {
-                Slog.e(TAG, "Error calling on  client fill request", err);
-                if (err instanceof TimeoutException) {
-                    dispatchCancellationSignal(cancellationSink.get());
-                    mCallbacks.onFillRequestTimeout(requestId);
-                } else if (err instanceof CancellationException) {
-                    dispatchCancellationSignal(cancellationSink.get());
-                } else {
-                    mCallbacks.onFillRequestFailure(requestId, err.getMessage());
-                }
-            }
-        }));
-    }
-
-    /**
-     * Gets the application info for the component.
-     */
-    @Nullable
-    static ApplicationInfo getAppInfo(ComponentName comp, @UserIdInt int userId) {
-        try {
-            ApplicationInfo si = AppGlobals.getPackageManager().getApplicationInfo(
-                    comp.getPackageName(),
-                    PackageManager.GET_META_DATA,
-                    userId);
-            if (si != null) {
-                return si;
-            }
-        } catch (RemoteException e) {
-        }
-        return null;
-    }
-
-    /**
-     * Gets the user-visible name of the application.
-     */
-    @Nullable
-    @GuardedBy("mLock")
-    static CharSequence getAppLabelLocked(Context context, ApplicationInfo appInfo) {
-        return appInfo == null ? null : appInfo.loadSafeLabel(
-                context.getPackageManager(), 0 /* do not ellipsize */,
-                TextUtils.SAFE_STRING_FLAG_FIRST_LINE | TextUtils.SAFE_STRING_FLAG_TRIM);
-    }
-
-    /**
-     * Gets the user-visible icon of the application.
-     */
-    @Nullable
-    @GuardedBy("mLock")
-    static Drawable getAppIconLocked(Context context, ApplicationInfo appInfo) {
-        return appInfo == null ? null : appInfo.loadIcon(context.getPackageManager());
-    }
-
-    int cancelCurrentRequest() {
-        synchronized (mLock) {
-            return mPendingFillRequest != null && mPendingFillRequest.cancel(false)
-                    ? mPendingFillRequestId
-                    : INVALID_REQUEST_ID;
-        }
-    }
-
-    /**
-     * The {@link AutofillId} which the client gets from its view is not contain the session id,
-     * but Autofill framework is using the {@link AutofillId} with a session id. So before using
-     * those ids in the Autofill framework, applies the current session id.
-     *
-     * @param res which response need to apply for a session id
-     */
-    private void processAutofillId(FillResponse res) {
-        if (res == null) {
-            return;
-        }
-
-        final List<Dataset> datasets = res.getDatasets();
-        if (datasets != null && !datasets.isEmpty()) {
-            for (int i = 0; i < datasets.size(); i++) {
-                final Dataset dataset = datasets.get(i);
-                if (dataset != null) {
-                    applySessionId(dataset.getFieldIds());
-                }
-            }
-        }
-
-        final SaveInfo saveInfo = res.getSaveInfo();
-        if (saveInfo != null) {
-            applySessionId(saveInfo.getOptionalIds());
-            applySessionId(saveInfo.getRequiredIds());
-            applySessionId(saveInfo.getSanitizerValues());
-            applySessionId(saveInfo.getTriggerId());
-        }
-    }
-
-    private void applySessionId(List<AutofillId> ids) {
-        if (ids == null || ids.isEmpty()) {
-            return;
-        }
-
-        for (int i = 0; i < ids.size(); i++) {
-            applySessionId(ids.get(i));
-        }
-    }
-
-    private void applySessionId(AutofillId[][] ids) {
-        if (ids == null) {
-            return;
-        }
-        for (int i = 0; i < ids.length; i++) {
-            applySessionId(ids[i]);
-        }
-    }
-
-    private void applySessionId(AutofillId[] ids) {
-        if (ids == null) {
-            return;
-        }
-        for (int i = 0; i < ids.length; i++) {
-            applySessionId(ids[i]);
-        }
-    }
-
-    private void applySessionId(AutofillId id) {
-        if (id == null) {
-            return;
-        }
-        id.setSessionId(mSessionId);
-    }
-
-    private void dispatchCancellationSignal(@Nullable ICancellationSignal signal) {
-        if (signal == null) {
-            return;
-        }
-        try {
-            signal.cancel();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Error requesting a cancellation", e);
-        }
-    }
-
-    private class FillCallbackImpl extends IFillCallback.Stub {
-        final AndroidFuture<FillResponse> mFillRequest;
-        final AtomicReference<AndroidFuture<FillResponse>> mFutureRef;
-        final AtomicReference<ICancellationSignal> mCancellationSink;
-
-        FillCallbackImpl(AndroidFuture<FillResponse> fillRequest,
-                AtomicReference<AndroidFuture<FillResponse>> futureRef,
-                AtomicReference<ICancellationSignal> cancellationSink) {
-            mFillRequest = fillRequest;
-            mFutureRef = futureRef;
-            mCancellationSink = cancellationSink;
-        }
-
-        @Override
-        public void onCancellable(ICancellationSignal cancellation) {
-            AndroidFuture<FillResponse> future = mFutureRef.get();
-            if (future != null && future.isCancelled()) {
-                dispatchCancellationSignal(cancellation);
-            } else {
-                mCancellationSink.set(cancellation);
-            }
-        }
-
-        @Override
-        public void onSuccess(FillResponse response) {
-            mFillRequest.complete(response);
-        }
-
-        @Override
-        public void onFailure(int requestId, CharSequence message) {
-            String errorMessage = message == null ? "" : String.valueOf(message);
-            mFillRequest.completeExceptionally(
-                    new RuntimeException(errorMessage));
-        }
-    }
-}
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index bc5d645..ac77043 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -16,13 +16,18 @@
 
 package com.android.server.autofill;
 
+import static com.android.server.autofill.Helper.sDebug;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.ViewNode;
 import android.app.assist.AssistStructure.WindowNode;
 import android.content.ComponentName;
+import android.content.Context;
+import android.hardware.display.DisplayManager;
 import android.metrics.LogMaker;
+import android.os.UserManager;
 import android.service.autofill.Dataset;
 import android.service.autofill.InternalSanitizer;
 import android.service.autofill.SaveInfo;
@@ -30,6 +35,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
+import android.view.Display;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.autofill.AutofillId;
@@ -37,6 +43,7 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.ArrayUtils;
+import com.android.server.utils.Slogf;
 
 import java.io.PrintWriter;
 import java.util.ArrayDeque;
@@ -281,6 +288,38 @@
         return true;
     }
 
+    /**
+     * Gets a context with the proper display id.
+     *
+     * <p>For most cases it will return the provided context, but on devices that
+     * {@link UserManager#isVisibleBackgroundUsersEnabled() support visible background users}, it
+     * will return a context with the display pased as parameter.
+     */
+    static Context getDisplayContext(Context context, int displayId) {
+        if (!UserManager.isVisibleBackgroundUsersEnabled()) {
+            return context;
+        }
+        if (context.getDisplayId() == displayId) {
+            if (sDebug) {
+                Slogf.d(TAG, "getDisplayContext(): context %s already has displayId %d", context,
+                        displayId);
+            }
+            return context;
+        }
+        if (sDebug) {
+            Slogf.d(TAG, "Creating context for display %d", displayId);
+        }
+        Display display = context.getSystemService(DisplayManager.class).getDisplay(displayId);
+        if (display == null) {
+            Slogf.wtf(TAG, "Could not get context with displayId %d, Autofill operations will "
+                    + "probably fail)", displayId);
+            return context;
+        }
+
+        return context.createDisplayContext(display);
+    }
+
+
     private interface ViewNodeFilter {
         boolean matches(ViewNode node);
     }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index b2e8ffc..3736262 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -36,7 +36,6 @@
 import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED;
 import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
 import static android.view.autofill.AutofillManager.COMMIT_REASON_UNKNOWN;
-import static android.view.autofill.AutofillManager.FLAG_ENABLED_CLIENT_SUGGESTIONS;
 import static android.view.autofill.AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
 import static android.view.autofill.AutofillManager.getSmartSuggestionModeToString;
 
@@ -79,11 +78,6 @@
 import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_REQUIRED_ID_CHANGE;
 import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_TRIGGER_ID_SET;
 import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_UNKNOWN;
-import static com.android.server.autofill.SessionCommittedEventLogger.CommitReason;
-import static com.android.server.autofill.SessionCommittedEventLogger.COMMIT_REASON_ACTIVITY_FINISHED;
-import static com.android.server.autofill.SessionCommittedEventLogger.COMMIT_REASON_VIEW_CHANGED;
-import static com.android.server.autofill.SessionCommittedEventLogger.COMMIT_REASON_VIEW_CLICKED;
-import static com.android.server.autofill.SessionCommittedEventLogger.COMMIT_REASON_VIEW_COMMITTED;
 import static com.android.server.autofill.SessionCommittedEventLogger.COMMIT_REASON_SESSION_DESTROYED;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
@@ -169,10 +163,12 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.ArrayUtils;
+import com.android.server.LocalServices;
 import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.autofill.ui.InlineFillUi;
 import com.android.server.autofill.ui.PendingUi;
 import com.android.server.inputmethod.InputMethodManagerInternal;
+import com.android.server.wm.ActivityTaskManagerInternal;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -219,7 +215,12 @@
     private final AutofillManagerServiceImpl mService;
     private final Handler mHandler;
     private final AutoFillUI mUi;
-    @NonNull private final Context mContext;
+
+    /**
+     * Context associated with the session, it has the same {@link Context#getDisplayId() displayId}
+     * of the activity being autofilled.
+     */
+    private final Context mContext;
 
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
@@ -444,9 +445,6 @@
      */
     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
@@ -588,9 +586,6 @@
         /** Whether the current {@link FillResponse} is expired. */
         private boolean mExpiredResponse;
 
-        /** Whether the client is using {@link android.view.autofill.AutofillRequestCallback}. */
-        private boolean mClientSuggestionsEnabled;
-
         /** Whether the fill dialog UI is disabled. */
         private boolean mFillDialogDisabled;
     }
@@ -621,21 +616,14 @@
                     }
                     mWaitForInlineRequest = inlineSuggestionsRequest != null;
                     mPendingInlineSuggestionsRequest = inlineSuggestionsRequest;
-                    mWaitForInlineRequest = inlineSuggestionsRequest != null;
-                    maybeRequestFillFromServiceLocked();
+                    maybeRequestFillLocked();
                     viewState.resetState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
                 }
             } : null;
         }
 
-        void newAutofillRequestLocked(@Nullable InlineSuggestionsRequest inlineRequest) {
-            mPendingFillRequest = null;
-            mWaitForInlineRequest = inlineRequest != null;
-            mPendingInlineSuggestionsRequest = inlineRequest;
-        }
-
         @GuardedBy("mLock")
-        void maybeRequestFillFromServiceLocked() {
+        void maybeRequestFillLocked() {
             if (mPendingFillRequest == null) {
                 return;
             }
@@ -645,15 +633,13 @@
                     return;
                 }
 
-                if (mPendingInlineSuggestionsRequest.isServiceSupported()) {
-                    mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(),
-                            mPendingFillRequest.getFillContexts(),
-                            mPendingFillRequest.getHints(),
-                            mPendingFillRequest.getClientState(),
-                            mPendingFillRequest.getFlags(),
-                            mPendingInlineSuggestionsRequest,
-                            mPendingFillRequest.getDelayedFillIntentSender());
-                }
+                mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(),
+                        mPendingFillRequest.getFillContexts(),
+                        mPendingFillRequest.getHints(),
+                        mPendingFillRequest.getClientState(),
+                        mPendingFillRequest.getFlags(),
+                        mPendingInlineSuggestionsRequest,
+                        mPendingFillRequest.getDelayedFillIntentSender());
             }
             mLastFillRequest = mPendingFillRequest;
 
@@ -775,7 +761,7 @@
                             : mDelayedFillPendingIntent.getIntentSender());
 
                 mPendingFillRequest = request;
-                maybeRequestFillFromServiceLocked();
+                maybeRequestFillLocked();
             }
 
             if (mActivityToken != null) {
@@ -1097,39 +1083,30 @@
     }
 
     /**
-     * Cancels the last request sent to the {@link #mRemoteFillService} or the
-     * {@link #mClientSuggestionsSession}.
+     * Cancels the last request sent to the {@link #mRemoteFillService}.
      */
     @GuardedBy("mLock")
     private void cancelCurrentRequestLocked() {
-        if (mRemoteFillService == null && mClientSuggestionsSession == null) {
-            wtf(null, "cancelCurrentRequestLocked() called without a remote service or a "
-                    + "client suggestions session.  mForAugmentedAutofillOnly: %s",
-                    mSessionFlags.mAugmentedAutofillOnly);
+        if (mRemoteFillService == null) {
+            wtf(null, "cancelCurrentRequestLocked() called without a remote service. "
+                + "mForAugmentedAutofillOnly: %s", mSessionFlags.mAugmentedAutofillOnly);
             return;
         }
+        final int canceledRequest = mRemoteFillService.cancelCurrentRequest();
 
-        if (mRemoteFillService != null) {
-            final int canceledRequest = mRemoteFillService.cancelCurrentRequest();
+        // Remove the FillContext as there will never be a response for the service
+        if (canceledRequest != INVALID_REQUEST_ID && mContexts != null) {
+            final int numContexts = mContexts.size();
 
-            // Remove the FillContext as there will never be a response for the service
-            if (canceledRequest != INVALID_REQUEST_ID && mContexts != null) {
-                final int numContexts = mContexts.size();
-
-                // It is most likely the last context, hence search backwards
-                for (int i = numContexts - 1; i >= 0; i--) {
-                    if (mContexts.get(i).getRequestId() == canceledRequest) {
-                        if (sDebug) Slog.d(TAG, "cancelCurrentRequest(): id = " + canceledRequest);
-                        mContexts.remove(i);
-                        break;
-                    }
+            // It is most likely the last context, hence search backwards
+            for (int i = numContexts - 1; i >= 0; i--) {
+                if (mContexts.get(i).getRequestId() == canceledRequest) {
+                    if (sDebug) Slog.d(TAG, "cancelCurrentRequest(): id = " + canceledRequest);
+                    mContexts.remove(i);
+                    break;
                 }
             }
         }
-
-        if (mClientSuggestionsSession != null) {
-            mClientSuggestionsSession.cancelCurrentRequest();
-        }
     }
 
     private boolean isViewFocusedLocked(int flags) {
@@ -1223,30 +1200,17 @@
             requestAssistStructureForPccLocked(flags | FLAG_PCC_DETECTION);
         }
 
-        // Only ask IME to create inline suggestions request when
-        // 1. Autofill provider supports it or client enabled client suggestions.
-        // 2. The render service is available.
-        // 3. The view is focused. (The view may not be focused if the autofill is triggered
-        //    manually.)
+        // Only ask IME to create inline suggestions request if Autofill provider supports it and
+        // the render service is available except the autofill is triggered manually and the view
+        // is also not focused.
         final RemoteInlineSuggestionRenderService remoteRenderService =
                 mService.getRemoteInlineSuggestionRenderServiceLocked();
-        if ((mSessionFlags.mInlineSupportedByService || mSessionFlags.mClientSuggestionsEnabled)
-                && remoteRenderService != null
-                && (isViewFocusedLocked(flags) || (isRequestSupportFillDialog(flags)))) {
-            final Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer;
-            if (mSessionFlags.mClientSuggestionsEnabled) {
-                final int finalRequestId = requestId;
-                inlineSuggestionsRequestConsumer = (inlineSuggestionsRequest) -> {
-                    // Using client suggestions
-                    synchronized (mLock) {
-                        onClientFillRequestLocked(finalRequestId, inlineSuggestionsRequest);
-                    }
-                    viewState.resetState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
-                };
-            } else {
-                inlineSuggestionsRequestConsumer = mAssistReceiver.newAutofillRequestLocked(
-                        viewState, /* isInlineRequest= */ true);
-            }
+        if (mSessionFlags.mInlineSupportedByService
+            && remoteRenderService != null
+            && (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) {
+            Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer =
+                mAssistReceiver.newAutofillRequestLocked(viewState,
+                    /* isInlineRequest= */ true);
             if (inlineSuggestionsRequestConsumer != null) {
                 final AutofillId focusedId = mCurrentViewId;
                 final int requestIdCopy = requestId;
@@ -1262,18 +1226,10 @@
                 );
                 viewState.setState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
             }
-        } else if (mSessionFlags.mClientSuggestionsEnabled) {
-            // Request client suggestions for the dropdown mode
-            onClientFillRequestLocked(requestId, null);
         } else {
             mAssistReceiver.newAutofillRequestLocked(viewState, /* isInlineRequest= */ false);
         }
 
-        if (mSessionFlags.mClientSuggestionsEnabled) {
-            // Using client suggestions, unnecessary request AssistStructure
-            return;
-        }
-
         // Now request the assist structure data.
         requestAssistStructureLocked(requestId, flags);
     }
@@ -1357,7 +1313,9 @@
         mHasCallback = hasCallback;
         mUiLatencyHistory = uiLatencyHistory;
         mWtfHistory = wtfHistory;
-        mContext = context;
+        int displayId = LocalServices.getService(ActivityTaskManagerInternal.class)
+                .getDisplayId(activityToken);
+        mContext = Helper.getDisplayContext(context, displayId);
         mComponentName = componentName;
         mCompatMode = compatMode;
         mSessionState = STATE_ACTIVE;
@@ -1376,11 +1334,6 @@
             mSessionFlags = new SessionFlags();
             mSessionFlags.mAugmentedAutofillOnly = forAugmentedAutofillOnly;
             mSessionFlags.mInlineSupportedByService = mService.isInlineSuggestionsEnabledLocked();
-            if (mContext.checkCallingPermission(PROVIDE_OWN_AUTOFILL_SUGGESTIONS)
-                    == PackageManager.PERMISSION_GRANTED) {
-                mSessionFlags.mClientSuggestionsEnabled =
-                        (mFlags & FLAG_ENABLED_CLIENT_SUGGESTIONS) != 0;
-            }
             setClientLocked(client);
         }
 
@@ -1518,15 +1471,14 @@
                 if (requestLog != null) {
                     requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, -1);
                 }
-                processNullResponseOrFallbackLocked(requestId, requestFlags);
+                processNullResponseLocked(requestId, requestFlags);
                 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()) {
+            if (fieldClassificationIds != null && !mService.isFieldClassificationEnabledLocked()) {
                 Slog.w(TAG, "Ignoring " + response + " because field detection is disabled");
                 processNullResponseLocked(requestId, requestFlags);
                 return;
@@ -1639,9 +1591,7 @@
                         || (ArrayUtils.isEmpty(saveInfo.getOptionalIds())
                             && ArrayUtils.isEmpty(saveInfo.getRequiredIds())
                             && ((saveInfo.getFlags() & SaveInfo.FLAG_DELAY_SAVE) == 0)))
-                    && (ArrayUtils.isEmpty(response.getFieldClassificationIds())
-                        || (!mSessionFlags.mClientSuggestionsEnabled
-                        && !mService.isFieldClassificationEnabledLocked())));
+                    && (ArrayUtils.isEmpty(response.getFieldClassificationIds())));
         }
     }
 
@@ -1971,40 +1921,6 @@
         }
     }
 
-    @GuardedBy("mLock")
-    private void processNullResponseOrFallbackLocked(int requestId, int flags) {
-        if (!mSessionFlags.mClientSuggestionsEnabled) {
-            processNullResponseLocked(requestId, flags);
-            return;
-        }
-
-        // fallback to the default platform password manager
-        mSessionFlags.mClientSuggestionsEnabled = false;
-        mLastFillDialogTriggerIds = null;
-        // Log the existing FillResponse event.
-        mFillResponseEventLogger.logAndEndEvent();
-
-        final InlineSuggestionsRequest inlineRequest =
-                (mLastInlineSuggestionsRequest != null
-                        && mLastInlineSuggestionsRequest.first == requestId)
-                        ? mLastInlineSuggestionsRequest.second : null;
-
-        // Start a new FillRequest logger for client suggestion fallback.
-        mFillRequestEventLogger.startLogForNewRequest();
-        mRequestCount++;
-        mFillRequestEventLogger.maybeSetAppPackageUid(uid);
-        mFillRequestEventLogger.maybeSetFlags(
-            flags & ~FLAG_ENABLED_CLIENT_SUGGESTIONS);
-        mFillRequestEventLogger.maybeSetRequestTriggerReason(
-            TRIGGER_REASON_NORMAL_TRIGGER);
-        mFillRequestEventLogger.maybeSetIsClientSuggestionFallback(true);
-
-        mAssistReceiver.newAutofillRequestLocked(inlineRequest);
-        requestAssistStructureLocked(requestId,
-                flags & ~FLAG_ENABLED_CLIENT_SUGGESTIONS);
-        return;
-    }
-
     // FillServiceCallbacks
     @Override
     @SuppressWarnings("GuardedBy")
@@ -3406,7 +3322,7 @@
                 final long saveUiDisplayStartTimestamp = SystemClock.elapsedRealtime();
                 getUiForShowing().showSaveUi(serviceLabel, serviceIcon,
                         mService.getServicePackageName(), saveInfo, this,
-                        mComponentName, this, mPendingSaveUi, isUpdate, mCompatMode,
+                        mComponentName, this, mContext,  mPendingSaveUi, isUpdate, mCompatMode,
                         response.getShowSaveDialogIcon());
                 mSaveEventLogger.maybeSetLatencySaveUiDisplayMillis(
                     SystemClock.elapsedRealtime()- saveUiDisplayStartTimestamp);
@@ -4201,22 +4117,13 @@
             filterText = value.getTextValue().toString();
         }
 
-        final CharSequence targetLabel;
-        final Drawable targetIcon;
-        synchronized (mLock) {
-            if (mSessionFlags.mClientSuggestionsEnabled) {
-                final ApplicationInfo appInfo = ClientSuggestionsSession.getAppInfo(mComponentName,
-                        mService.getUserId());
-                targetLabel = ClientSuggestionsSession.getAppLabelLocked(
-                        mService.getMaster().getContext(), appInfo);
-                targetIcon = ClientSuggestionsSession.getAppIconLocked(
-                        mService.getMaster().getContext(), appInfo);
-            } else {
-                targetLabel = mService.getServiceLabelLocked();
-                targetIcon = mService.getServiceIconLocked();
-            }
+        final CharSequence serviceLabel;
+        final Drawable serviceIcon;
+        synchronized (this.mService.mLock) {
+            serviceLabel = mService.getServiceLabelLocked();
+            serviceIcon = mService.getServiceIconLocked();
         }
-        if (targetLabel == null || targetIcon == null) {
+        if (serviceLabel == null || serviceIcon == null) {
             wtf(null, "onFillReady(): no service label or icon");
             return;
         }
@@ -4277,7 +4184,7 @@
 
         getUiForShowing().showFillUi(filledId, response, filterText,
                 mService.getServicePackageName(), mComponentName,
-                targetLabel, targetIcon, this, userId, id, mCompatMode);
+                serviceLabel, serviceIcon, this, mContext, id, mCompatMode);
 
         synchronized (mLock) {
             mPresentationStatsEventLogger.maybeSetCountShown(
@@ -4473,17 +4380,6 @@
             return false;
         }
 
-        final InlineSuggestionsRequest request = inlineSuggestionsRequest.get();
-        if (mSessionFlags.mClientSuggestionsEnabled && !request.isClientSupported()
-                || !mSessionFlags.mClientSuggestionsEnabled && !request.isServiceSupported()) {
-            if (sDebug) {
-                Slog.d(TAG, "Inline suggestions not supported for "
-                        + (mSessionFlags.mClientSuggestionsEnabled ? "client" : "service")
-                        + ". Falling back to dropdown.");
-            }
-            return false;
-        }
-
         final RemoteInlineSuggestionRenderService remoteRenderService =
                 mService.getRemoteInlineSuggestionRenderServiceLocked();
         if (remoteRenderService == null) {
@@ -4498,8 +4394,8 @@
         }
 
         final InlineFillUi.InlineFillUiInfo inlineFillUiInfo =
-                new InlineFillUi.InlineFillUiInfo(request, focusedId,
-                        filterText, remoteRenderService, userId, id);
+            new InlineFillUi.InlineFillUiInfo(inlineSuggestionsRequest.get(), focusedId,
+                filterText, remoteRenderService, userId, id);
         InlineFillUi inlineFillUi = InlineFillUi.forAutofill(inlineFillUiInfo, response,
                 new InlineFillUi.InlineSuggestionUiCallback() {
                     @Override
@@ -5150,26 +5046,6 @@
         }
     }
 
-    @GuardedBy("mLock")
-    private void onClientFillRequestLocked(int requestId,
-            InlineSuggestionsRequest inlineSuggestionsRequest) {
-        if (mClientSuggestionsSession == null) {
-            mClientSuggestionsSession = new ClientSuggestionsSession(id, mClient, mHandler,
-                    mComponentName, this);
-        }
-
-        if (mContexts == null) {
-            mContexts = new ArrayList<>(1);
-        }
-        mContexts.add(new FillContext(requestId, new AssistStructure(), mCurrentViewId));
-
-        if (inlineSuggestionsRequest != null && !inlineSuggestionsRequest.isClientSupported()) {
-            inlineSuggestionsRequest = null;
-        }
-
-        mClientSuggestionsSession.onFillRequest(requestId, inlineSuggestionsRequest, mFlags);
-    }
-
     /**
      * The result of checking whether to show the save dialog, when session can be saved.
      *
@@ -5458,6 +5334,7 @@
         pw.print(prefix); pw.print("uid: "); pw.println(uid);
         pw.print(prefix); pw.print("taskId: "); pw.println(taskId);
         pw.print(prefix); pw.print("flags: "); pw.println(mFlags);
+        pw.print(prefix); pw.print("displayId: "); pw.println(mContext.getDisplayId());
         pw.print(prefix); pw.print("state: "); pw.println(sessionStateAsString(mSessionState));
         pw.print(prefix); pw.print("mComponentName: "); pw.println(mComponentName);
         pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index a631818..b3cbe45 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -23,7 +23,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UserIdInt;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -53,6 +52,7 @@
 import com.android.server.UiModeManagerInternal;
 import com.android.server.UiThread;
 import com.android.server.autofill.Helper;
+import com.android.server.utils.Slogf;
 
 import java.io.PrintWriter;
 
@@ -198,6 +198,7 @@
      * @param serviceIcon icon of autofill service
      * @param callback identifier for the caller
      * @param userId the user associated wit the session
+     * @param context context with the proper state (like display id) to show the UI
      * @param sessionId id of the autofill session
      * @param compatMode whether the app is being autofilled in compatibility mode.
      */
@@ -205,11 +206,11 @@
             @Nullable String filterText, @Nullable String servicePackageName,
             @NonNull ComponentName componentName, @NonNull CharSequence serviceLabel,
             @NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback,
-            @UserIdInt int userId, int sessionId, boolean compatMode) {
+            @NonNull Context context, int sessionId, boolean compatMode) {
         if (sDebug) {
             final int size = filterText == null ? 0 : filterText.length();
-            Slog.d(TAG, "showFillUi(): id=" + focusedId + ", filter=" + size + " chars, userId="
-                    + userId);
+            Slogf.d(TAG, "showFillUi(): id=%s, filter=%d chars, displayId=%d", focusedId, size,
+                    context.getDisplayId());
         }
         final LogMaker log = Helper
                 .newLogMaker(MetricsEvent.AUTOFILL_FILL_UI, componentName, servicePackageName,
@@ -224,10 +225,8 @@
                 return;
             }
             hideAllUiThread(callback);
-            mFillUi = new FillUi(mContext, userId, response, focusedId,
-                    filterText, mOverlayControl, serviceLabel, serviceIcon,
-                    mUiModeMgr.isNightMode(),
-                    new FillUi.Callback() {
+            mFillUi = new FillUi(context, response, focusedId, filterText, mOverlayControl,
+                    serviceLabel, serviceIcon, mUiModeMgr.isNightMode(), new FillUi.Callback() {
                 @Override
                 public void onResponsePicked(FillResponse response) {
                     log.setType(MetricsEvent.TYPE_DETAIL);
@@ -325,11 +324,12 @@
     public void showSaveUi(@NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon,
             @Nullable String servicePackageName, @NonNull SaveInfo info,
             @NonNull ValueFinder valueFinder, @NonNull ComponentName componentName,
-            @NonNull AutoFillUiCallback callback, @NonNull PendingUi pendingSaveUi,
-            boolean isUpdate, boolean compatMode, boolean showServiceIcon) {
+            @NonNull AutoFillUiCallback callback, @NonNull Context context,
+            @NonNull PendingUi pendingSaveUi, boolean isUpdate, boolean compatMode,
+            boolean showServiceIcon) {
         if (sVerbose) {
-            Slog.v(TAG, "showSaveUi(update=" + isUpdate + ") for " + componentName.toShortString()
-                    + ": " + info);
+            Slogf.v(TAG, "showSaveUi(update=%b) for %s and display %d: %s", isUpdate,
+                    componentName.toShortString(), context.getDisplayId(), info);
         }
         int numIds = 0;
         numIds += info.getRequiredIds() == null ? 0 : info.getRequiredIds().length;
@@ -349,7 +349,7 @@
             }
             hideAllUiThread(callback);
             mSaveUiCallback = callback;
-            mSaveUi = new SaveUi(mContext, pendingSaveUi, serviceLabel, serviceIcon,
+            mSaveUi = new SaveUi(context, pendingSaveUi, serviceLabel, serviceIcon,
                     servicePackageName, componentName, info, valueFinder, mOverlayControl,
                     new SaveUi.OnSaveListener() {
                 @Override
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index 30d2fe4..129ce72 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -22,15 +22,12 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UserIdInt;
 import android.content.Context;
 import android.content.IntentSender;
 import android.content.pm.PackageManager;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
-import android.os.UserManager;
 import android.service.autofill.Dataset;
 import android.service.autofill.Dataset.DatasetFieldFilter;
 import android.service.autofill.FillResponse;
@@ -39,7 +36,6 @@
 import android.util.Slog;
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
-import android.view.Display;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -61,11 +57,9 @@
 import android.widget.TextView;
 
 import com.android.internal.R;
-import com.android.server.LocalServices;
 import com.android.server.UiThread;
 import com.android.server.autofill.AutofillManagerService;
 import com.android.server.autofill.Helper;
-import com.android.server.pm.UserManagerInternal;
 import com.android.server.utils.Slogf;
 
 import java.io.PrintWriter;
@@ -140,29 +134,15 @@
         return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
     }
 
-    FillUi(@NonNull Context context, @UserIdInt int userId, @NonNull FillResponse response,
+    FillUi(@NonNull Context context, @NonNull FillResponse response,
             @NonNull AutofillId focusedViewId, @Nullable String filterText,
             @NonNull OverlayControl overlayControl, @NonNull CharSequence serviceLabel,
             @NonNull Drawable serviceIcon, boolean nightMode, @NonNull Callback callback) {
-        if (sVerbose) Slog.v(TAG, "nightMode: " + nightMode);
+        if (sVerbose) {
+            Slogf.v(TAG, "nightMode: %b displayId: %d", nightMode, context.getDisplayId());
+        }
         mThemeId = nightMode ? THEME_ID_DARK : THEME_ID_LIGHT;
         mCallback = callback;
-
-        if (UserManager.isVisibleBackgroundUsersEnabled()) {
-            UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
-            int displayId = umi.getMainDisplayAssignedToUser(userId);
-            if (sDebug) {
-                Slogf.d(TAG, "Creating context for display %d for user %d", displayId, userId);
-            }
-            Display display = context.getSystemService(DisplayManager.class).getDisplay(displayId);
-            if (display != null) {
-                context = context.createDisplayContext(display);
-            } else {
-                Slogf.d(TAG, "Could not get display with id %d (which is associated with user %d; "
-                        + "FillUi operations will probably fail", displayId, userId);
-            }
-        }
-
         mFullScreen = isFullScreen(context);
         mContext = new ContextThemeWrapper(context, mThemeId);
 
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..1204259 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -70,6 +70,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.server.UiThread;
 import com.android.server.autofill.Helper;
+import com.android.server.utils.Slogf;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -178,7 +179,9 @@
            @NonNull SaveInfo info, @NonNull ValueFinder valueFinder,
            @NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener,
            boolean nightMode, boolean isUpdate, boolean compatMode, boolean showServiceIcon) {
-        if (sVerbose) Slog.v(TAG, "nightMode: " + nightMode);
+        if (sVerbose) {
+            Slogf.v(TAG, "nightMode: %b displayId: %d", nightMode, context.getDisplayId());
+        }
         mThemeId = nightMode ? THEME_ID_DARK : THEME_ID_LIGHT;
         mPendingUi = pendingUi;
         mListener = new OneActionThenDestroyListener(listener);
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index d8fbd08..0172eaf 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -107,6 +107,9 @@
 import com.android.server.SystemService;
 import com.android.server.companion.datatransfer.SystemDataTransferProcessor;
 import com.android.server.companion.datatransfer.SystemDataTransferRequestStore;
+import com.android.server.companion.datatransfer.contextsync.CrossDeviceCall;
+import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController;
+import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncControllerCallback;
 import com.android.server.companion.presence.CompanionDevicePresenceMonitor;
 import com.android.server.companion.transport.CompanionTransportManager;
 import com.android.server.pm.UserManagerInternal;
@@ -116,6 +119,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -199,6 +203,8 @@
     private final RemoteCallbackList<IOnAssociationsChangedListener> mListeners =
             new RemoteCallbackList<>();
 
+    private CrossDeviceSyncController mCrossDeviceSyncController;
+
     public CompanionDeviceManagerService(Context context) {
         super(context);
 
@@ -238,6 +244,8 @@
         mTransportManager = new CompanionTransportManager(context, mAssociationStore);
         mSystemDataTransferProcessor = new SystemDataTransferProcessor(this, mAssociationStore,
                 mSystemDataTransferRequestStore, mTransportManager);
+        // TODO(b/279663946): move context sync to a dedicated system service
+        mCrossDeviceSyncController = new CrossDeviceSyncController(getContext(), mTransportManager);
 
         // Publish "binder" service.
         final CompanionDeviceManagerImpl impl = new CompanionDeviceManagerImpl();
@@ -1353,6 +1361,39 @@
         public void removeInactiveSelfManagedAssociations() {
             CompanionDeviceManagerService.this.removeInactiveSelfManagedAssociations();
         }
+
+        @Override
+        public void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback) {
+            if (CompanionDeviceConfig.isEnabled(
+                    CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+                mCrossDeviceSyncController.registerCallMetadataSyncCallback(callback);
+            }
+        }
+
+        @Override
+        public void crossDeviceSync(int userId, Collection<CrossDeviceCall> calls) {
+            if (CompanionDeviceConfig.isEnabled(
+                    CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+                mCrossDeviceSyncController.syncToAllDevicesForUserId(userId, calls);
+            }
+        }
+
+        @Override
+        public void crossDeviceSync(AssociationInfo associationInfo,
+                Collection<CrossDeviceCall> calls) {
+            if (CompanionDeviceConfig.isEnabled(
+                    CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+                mCrossDeviceSyncController.syncToSingleDevice(associationInfo, calls);
+            }
+        }
+
+        @Override
+        public void sendCrossDeviceSyncMessage(int associationId, byte[] message) {
+            if (CompanionDeviceConfig.isEnabled(
+                    CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+                mCrossDeviceSyncController.syncMessageToDevice(associationId, message);
+            }
+        }
     }
 
     /**
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java
index 3649240..3b108e6 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java
@@ -16,12 +16,41 @@
 
 package com.android.server.companion;
 
+import android.companion.AssociationInfo;
+
+import com.android.server.companion.datatransfer.contextsync.CrossDeviceCall;
+import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncControllerCallback;
+
+import java.util.Collection;
+
 /**
  * Companion Device Manager Local System Service Interface.
  */
-interface CompanionDeviceManagerServiceInternal {
+public interface CompanionDeviceManagerServiceInternal {
     /**
      * @see CompanionDeviceManagerService#removeInactiveSelfManagedAssociations
      */
     void removeInactiveSelfManagedAssociations();
+
+    /**
+     * Registers a callback from an InCallService / ConnectionService to CDM to process sync
+     * requests and perform call control actions.
+     */
+    void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback);
+
+    /**
+     * Requests a sync from an InCallService / ConnectionService to CDM, for the given association
+     * and message.
+     */
+    void sendCrossDeviceSyncMessage(int associationId, byte[] message);
+
+    /**
+     * Requests a sync from an InCallService to CDM, for the given user and call metadata.
+     */
+    void crossDeviceSync(int userId, Collection<CrossDeviceCall> calls);
+
+    /**
+     * Requests a sync from an InCallService to CDM, for the given association and call metadata.
+     */
+    void crossDeviceSync(AssociationInfo associationInfo, Collection<CrossDeviceCall> calls);
 }
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java
index ae4766a..443a732 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java
@@ -17,15 +17,20 @@
 package com.android.server.companion.datatransfer.contextsync;
 
 import android.annotation.Nullable;
+import android.companion.AssociationInfo;
 import android.telecom.Call;
 import android.telecom.InCallService;
 import android.telecom.TelecomManager;
+import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
 import com.android.server.companion.CompanionDeviceConfig;
+import com.android.server.companion.CompanionDeviceManagerServiceInternal;
 
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.stream.Collectors;
 
@@ -35,90 +40,132 @@
  */
 public class CallMetadataSyncInCallService extends InCallService {
 
+    private static final String TAG = "CallMetadataIcs";
     private static final long NOT_VALID = -1L;
 
+    private CompanionDeviceManagerServiceInternal mCdmsi;
+
     @VisibleForTesting
     final Map<Call, CrossDeviceCall> mCurrentCalls = new HashMap<>();
-    @VisibleForTesting
-    boolean mShouldSync;
+    @VisibleForTesting int mNumberOfActiveSyncAssociations;
     final Call.Callback mTelecomCallback = new Call.Callback() {
         @Override
         public void onDetailsChanged(Call call, Call.Details details) {
-            mCurrentCalls.get(call).updateCallDetails(details);
-        }
-    };
-    final CallMetadataSyncCallback mCallMetadataSyncCallback = new CallMetadataSyncCallback() {
-        @Override
-        void processCallControlAction(int crossDeviceCallId, int callControlAction) {
-            final CrossDeviceCall crossDeviceCall = getCallForId(crossDeviceCallId,
-                    mCurrentCalls.values());
-            switch (callControlAction) {
-                case android.companion.Telecom.Call.ACCEPT:
-                    if (crossDeviceCall != null) {
-                        crossDeviceCall.doAccept();
-                    }
-                    break;
-                case android.companion.Telecom.Call.REJECT:
-                    if (crossDeviceCall != null) {
-                        crossDeviceCall.doReject();
-                    }
-                    break;
-                case android.companion.Telecom.Call.SILENCE:
-                    doSilence();
-                    break;
-                case android.companion.Telecom.Call.MUTE:
-                    doMute();
-                    break;
-                case android.companion.Telecom.Call.UNMUTE:
-                    doUnmute();
-                    break;
-                case android.companion.Telecom.Call.END:
-                    if (crossDeviceCall != null) {
-                        crossDeviceCall.doEnd();
-                    }
-                    break;
-                case android.companion.Telecom.Call.PUT_ON_HOLD:
-                    if (crossDeviceCall != null) {
-                        crossDeviceCall.doPutOnHold();
-                    }
-                    break;
-                case android.companion.Telecom.Call.TAKE_OFF_HOLD:
-                    if (crossDeviceCall != null) {
-                        crossDeviceCall.doTakeOffHold();
-                    }
-                    break;
-                default:
-            }
-        }
-
-        @Override
-        void requestCrossDeviceSync(int userId) {
-        }
-
-        @Override
-        void updateStatus(int userId, boolean shouldSyncCallMetadata) {
-            if (userId == getUserId()) {
-                mShouldSync = shouldSyncCallMetadata;
-                if (shouldSyncCallMetadata) {
-                    initializeCalls();
+            if (mNumberOfActiveSyncAssociations > 0) {
+                final CrossDeviceCall crossDeviceCall = mCurrentCalls.get(call);
+                if (crossDeviceCall != null) {
+                    crossDeviceCall.updateCallDetails(details);
+                    sync(getUserId());
                 } else {
-                    mCurrentCalls.clear();
+                    Slog.w(TAG, "Could not update details for nonexistent call");
                 }
             }
         }
     };
+    final CrossDeviceSyncControllerCallback
+            mCrossDeviceSyncControllerCallback = new CrossDeviceSyncControllerCallback() {
+                @Override
+                void processContextSyncMessage(int associationId,
+                        CallMetadataSyncData callMetadataSyncData) {
+                    final Iterator<CallMetadataSyncData.Call> iterator =
+                            callMetadataSyncData.getRequests().iterator();
+                    while (iterator.hasNext()) {
+                        final CallMetadataSyncData.Call call = iterator.next();
+                        if (call.getId() != 0) {
+                            // The call is already assigned an id; treat as control invocations.
+                            for (int control : call.getControls()) {
+                                processCallControlAction(call.getId(), control);
+                            }
+                        }
+                        iterator.remove();
+                    }
+                }
+
+                private void processCallControlAction(long crossDeviceCallId,
+                        int callControlAction) {
+                    final CrossDeviceCall crossDeviceCall = getCallForId(crossDeviceCallId,
+                            mCurrentCalls.values());
+                    switch (callControlAction) {
+                        case android.companion.Telecom.Call.ACCEPT:
+                            if (crossDeviceCall != null) {
+                                crossDeviceCall.doAccept();
+                            }
+                            break;
+                        case android.companion.Telecom.Call.REJECT:
+                            if (crossDeviceCall != null) {
+                                crossDeviceCall.doReject();
+                            }
+                            break;
+                        case android.companion.Telecom.Call.SILENCE:
+                            doSilence();
+                            break;
+                        case android.companion.Telecom.Call.MUTE:
+                            doMute();
+                            break;
+                        case android.companion.Telecom.Call.UNMUTE:
+                            doUnmute();
+                            break;
+                        case android.companion.Telecom.Call.END:
+                            if (crossDeviceCall != null) {
+                                crossDeviceCall.doEnd();
+                            }
+                            break;
+                        case android.companion.Telecom.Call.PUT_ON_HOLD:
+                            if (crossDeviceCall != null) {
+                                crossDeviceCall.doPutOnHold();
+                            }
+                            break;
+                        case android.companion.Telecom.Call.TAKE_OFF_HOLD:
+                            if (crossDeviceCall != null) {
+                                crossDeviceCall.doTakeOffHold();
+                            }
+                            break;
+                        default:
+                    }
+                }
+
+                @Override
+                void requestCrossDeviceSync(AssociationInfo associationInfo) {
+                    if (associationInfo.getUserId() == getUserId()) {
+                        sync(associationInfo);
+                    }
+                }
+
+                @Override
+                void updateNumberOfActiveSyncAssociations(int userId, boolean added) {
+                    if (userId == getUserId()) {
+                        final boolean wasActivelySyncing = mNumberOfActiveSyncAssociations > 0;
+                        if (added) {
+                            mNumberOfActiveSyncAssociations++;
+                        } else {
+                            mNumberOfActiveSyncAssociations--;
+                        }
+                        if (!wasActivelySyncing && mNumberOfActiveSyncAssociations > 0) {
+                            initializeCalls();
+                        } else if (wasActivelySyncing && mNumberOfActiveSyncAssociations <= 0) {
+                            mCurrentCalls.clear();
+                        }
+                    }
+                }
+    };
 
     @Override
     public void onCreate() {
         super.onCreate();
-        initializeCalls();
+        if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+            mCdmsi = LocalServices.getService(CompanionDeviceManagerServiceInternal.class);
+            mCdmsi.registerCallMetadataSyncCallback(mCrossDeviceSyncControllerCallback);
+        }
     }
 
     private void initializeCalls() {
         if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
-                && mShouldSync) {
+                && mNumberOfActiveSyncAssociations > 0) {
             mCurrentCalls.putAll(getCalls().stream().collect(Collectors.toMap(call -> call,
                     call -> new CrossDeviceCall(getPackageManager(), call, getCallAudioState()))));
+            mCurrentCalls.keySet().forEach(call -> call.registerCallback(mTelecomCallback,
+                    getMainThreadHandler()));
+            sync(getUserId());
         }
     }
 
@@ -139,33 +186,39 @@
     @Override
     public void onCallAdded(Call call) {
         if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
-                && mShouldSync) {
+                && mNumberOfActiveSyncAssociations > 0) {
             mCurrentCalls.put(call,
                     new CrossDeviceCall(getPackageManager(), call, getCallAudioState()));
+            call.registerCallback(mTelecomCallback);
+            sync(getUserId());
         }
     }
 
     @Override
     public void onCallRemoved(Call call) {
         if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
-                && mShouldSync) {
+                && mNumberOfActiveSyncAssociations > 0) {
             mCurrentCalls.remove(call);
+            call.unregisterCallback(mTelecomCallback);
+            sync(getUserId());
         }
     }
 
     @Override
     public void onMuteStateChanged(boolean isMuted) {
         if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
-                && mShouldSync) {
+                && mNumberOfActiveSyncAssociations > 0) {
             mCurrentCalls.values().forEach(call -> call.updateMuted(isMuted));
+            sync(getUserId());
         }
     }
 
     @Override
     public void onSilenceRinger() {
         if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
-                && mShouldSync) {
+                && mNumberOfActiveSyncAssociations > 0) {
             mCurrentCalls.values().forEach(call -> call.updateSilencedIfRinging());
+            sync(getUserId());
         }
     }
 
@@ -183,4 +236,12 @@
             telecomManager.silenceRinger();
         }
     }
+
+    private void sync(int userId) {
+        mCdmsi.crossDeviceSync(userId, mCurrentCalls.values());
+    }
+
+    private void sync(AssociationInfo associationInfo) {
+        mCdmsi.crossDeviceSync(associationInfo, mCurrentCalls.values());
+    }
 }
\ No newline at end of file
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
index dd0bbf2..ac981d4 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
@@ -16,12 +16,14 @@
 
 package com.android.server.companion.datatransfer.contextsync;
 
+import android.annotation.NonNull;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.telecom.Call;
 import android.telecom.CallAudioState;
 import android.telecom.VideoProfile;
@@ -46,7 +48,7 @@
     private static final AtomicLong sNextId = new AtomicLong(1);
 
     private final long mId;
-    private final Call mCall;
+    private Call mCall;
     @VisibleForTesting boolean mIsEnterprise;
     @VisibleForTesting boolean mIsOtt;
     private final String mCallingAppPackageName;
@@ -58,17 +60,23 @@
     private boolean mIsMuted;
     private final Set<Integer> mControls = new HashSet<>();
 
-    public CrossDeviceCall(PackageManager packageManager, Call call,
+    public CrossDeviceCall(PackageManager packageManager, @NonNull Call call,
+            CallAudioState callAudioState) {
+        this(packageManager, call.getDetails(), callAudioState);
+        mCall = call;
+        final Bundle extras = new Bundle();
+        extras.putLong(EXTRA_CALL_ID, mId);
+        call.putExtras(extras);
+    }
+
+    CrossDeviceCall(PackageManager packageManager, Call.Details callDetails,
             CallAudioState callAudioState) {
         mId = sNextId.getAndIncrement();
-        mCall = call;
-        mCallingAppPackageName = call != null
-                ? call.getDetails().getAccountHandle().getComponentName().getPackageName() : null;
-        mIsOtt = call != null
-                && (call.getDetails().getCallCapabilities() & Call.Details.PROPERTY_SELF_MANAGED)
+        mCallingAppPackageName =
+                callDetails.getAccountHandle().getComponentName().getPackageName();
+        mIsOtt = (callDetails.getCallCapabilities() & Call.Details.PROPERTY_SELF_MANAGED)
                 == Call.Details.PROPERTY_SELF_MANAGED;
-        mIsEnterprise = call != null
-                && (call.getDetails().getCallProperties() & Call.Details.PROPERTY_ENTERPRISE_CALL)
+        mIsEnterprise = (callDetails.getCallProperties() & Call.Details.PROPERTY_ENTERPRISE_CALL)
                 == Call.Details.PROPERTY_ENTERPRISE_CALL;
         try {
             final ApplicationInfo applicationInfo = packageManager
@@ -81,9 +89,7 @@
             Slog.e(TAG, "Could not get application info for package " + mCallingAppPackageName, e);
         }
         mIsMuted = callAudioState != null && callAudioState.isMuted();
-        if (call != null) {
-            updateCallDetails(call.getDetails());
-        }
+        updateCallDetails(callDetails);
     }
 
     private byte[] renderDrawableToByteArray(Drawable drawable) {
@@ -108,10 +114,10 @@
             final Canvas canvas = new Canvas(bitmap);
             drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
             drawable.draw(canvas);
+            return renderBitmapToByteArray(bitmap);
         } finally {
             bitmap.recycle();
         }
-        return renderBitmapToByteArray(bitmap);
     }
 
     private byte[] renderBitmapToByteArray(Bitmap bitmap) {
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
index 3d8fb7a..adc5faf 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
@@ -16,27 +16,32 @@
 
 package com.android.server.companion.datatransfer.contextsync;
 
+import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_CONTEXT_SYNC;
+
 import android.app.admin.DevicePolicyManager;
 import android.companion.AssociationInfo;
 import android.companion.ContextSyncMessage;
+import android.companion.IOnMessageReceivedListener;
+import android.companion.IOnTransportsChangedListener;
 import android.companion.Telecom;
-import android.companion.Telecom.Call;
 import android.content.Context;
+import android.os.Binder;
 import android.os.UserHandle;
-import android.util.Pair;
 import android.util.Slog;
+import android.util.proto.ProtoInputStream;
 import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoParseException;
+import android.util.proto.ProtoUtils;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.companion.CompanionDeviceConfig;
+import com.android.server.companion.transport.CompanionTransportManager;
+
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -45,149 +50,308 @@
 public class CrossDeviceSyncController {
 
     private static final String TAG = "CrossDeviceSyncController";
-    private static final int BYTE_ARRAY_SIZE = 64;
+
+    private static final int VERSION_1 = 1;
+    private static final int CURRENT_VERSION = VERSION_1;
 
     private final Context mContext;
-    private final Callback mCdmCallback;
-    private final Map<Integer, List<AssociationInfo>> mUserIdToAssociationInfo = new HashMap<>();
-    private final Map<Integer, Pair<InputStream, OutputStream>> mAssociationIdToStreams =
-            new HashMap<>();
+    private final CompanionTransportManager mCompanionTransportManager;
+    private final List<AssociationInfo> mConnectedAssociations = new ArrayList<>();
     private final Set<Integer> mBlocklist = new HashSet<>();
 
-    private CallMetadataSyncCallback mInCallServiceCallMetadataSyncCallback;
+    private CrossDeviceSyncControllerCallback mCrossDeviceSyncControllerCallback;
 
-    public CrossDeviceSyncController(Context context, Callback callback) {
+    public CrossDeviceSyncController(Context context,
+            CompanionTransportManager companionTransportManager) {
         mContext = context;
-        mCdmCallback = callback;
+        mCompanionTransportManager = companionTransportManager;
+        mCompanionTransportManager.addListener(new IOnTransportsChangedListener.Stub() {
+            @Override
+            public void onTransportsChanged(List<AssociationInfo> newAssociations) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    if (!CompanionDeviceConfig.isEnabled(
+                            CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+                        return;
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+                final List<AssociationInfo> existingAssociations = new ArrayList<>(
+                        mConnectedAssociations);
+                mConnectedAssociations.clear();
+                mConnectedAssociations.addAll(newAssociations);
+
+                if (mCrossDeviceSyncControllerCallback == null) {
+                    Slog.w(TAG, "No callback to report transports changed");
+                    return;
+                }
+                for (AssociationInfo associationInfo : newAssociations) {
+                    if (!existingAssociations.contains(associationInfo)
+                            && !isAssociationBlocked(associationInfo.getId())) {
+                        mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
+                                associationInfo.getUserId(), /* added= */ true);
+                        mCrossDeviceSyncControllerCallback.requestCrossDeviceSync(associationInfo);
+                    }
+                }
+                for (AssociationInfo associationInfo : existingAssociations) {
+                    if (!newAssociations.contains(associationInfo)) {
+                        if (isAssociationBlocked(associationInfo.getId())) {
+                            mBlocklist.remove(associationInfo.getId());
+                        } else {
+                            mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
+                                    associationInfo.getUserId(), /* added= */ false);
+                        }
+                    }
+                }
+            }
+        });
+        mCompanionTransportManager.addListener(MESSAGE_REQUEST_CONTEXT_SYNC,
+                new IOnMessageReceivedListener.Stub() {
+                    @Override
+                    public void onMessageReceived(int associationId, byte[] data) {
+                        if (mCrossDeviceSyncControllerCallback == null) {
+                            Slog.w(TAG, "No callback to process context sync message");
+                            return;
+                        }
+                        mCrossDeviceSyncControllerCallback.processContextSyncMessage(associationId,
+                                processTelecomDataFromSync(data));
+                    }
+                });
+    }
+
+    private boolean isAssociationBlocked(int associationId) {
+        return mBlocklist.contains(associationId);
     }
 
     /** Registers the call metadata callback. */
-    public void registerCallMetadataSyncCallback(CallMetadataSyncCallback callback) {
-        mInCallServiceCallMetadataSyncCallback = callback;
+    public void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback) {
+        mCrossDeviceSyncControllerCallback = callback;
+        for (AssociationInfo associationInfo : mConnectedAssociations) {
+            if (!isAssociationBlocked(associationInfo.getId())) {
+                mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
+                        associationInfo.getUserId(), /* added= */ true);
+                mCrossDeviceSyncControllerCallback.requestCrossDeviceSync(associationInfo);
+            }
+        }
     }
 
     /** Allow specific associated devices to enable / disable syncing. */
     public void setSyncEnabled(AssociationInfo associationInfo, boolean enabled) {
         if (enabled) {
-            if (mBlocklist.contains(associationInfo.getId())) {
+            if (isAssociationBlocked(associationInfo.getId())) {
                 mBlocklist.remove(associationInfo.getId());
-                openChannel(associationInfo);
+                mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
+                        associationInfo.getUserId(), /* added= */ true);
+                mCrossDeviceSyncControllerCallback.requestCrossDeviceSync(associationInfo);
             }
         } else {
-            if (!mBlocklist.contains(associationInfo.getId())) {
+            if (!isAssociationBlocked(associationInfo.getId())) {
                 mBlocklist.add(associationInfo.getId());
-                closeChannel(associationInfo);
+                mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
+                        associationInfo.getUserId(), /* added= */ false);
+                // Send empty message to device to clear its data (otherwise it will get stale)
+                syncMessageToDevice(associationInfo.getId(), createEmptyMessage());
             }
         }
     }
 
-    /**
-     * Opens channels to newly associated devices, and closes channels to newly disassociated
-     * devices.
-     *
-     * TODO(b/265466098): this needs to be limited to just connected devices
-     */
-    public void onAssociationsChanged(int userId, List<AssociationInfo> newAssociationInfoList) {
-        final List<AssociationInfo> existingAssociationInfoList = mUserIdToAssociationInfo.get(
-                userId);
-        // Close channels to newly-disconnected devices.
-        for (AssociationInfo existingAssociationInfo : existingAssociationInfoList) {
-            if (!newAssociationInfoList.contains(existingAssociationInfo) && !mBlocklist.contains(
-                    existingAssociationInfo.getId())) {
-                closeChannel(existingAssociationInfo);
-            }
-        }
-        // Open channels to newly-connected devices.
-        for (AssociationInfo newAssociationInfo : newAssociationInfoList) {
-            if (!existingAssociationInfoList.contains(newAssociationInfo) && !mBlocklist.contains(
-                    newAssociationInfo.getId())) {
-                openChannel(newAssociationInfo);
-            }
-        }
-        mUserIdToAssociationInfo.put(userId, newAssociationInfoList);
-    }
-
     private boolean isAdminBlocked(int userId) {
         return mContext.getSystemService(DevicePolicyManager.class)
                 .getBluetoothContactSharingDisabled(UserHandle.of(userId));
     }
 
-    /** Stop reading, close streams, and close secure channel. */
-    private void closeChannel(AssociationInfo associationInfo) {
-        // TODO(b/265466098): stop reading from secure channel
-        final Pair<InputStream, OutputStream> streams = mAssociationIdToStreams.get(
-                associationInfo.getId());
-        if (streams != null) {
-            try {
-                if (streams.first != null) {
-                    streams.first.close();
-                }
-                if (streams.second != null) {
-                    streams.second.close();
-                }
-            } catch (IOException e) {
-                Slog.e(TAG, "Could not close streams for association " + associationInfo.getId(),
-                        e);
-            }
-        }
-        mCdmCallback.closeSecureChannel(associationInfo.getId());
-    }
-
-    /** Sync initial snapshot and start reading. */
-    private void openChannel(AssociationInfo associationInfo) {
-        final InputStream is = new ByteArrayInputStream(new byte[BYTE_ARRAY_SIZE]);
-        final OutputStream os = new ByteArrayOutputStream(BYTE_ARRAY_SIZE);
-        mAssociationIdToStreams.put(associationInfo.getId(), new Pair<>(is, os));
-        mCdmCallback.createSecureChannel(associationInfo.getId(), is, os);
-        // TODO(b/265466098): only requestSync for this specific association / connection?
-        mInCallServiceCallMetadataSyncCallback.requestCrossDeviceSync(associationInfo.getUserId());
-        // TODO(b/265466098): start reading from secure channel
-    }
-
     /**
      * Sync data to associated devices.
      *
      * @param userId The user whose data should be synced.
      * @param calls The full list of current calls for all users.
      */
-    public void crossDeviceSync(int userId, Collection<CrossDeviceCall> calls) {
-        final boolean isAdminBlocked = isAdminBlocked(userId);
-        for (AssociationInfo associationInfo : mUserIdToAssociationInfo.get(userId)) {
-            final Pair<InputStream, OutputStream> streams = mAssociationIdToStreams.get(
-                    associationInfo.getId());
-            final ProtoOutputStream pos = new ProtoOutputStream(streams.second);
-            final long telecomToken = pos.start(ContextSyncMessage.TELECOM);
-            for (CrossDeviceCall call : calls) {
-                final long callsToken = pos.start(Telecom.CALLS);
-                pos.write(Call.ID, call.getId());
-                final long originToken = pos.start(Call.ORIGIN);
-                pos.write(Call.Origin.CALLER_ID, call.getReadableCallerId(isAdminBlocked));
-                pos.write(Call.Origin.APP_ICON, call.getCallingAppIcon());
-                pos.write(Call.Origin.APP_NAME, call.getCallingAppName());
-                pos.end(originToken);
-                pos.write(Call.STATUS, call.getStatus());
-                for (int control : call.getControls()) {
-                    pos.write(Call.CONTROLS_AVAILABLE, control);
-                }
-                pos.end(callsToken);
+    public void syncToAllDevicesForUserId(int userId, Collection<CrossDeviceCall> calls) {
+        final Set<Integer> associationIds = new HashSet<>();
+        for (AssociationInfo associationInfo : mConnectedAssociations) {
+            if (associationInfo.getUserId() == userId && !isAssociationBlocked(
+                    associationInfo.getId())) {
+                associationIds.add(associationInfo.getId());
             }
-            pos.end(telecomToken);
-            pos.flush();
         }
+        if (associationIds.isEmpty()) {
+            Slog.w(TAG, "No eligible devices to sync to");
+            return;
+        }
+
+        mCompanionTransportManager.sendMessage(MESSAGE_REQUEST_CONTEXT_SYNC,
+                createCallUpdateMessage(calls, userId),
+                associationIds.stream().mapToInt(Integer::intValue).toArray());
     }
 
     /**
-     * Callback to be implemented by CompanionDeviceManagerService.
+     * Sync data to associated devices.
+     *
+     * @param associationInfo The association whose data should be synced.
+     * @param calls           The full list of current calls for all users.
      */
-    public interface Callback {
-        /**
-         * Create a secure channel to send messages.
-         */
-        void createSecureChannel(int associationId, InputStream input, OutputStream output);
+    public void syncToSingleDevice(AssociationInfo associationInfo,
+            Collection<CrossDeviceCall> calls) {
+        if (isAssociationBlocked(associationInfo.getId())) {
+            Slog.e(TAG, "Cannot sync to requested device; connection is blocked");
+            return;
+        }
 
-        /**
-         * Close the secure channel created previously.
-         */
-        void closeSecureChannel(int associationId);
+        mCompanionTransportManager.sendMessage(MESSAGE_REQUEST_CONTEXT_SYNC,
+                createCallUpdateMessage(calls, associationInfo.getUserId()),
+                new int[]{associationInfo.getId()});
+    }
+
+    /**
+     * Sync data to associated devices.
+     *
+     * @param associationId   The association whose data should be synced.
+     * @param message         The message to sync.
+     */
+    public void syncMessageToDevice(int associationId, byte[] message) {
+        if (isAssociationBlocked(associationId)) {
+            Slog.e(TAG, "Cannot sync to requested device; connection is blocked");
+            return;
+        }
+
+        mCompanionTransportManager.sendMessage(MESSAGE_REQUEST_CONTEXT_SYNC, message,
+                new int[]{associationId});
+    }
+
+    @VisibleForTesting
+    CallMetadataSyncData processTelecomDataFromSync(byte[] data) {
+        final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+        final ProtoInputStream pis = new ProtoInputStream(data);
+        try {
+            int version = -1;
+            while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                switch (pis.getFieldNumber()) {
+                    case (int) ContextSyncMessage.VERSION:
+                        version = pis.readInt(ContextSyncMessage.VERSION);
+                        Slog.e(TAG, "Processing context sync message version " + version);
+                        break;
+                    case (int) ContextSyncMessage.TELECOM:
+                        if (version == VERSION_1) {
+                            final long telecomToken = pis.start(ContextSyncMessage.TELECOM);
+                            while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                                if (pis.getFieldNumber() == (int) Telecom.CALLS) {
+                                    final long callsToken = pis.start(Telecom.CALLS);
+                                    callMetadataSyncData.addCall(processCallDataFromSync(pis));
+                                    pis.end(callsToken);
+                                } else if (pis.getFieldNumber() == (int) Telecom.REQUESTS) {
+                                    final long requestsToken = pis.start(Telecom.REQUESTS);
+                                    callMetadataSyncData.addRequest(processCallDataFromSync(pis));
+                                    pis.end(requestsToken);
+                                } else {
+                                    Slog.e(TAG, "Unhandled field in Telecom:"
+                                            + ProtoUtils.currentFieldToString(pis));
+                                }
+                            }
+                            pis.end(telecomToken);
+                        } else {
+                            Slog.e(TAG, "Cannot process unsupported version " + version);
+                        }
+                        break;
+                    default:
+                        Slog.e(TAG, "Unhandled field in ContextSyncMessage:"
+                                + ProtoUtils.currentFieldToString(pis));
+                }
+            }
+        } catch (IOException | ProtoParseException e) {
+            throw new RuntimeException(e);
+        }
+        return callMetadataSyncData;
+    }
+
+    @VisibleForTesting
+    CallMetadataSyncData.Call processCallDataFromSync(ProtoInputStream pis) throws IOException {
+        final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+        while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pis.getFieldNumber()) {
+                case (int) Telecom.Call.ID:
+                    call.setId(pis.readLong(Telecom.Call.ID));
+                    break;
+                case (int) Telecom.Call.ORIGIN:
+                    final long originToken = pis.start(Telecom.Call.ORIGIN);
+                    while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                        switch (pis.getFieldNumber()) {
+                            case (int) Telecom.Call.Origin.APP_ICON:
+                                call.setAppIcon(pis.readBytes(Telecom.Call.Origin.APP_ICON));
+                                break;
+                            case (int) Telecom.Call.Origin.APP_NAME:
+                                call.setAppName(pis.readString(Telecom.Call.Origin.APP_NAME));
+                                break;
+                            case (int) Telecom.Call.Origin.CALLER_ID:
+                                call.setCallerId(pis.readString(Telecom.Call.Origin.CALLER_ID));
+                                break;
+                            case (int) Telecom.Call.Origin.APP_IDENTIFIER:
+                                call.setAppIdentifier(
+                                        pis.readString(Telecom.Call.Origin.APP_IDENTIFIER));
+                                break;
+                            default:
+                                Slog.e(TAG, "Unhandled field in Origin:"
+                                        + ProtoUtils.currentFieldToString(pis));
+                        }
+                    }
+                    pis.end(originToken);
+                    break;
+                case (int) Telecom.Call.STATUS:
+                    call.setStatus(pis.readInt(Telecom.Call.STATUS));
+                    break;
+                case (int) Telecom.Call.CONTROLS:
+                    call.addControl(pis.readInt(Telecom.Call.CONTROLS));
+                    break;
+                default:
+                    Slog.e(TAG,
+                            "Unhandled field in Telecom:" + ProtoUtils.currentFieldToString(pis));
+            }
+        }
+        return call;
+    }
+
+    @VisibleForTesting
+    byte[] createCallUpdateMessage(Collection<CrossDeviceCall> calls, int userId) {
+        final ProtoOutputStream pos = new ProtoOutputStream();
+        pos.write(ContextSyncMessage.VERSION, CURRENT_VERSION);
+        final long telecomToken = pos.start(ContextSyncMessage.TELECOM);
+        for (CrossDeviceCall call : calls) {
+            final long callsToken = pos.start(Telecom.CALLS);
+            pos.write(Telecom.Call.ID, call.getId());
+            final long originToken = pos.start(Telecom.Call.ORIGIN);
+            pos.write(Telecom.Call.Origin.CALLER_ID,
+                    call.getReadableCallerId(isAdminBlocked(userId)));
+            pos.write(Telecom.Call.Origin.APP_ICON, call.getCallingAppIcon());
+            pos.write(Telecom.Call.Origin.APP_NAME, call.getCallingAppName());
+            pos.write(Telecom.Call.Origin.APP_IDENTIFIER, call.getCallingAppPackageName());
+            pos.end(originToken);
+            pos.write(Telecom.Call.STATUS, call.getStatus());
+            for (int control : call.getControls()) {
+                pos.write(Telecom.Call.CONTROLS, control);
+            }
+            pos.end(callsToken);
+        }
+        pos.end(telecomToken);
+        return pos.getBytes();
+    }
+
+    /** Create a call control message. */
+    public static byte[] createCallControlMessage(long callId, int control) {
+        final ProtoOutputStream pos = new ProtoOutputStream();
+        pos.write(ContextSyncMessage.VERSION, CURRENT_VERSION);
+        final long telecomToken = pos.start(ContextSyncMessage.TELECOM);
+        final long requestsToken = pos.start(Telecom.REQUESTS);
+        pos.write(Telecom.Call.ID, callId);
+        pos.write(Telecom.Call.CONTROLS, control);
+        pos.end(requestsToken);
+        pos.end(telecomToken);
+        return pos.getBytes();
+    }
+
+    /** Create an empty context sync message, used to clear state. */
+    public static byte[] createEmptyMessage() {
+        final ProtoOutputStream pos = new ProtoOutputStream();
+        pos.write(ContextSyncMessage.VERSION, CURRENT_VERSION);
+        return pos.getBytes();
     }
 }
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java
similarity index 67%
rename from services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java
rename to services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java
index 7c339d2..31e10a8 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncCallback.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java
@@ -16,12 +16,14 @@
 
 package com.android.server.companion.datatransfer.contextsync;
 
+import android.companion.AssociationInfo;
+
 /** Callback for call metadata syncing. */
-public abstract class CallMetadataSyncCallback {
+public abstract class CrossDeviceSyncControllerCallback {
 
-    abstract void processCallControlAction(int crossDeviceCallId, int callControlAction);
+    void processContextSyncMessage(int associationId, CallMetadataSyncData callMetadataSyncData) {}
 
-    abstract void requestCrossDeviceSync(int userId);
+    void requestCrossDeviceSync(AssociationInfo associationInfo) {}
 
-    abstract void updateStatus(int userId, boolean shouldSyncCallMetadata);
+    void updateNumberOfActiveSyncAssociations(int userId, boolean added) {}
 }
diff --git a/services/core/java/com/android/server/SoundTriggerInternal.java b/services/core/java/com/android/server/SoundTriggerInternal.java
index e6c1750..f184574 100644
--- a/services/core/java/com/android/server/SoundTriggerInternal.java
+++ b/services/core/java/com/android/server/SoundTriggerInternal.java
@@ -52,11 +52,6 @@
     // Enumerate possible STModules to attach to
     List<ModuleProperties> listModuleProperties(Identity originatorIdentity);
 
-    /**
-     * Dumps service-wide information.
-     */
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args);
-
     interface Session {
         /**
          * Starts recognition for the given keyphraseId.
@@ -142,13 +137,14 @@
                 @ModelParams int modelParam);
 
         /**
+         * Invalidates the sound trigger session and clears any associated resources. Subsequent
+         * calls to this object will throw IllegalStateException.
+         */
+        void detach();
+
+        /**
          * Unloads (and stops if running) the given keyphraseId
          */
         int unloadKeyphraseModel(int keyphaseId);
-
-        /**
-         * Dumps session-wide information.
-         */
-        void dump(FileDescriptor fd, PrintWriter pw, String[] args);
     }
 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index e76b628..a641e85 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -3534,21 +3534,29 @@
         // - Sanitized ServiceState sent to all other apps with READ_PHONE_STATE
         // - Sanitized ServiceState sent to all other apps with READ_PRIVILEGED_PHONE_STATE but not
         //   READ_PHONE_STATE
-        BroadcastOptions options = createServiceStateBroadcastOptions(subId, phoneId);
+        //
+        // Create a unique delivery group key for each variant for SERVICE_STATE broadcast so
+        // that a new broadcast only replaces the pending broadcasts of the same variant.
+        // In order to create a unique delivery group key, append tag of the form
+        // "I:Included-permissions[,E:Excluded-permissions][,lbp]"
+        // Note: Given that location-bypass-packages are static, we can just append "lbp" to the
+        // tag to create a unique delivery group but if location-bypass-packages become dynamic
+        // in the future, we would need to create a unique key for each group of
+        // location-bypass-packages.
         if (LocationAccessPolicy.isLocationModeEnabled(mContext, mContext.getUserId())) {
             Intent fullIntent = createServiceStateIntent(state, subId, phoneId, false);
             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
                     fullIntent,
                     new String[]{Manifest.permission.READ_PHONE_STATE,
                             Manifest.permission.ACCESS_FINE_LOCATION},
-                    options);
+                    createServiceStateBroadcastOptions(subId, phoneId, "I:RA"));
             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
                     fullIntent,
                     new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
                             Manifest.permission.ACCESS_FINE_LOCATION},
                     new String[]{Manifest.permission.READ_PHONE_STATE},
                     null,
-                    options);
+                    createServiceStateBroadcastOptions(subId, phoneId, "I:RPA,E:R"));
 
             Intent sanitizedIntent = createServiceStateIntent(state, subId, phoneId, true);
             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
@@ -3556,14 +3564,14 @@
                     new String[]{Manifest.permission.READ_PHONE_STATE},
                     new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                     null,
-                    options);
+                    createServiceStateBroadcastOptions(subId, phoneId, "I:R,E:A"));
             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
                     sanitizedIntent,
                     new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
                     new String[]{Manifest.permission.READ_PHONE_STATE,
                             Manifest.permission.ACCESS_FINE_LOCATION},
                     null,
-                    options);
+                    createServiceStateBroadcastOptions(subId, phoneId, "I:RP,E:RA"));
         } else {
             String[] locationBypassPackages = Binder.withCleanCallingIdentity(() ->
                     LocationAccessPolicy.getLocationBypassPackages(mContext));
@@ -3573,13 +3581,13 @@
                 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
                         fullIntent,
                         new String[]{Manifest.permission.READ_PHONE_STATE},
-                        options);
+                        createServiceStateBroadcastOptions(subId, phoneId, "I:R"));
                 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
                         fullIntent,
                         new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
                         new String[]{Manifest.permission.READ_PHONE_STATE},
                         null,
-                        options);
+                        createServiceStateBroadcastOptions(subId, phoneId, "I:RP,E:R"));
             }
 
             Intent sanitizedIntent = createServiceStateIntent(state, subId, phoneId, true);
@@ -3588,13 +3596,13 @@
                     new String[]{Manifest.permission.READ_PHONE_STATE},
                     new String[]{/* no excluded permissions */},
                     locationBypassPackages,
-                    options);
+                    createServiceStateBroadcastOptions(subId, phoneId, "I:R,lbp"));
             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
                     sanitizedIntent,
                     new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
                     new String[]{Manifest.permission.READ_PHONE_STATE},
                     locationBypassPackages,
-                    options);
+                    createServiceStateBroadcastOptions(subId, phoneId, "I:RP,E:R,lbp"));
         }
     }
 
@@ -3616,12 +3624,14 @@
         return intent;
     }
 
-    private BroadcastOptions createServiceStateBroadcastOptions(int subId, int phoneId) {
+    private BroadcastOptions createServiceStateBroadcastOptions(int subId, int phoneId,
+            String tag) {
         return new BroadcastOptions()
                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
                 // Use a combination of subId and phoneId as the key so that older broadcasts
                 // with same subId and phoneId will get discarded.
-                .setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE, subId + "-" + phoneId)
+                .setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE,
+                        subId + "-" + phoneId + "-" + tag)
                 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
     }
 
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 7c32627..55e805a 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -28,6 +28,7 @@
 import static android.app.UiModeManager.PROJECTION_TYPE_AUTOMOTIVE;
 import static android.app.UiModeManager.PROJECTION_TYPE_NONE;
 import static android.os.UserHandle.USER_SYSTEM;
+import static android.os.UserHandle.getCallingUserId;
 import static android.provider.Settings.Secure.CONTRAST_LEVEL;
 import static android.util.TimeUtils.isTimeBetween;
 
@@ -199,8 +200,8 @@
     private PowerManagerInternal mLocalPowerManager;
 
     @GuardedBy("mLock")
-    private final RemoteCallbackList<IUiModeManagerCallback> mUiModeManagerCallbacks =
-            new RemoteCallbackList<IUiModeManagerCallback>();
+    private final SparseArray<RemoteCallbackList<IUiModeManagerCallback>> mUiModeManagerCallbacks =
+            new SparseArray<>();
 
     @GuardedBy("mLock")
     @Nullable
@@ -371,8 +372,9 @@
             synchronized (mLock) {
                 if (updateContrastLocked()) {
                     float contrast = getContrastLocked();
-                    mUiModeManagerCallbacks.broadcast(ignoreRemoteException(callback ->
-                            callback.notifyContrastChanged(contrast)));
+                    mUiModeManagerCallbacks.get(mCurrentUser, new RemoteCallbackList<>())
+                            .broadcast(ignoreRemoteException(
+                                    callback -> callback.notifyContrastChanged(contrast)));
                 }
             }
         }
@@ -664,8 +666,12 @@
     private final IUiModeManager.Stub mService = new IUiModeManager.Stub() {
         @Override
         public void addCallback(IUiModeManagerCallback callback) {
+            int userId = getCallingUserId();
             synchronized (mLock) {
-                mUiModeManagerCallbacks.register(callback);
+                if (!mUiModeManagerCallbacks.contains(userId)) {
+                    mUiModeManagerCallbacks.put(userId, new RemoteCallbackList<>());
+                }
+                mUiModeManagerCallbacks.get(userId).register(callback);
             }
         }
 
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index df3c95b..1f1f0e9 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -52,6 +52,7 @@
 import static android.os.PowerExemptionManager.REASON_ACTIVE_DEVICE_ADMIN;
 import static android.os.PowerExemptionManager.REASON_ACTIVITY_STARTER;
 import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD;
+import static android.os.PowerExemptionManager.REASON_ALARM_MANAGER_ALARM_CLOCK;
 import static android.os.PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE;
 import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION;
 import static android.os.PowerExemptionManager.REASON_BACKGROUND_FGS_PERMISSION;
@@ -458,11 +459,12 @@
         public void updateBackgroundRestrictedForUidPackage(int uid, String packageName,
                 boolean restricted) {
             synchronized (mAm) {
-                if (!isForegroundServiceAllowedInBackgroundRestricted(uid, packageName)) {
-                    stopAllForegroundServicesLocked(uid, packageName);
-                }
                 mAm.mProcessList.updateBackgroundRestrictedForUidPackageLocked(
                         uid, packageName, restricted);
+                if (!isForegroundServiceAllowedInBackgroundRestricted(uid, packageName)
+                        && !isTempAllowedByAlarmClock(uid)) {
+                    stopAllForegroundServicesLocked(uid, packageName);
+                }
             }
         }
     }
@@ -475,7 +477,11 @@
             final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i);
             if (uid == r.serviceInfo.applicationInfo.uid
                     || packageName.equals(r.serviceInfo.packageName)) {
-                if (r.isForeground) {
+                // If the FGS is started by temp allowlist of alarm-clock
+                // (REASON_ALARM_MANAGER_ALARM_CLOCK), allow it to continue and do not stop it,
+                // even the app is background-restricted.
+                if (r.isForeground
+                        && r.mAllowStartForegroundAtEntering != REASON_ALARM_MANAGER_ALARM_CLOCK) {
                     toStop.add(r);
                 }
             }
@@ -762,6 +768,15 @@
         }
     }
 
+    private static void traceInstant(@NonNull String message, @NonNull ServiceRecord service) {
+        if (!Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+            return;
+        }
+        final String serviceName = (service.getComponentName() != null)
+                ? service.getComponentName().toShortString() : "(?)";
+        Trace.instant(Trace.TRACE_TAG_ACTIVITY_MANAGER, message + serviceName);
+    }
+
     ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
             int callingPid, int callingUid, boolean fgRequired, String callingPackage,
             @Nullable String callingFeatureId, final int userId, boolean isSdkSandboxService,
@@ -818,6 +833,9 @@
         }
 
         ServiceRecord r = res.record;
+
+        traceInstant("startService(): ", r);
+
         // Note, when startService() or startForegroundService() is called on an already
         // running SHORT_SERVICE FGS, the call will succeed (i.e. we won't throw
         // ForegroundServiceStartNotAllowedException), even when the service is already timed
@@ -860,7 +878,9 @@
         // start analogously to the legacy-app forced-restrictions case, regardless
         // of its target SDK version.
         boolean forcedStandby = false;
-        if (bgLaunch && appRestrictedAnyInBackground(appUid, appPackageName)) {
+        if (bgLaunch
+                && appRestrictedAnyInBackground(appUid, appPackageName)
+                && !isTempAllowedByAlarmClock(appUid)) {
             if (DEBUG_FOREGROUND_SERVICE) {
                 Slog.d(TAG, "Forcing bg-only service start only for " + r.shortInstanceName
                         + " : bgLaunch=" + bgLaunch + " callerFg=" + callerFg);
@@ -1407,6 +1427,7 @@
     }
 
     private void stopServiceLocked(ServiceRecord service, boolean enqueueOomAdj) {
+        traceInstant("stopService(): ", service);
         try {
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "stopServiceLocked()");
             if (service.delayed) {
@@ -1918,6 +1939,20 @@
                 && isForegroundServiceAllowedInBackgroundRestricted(app);
     }
 
+    /*
+     * If the FGS start is temp allowlisted by alarm-clock(REASON_ALARM_MANAGER_ALARM_CLOCK), it is
+     * allowed even the app is background-restricted.
+     */
+    private boolean isTempAllowedByAlarmClock(int uid) {
+        final ActivityManagerService.FgsTempAllowListItem item =
+                mAm.isAllowlistedForFgsStartLOSP(uid);
+        if (item != null) {
+            return item.mReasonCode == REASON_ALARM_MANAGER_ALARM_CLOCK;
+        } else {
+            return false;
+        }
+    }
+
     void logFgsApiBeginLocked(int uid, int pid, int apiType) {
         synchronized (mFGSLogger) {
             mFGSLogger.logForegroundServiceApiEventBegin(uid, pid, apiType, "");
@@ -1946,6 +1981,7 @@
             if (notification == null) {
                 throw new IllegalArgumentException("null notification");
             }
+            traceInstant("startForeground(): ", r);
             final int foregroundServiceStartType = foregroundServiceType;
             // Instant apps need permission to create foreground services.
             if (r.appInfo.isInstantApp()) {
@@ -2050,7 +2086,8 @@
                 // Apps that are TOP or effectively similar may call startForeground() on
                 // their services even if they are restricted from doing that while in bg.
                 if (!ignoreForeground
-                        && !isForegroundServiceAllowedInBackgroundRestricted(r.app)) {
+                        && !isForegroundServiceAllowedInBackgroundRestricted(r.app)
+                        && !isTempAllowedByAlarmClock(r.app.uid)) {
                     Slog.w(TAG,
                             "Service.startForeground() not allowed due to bg restriction: service "
                                     + r.shortInstanceName);
@@ -2484,6 +2521,7 @@
             }
         } else {
             if (r.isForeground) {
+                traceInstant("stopForeground(): ", r);
                 final ServiceMap smap = getServiceMapLocked(r.userId);
                 if (smap != null) {
                     decActiveForegroundAppLocked(smap, r);
@@ -3311,6 +3349,7 @@
                     Slog.i(TAG_SERVICE, "Short FGS started: " + sr);
                 }
             }
+            traceInstant("short FGS start/extend: ", sr);
             sr.setShortFgsInfo(SystemClock.uptimeMillis());
 
             // We'll restart the timeout.
@@ -3356,10 +3395,11 @@
                 return;
             }
             Slog.e(TAG_SERVICE, "Short FGS timed out: " + sr);
-            final long now = SystemClock.uptimeMillis();
+            traceInstant("short FGS timeout: ", sr);
+
             logFGSStateChangeLocked(sr,
                     FOREGROUND_SERVICE_STATE_CHANGED__STATE__TIMED_OUT,
-                    now > sr.mFgsEnterTime ? (int) (now - sr.mFgsEnterTime) : 0,
+                    nowUptime > sr.mFgsEnterTime ? (int) (nowUptime - sr.mFgsEnterTime) : 0,
                     FGS_STOP_REASON_UNKNOWN,
                     FGS_TYPE_POLICY_CHECK_UNKNOWN);
             try {
@@ -3410,6 +3450,7 @@
             }
 
             Slog.e(TAG_SERVICE, "Short FGS procstate demoted: " + sr);
+            traceInstant("short FGS demote: ", sr);
 
             mAm.updateOomAdjLocked(sr.app, OOM_ADJ_REASON_SHORT_FGS_TIMEOUT);
         }
@@ -3440,6 +3481,9 @@
             } else {
                 Slog.e(TAG_SERVICE, message);
             }
+
+            traceInstant("short FGS ANR: ", sr);
+
             mAm.appNotResponding(sr.app, tr);
 
             // TODO: Can we close the ANR dialog here, if it's still shown? Currently, the ANR
@@ -3866,7 +3910,7 @@
         if (UserHandle.isCore(callingUid)) {
             return;
         }
-        final int callingUserId = UserHandle.getCallingUserId();
+        final int callingUserId = UserHandle.getUserId(callingUid);
         if (callingUserId == userId
                 || !mAm.mUserController.isSameProfileGroup(callingUserId, userId)) {
             return;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index def2a2f..1a5d425 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5190,7 +5190,10 @@
                         throw new IllegalArgumentException(
                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
                     }
-                    if (PendingIntent.isNewMutableDisallowedImplicitPendingIntent(flags, intent)) {
+                    boolean isActivityResultType =
+                            type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT;
+                    if (PendingIntent.isNewMutableDisallowedImplicitPendingIntent(flags, intent,
+                            isActivityResultType)) {
                         boolean isChangeEnabled = CompatChanges.isChangeEnabled(
                                         PendingIntent.BLOCK_MUTABLE_IMPLICIT_PENDING_INTENT,
                                         owningUid);
@@ -6915,7 +6918,7 @@
         mActivityTaskManager.unhandledBack();
     }
 
-    // TODO: Move to ContentProviderHelper?
+    // TODO: Replace this method with one that returns a bound IContentProvider.
     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
         enforceNotIsolatedCaller("openContentUri");
         final int userId = UserHandle.getCallingUserId();
@@ -6944,6 +6947,16 @@
                     Log.e(TAG, "Cannot find package for uid: " + uid);
                     return null;
                 }
+
+                final ApplicationInfo appInfo = mPackageManagerInt.getApplicationInfo(
+                        androidPackage.getPackageName(), /*flags*/0, Process.SYSTEM_UID,
+                        UserHandle.USER_SYSTEM);
+                if (!appInfo.isVendor() && !appInfo.isSystemApp() && !appInfo.isSystemExt()
+                        && !appInfo.isProduct()) {
+                    Log.e(TAG, "openContentUri may only be used by vendor/system/product.");
+                    return null;
+                }
+
                 final AttributionSource attributionSource = new AttributionSource(
                         Binder.getCallingUid(), androidPackage.getPackageName(), null);
                 pfd = cph.provider.openFile(attributionSource, uri, "r", null);
@@ -7025,7 +7038,7 @@
 
     @Override
     public void notifyLockedProfile(@UserIdInt int userId) {
-        mAtmInternal.notifyLockedProfile(userId, mUserController.getCurrentUserId());
+        mAtmInternal.notifyLockedProfile(userId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index f29a2e1..c687184a 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -1199,6 +1199,9 @@
                     .sendToTarget();
         }
 
+        mCachedAppsWatermarkData.updateCachedAppsHighWatermarkIfNecessaryLocked(
+                numCached + numEmpty, now);
+
         if (mService.mConstants.USE_MODERN_TRIM) {
             // Modern trim is not sent based on lowmem state
             // Dispatch UI_HIDDEN to processes that need it
@@ -1316,8 +1319,6 @@
                 profile.setTrimMemoryLevel(0);
             });
         }
-        mCachedAppsWatermarkData.updateCachedAppsHighWatermarkIfNecessaryLocked(
-                numCached + numEmpty, now);
         return allChanged;
     }
 
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index d140403..6360e2a 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -167,7 +167,7 @@
                     .onMalformedInput(CodingErrorAction.REPLACE)
                     .onUnmappableCharacter(CodingErrorAction.REPLACE)
                     .replaceWith("?");
-    private static final int MAX_LOW_POWER_STATS_SIZE = 16384;
+    private static final int MAX_LOW_POWER_STATS_SIZE = 32768;
     private static final int POWER_STATS_QUERY_TIMEOUT_MILLIS = 2000;
     private static final String EMPTY = "Empty";
 
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 0767218..5c68e67 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -242,8 +242,7 @@
      */
     @Nullable
     public BroadcastRecord enqueueOrReplaceBroadcast(@NonNull BroadcastRecord record,
-            int recordIndex, boolean wouldBeSkipped,
-            @NonNull BroadcastConsumer deferredStatesApplyConsumer) {
+            int recordIndex, @NonNull BroadcastConsumer deferredStatesApplyConsumer) {
         // When updateDeferredStates() has already applied a deferred state to
         // all pending items, apply to this new broadcast too
         if (mLastDeferredStates && record.deferUntilActive
@@ -252,8 +251,7 @@
         }
 
         if (record.isReplacePending()) {
-            final BroadcastRecord replacedBroadcastRecord = replaceBroadcast(record, recordIndex,
-                    wouldBeSkipped);
+            final BroadcastRecord replacedBroadcastRecord = replaceBroadcast(record, recordIndex);
             if (replacedBroadcastRecord != null) {
                 return replacedBroadcastRecord;
             }
@@ -264,14 +262,13 @@
         SomeArgs newBroadcastArgs = SomeArgs.obtain();
         newBroadcastArgs.arg1 = record;
         newBroadcastArgs.argi1 = recordIndex;
-        newBroadcastArgs.argi2 = (wouldBeSkipped ? 1 : 0);
 
         // Cross-broadcast prioritization policy:  some broadcasts might warrant being
         // issued ahead of others that are already pending, for example if this new
         // broadcast is in a different delivery class or is tied to a direct user interaction
         // with implicit responsiveness expectations.
         getQueueForBroadcast(record).addLast(newBroadcastArgs);
-        onBroadcastEnqueued(record, recordIndex, wouldBeSkipped);
+        onBroadcastEnqueued(record, recordIndex);
         return null;
     }
 
@@ -285,10 +282,9 @@
      *         wasn't any broadcast that was replaced.
      */
     @Nullable
-    private BroadcastRecord replaceBroadcast(@NonNull BroadcastRecord record, int recordIndex,
-            boolean wouldBeSkipped) {
+    private BroadcastRecord replaceBroadcast(@NonNull BroadcastRecord record, int recordIndex) {
         final ArrayDeque<SomeArgs> queue = getQueueForBroadcast(record);
-        return replaceBroadcastInQueue(queue, record, recordIndex, wouldBeSkipped);
+        return replaceBroadcastInQueue(queue, record, recordIndex);
     }
 
     /**
@@ -302,15 +298,13 @@
      */
     @Nullable
     private BroadcastRecord replaceBroadcastInQueue(@NonNull ArrayDeque<SomeArgs> queue,
-            @NonNull BroadcastRecord record, int recordIndex,
-            boolean wouldBeSkipped) {
+            @NonNull BroadcastRecord record, int recordIndex) {
         final Iterator<SomeArgs> it = queue.descendingIterator();
         final Object receiver = record.receivers.get(recordIndex);
         while (it.hasNext()) {
             final SomeArgs args = it.next();
             final BroadcastRecord testRecord = (BroadcastRecord) args.arg1;
             final int testRecordIndex = args.argi1;
-            final boolean testWouldBeSkipped = (args.argi2 == 1);
             final Object testReceiver = testRecord.receivers.get(testRecordIndex);
             if ((record.callingUid == testRecord.callingUid)
                     && (record.userId == testRecord.userId)
@@ -320,10 +314,9 @@
                 // Exact match found; perform in-place swap
                 args.arg1 = record;
                 args.argi1 = recordIndex;
-                args.argi2 = (wouldBeSkipped ? 1 : 0);
                 record.copyEnqueueTimeFrom(testRecord);
-                onBroadcastDequeued(testRecord, testRecordIndex, testWouldBeSkipped);
-                onBroadcastEnqueued(record, recordIndex, wouldBeSkipped);
+                onBroadcastDequeued(testRecord, testRecordIndex);
+                onBroadcastEnqueued(record, recordIndex);
                 return testRecord;
             }
         }
@@ -383,13 +376,12 @@
             final SomeArgs args = it.next();
             final BroadcastRecord record = (BroadcastRecord) args.arg1;
             final int recordIndex = args.argi1;
-            final boolean recordWouldBeSkipped = (args.argi2 == 1);
             if (predicate.test(record, recordIndex)) {
                 consumer.accept(record, recordIndex);
                 if (andRemove) {
                     args.recycle();
                     it.remove();
-                    onBroadcastDequeued(record, recordIndex, recordWouldBeSkipped);
+                    onBroadcastDequeued(record, recordIndex);
                 } else {
                     // Even if we're leaving broadcast in queue, it may have
                     // been mutated in such a way to change our runnable time
@@ -539,12 +531,11 @@
         final SomeArgs next = removeNextBroadcast();
         mActive = (BroadcastRecord) next.arg1;
         mActiveIndex = next.argi1;
-        final boolean wouldBeSkipped = (next.argi2 == 1);
         mActiveCountSinceIdle++;
         mActiveViaColdStart = false;
         mActiveWasStopped = false;
         next.recycle();
-        onBroadcastDequeued(mActive, mActiveIndex, wouldBeSkipped);
+        onBroadcastDequeued(mActive, mActiveIndex);
     }
 
     /**
@@ -561,8 +552,7 @@
     /**
      * Update summary statistics when the given record has been enqueued.
      */
-    private void onBroadcastEnqueued(@NonNull BroadcastRecord record, int recordIndex,
-            boolean wouldBeSkipped) {
+    private void onBroadcastEnqueued(@NonNull BroadcastRecord record, int recordIndex) {
         mCountEnqueued++;
         if (record.deferUntilActive) {
             mCountDeferred++;
@@ -594,8 +584,7 @@
         if (record.callerInstrumented) {
             mCountInstrumented++;
         }
-        if (!wouldBeSkipped
-                && (record.receivers.get(recordIndex) instanceof ResolveInfo)) {
+        if (record.receivers.get(recordIndex) instanceof ResolveInfo) {
             mCountManifest++;
         }
         invalidateRunnableAt();
@@ -604,8 +593,7 @@
     /**
      * Update summary statistics when the given record has been dequeued.
      */
-    private void onBroadcastDequeued(@NonNull BroadcastRecord record, int recordIndex,
-            boolean wouldBeSkipped) {
+    private void onBroadcastDequeued(@NonNull BroadcastRecord record, int recordIndex) {
         mCountEnqueued--;
         if (record.deferUntilActive) {
             mCountDeferred--;
@@ -637,8 +625,7 @@
         if (record.callerInstrumented) {
             mCountInstrumented--;
         }
-        if (!wouldBeSkipped
-                && (record.receivers.get(recordIndex) instanceof ResolveInfo)) {
+        if (record.receivers.get(recordIndex) instanceof ResolveInfo) {
             mCountManifest--;
         }
         invalidateRunnableAt();
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index 8735f8a..96e1523 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -606,24 +606,18 @@
             final BroadcastProcessQueue queue = getOrCreateProcessQueue(
                     getReceiverProcessName(receiver), getReceiverUid(receiver));
 
-            boolean wouldBeSkipped = false;
-            if (receiver instanceof ResolveInfo) {
-                // If the app is running but would not have been started if the process weren't
-                // running, we're going to deliver the broadcast but mark that it's not a manifest
-                // broadcast that would have started the app. This allows BroadcastProcessQueue to
-                // defer the broadcast as though it were a normal runtime receiver.
-                wouldBeSkipped = (mSkipPolicy.shouldSkipMessage(r, receiver) != null);
-                if (wouldBeSkipped && queue.app == null && !queue.getActiveViaColdStart()) {
-                    // Skip receiver if there's no running app, the app is not being started, and
-                    // the app wouldn't be launched for this broadcast
-                    setDeliveryState(null, null, r, i, receiver, BroadcastRecord.DELIVERY_SKIPPED,
-                            "skipped by policy to avoid cold start");
-                    continue;
-                }
+            // If this receiver is going to be skipped, skip it now itself and don't even enqueue
+            // it.
+            final boolean wouldBeSkipped = (mSkipPolicy.shouldSkipMessage(r, receiver) != null);
+            if (wouldBeSkipped) {
+                setDeliveryState(null, null, r, i, receiver, BroadcastRecord.DELIVERY_SKIPPED,
+                        "skipped by policy at enqueue");
+                continue;
             }
+
             enqueuedBroadcast = true;
             final BroadcastRecord replacedBroadcast = queue.enqueueOrReplaceBroadcast(
-                    r, i, wouldBeSkipped, mBroadcastConsumerDeferApply);
+                    r, i, mBroadcastConsumerDeferApply);
             if (replacedBroadcast != null) {
                 replacedBroadcasts.add(replacedBroadcast);
             }
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 1426cfd..3bc5de9 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -2100,9 +2100,12 @@
             final boolean frozen;
             final ProcessCachedOptimizerRecord opt = proc.mOptRecord;
 
-            opt.setPendingFreeze(false);
-
             synchronized (mProcLock) {
+                // someone has canceled this freeze
+                if (!opt.isPendingFreeze()) {
+                    return;
+                }
+                opt.setPendingFreeze(false);
                 pid = proc.getPid();
 
                 if (mFreezerOverride) {
@@ -2148,7 +2151,6 @@
                 try {
                     traceAppFreeze(proc.processName, pid, -1);
                     Process.setProcessFrozen(pid, proc.uid, true);
-
                     opt.setFreezeUnfreezeTime(SystemClock.uptimeMillis());
                     opt.setFrozen(true);
                     opt.setHasCollectedFrozenPSS(false);
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index d8cb094..6015e5f 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -778,7 +778,7 @@
      * Drop a content provider from a ProcessRecord's bookkeeping
      */
     void removeContentProvider(IBinder connection, boolean stable) {
-        mService.enforceNotIsolatedOrSdkSandboxCaller("removeContentProvider");
+        mService.enforceNotIsolatedCaller("removeContentProvider");
         final long ident = Binder.clearCallingIdentity();
         try {
             ContentProviderConnection conn;
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 78aafeb..6551db9 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -643,6 +643,7 @@
 
         pw.print(prefix); pw.print("lastUntrustedSetFgsRestrictionAllowedTime=");
         TimeUtils.formatDuration(mLastUntrustedSetFgsRestrictionAllowedTime, now, pw);
+        pw.println();
 
         if (delayed) {
             pw.print(prefix); pw.print("delayed="); pw.println(delayed);
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index a181402..b2fdee7 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -3747,7 +3747,8 @@
             synchronized (mUserSwitchingDialogLock) {
                 dismissUserSwitchingDialog(null);
                 mUserSwitchingDialog = new UserSwitchingDialog(mService.mContext, fromUser, toUser,
-                        switchingFromSystemUserMessage, switchingToSystemUserMessage);
+                        switchingFromSystemUserMessage, switchingToSystemUserMessage,
+                        getWindowManager());
                 mUserSwitchingDialog.show(onShown);
             }
         }
diff --git a/services/core/java/com/android/server/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java
index 649305f..412fbe79 100644
--- a/services/core/java/com/android/server/am/UserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.app.ActivityManager;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.pm.UserInfo;
@@ -38,6 +37,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.util.Slog;
 import android.util.TypedValue;
 import android.view.View;
@@ -51,6 +51,7 @@
 import com.android.internal.R;
 import com.android.internal.util.ObjectUtils;
 import com.android.internal.util.UserIcons;
+import com.android.server.wm.WindowManagerService;
 
 /**
  * Dialog to show during the user switch. This dialog shows target user's name and their profile
@@ -70,11 +71,14 @@
     protected final UserInfo mNewUser;
     private final String mSwitchingFromSystemUserMessage;
     private final String mSwitchingToSystemUserMessage;
+    private final WindowManagerService mWindowManager;
     protected final Context mContext;
     private final int mTraceCookie;
+    private final boolean mNeedToFreezeScreen;
 
     UserSwitchingDialog(Context context, UserInfo oldUser, UserInfo newUser,
-            String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
+            String switchingFromSystemUserMessage, String switchingToSystemUserMessage,
+            WindowManagerService windowManager) {
         // TODO(b/278857848): Make full screen user switcher cover top part of the screen as well.
         //                    This problem is seen only on phones, it works fine on tablets.
         super(context, R.style.Theme_Material_NoActionBar_Fullscreen);
@@ -84,8 +88,10 @@
         mNewUser = newUser;
         mSwitchingFromSystemUserMessage = switchingFromSystemUserMessage;
         mSwitchingToSystemUserMessage = switchingToSystemUserMessage;
-        mDisableAnimations = ActivityManager.isLowRamDeviceStatic() || SystemProperties.getBoolean(
+        mDisableAnimations = SystemProperties.getBoolean(
                 "debug.usercontroller.disable_user_switching_dialog_animations", false);
+        mWindowManager = windowManager;
+        mNeedToFreezeScreen = !mDisableAnimations && !isUserSetupComplete(newUser);
         mTraceCookie = UserHandle.MAX_SECONDARY_USER_ID * oldUser.id + newUser.id;
 
         inflateContent();
@@ -167,6 +173,11 @@
                 : res.getString(R.string.user_switching_message, mNewUser.name);
     }
 
+    private boolean isUserSetupComplete(UserInfo user) {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.USER_SETUP_COMPLETE, /* default= */ 0, user.id) == 1;
+    }
+
     @Override
     public void show() {
         asyncTraceBegin("", 0);
@@ -176,29 +187,24 @@
     @Override
     public void dismiss() {
         super.dismiss();
+        stopFreezingScreen();
         asyncTraceEnd("", 0);
     }
 
     public void show(@NonNull Runnable onShown) {
         if (DEBUG) Slog.d(TAG, "show called");
         show();
-
-        if (mDisableAnimations) {
+        startShowAnimation(() -> {
+            startFreezingScreen();
             onShown.run();
-        } else {
-            startShowAnimation(onShown);
-        }
+        });
     }
 
     public void dismiss(@Nullable Runnable onDismissed) {
         if (DEBUG) Slog.d(TAG, "dismiss called");
-
         if (onDismissed == null) {
             // no animation needed
             dismiss();
-        } else if (mDisableAnimations) {
-            dismiss();
-            onDismissed.run();
         } else {
             startDismissAnimation(() -> {
                 dismiss();
@@ -207,7 +213,31 @@
         }
     }
 
+    private void startFreezingScreen() {
+        if (!mNeedToFreezeScreen) {
+            return;
+        }
+        if (DEBUG) Slog.d(TAG, "startFreezingScreen");
+        Trace.traceBegin(TRACE_TAG, "startFreezingScreen");
+        mWindowManager.startFreezingScreen(0, 0);
+        Trace.traceEnd(TRACE_TAG);
+    }
+
+    private void stopFreezingScreen() {
+        if (!mNeedToFreezeScreen) {
+            return;
+        }
+        if (DEBUG) Slog.d(TAG, "stopFreezingScreen");
+        Trace.traceBegin(TRACE_TAG, "stopFreezingScreen");
+        mWindowManager.stopFreezingScreen();
+        Trace.traceEnd(TRACE_TAG);
+    }
+
     private void startShowAnimation(Runnable onAnimationEnd) {
+        if (mDisableAnimations) {
+            onAnimationEnd.run();
+            return;
+        }
         asyncTraceBegin("-showAnimation", 1);
         startDialogAnimation(new AlphaAnimation(0, 1), () -> {
             asyncTraceEnd("-showAnimation", 1);
@@ -222,6 +252,11 @@
     }
 
     private void startDismissAnimation(Runnable onAnimationEnd) {
+        if (mDisableAnimations || mNeedToFreezeScreen) {
+            // animations are disabled or screen is frozen, no need to play an animation
+            onAnimationEnd.run();
+            return;
+        }
         asyncTraceBegin("-dismissAnimation", 3);
         startDialogAnimation(new AlphaAnimation(1, 0), () -> {
             asyncTraceEnd("-dismissAnimation", 3);
@@ -231,8 +266,11 @@
     }
 
     private void startProgressAnimation(Runnable onAnimationEnd) {
-        final ImageView progressCircular = findViewById(R.id.progress_circular);
-        final AnimatedVectorDrawable avd = (AnimatedVectorDrawable) progressCircular.getDrawable();
+        final AnimatedVectorDrawable avd = getSpinnerAVD();
+        if (mDisableAnimations || avd == null) {
+            onAnimationEnd.run();
+            return;
+        }
         avd.registerAnimationCallback(new Animatable2.AnimationCallback() {
             @Override
             public void onAnimationEnd(Drawable drawable) {
@@ -242,7 +280,23 @@
         avd.start();
     }
 
+    private AnimatedVectorDrawable getSpinnerAVD() {
+        final ImageView view = findViewById(R.id.progress_circular);
+        if (view != null) {
+            final Drawable drawable = view.getDrawable();
+            if (drawable instanceof AnimatedVectorDrawable) {
+                return (AnimatedVectorDrawable) drawable;
+            }
+        }
+        return null;
+    }
+
     private void startDialogAnimation(Animation animation, Runnable onAnimationEnd) {
+        final View view = findViewById(R.id.content);
+        if (mDisableAnimations || view == null) {
+            onAnimationEnd.run();
+            return;
+        }
         animation.setDuration(DIALOG_SHOW_HIDE_ANIMATION_DURATION_MS);
         animation.setAnimationListener(new Animation.AnimationListener() {
             @Override
@@ -260,7 +314,7 @@
 
             }
         });
-        findViewById(R.id.content).startAnimation(animation);
+        view.startAnimation(animation);
     }
 
     private void asyncTraceBegin(String subTag, int subCookie) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 13c42eb..ada92f5 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -957,6 +957,10 @@
         }
     }
 
+    /*package*/ void postSetA2dpSuspended(boolean enable, String eventSource) {
+        sendILMsgNoDelay(MSG_IL_SET_A2DP_SUSPENDED, SENDMSG_QUEUE, (enable ? 1 : 0), eventSource);
+    }
+
     /*package*/ void setA2dpSuspended(boolean enable, boolean internal, String eventSource) {
         if (AudioService.DEBUG_COMM_RTE) {
             Log.v(TAG, "setA2dpSuspended source: " + eventSource + ", enable: "
@@ -985,6 +989,11 @@
         }
     }
 
+    /*package*/ void postSetLeAudioSuspended(boolean enable, String eventSource) {
+        sendILMsgNoDelay(
+                MSG_IL_SET_LEAUDIO_SUSPENDED, SENDMSG_QUEUE, (enable ? 1 : 0), eventSource);
+    }
+
     /*package*/ void setLeAudioSuspended(boolean enable, boolean internal, String eventSource) {
         if (AudioService.DEBUG_COMM_RTE) {
             Log.v(TAG, "setLeAudioSuspended source: " + eventSource + ", enable: "
@@ -1795,6 +1804,12 @@
                     final int capturePreset = msg.arg1;
                     mDeviceInventory.onSaveClearPreferredDevicesForCapturePreset(capturePreset);
                 } break;
+                case MSG_IL_SET_A2DP_SUSPENDED: {
+                    setA2dpSuspended((msg.arg1 == 1), false /*internal*/, (String) msg.obj);
+                } break;
+                case MSG_IL_SET_LEAUDIO_SUSPENDED: {
+                    setLeAudioSuspended((msg.arg1 == 1), false /*internal*/, (String) msg.obj);
+                } break;
                 default:
                     Log.wtf(TAG, "Invalid message " + msg.what);
             }
@@ -1869,6 +1884,8 @@
     private static final int MSG_IL_SAVE_NDEF_DEVICE_FOR_STRATEGY = 47;
     private static final int MSG_IL_SAVE_REMOVE_NDEF_DEVICE_FOR_STRATEGY = 48;
     private static final int MSG_IL_BTLEAUDIO_TIMEOUT = 49;
+    private static final int MSG_IL_SET_A2DP_SUSPENDED = 50;
+    private static final int MSG_IL_SET_LEAUDIO_SUSPENDED = 51;
 
     private static boolean isMessageHandledUnderWakelock(int msgId) {
         switch(msgId) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 3487fc2..2039325 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -6412,7 +6412,7 @@
         final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable)
                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
                 .append(Binder.getCallingPid()).toString();
-        mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource);
+        mDeviceBroker.postSetA2dpSuspended(enable, eventSource);
     }
 
     /** @see AudioManager#setA2dpSuspended(boolean) */
@@ -6422,7 +6422,7 @@
         final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable)
                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
                 .append(Binder.getCallingPid()).toString();
-        mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource);
+        mDeviceBroker.postSetLeAudioSuspended(enable, eventSource);
     }
 
     /** @see AudioManager#isBluetoothScoOn()
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index a57dd40..9429b4c 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -57,6 +57,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
@@ -87,10 +88,11 @@
     private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3;  // unconfirmed
 
     private static final int MSG_CONFIGURE_SAFE_MEDIA = SAFE_MEDIA_VOLUME_MSG_START + 1;
-    private static final int MSG_PERSIST_SAFE_VOLUME_STATE = SAFE_MEDIA_VOLUME_MSG_START + 2;
-    private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = SAFE_MEDIA_VOLUME_MSG_START + 3;
-    private static final int MSG_PERSIST_CSD_VALUES = SAFE_MEDIA_VOLUME_MSG_START + 4;
-    /*package*/ static final int MSG_CSD_UPDATE_ATTENUATION = SAFE_MEDIA_VOLUME_MSG_START + 5;
+    private static final int MSG_CONFIGURE_SAFE_MEDIA_FORCED = SAFE_MEDIA_VOLUME_MSG_START + 2;
+    private static final int MSG_PERSIST_SAFE_VOLUME_STATE = SAFE_MEDIA_VOLUME_MSG_START + 3;
+    private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = SAFE_MEDIA_VOLUME_MSG_START + 4;
+    private static final int MSG_PERSIST_CSD_VALUES = SAFE_MEDIA_VOLUME_MSG_START + 5;
+    /*package*/ static final int MSG_CSD_UPDATE_ATTENUATION = SAFE_MEDIA_VOLUME_MSG_START + 6;
 
     private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours
 
@@ -167,7 +169,7 @@
     @NonNull private final AudioHandler mAudioHandler;
     @NonNull private final ISafeHearingVolumeController mVolumeController;
 
-    private final boolean mEnableCsd;
+    private final AtomicBoolean mEnableCsd = new AtomicBoolean(false);
 
     private final Object mCsdStateLock = new Object();
 
@@ -194,7 +196,7 @@
 
     private final ISoundDoseCallback.Stub mSoundDoseCallback = new ISoundDoseCallback.Stub() {
         public void onMomentaryExposure(float currentMel, int deviceId) {
-            if (!mEnableCsd) {
+            if (!mEnableCsd.get()) {
                 Log.w(TAG, "onMomentaryExposure: csd not supported, ignoring callback");
                 return;
             }
@@ -221,7 +223,7 @@
         }
 
         public void onNewCsdValue(float currentCsd, SoundDoseRecord[] records) {
-            if (!mEnableCsd) {
+            if (!mEnableCsd.get()) {
                 Log.w(TAG, "onNewCsdValue: csd not supported, ignoring value");
                 return;
             }
@@ -271,8 +273,6 @@
 
         mContext = context;
 
-        mEnableCsd = mContext.getResources().getBoolean(R.bool.config_audio_csd_enabled_default);
-        initCsd();
         initSafeVolumes();
 
         mSafeMediaVolumeState = mSettings.getGlobalInt(audioService.getContentResolver(),
@@ -284,6 +284,10 @@
         mSafeMediaVolumeIndex = mContext.getResources().getInteger(
                 R.integer.config_safe_media_volume_index) * 10;
 
+        mSoundDose.set(AudioSystem.getSoundDoseInterface(mSoundDoseCallback));
+        // Csd will be initially disabled until the mcc is read in onConfigureSafeMedia()
+        initCsd();
+
         mAlarmManager = (AlarmManager) mContext.getSystemService(
                 Context.ALARM_SERVICE);
     }
@@ -309,7 +313,7 @@
     }
 
     float getOutputRs2UpperBound() {
-        if (!mEnableCsd) {
+        if (!mEnableCsd.get()) {
             return 0.f;
         }
 
@@ -328,7 +332,7 @@
     }
 
     void setOutputRs2UpperBound(float rs2Value) {
-        if (!mEnableCsd) {
+        if (!mEnableCsd.get()) {
             return;
         }
 
@@ -346,7 +350,7 @@
     }
 
     float getCsd() {
-        if (!mEnableCsd) {
+        if (!mEnableCsd.get()) {
             return -1.f;
         }
 
@@ -365,7 +369,7 @@
     }
 
     void setCsd(float csd) {
-        if (!mEnableCsd) {
+        if (!mEnableCsd.get()) {
             return;
         }
 
@@ -399,7 +403,7 @@
     }
 
     void resetCsdTimeouts() {
-        if (!mEnableCsd) {
+        if (!mEnableCsd.get()) {
             return;
         }
 
@@ -415,7 +419,7 @@
     }
 
     void forceUseFrameworkMel(boolean useFrameworkMel) {
-        if (!mEnableCsd) {
+        if (!mEnableCsd.get()) {
             return;
         }
 
@@ -433,7 +437,7 @@
     }
 
     void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) {
-        if (!mEnableCsd) {
+        if (!mEnableCsd.get()) {
             return;
         }
 
@@ -453,7 +457,7 @@
     }
 
     boolean isCsdEnabled() {
-        if (!mEnableCsd) {
+        if (!mEnableCsd.get()) {
             return false;
         }
 
@@ -611,8 +615,7 @@
     }
 
     /*package*/ void configureSafeMedia(boolean forced, String caller) {
-        int msg = MSG_CONFIGURE_SAFE_MEDIA;
-
+        int msg = forced ? MSG_CONFIGURE_SAFE_MEDIA_FORCED : MSG_CONFIGURE_SAFE_MEDIA;
         mAudioHandler.removeMessages(msg);
 
         long time = 0;
@@ -622,7 +625,7 @@
         }
 
         mAudioHandler.sendMessageAtTime(
-                mAudioHandler.obtainMessage(msg, /*arg1=*/forced ? 1 : 0, /*arg2=*/0, caller),
+                mAudioHandler.obtainMessage(msg, /*arg1=*/0, /*arg2=*/0, caller),
                 time);
     }
 
@@ -664,8 +667,10 @@
 
     /*package*/ void handleMessage(Message msg) {
         switch (msg.what) {
+            case MSG_CONFIGURE_SAFE_MEDIA_FORCED:
             case MSG_CONFIGURE_SAFE_MEDIA:
-                onConfigureSafeMedia((msg.arg1 == 1), (String) msg.obj);
+                onConfigureSafeMedia((msg.what == MSG_CONFIGURE_SAFE_MEDIA_FORCED),
+                        (String) msg.obj);
                 break;
             case MSG_PERSIST_SAFE_VOLUME_STATE:
                 onPersistSafeVolumeState(msg.arg1);
@@ -695,8 +700,8 @@
     }
 
     /*package*/ void dump(PrintWriter pw) {
-        pw.print("  mEnableCsd="); pw.println(mEnableCsd);
-        if (mEnableCsd) {
+        pw.print("  mEnableCsd="); pw.println(mEnableCsd.get());
+        if (mEnableCsd.get()) {
             synchronized (mCsdStateLock) {
                 pw.print("  mCurrentCsd="); pw.println(mCurrentCsd);
             }
@@ -717,9 +722,11 @@
         pw.println();
     }
 
-    /*package*/void reset() {
+    /*package*/void  reset() {
         Log.d(TAG, "Reset the sound dose helper");
-        mSoundDose.set(AudioSystem.getSoundDoseInterface(mSoundDoseCallback));
+
+        mSoundDose.compareAndExchange(/*expectedValue=*/null,
+                AudioSystem.getSoundDoseInterface(mSoundDoseCallback));
 
         synchronized (mCsdStateLock) {
             try {
@@ -741,7 +748,7 @@
 
     private void updateDoseAttenuation(int newIndex, int device, int streamType,
             boolean isAbsoluteVolume) {
-        if (!mEnableCsd) {
+        if (!mEnableCsd.get()) {
             return;
         }
 
@@ -773,17 +780,19 @@
     }
 
     private void initCsd() {
-        if (!mEnableCsd) {
-            final ISoundDose soundDose = AudioSystem.getSoundDoseInterface(mSoundDoseCallback);
-            if (soundDose == null) {
-                Log.w(TAG,  "ISoundDose instance is null.");
-                return;
-            }
-            try {
-                soundDose.disableCsd();
-            } catch (RemoteException e) {
-                Log.e(TAG, "Cannot disable CSD", e);
-            }
+        ISoundDose soundDose = mSoundDose.get();
+        if (soundDose == null) {
+            Log.w(TAG, "ISoundDose instance is null.");
+            return;
+        }
+
+        try {
+            soundDose.setCsdEnabled(mEnableCsd.get());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Cannot disable CSD", e);
+        }
+
+        if (!mEnableCsd.get()) {
             return;
         }
 
@@ -827,7 +836,6 @@
                         SystemProperties.getBoolean("audio.safemedia.force", false)
                                 || mContext.getResources().getBoolean(
                                 com.android.internal.R.bool.config_safe_media_volume_enabled);
-
                 boolean safeMediaVolumeBypass =
                         SystemProperties.getBoolean("audio.safemedia.bypass", false);
 
@@ -858,6 +866,13 @@
                         mAudioHandler.obtainMessage(MSG_PERSIST_SAFE_VOLUME_STATE,
                                 persistedState, /*arg2=*/0,
                                 /*obj=*/null), /*delay=*/0);
+
+                boolean newEnableCsd = SystemProperties.getBoolean("audio.safemedia.force", false)
+                        || mContext.getResources().getBoolean(
+                        R.bool.config_safe_sound_dosage_enabled);
+                if (mEnableCsd.compareAndSet(!newEnableCsd, newEnableCsd)) {
+                    initCsd();
+                }
             }
         }
     }
@@ -911,7 +926,7 @@
         // legacy implementation uses mSafeMediaVolumeIndex for wired HS/HP
         // instead of computing it from the volume curves
         if ((deviceType == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE
-                || deviceType == AudioSystem.DEVICE_OUT_WIRED_HEADSET) && !mEnableCsd) {
+                || deviceType == AudioSystem.DEVICE_OUT_WIRED_HEADSET) && !mEnableCsd.get()) {
             return mSafeMediaVolumeIndex;
         }
 
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 5127d26..bf5e8ee 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -704,7 +704,8 @@
             }
 
             BiometricFrameworkStatsLogger.getInstance().authenticate(
-                    mBiometricContext.updateContext(new OperationContextExt(), isCrypto()),
+                    mBiometricContext.updateContext(new OperationContextExt(true /* isBP */),
+                            isCrypto()),
                     statsModality(),
                     BiometricsProtoEnums.ACTION_UNKNOWN,
                     BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
@@ -734,7 +735,8 @@
             }
             // Auth canceled
             BiometricFrameworkStatsLogger.getInstance().error(
-                    mBiometricContext.updateContext(new OperationContextExt(), isCrypto()),
+                    mBiometricContext.updateContext(new OperationContextExt(true /* isBP */),
+                            isCrypto()),
                     statsModality(),
                     BiometricsProtoEnums.ACTION_AUTHENTICATE,
                     BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
diff --git a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
index d1de80b..4d821e9 100644
--- a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
+++ b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
@@ -46,15 +46,17 @@
     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
     @Surface.Rotation private int mOrientation = Surface.ROTATION_0;
     private int mFoldState = IBiometricContextListener.FoldState.UNKNOWN;
+    private final boolean mIsBP;
 
-    /** Create a new empty context. */
-    public OperationContextExt() {
-        this(new OperationContext());
+    /** Create a context. */
+    public OperationContextExt(boolean isBP) {
+        this(new OperationContext(), isBP);
     }
 
     /** Create a wrapped context. */
-    public OperationContextExt(@NonNull OperationContext context) {
+    public OperationContextExt(@NonNull OperationContext context, boolean isBP) {
         mAidlContext = context;
+        mIsBP = isBP;
     }
 
     /**
@@ -268,18 +270,20 @@
     }
 
     private void setFirstSessionId(@NonNull BiometricContext biometricContext) {
-        mSessionInfo = biometricContext.getKeyguardEntrySessionInfo();
-        if (mSessionInfo != null) {
-            mAidlContext.id = mSessionInfo.getId();
-            mAidlContext.reason = OperationReason.KEYGUARD;
-            return;
-        }
-
-        mSessionInfo = biometricContext.getBiometricPromptSessionInfo();
-        if (mSessionInfo != null) {
-            mAidlContext.id = mSessionInfo.getId();
-            mAidlContext.reason = OperationReason.BIOMETRIC_PROMPT;
-            return;
+        if (mIsBP) {
+            mSessionInfo = biometricContext.getBiometricPromptSessionInfo();
+            if (mSessionInfo != null) {
+                mAidlContext.id = mSessionInfo.getId();
+                mAidlContext.reason = OperationReason.BIOMETRIC_PROMPT;
+                return;
+            }
+        } else {
+            mSessionInfo = biometricContext.getKeyguardEntrySessionInfo();
+            if (mSessionInfo != null) {
+                mAidlContext.id = mSessionInfo.getId();
+                mAidlContext.reason = OperationReason.KEYGUARD;
+                return;
+            }
         }
 
         // no session
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 7b9fc36..05ca6e4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -133,10 +133,6 @@
         binderDiedInternal(clearListener);
     }
 
-    public boolean isBiometricPrompt() {
-        return getCookie() != 0;
-    }
-
     public long getOperationId() {
         return mOperationId;
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java
index d0a4807..03658ce 100644
--- a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java
@@ -37,7 +37,7 @@
     protected final Supplier<T> mLazyDaemon;
 
     @NonNull
-    private final OperationContextExt mOperationContext = new OperationContextExt();
+    private final OperationContextExt mOperationContext;
 
     /**
      * @param context    system_server context
@@ -58,6 +58,7 @@
         super(context, token, listener, userId, owner, cookie, sensorId,
                 biometricLogger, biometricContext);
         mLazyDaemon = lazyDaemon;
+        mOperationContext = new OperationContextExt(isBiometricPrompt());
     }
 
     @Nullable
@@ -85,6 +86,10 @@
         unsubscribeBiometricContext();
     }
 
+    public boolean isBiometricPrompt() {
+        return getCookie() != 0;
+    }
+
     protected OperationContextExt getOperationContext() {
         return getBiometricContext().updateContext(mOperationContext, isCryptoOperation());
     }
diff --git a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
index 38b3233..4b847a2 100644
--- a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
+++ b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
@@ -39,18 +39,24 @@
      */
     public static boolean isCurrentOrSystemUser() {
         int callingUser = Binder.getCallingUserHandle().getIdentifier();
+        return callingUser == getCurrentUser() || callingUser == UserHandle.USER_SYSTEM;
+    }
+
+    /**
+     * Get current foreground user for Broadcast Radio Service
+     *
+     * @return foreground user id.
+     */
+    public static int getCurrentUser() {
         final long identity = Binder.clearCallingIdentity();
+        int userId = UserHandle.USER_NULL;
         try {
-            int currentUser = ActivityManager.getCurrentUser();
-            if (callingUser != currentUser && callingUser != UserHandle.USER_SYSTEM) {
-                return false;
-            }
-            return true;
+            userId = ActivityManager.getCurrentUser();
         } catch (RuntimeException e) {
             // Activity manager not running, nothing we can do assume user 0.
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
-        return false;
+        return userId;
     }
 }
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
index aab815c..adea13f 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
@@ -102,6 +102,8 @@
                 return new UnsupportedOperationException(action + ": NOT_SUPPORTED");
             case Result.TIMEOUT:
                 return new ParcelableException(new RuntimeException(action + ": TIMEOUT"));
+            case Result.CANCELED:
+                return new IllegalStateException(action + ": CANCELED");
             default:
                 return new ParcelableException(new RuntimeException(
                         action + ": unknown error (" + result + ")"));
@@ -123,6 +125,8 @@
                 return RadioTuner.TUNER_RESULT_NOT_SUPPORTED;
             case Result.TIMEOUT:
                 return RadioTuner.TUNER_RESULT_TIMEOUT;
+            case Result.CANCELED:
+                return RadioTuner.TUNER_RESULT_CANCELED;
             case Result.UNKNOWN_ERROR:
             default:
                 return RadioTuner.TUNER_RESULT_UNKNOWN_ERROR;
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
index 132fb8e..7c87c6c 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
@@ -36,11 +36,13 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.broadcastradio.RadioServiceUserController;
 import com.android.server.utils.Slogf;
 
 import java.util.ArrayList;
@@ -419,8 +421,13 @@
 
     @GuardedBy("mLock")
     private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) {
+        int currentUserId = RadioServiceUserController.getCurrentUser();
         List<TunerSession> deadSessions = null;
         for (int i = 0; i < mAidlTunerSessions.size(); i++) {
+            if (mAidlTunerSessions.valueAt(i).mUserId != currentUserId
+                    && mAidlTunerSessions.valueAt(i).mUserId != UserHandle.USER_SYSTEM) {
+                continue;
+            }
             try {
                 runnable.run(mAidlTunerSessions.valueAt(i).mCallback,
                         mAidlTunerSessions.valueAt(i).getUid());
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
index 0a3823f..beff7bd 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
@@ -46,6 +46,7 @@
 
     private final RadioLogger mLogger;
     private final RadioModule mModule;
+    final int mUserId;
     final android.hardware.radio.ITunerCallback mCallback;
     private final int mUid;
     private final IBroadcastRadio mService;
@@ -65,6 +66,7 @@
             android.hardware.radio.ITunerCallback callback) {
         mModule = Objects.requireNonNull(radioModule, "radioModule cannot be null");
         mService = Objects.requireNonNull(service, "service cannot be null");
+        mUserId = Binder.getCallingUserHandle().getIdentifier();
         mCallback = Objects.requireNonNull(callback, "callback cannot be null");
         mUid = Binder.getCallingUid();
         mLogger = new RadioLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index 59a8154..7b5cb898 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -38,12 +38,14 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.IndentingPrintWriter;
 import android.util.MutableInt;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.broadcastradio.RadioServiceUserController;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -374,8 +376,13 @@
 
     @GuardedBy("mLock")
     private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) {
+        int currentUserId = RadioServiceUserController.getCurrentUser();
         List<TunerSession> deadSessions = null;
         for (TunerSession tunerSession : mAidlTunerSessions) {
+            if (tunerSession.mUserId != currentUserId && tunerSession.mUserId
+                    != UserHandle.USER_SYSTEM) {
+                continue;
+            }
             try {
                 runnable.run(tunerSession.mCallback);
             } catch (DeadObjectException ex) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
index 204b964..1efc4a5 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
@@ -26,6 +26,7 @@
 import android.hardware.radio.ProgramList;
 import android.hardware.radio.ProgramSelector;
 import android.hardware.radio.RadioManager;
+import android.os.Binder;
 import android.os.RemoteException;
 import android.util.ArrayMap;
 import android.util.IndentingPrintWriter;
@@ -52,6 +53,7 @@
 
     private final RadioModule mModule;
     private final ITunerSession mHwSession;
+    final int mUserId;
     final android.hardware.radio.ITunerCallback mCallback;
 
     @GuardedBy("mLock")
@@ -68,6 +70,7 @@
             @NonNull android.hardware.radio.ITunerCallback callback) {
         mModule = Objects.requireNonNull(module);
         mHwSession = Objects.requireNonNull(hwSession);
+        mUserId = Binder.getCallingUserHandle().getIdentifier();
         mCallback = Objects.requireNonNull(callback);
         mEventLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);
     }
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 1f82961..6d43061 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -41,6 +41,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.BitUtils;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.RingBuffer;
@@ -278,6 +279,11 @@
         }
     }
 
+    private boolean hasWifiTransport(Network network) {
+        final NetworkCapabilities nc = mCm.getNetworkCapabilities(network);
+        return nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
+    }
+
     @Override
     public synchronized void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader,
             byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs) {
@@ -286,12 +292,21 @@
             throw new IllegalArgumentException("Prefix " + prefix
                     + " required in format <nethandle>:<interface>");
         }
+        final long netHandle = Long.parseLong(prefixParts[0]);
+        final Network network = Network.fromNetworkHandle(netHandle);
 
         final WakeupEvent event = new WakeupEvent();
         event.iface = prefixParts[1];
         event.uid = uid;
         event.ethertype = ethertype;
-        event.dstHwAddr = MacAddress.fromBytes(dstHw);
+        if (ArrayUtils.isEmpty(dstHw)) {
+            if (hasWifiTransport(network)) {
+                Log.e(TAG, "Empty mac address on WiFi transport, network: " + network);
+            }
+            event.dstHwAddr = null;
+        } else {
+            event.dstHwAddr = MacAddress.fromBytes(dstHw);
+        }
         event.srcIp = srcIp;
         event.dstIp = dstIp;
         event.ipNextHeader = ipNextHeader;
@@ -306,14 +321,12 @@
 
         final BatteryStatsInternal bsi = LocalServices.getService(BatteryStatsInternal.class);
         if (bsi != null) {
-            final long netHandle = Long.parseLong(prefixParts[0]);
             final long elapsedMs = SystemClock.elapsedRealtime() + event.timestampMs
                     - System.currentTimeMillis();
-            bsi.noteCpuWakingNetworkPacket(Network.fromNetworkHandle(netHandle), elapsedMs,
-                    event.uid);
+            bsi.noteCpuWakingNetworkPacket(network, elapsedMs, event.uid);
         }
 
-        final String dstMac = event.dstHwAddr.toString();
+        final String dstMac = String.valueOf(event.dstHwAddr);
         FrameworkStatsLog.write(FrameworkStatsLog.PACKET_WAKEUP_OCCURRED,
                 uid, event.iface, ethertype, dstMac, srcIp, dstIp, ipNextHeader, srcPort, dstPort);
     }
diff --git a/services/core/java/com/android/server/cpu/CpuMonitorService.java b/services/core/java/com/android/server/cpu/CpuMonitorService.java
index df8cfad..7ea2c1b 100644
--- a/services/core/java/com/android/server/cpu/CpuMonitorService.java
+++ b/services/core/java/com/android/server/cpu/CpuMonitorService.java
@@ -653,8 +653,17 @@
             }
 
             public int getAverageAvailableCpuFreqPercent() {
-                return (int) ((totalNormalizedAvailableCpuFreqKHz * 100.0)
+                int percent = (int) ((totalNormalizedAvailableCpuFreqKHz * 100.0)
                         / totalOnlineMaxCpuFreqKHz);
+                if (percent < 0) {
+                    // TODO(b/279478586): This case should never happen. But this case happens
+                    // rarely on certain hardware, which indicates a deeper issue. Once this
+                    // issue is reproduced, use this log to debug the issue and fix it.
+                    Slogf.wtf(TAG, "Computed negative CPU availability percent(%d) for %s ",
+                            percent, toString());
+                    return 0;
+                }
+                return percent;
             }
 
             @Override
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 378363c..774087c 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -366,7 +366,12 @@
         return getAutomaticScreenBrightness(null);
     }
 
-    float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) {
+    /**
+     * @return The current brightness recommendation calculated from the current conditions.
+     * @param brightnessEvent Event object to populate with details about why the specific
+     *                        brightness was chosen.
+     */
+    public float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) {
         if (brightnessEvent != null) {
             brightnessEvent.setLux(
                     mAmbientLuxValid ? mAmbientLux : PowerManager.BRIGHTNESS_INVALID_FLOAT);
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index a4bd6a6..46cd496 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -191,7 +191,7 @@
         }
 
         if (!(createEglContext(isProtected) && createEglSurface(isProtected, isWideColor)
-                && setScreenshotTextureAndSetViewport(hardwareBuffer))) {
+                && setScreenshotTextureAndSetViewport(hardwareBuffer, displayInfo.rotation))) {
             dismiss();
             return false;
         }
@@ -500,7 +500,8 @@
     }
 
     private boolean setScreenshotTextureAndSetViewport(
-            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer) {
+            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer,
+            @Surface.Rotation int rotation) {
         if (!attachEglContext()) {
             return false;
         }
@@ -525,14 +526,22 @@
                 s.release();
                 st.release();
             }
+            // if screen is rotated, map texture starting different corner
+            int indexDelta = (rotation == Surface.ROTATION_90) ? 2
+                            : (rotation == Surface.ROTATION_180) ? 4
+                            : (rotation == Surface.ROTATION_270) ? 6 : 0;
 
             // Set up texture coordinates for a quad.
             // We might need to change this if the texture ends up being
             // a different size from the display for some reason.
-            mTexCoordBuffer.put(0, 0f); mTexCoordBuffer.put(1, 0f);
-            mTexCoordBuffer.put(2, 0f); mTexCoordBuffer.put(3, 1f);
-            mTexCoordBuffer.put(4, 1f); mTexCoordBuffer.put(5, 1f);
-            mTexCoordBuffer.put(6, 1f); mTexCoordBuffer.put(7, 0f);
+            mTexCoordBuffer.put(indexDelta, 0f);
+            mTexCoordBuffer.put(indexDelta + 1, 0f);
+            mTexCoordBuffer.put((indexDelta + 2) % 8, 0f);
+            mTexCoordBuffer.put((indexDelta + 3) % 8, 1f);
+            mTexCoordBuffer.put((indexDelta + 4) % 8, 1f);
+            mTexCoordBuffer.put((indexDelta + 5) % 8, 1f);
+            mTexCoordBuffer.put((indexDelta + 6) % 8, 1f);
+            mTexCoordBuffer.put((indexDelta + 7) % 8, 0f);
 
             // Set up our viewport.
             GLES20.glViewport(0, 0, mDisplayWidth, mDisplayHeight);
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index a021174..ca482dc 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -2396,7 +2396,6 @@
             mHbmData.timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000;
             mHbmData.timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000;
             mHbmData.timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000;
-            mHbmData.thermalStatusLimit = convertThermalStatus(hbm.getThermalStatusLimit_all());
             mHbmData.allowInLowPowerMode = hbm.getAllowInLowPowerMode_all();
             final RefreshRateRange rr = hbm.getRefreshRate_all();
             if (rr != null) {
@@ -2972,9 +2971,6 @@
         /** Brightness level at which we transition from normal to high-brightness. */
         public float transitionPoint;
 
-        /** Enable HBM only if the thermal status is not higher than this. */
-        public @PowerManager.ThermalStatus int thermalStatusLimit;
-
         /** Whether HBM is allowed when {@code Settings.Global.LOW_POWER_MODE} is active. */
         public boolean allowInLowPowerMode;
 
@@ -2993,15 +2989,13 @@
         HighBrightnessModeData() {}
 
         HighBrightnessModeData(float minimumLux, float transitionPoint, long timeWindowMillis,
-                long timeMaxMillis, long timeMinMillis,
-                @PowerManager.ThermalStatus int thermalStatusLimit, boolean allowInLowPowerMode,
+                long timeMaxMillis, long timeMinMillis, boolean allowInLowPowerMode,
                 float minimumHdrPercentOfScreen) {
             this.minimumLux = minimumLux;
             this.transitionPoint = transitionPoint;
             this.timeWindowMillis = timeWindowMillis;
             this.timeMaxMillis = timeMaxMillis;
             this.timeMinMillis = timeMinMillis;
-            this.thermalStatusLimit = thermalStatusLimit;
             this.allowInLowPowerMode = allowInLowPowerMode;
             this.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen;
         }
@@ -3016,7 +3010,6 @@
             other.timeMaxMillis = timeMaxMillis;
             other.timeMinMillis = timeMinMillis;
             other.transitionPoint = transitionPoint;
-            other.thermalStatusLimit = thermalStatusLimit;
             other.allowInLowPowerMode = allowInLowPowerMode;
             other.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen;
         }
@@ -3029,7 +3022,6 @@
                     + ", timeWindow: " + timeWindowMillis + "ms"
                     + ", timeMax: " + timeMaxMillis + "ms"
                     + ", timeMin: " + timeMinMillis + "ms"
-                    + ", thermalStatusLimit: " + thermalStatusLimit
                     + ", allowInLowPowerMode: " + allowInLowPowerMode
                     + ", minimumHdrPercentOfScreen: " + minimumHdrPercentOfScreen
                     + "} ";
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 26b6cb0..5771a04 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2548,7 +2548,6 @@
             final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
             captureArgs = new ScreenCapture.DisplayCaptureArgs.Builder(token)
                     .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight())
-                    .setUseIdentityTransform(true)
                     .setCaptureSecureLayers(true)
                     .setAllowProtected(true)
                     .build();
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index f1efec0..0861cb5 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -83,6 +83,7 @@
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
+import java.util.Objects;
 
 /**
  * Controls the power state of the display.
@@ -167,6 +168,51 @@
 
     private static final int RINGBUFFER_MAX = 100;
 
+    private static final float[] BRIGHTNESS_RANGE_BOUNDARIES = {
+        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80,
+        90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1200,
+        1400, 1600, 1800, 2000, 2250, 2500, 2750, 3000};
+    private static final int[] BRIGHTNESS_RANGE_INDEX = {
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_UNKNOWN,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_0_1,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1_2,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2_3,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3_4,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_4_5,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_5_6,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_6_7,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_7_8,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_8_9,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_9_10,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_10_20,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_20_30,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_30_40,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_40_50,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_50_60,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_60_70,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_70_80,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_80_90,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_90_100,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_100_200,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_200_300,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_300_400,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_400_500,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_500_600,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_600_700,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_700_800,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_800_900,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_900_1000,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1000_1200,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1200_1400,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1400_1600,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1600_1800,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1800_2000,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2000_2250,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2250_2500,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2500_2750,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2750_3000,
+    };
+
     private final String mTag;
 
     private final Object mLock = new Object();
@@ -560,7 +606,7 @@
         mLastBrightnessEvent = new BrightnessEvent(mDisplayId);
         mTempBrightnessEvent = new BrightnessEvent(mDisplayId);
         mThermalBrightnessThrottlingDataId =
-            logicalDisplay.getThermalBrightnessThrottlingDataIdLocked();
+                logicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
 
         if (mDisplayId == Display.DEFAULT_DISPLAY) {
             mBatteryStats = BatteryStatsService.getService();
@@ -910,7 +956,7 @@
                 && mLogicalDisplay.getPrimaryDisplayDeviceLocked()
                 .getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL;
         final String thermalBrightnessThrottlingDataId =
-                mLogicalDisplay.getThermalBrightnessThrottlingDataIdLocked();
+                mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
         mHandler.postAtTime(() -> {
             boolean changed = false;
             if (mDisplayDevice != device) {
@@ -927,8 +973,8 @@
                 // last command that was sent to change it's state. Let's assume it is unknown so
                 // that we trigger a change immediately.
                 mPowerState.resetScreenState();
-            } else if (
-                    !mThermalBrightnessThrottlingDataId.equals(thermalBrightnessThrottlingDataId)) {
+            } else if (!Objects.equals(mThermalBrightnessThrottlingDataId,
+                    thermalBrightnessThrottlingDataId)) {
                 changed = true;
                 mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId;
                 mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
@@ -1937,8 +1983,9 @@
                     ? BrightnessEvent.FLAG_USER_SET : 0));
             Slog.i(mTag, newEvent.toString(/* includeTime= */ false));
 
-            if (userSetBrightnessChanged) {
-                logManualBrightnessEvent(newEvent);
+            if (userSetBrightnessChanged
+                    || newEvent.getReason().getReason() != BrightnessReason.REASON_TEMPORARY) {
+                logBrightnessEvent(newEvent, unthrottledBrightnessState);
             }
             if (mBrightnessEventRingBuffer != null) {
                 mBrightnessEventRingBuffer.append(newEvent);
@@ -2143,7 +2190,8 @@
                 () -> {
                     sendUpdatePowerState();
                     postBrightnessChangeRunnable();
-                }, mUniqueDisplayId, mLogicalDisplay.getThermalBrightnessThrottlingDataIdLocked(),
+                }, mUniqueDisplayId,
+                mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId,
                 ddConfig.getThermalBrightnessThrottlingDataMapByThrottlingId());
     }
 
@@ -2228,14 +2276,14 @@
                 && !mScreenOffBecauseOfProximity) {
             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
             unblockScreenOn();
-            mWindowManagerPolicy.screenTurnedOff(mDisplayId);
+            mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
         } else if (!isOff
                 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
 
             // We told policy already that screen was turning off, but now we changed our minds.
             // Complete the full state transition on -> turningOff -> off.
             unblockScreenOff();
-            mWindowManagerPolicy.screenTurnedOff(mDisplayId);
+            mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
         }
         if (!isOff
@@ -2828,6 +2876,7 @@
             pw.println("  mDisplayId=" + mDisplayId);
             pw.println("  mLeadDisplayId=" + mLeadDisplayId);
             pw.println("  mLightSensor=" + mLightSensor);
+            pw.println("  mDisplayBrightnessFollowers=" + mDisplayBrightnessFollowers);
 
             pw.println();
             pw.println("Display Power Controller Locked State:");
@@ -3090,7 +3139,63 @@
         }
     }
 
-    private void logManualBrightnessEvent(BrightnessEvent event) {
+    // Return bucket index of range_[left]_[right] where
+    // left <= nits < right
+    private int nitsToRangeIndex(float nits) {
+        for (int i = 0; i < BRIGHTNESS_RANGE_BOUNDARIES.length; i++) {
+            if (nits < BRIGHTNESS_RANGE_BOUNDARIES[i]) {
+                return BRIGHTNESS_RANGE_INDEX[i];
+            }
+        }
+        return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3000_INF;
+    }
+
+    private int convertBrightnessReasonToStatsEnum(int brightnessReason) {
+        switch(brightnessReason) {
+            case BrightnessReason.REASON_UNKNOWN:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
+            case BrightnessReason.REASON_MANUAL:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_MANUAL;
+            case BrightnessReason.REASON_DOZE:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE;
+            case BrightnessReason.REASON_DOZE_DEFAULT:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE_DEFAULT;
+            case BrightnessReason.REASON_AUTOMATIC:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_AUTOMATIC;
+            case BrightnessReason.REASON_SCREEN_OFF:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF;
+            case BrightnessReason.REASON_OVERRIDE:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_OVERRIDE;
+            case BrightnessReason.REASON_TEMPORARY:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_TEMPORARY;
+            case BrightnessReason.REASON_BOOST:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_BOOST;
+            case BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
+            case BrightnessReason.REASON_FOLLOWER:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_FOLLOWER;
+        }
+        return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
+    }
+
+    private void logBrightnessEvent(BrightnessEvent event, float unmodifiedBrightness) {
+        int modifier = event.getReason().getModifier();
+        int flags = event.getFlags();
+        // It's easier to check if the brightness is at maximum level using the brightness
+        // value untouched by any modifiers
+        boolean brightnessIsMax = unmodifiedBrightness == event.getHbmMax();
+        float brightnessInNits = convertToAdjustedNits(event.getBrightness());
         float appliedLowPowerMode = event.isLowPowerModeSet() ? event.getPowerFactor() : -1f;
         int appliedRbcStrength  = event.isRbcEnabled() ? event.getRbcStrength() : -1;
         float appliedHbmMaxNits =
@@ -3104,7 +3209,7 @@
         if (mIsDisplayInternal) {
             FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED,
                     convertToAdjustedNits(event.getInitialBrightness()),
-                    convertToAdjustedNits(event.getBrightness()),
+                    brightnessInNits,
                     event.getLux(),
                     event.getPhysicalDisplayId(),
                     event.wasShortTermModelActive(),
@@ -3113,7 +3218,21 @@
                     appliedHbmMaxNits,
                     appliedThermalCapNits,
                     event.isAutomaticBrightnessEnabled(),
-                    FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL);
+                    FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL,
+                    convertBrightnessReasonToStatsEnum(event.getReason().getReason()),
+                    nitsToRangeIndex(brightnessInNits),
+                    brightnessIsMax,
+                    event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+                    event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR,
+                    (modifier & BrightnessReason.MODIFIER_LOW_POWER) > 0,
+                    mBrightnessThrottler.getBrightnessMaxReason(),
+                    (modifier & BrightnessReason.MODIFIER_DIMMED) > 0,
+                    event.isRbcEnabled(),
+                    (flags & BrightnessEvent.FLAG_INVALID_LUX) > 0,
+                    (flags & BrightnessEvent.FLAG_DOZE_SCALE) > 0,
+                    (flags & BrightnessEvent.FLAG_USER_SET) > 0,
+                    (flags & BrightnessEvent.FLAG_IDLE_CURVE) > 0,
+                    (flags & BrightnessEvent.FLAG_LOW_POWER_MODE) > 0);
         }
     }
 
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 59e112e..3b3d5da 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -85,6 +85,7 @@
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
+import java.util.Objects;
 
 /**
  * Controls the power state of the display.
@@ -157,6 +158,51 @@
 
     private static final int RINGBUFFER_MAX = 100;
 
+    private static final float[] BRIGHTNESS_RANGE_BOUNDARIES = {
+        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80,
+        90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1200,
+        1400, 1600, 1800, 2000, 2250, 2500, 2750, 3000};
+    private static final int[] BRIGHTNESS_RANGE_INDEX = {
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_UNKNOWN,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_0_1,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1_2,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2_3,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3_4,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_4_5,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_5_6,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_6_7,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_7_8,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_8_9,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_9_10,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_10_20,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_20_30,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_30_40,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_40_50,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_50_60,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_60_70,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_70_80,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_80_90,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_90_100,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_100_200,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_200_300,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_300_400,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_400_500,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_500_600,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_600_700,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_700_800,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_800_900,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_900_1000,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1000_1200,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1200_1400,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1400_1600,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1600_1800,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1800_2000,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2000_2250,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2250_2500,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2500_2750,
+        FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2750_3000,
+    };
+
     private final String mTag;
 
     private final Object mLock = new Object();
@@ -443,7 +489,7 @@
         mAutomaticBrightnessStrategy = new AutomaticBrightnessStrategy(context, mDisplayId);
         mTag = "DisplayPowerController2[" + mDisplayId + "]";
         mThermalBrightnessThrottlingDataId =
-            logicalDisplay.getThermalBrightnessThrottlingDataIdLocked();
+                logicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
 
         mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
         mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
@@ -715,7 +761,7 @@
                 && mLogicalDisplay.getPrimaryDisplayDeviceLocked()
                 .getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL;
         final String thermalBrightnessThrottlingDataId =
-                mLogicalDisplay.getThermalBrightnessThrottlingDataIdLocked();
+                mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId;
 
         mHandler.postAtTime(() -> {
             boolean changed = false;
@@ -733,8 +779,8 @@
                 // last command that was sent to change it's state. Let's assume it is unknown so
                 // that we trigger a change immediately.
                 mPowerState.resetScreenState();
-            } else if (
-                    !mThermalBrightnessThrottlingDataId.equals(thermalBrightnessThrottlingDataId)) {
+            } else if (!Objects.equals(mThermalBrightnessThrottlingDataId,
+                    thermalBrightnessThrottlingDataId)) {
                 changed = true;
                 mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId;
                 mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(
@@ -1256,7 +1302,8 @@
         int brightnessAdjustmentFlags = 0;
         if (Float.isNaN(brightnessState)) {
             if (mAutomaticBrightnessStrategy.isAutoBrightnessEnabled()) {
-                brightnessState = mAutomaticBrightnessStrategy.getAutomaticScreenBrightness();
+                brightnessState = mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(
+                        mTempBrightnessEvent);
                 if (BrightnessUtils.isValidBrightnessValue(brightnessState)
                         || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) {
                     rawBrightnessState = mAutomaticBrightnessController
@@ -1570,8 +1617,9 @@
                     ? BrightnessEvent.FLAG_USER_SET : 0));
             Slog.i(mTag, newEvent.toString(/* includeTime= */ false));
 
-            if (userSetBrightnessChanged) {
-                logManualBrightnessEvent(newEvent);
+            if (userSetBrightnessChanged
+                    || newEvent.getReason().getReason() != BrightnessReason.REASON_TEMPORARY) {
+                logBrightnessEvent(newEvent, unthrottledBrightnessState);
             }
             if (mBrightnessEventRingBuffer != null) {
                 mBrightnessEventRingBuffer.append(newEvent);
@@ -1774,7 +1822,8 @@
                 () -> {
                     sendUpdatePowerState();
                     postBrightnessChangeRunnable();
-                }, mUniqueDisplayId, mLogicalDisplay.getThermalBrightnessThrottlingDataIdLocked(),
+                }, mUniqueDisplayId,
+                mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId,
                 ddConfig.getThermalBrightnessThrottlingDataMapByThrottlingId());
     }
 
@@ -1859,14 +1908,14 @@
                 && !mDisplayPowerProximityStateController.isScreenOffBecauseOfProximity()) {
             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
             unblockScreenOn();
-            mWindowManagerPolicy.screenTurnedOff(mDisplayId);
+            mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
         } else if (!isOff
                 && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
 
             // We told policy already that screen was turning off, but now we changed our minds.
             // Complete the full state transition on -> turningOff -> off.
             unblockScreenOff();
-            mWindowManagerPolicy.screenTurnedOff(mDisplayId);
+            mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
             setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
         }
         if (!isOff
@@ -2222,6 +2271,7 @@
             pw.println("  mDisplayId=" + mDisplayId);
             pw.println("  mLeadDisplayId=" + mLeadDisplayId);
             pw.println("  mLightSensor=" + mLightSensor);
+            pw.println("  mDisplayBrightnessFollowers=" + mDisplayBrightnessFollowers);
 
             pw.println();
             pw.println("Display Power Controller Locked State:");
@@ -2447,7 +2497,64 @@
         }
     }
 
-    private void logManualBrightnessEvent(BrightnessEvent event) {
+    // Return bucket index of range_[left]_[right] where
+    // left <= nits < right
+    private int nitsToRangeIndex(float nits) {
+        for (int i = 0; i < BRIGHTNESS_RANGE_BOUNDARIES.length; i++) {
+            if (nits < BRIGHTNESS_RANGE_BOUNDARIES[i]) {
+                return BRIGHTNESS_RANGE_INDEX[i];
+            }
+        }
+        return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3000_INF;
+    }
+
+    private int convertBrightnessReasonToStatsEnum(int brightnessReason) {
+        switch(brightnessReason) {
+            case BrightnessReason.REASON_UNKNOWN:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
+            case BrightnessReason.REASON_MANUAL:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_MANUAL;
+            case BrightnessReason.REASON_DOZE:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE;
+            case BrightnessReason.REASON_DOZE_DEFAULT:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE_DEFAULT;
+            case BrightnessReason.REASON_AUTOMATIC:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_AUTOMATIC;
+            case BrightnessReason.REASON_SCREEN_OFF:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF;
+            case BrightnessReason.REASON_OVERRIDE:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_OVERRIDE;
+            case BrightnessReason.REASON_TEMPORARY:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_TEMPORARY;
+            case BrightnessReason.REASON_BOOST:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_BOOST;
+            case BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
+            case BrightnessReason.REASON_FOLLOWER:
+                return FrameworkStatsLog
+                    .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_FOLLOWER;
+        }
+        return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
+    }
+
+    private void logBrightnessEvent(BrightnessEvent event, float unmodifiedBrightness) {
+        int modifier = event.getReason().getModifier();
+        int flags = event.getFlags();
+        // It's easier to check if the brightness is at maximum level using the brightness
+        // value untouched by any modifiers
+        boolean brightnessIsMax = unmodifiedBrightness == event.getHbmMax();
+        float brightnessInNits =
+                mDisplayBrightnessController.convertToAdjustedNits(event.getBrightness());
         float appliedLowPowerMode = event.isLowPowerModeSet() ? event.getPowerFactor() : -1f;
         int appliedRbcStrength  = event.isRbcEnabled() ? event.getRbcStrength() : -1;
         float appliedHbmMaxNits =
@@ -2461,7 +2568,7 @@
             FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED,
                     mDisplayBrightnessController
                             .convertToAdjustedNits(event.getInitialBrightness()),
-                    mDisplayBrightnessController.convertToAdjustedNits(event.getBrightness()),
+                    brightnessInNits,
                     event.getLux(),
                     event.getPhysicalDisplayId(),
                     event.wasShortTermModelActive(),
@@ -2470,7 +2577,21 @@
                     appliedHbmMaxNits,
                     appliedThermalCapNits,
                     event.isAutomaticBrightnessEnabled(),
-                    FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL);
+                    FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL,
+                    convertBrightnessReasonToStatsEnum(event.getReason().getReason()),
+                    nitsToRangeIndex(brightnessInNits),
+                    brightnessIsMax,
+                    event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+                    event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR,
+                    (modifier & BrightnessReason.MODIFIER_LOW_POWER) > 0,
+                    mBrightnessThrottler.getBrightnessMaxReason(),
+                    (modifier & BrightnessReason.MODIFIER_DIMMED) > 0,
+                    event.isRbcEnabled(),
+                    (flags & BrightnessEvent.FLAG_INVALID_LUX) > 0,
+                    (flags & BrightnessEvent.FLAG_DOZE_SCALE) > 0,
+                    (flags & BrightnessEvent.FLAG_USER_SET) > 0,
+                    (flags & BrightnessEvent.FLAG_IDLE_CURVE) > 0,
+                    (flags & BrightnessEvent.FLAG_LOW_POWER_MODE) > 0);
         }
     }
 
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java
index ca208ac..11160a5 100644
--- a/services/core/java/com/android/server/display/HighBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java
@@ -22,13 +22,8 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.IThermalEventListener;
-import android.os.IThermalService;
 import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.os.Temperature;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.MathUtils;
@@ -75,7 +70,6 @@
     private final Runnable mHbmChangeCallback;
     private final Runnable mRecalcRunnable;
     private final Clock mClock;
-    private final SkinThermalStatusObserver mSkinThermalStatusObserver;
     private final Context mContext;
     private final SettingsObserver mSettingsObserver;
     private final Injector mInjector;
@@ -100,10 +94,8 @@
 
     private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
     private boolean mIsHdrLayerPresent = false;
-
     // mMaxDesiredHdrSdrRatio should only be applied when there is a valid backlight->nits mapping
     private float mMaxDesiredHdrSdrRatio = DEFAULT_MAX_DESIRED_HDR_SDR_RATIO;
-    private boolean mIsThermalStatusWithinLimit = true;
     private boolean mIsBlockedByLowPowerMode = false;
     private int mWidth;
     private int mHeight;
@@ -138,7 +130,6 @@
         mBrightnessMax = brightnessMax;
         mHbmChangeCallback = hbmChangeCallback;
         mHighBrightnessModeMetadata = hbmMetadata;
-        mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler);
         mSettingsObserver = new SettingsObserver(mHandler);
         mRecalcRunnable = this::recalculateTimeAllowance;
         mHdrListener = new HdrListener();
@@ -261,7 +252,6 @@
 
     void stop() {
         registerHdrListener(null /*displayToken*/);
-        mSkinThermalStatusObserver.stopObserving();
         mSettingsObserver.stopObserving();
     }
 
@@ -278,15 +268,10 @@
         mDisplayStatsId = displayUniqueId.hashCode();
 
         unregisterHdrListener();
-        mSkinThermalStatusObserver.stopObserving();
         mSettingsObserver.stopObserving();
         if (deviceSupportsHbm()) {
             registerHdrListener(displayToken);
             recalculateTimeAllowance();
-            if (mHbmData.thermalStatusLimit > PowerManager.THERMAL_STATUS_NONE) {
-                mIsThermalStatusWithinLimit = true;
-                mSkinThermalStatusObserver.startObserving();
-            }
             if (!mHbmData.allowInLowPowerMode) {
                 mIsBlockedByLowPowerMode = false;
                 mSettingsObserver.startObserving();
@@ -327,7 +312,6 @@
         pw.println("  mIsTimeAvailable= " + mIsTimeAvailable);
         pw.println("  mRunningStartTimeMillis="
                 + TimeUtils.formatUptime(mHighBrightnessModeMetadata.getRunningStartTimeMillis()));
-        pw.println("  mIsThermalStatusWithinLimit=" + mIsThermalStatusWithinLimit);
         pw.println("  mIsBlockedByLowPowerMode=" + mIsBlockedByLowPowerMode);
         pw.println("  width*height=" + mWidth + "*" + mHeight);
         pw.println("  mEvents=");
@@ -344,8 +328,6 @@
             }
             lastStartTime = dumpHbmEvent(pw, event);
         }
-
-        mSkinThermalStatusObserver.dump(pw);
     }
 
     private long dumpHbmEvent(PrintWriter pw, HbmEvent event) {
@@ -367,7 +349,7 @@
         // See {@link #getHdrBrightnessValue}.
         return !mIsHdrLayerPresent
                 && (mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange
-                && mIsThermalStatusWithinLimit && !mIsBlockedByLowPowerMode);
+                && !mIsBlockedByLowPowerMode);
     }
 
     private boolean deviceSupportsHbm() {
@@ -469,7 +451,6 @@
                     + ", isAutoBrightnessEnabled: " +  mIsAutoBrightnessEnabled
                     + ", mIsTimeAvailable: " + mIsTimeAvailable
                     + ", mIsInAllowedAmbientRange: " + mIsInAllowedAmbientRange
-                    + ", mIsThermalStatusWithinLimit: " + mIsThermalStatusWithinLimit
                     + ", mIsBlockedByLowPowerMode: " + mIsBlockedByLowPowerMode
                     + ", mBrightness: " + mBrightness
                     + ", mUnthrottledBrightness: " + mUnthrottledBrightness
@@ -499,13 +480,12 @@
     }
 
     private void updateHbmStats(int newMode) {
-        final float transitionPoint = mHbmData.transitionPoint;
         int state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF;
         if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
-                && getHdrBrightnessValue() > transitionPoint) {
+                && getHdrBrightnessValue() > mHbmData.transitionPoint) {
             state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_HDR;
         } else if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT
-                && mBrightness > transitionPoint) {
+                && mBrightness > mHbmData.transitionPoint) {
             state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT;
         }
         if (state == mHbmStatsState) {
@@ -519,16 +499,6 @@
         final boolean newHbmSv =
                 (state == FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT);
         if (oldHbmSv && !newHbmSv) {
-            // HighBrightnessModeController (HBMC) currently supports throttling from two sources:
-            //     1. Internal, received from HBMC.SkinThermalStatusObserver.notifyThrottling()
-            //     2. External, received from HBMC.onBrightnessChanged()
-            // TODO(b/216373254): Deprecate internal throttling source
-            final boolean internalThermalThrottling = !mIsThermalStatusWithinLimit;
-            final boolean externalThermalThrottling =
-                mUnthrottledBrightness > transitionPoint && // We would've liked HBM brightness...
-                mBrightness <= transitionPoint &&           // ...but we got NBM, because of...
-                mThrottlingReason == BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; // ...thermals.
-
             // If more than one conditions are flipped and turn off HBM sunlight
             // visibility, only one condition will be reported to make it simple.
             if (!mIsAutoBrightnessEnabled && mIsAutoBrightnessOffByState) {
@@ -541,7 +511,7 @@
                 reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_LUX_DROP;
             } else if (!mIsTimeAvailable) {
                 reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_TIME_LIMIT;
-            } else if (internalThermalThrottling || externalThermalThrottling) {
+            } else if (isThermalThrottlingActive()) {
                 reason = FrameworkStatsLog
                                  .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_THERMAL_LIMIT;
             } else if (mIsHdrLayerPresent) {
@@ -561,6 +531,14 @@
         mHbmStatsState = state;
     }
 
+    @VisibleForTesting
+    boolean isThermalThrottlingActive() {
+        // We would've liked HBM, but we got NBM (normal brightness mode) because of thermals.
+        return mUnthrottledBrightness > mHbmData.transitionPoint
+                && mBrightness <= mHbmData.transitionPoint
+                && mThrottlingReason == BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL;
+    }
+
     private String hbmStatsStateToString(int hbmStatsState) {
         switch (hbmStatsState) {
         case FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF:
@@ -635,82 +613,6 @@
         }
     }
 
-    private final class SkinThermalStatusObserver extends IThermalEventListener.Stub {
-        private final Injector mInjector;
-        private final Handler mHandler;
-
-        private IThermalService mThermalService;
-        private boolean mStarted;
-
-        SkinThermalStatusObserver(Injector injector, Handler handler) {
-            mInjector = injector;
-            mHandler = handler;
-        }
-
-        @Override
-        public void notifyThrottling(Temperature temp) {
-            if (DEBUG) {
-                Slog.d(TAG, "New thermal throttling status "
-                        + ", current thermal status = " + temp.getStatus()
-                        + ", threshold = " + mHbmData.thermalStatusLimit);
-            }
-            mHandler.post(() -> {
-                mIsThermalStatusWithinLimit = temp.getStatus() <= mHbmData.thermalStatusLimit;
-                // This recalculates HbmMode and runs mHbmChangeCallback if the mode has changed
-                updateHbmMode();
-            });
-        }
-
-        void startObserving() {
-            if (mStarted) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Thermal status observer already started");
-                }
-                return;
-            }
-            mThermalService = mInjector.getThermalService();
-            if (mThermalService == null) {
-                Slog.w(TAG, "Could not observe thermal status. Service not available");
-                return;
-            }
-            try {
-                // We get a callback immediately upon registering so there's no need to query
-                // for the current value.
-                mThermalService.registerThermalEventListenerWithType(this, Temperature.TYPE_SKIN);
-                mStarted = true;
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to register thermal status listener", e);
-            }
-        }
-
-        void stopObserving() {
-            mIsThermalStatusWithinLimit = true;
-            if (!mStarted) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Stop skipped because thermal status observer not started");
-                }
-                return;
-            }
-            try {
-                mThermalService.unregisterThermalEventListener(this);
-                mStarted = false;
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to unregister thermal status listener", e);
-            }
-            mThermalService = null;
-        }
-
-        void dump(PrintWriter writer) {
-            writer.println("  SkinThermalStatusObserver:");
-            writer.println("    mStarted: " + mStarted);
-            if (mThermalService != null) {
-                writer.println("    ThermalService available");
-            } else {
-                writer.println("    ThermalService not available");
-            }
-        }
-    }
-
     private final class SettingsObserver extends ContentObserver {
         private final Uri mLowPowerModeSetting = Settings.Global.getUriFor(
                 Settings.Global.LOW_POWER_MODE);
@@ -766,11 +668,6 @@
             return SystemClock::uptimeMillis;
         }
 
-        public IThermalService getThermalService() {
-            return IThermalService.Stub.asInterface(
-                    ServiceManager.getService(Context.THERMAL_SERVICE));
-        }
-
         public void reportHbmStateChange(int display, int state, int reason) {
             FrameworkStatsLog.write(
                     FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED, display, state, reason);
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 0b6d1c8..e5c50e6 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -203,6 +203,7 @@
         mIsEnabled = true;
         mIsInTransition = false;
         mThermalBrightnessThrottlingDataId = DisplayDeviceConfig.DEFAULT_ID;
+        mBaseDisplayInfo.thermalBrightnessThrottlingDataId = mThermalBrightnessThrottlingDataId;
     }
 
     public void setDevicePositionLocked(int position) {
@@ -514,6 +515,7 @@
 
             mBaseDisplayInfo.layoutLimitedRefreshRate = mLayoutLimitedRefreshRate;
             mBaseDisplayInfo.thermalRefreshRateThrottling = mThermalRefreshRateThrottling;
+            mBaseDisplayInfo.thermalBrightnessThrottlingDataId = mThermalBrightnessThrottlingDataId;
 
             mPrimaryDisplayDeviceInfo = deviceInfo;
             mInfo.set(null);
@@ -886,19 +888,14 @@
     }
 
     /**
-     * @return The ID of the brightness throttling data that this display should use.
-     */
-    public String getThermalBrightnessThrottlingDataIdLocked() {
-        return mThermalBrightnessThrottlingDataId;
-    }
-
-    /**
      * @param brightnessThrottlingDataId The ID of the brightness throttling data that this
      *                                  display should use.
      */
     public void setThermalBrightnessThrottlingDataIdLocked(String brightnessThrottlingDataId) {
-        mThermalBrightnessThrottlingDataId =
-                brightnessThrottlingDataId;
+        if (!Objects.equals(brightnessThrottlingDataId, mThermalBrightnessThrottlingDataId)) {
+            mThermalBrightnessThrottlingDataId = brightnessThrottlingDataId;
+            mDirty = true;
+        }
     }
 
     /**
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 a3f8c4d..7574de8 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
@@ -437,6 +437,7 @@
      * persist the nit value, the nit value for the default display will be loaded.
      */
     private void loadNitBasedBrightnessSetting() {
+        float currentBrightnessSetting = Float.NaN;
         if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
             float brightnessNitsForDefaultDisplay =
                     mBrightnessSetting.getBrightnessNitsForDefaultDisplay();
@@ -445,15 +446,17 @@
                         brightnessNitsForDefaultDisplay);
                 if (BrightnessUtils.isValidBrightnessValue(brightnessForDefaultDisplay)) {
                     mBrightnessSetting.setBrightness(brightnessForDefaultDisplay);
-                    synchronized (mLock) {
-                        mCurrentScreenBrightness = brightnessForDefaultDisplay;
-                    }
-                    return;
+                    currentBrightnessSetting = brightnessForDefaultDisplay;
                 }
             }
         }
+
+        if (Float.isNaN(currentBrightnessSetting)) {
+            currentBrightnessSetting = getScreenBrightnessSetting();
+        }
+
         synchronized (mLock) {
-            mCurrentScreenBrightness = getScreenBrightnessSetting();
+            mCurrentScreenBrightness = currentBrightnessSetting;
         }
     }
 }
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
index f6cf866..95cbf98 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
@@ -25,6 +25,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.display.AutomaticBrightnessController;
+import com.android.server.display.brightness.BrightnessEvent;
 import com.android.server.display.brightness.BrightnessReason;
 import com.android.server.display.brightness.BrightnessUtils;
 
@@ -252,10 +253,12 @@
 
     /**
      * Evaluates the target automatic brightness of the associated display.
+     * @param brightnessEvent Event object to populate with details about why the specific
+     *                        brightness was chosen.
      */
-    public float getAutomaticScreenBrightness() {
+    public float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) {
         float brightness = (mAutomaticBrightnessController != null)
-                ? mAutomaticBrightnessController.getAutomaticScreenBrightness()
+                ? mAutomaticBrightnessController.getAutomaticScreenBrightness(brightnessEvent)
                 : PowerManager.BRIGHTNESS_INVALID_FLOAT;
         adjustAutomaticBrightnessStateIfValid(brightness);
         return brightness;
diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
index 06b7698..17f928a 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -65,7 +65,6 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.display.BrightnessSynchronizer;
-import com.android.internal.display.RefreshRateSettingsUtils;
 import com.android.internal.os.BackgroundThread;
 import com.android.server.LocalServices;
 import com.android.server.display.DisplayDeviceConfig;
@@ -103,10 +102,6 @@
     private static final int MSG_REFRESH_RATE_IN_HBM_SUNLIGHT_CHANGED = 7;
     private static final int MSG_REFRESH_RATE_IN_HBM_HDR_CHANGED = 8;
 
-    // Special ID used to indicate that given vote is to be applied globally, rather than to a
-    // specific display.
-    private static final int GLOBAL_ID = -1;
-
     private static final float FLOAT_TOLERANCE = RefreshRateRange.FLOAT_TOLERANCE;
 
     private final Object mLock = new Object();
@@ -129,10 +124,6 @@
     @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.
-    private SparseArray<SparseArray<Vote>> mVotesByDisplay;
     // A map from the display ID to the supported modes on that display.
     private SparseArray<Display.Mode[]> mSupportedModesByDisplay;
     // A map from the display ID to the default mode of that display.
@@ -146,6 +137,8 @@
 
     private final boolean mSupportsFrameRateOverride;
 
+    private final VotesStorage mVotesStorage;
+
     /**
      * The allowed refresh rate switching type. This is used by SurfaceFlinger.
      */
@@ -161,7 +154,6 @@
         mContext = context;
         mHandler = new DisplayModeDirectorHandler(handler.getLooper());
         mInjector = injector;
-        mVotesByDisplay = new SparseArray<>();
         mSupportedModesByDisplay = new SparseArray<>();
         mDefaultModeByDisplay = new SparseArray<>();
         mAppRequestObserver = new AppRequestObserver();
@@ -171,15 +163,11 @@
         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(),
+        mVotesStorage = new VotesStorage(this::notifyDesiredDisplayModeSpecsChangedLocked);
+        mDisplayObserver = new DisplayObserver(context, handler, mVotesStorage);
+        mSensorObserver = new SensorObserver(context, mVotesStorage, injector);
+        mSkinThermalStatusObserver = new SkinThermalStatusObserver(injector, mVotesStorage);
+        mHbmObserver = new HbmObserver(injector, mVotesStorage, BackgroundThread.getHandler(),
                 mDeviceConfigDisplaySettings);
         mAlwaysRespectAppRequest = false;
         mSupportsFrameRateOverride = injector.supportsFrameRateOverride();
@@ -226,29 +214,7 @@
         mLoggingEnabled = loggingEnabled;
         mBrightnessObserver.setLoggingEnabled(loggingEnabled);
         mSkinThermalStatusObserver.setLoggingEnabled(loggingEnabled);
-    }
-
-    @NonNull
-    private SparseArray<Vote> getVotesLocked(int displayId) {
-        SparseArray<Vote> displayVotes = mVotesByDisplay.get(displayId);
-        final SparseArray<Vote> votes;
-        if (displayVotes != null) {
-            votes = displayVotes.clone();
-        } else {
-            votes = new SparseArray<>();
-        }
-
-        SparseArray<Vote> globalVotes = mVotesByDisplay.get(GLOBAL_ID);
-        if (globalVotes != null) {
-            for (int i = 0; i < globalVotes.size(); i++) {
-                int priority = globalVotes.keyAt(i);
-                if (votes.indexOfKey(priority) < 0) {
-                    votes.put(priority, globalVotes.valueAt(i));
-                }
-            }
-        }
-
-        return votes;
+        mVotesStorage.setLoggingEnabled(loggingEnabled);
     }
 
     private static final class VoteSummary {
@@ -407,7 +373,7 @@
     @NonNull
     public DesiredDisplayModeSpecs getDesiredDisplayModeSpecs(int displayId) {
         synchronized (mLock) {
-            SparseArray<Vote> votes = getVotesLocked(displayId);
+            SparseArray<Vote> votes = mVotesStorage.getVotes(displayId);
             Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
             Display.Mode defaultMode = mDefaultModeByDisplay.get(displayId);
             if (modes == null || defaultMode == null) {
@@ -780,10 +746,8 @@
     @VisibleForTesting
     @Nullable
     Vote getVote(int displayId, int priority) {
-        synchronized (mLock) {
-            SparseArray<Vote> votes = getVotesLocked(displayId);
-            return votes.get(priority);
-        }
+        SparseArray<Vote> votes = mVotesStorage.getVotes(displayId);
+        return votes.get(priority);
     }
 
     /**
@@ -806,18 +770,6 @@
                 final Display.Mode mode = mDefaultModeByDisplay.valueAt(i);
                 pw.println("    " + id + " -> " + mode);
             }
-            pw.println("  mVotesByDisplay:");
-            for (int i = 0; i < mVotesByDisplay.size(); i++) {
-                pw.println("    " + mVotesByDisplay.keyAt(i) + ":");
-                SparseArray<Vote> votes = mVotesByDisplay.valueAt(i);
-                for (int p = Vote.MAX_PRIORITY; p >= Vote.MIN_PRIORITY; p--) {
-                    Vote vote = votes.get(p);
-                    if (vote == null) {
-                        continue;
-                    }
-                    pw.println("      " + Vote.priorityToString(p) + " -> " + vote);
-                }
-            }
             pw.println("  mModeSwitchingType: " + switchingTypeToString(mModeSwitchingType));
             pw.println("  mAlwaysRespectAppRequest: " + mAlwaysRespectAppRequest);
             mSettingsObserver.dumpLocked(pw);
@@ -827,44 +779,10 @@
             mHbmObserver.dumpLocked(pw);
             mSkinThermalStatusObserver.dumpLocked(pw);
         }
-
+        mVotesStorage.dump(pw);
         mSensorObserver.dump(pw);
     }
 
-    private void updateVoteLocked(int priority, Vote vote) {
-        updateVoteLocked(GLOBAL_ID, priority, vote);
-    }
-
-    private void updateVoteLocked(int displayId, int priority, Vote vote) {
-        if (mLoggingEnabled) {
-            Slog.i(TAG, "updateVoteLocked(displayId=" + displayId
-                    + ", priority=" + Vote.priorityToString(priority)
-                    + ", vote=" + vote + ")");
-        }
-        if (priority < Vote.MIN_PRIORITY || priority > Vote.MAX_PRIORITY) {
-            Slog.w(TAG, "Received a vote with an invalid priority, ignoring:"
-                    + " priority=" + Vote.priorityToString(priority)
-                    + ", vote=" + vote, new Throwable());
-            return;
-        }
-        final SparseArray<Vote> votes = getOrCreateVotesByDisplay(displayId);
-
-        if (vote != null) {
-            votes.put(priority, vote);
-        } else {
-            votes.remove(priority);
-        }
-
-        if (votes.size() == 0) {
-            if (mLoggingEnabled) {
-                Slog.i(TAG, "No votes left for display " + displayId + ", removing.");
-            }
-            mVotesByDisplay.remove(displayId);
-        }
-
-        notifyDesiredDisplayModeSpecsChangedLocked();
-    }
-
     @GuardedBy("mLock")
     private float getMaxRefreshRateLocked(int displayId) {
         Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
@@ -890,16 +808,6 @@
         }
     }
 
-    private SparseArray<Vote> getOrCreateVotesByDisplay(int displayId) {
-        if (mVotesByDisplay.indexOfKey(displayId) >= 0) {
-            return mVotesByDisplay.get(displayId);
-        } else {
-            SparseArray<Vote> votes = new SparseArray<>();
-            mVotesByDisplay.put(displayId, votes);
-            return votes;
-        }
-    }
-
     private static String switchingTypeToString(@DisplayManager.SwitchingType int type) {
         switch (type) {
             case DisplayManager.SWITCHING_TYPE_NONE:
@@ -927,7 +835,7 @@
 
     @VisibleForTesting
     void injectVotesByDisplay(SparseArray<SparseArray<Vote>> votesByDisplay) {
-        mVotesByDisplay = votesByDisplay;
+        mVotesStorage.injectVotesByDisplay(votesByDisplay);
     }
 
     @VisibleForTesting
@@ -1157,230 +1065,11 @@
     }
 
     @VisibleForTesting
-    static final class Vote {
-        // DEFAULT_RENDER_FRAME_RATE votes for render frame rate [0, DEFAULT]. As the lowest
-        // priority vote, it's overridden by all other considerations. It acts to set a default
-        // frame rate for a device.
-        public static final int PRIORITY_DEFAULT_RENDER_FRAME_RATE = 0;
-
-        // PRIORITY_FLICKER_REFRESH_RATE votes for a single refresh rate like [60,60], [90,90] or
-        // null. It is used to set a preferred refresh rate value in case the higher priority votes
-        // result is a range.
-        public static final int PRIORITY_FLICKER_REFRESH_RATE = 1;
-
-        // High-brightness-mode may need a specific range of refresh-rates to function properly.
-        public static final int PRIORITY_HIGH_BRIGHTNESS_MODE = 2;
-
-        // SETTING_MIN_RENDER_FRAME_RATE is used to propose a lower bound of the render frame rate.
-        // It votes [minRefreshRate, Float.POSITIVE_INFINITY]
-        public static final int PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE = 3;
-
-        // APP_REQUEST_RENDER_FRAME_RATE_RANGE is used to for internal apps to limit the render
-        // frame rate in certain cases, mostly to preserve power.
-        // @see android.view.WindowManager.LayoutParams#preferredMinRefreshRate
-        // @see android.view.WindowManager.LayoutParams#preferredMaxRefreshRate
-        // It votes to [preferredMinRefreshRate, preferredMaxRefreshRate].
-        public static final int PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE = 4;
-
-        // We split the app request into different priorities in case we can satisfy one desire
-        // without the other.
-
-        // Application can specify preferred refresh rate with below attrs.
-        // @see android.view.WindowManager.LayoutParams#preferredRefreshRate
-        // @see android.view.WindowManager.LayoutParams#preferredDisplayModeId
-        //
-        // When the app specifies a LayoutParams#preferredDisplayModeId, in addition to the
-        // refresh rate, it also chooses a preferred size (resolution) as part of the selected
-        // mode id. The app preference is then translated to APP_REQUEST_BASE_MODE_REFRESH_RATE and
-        // optionally to APP_REQUEST_SIZE as well, if a mode id was selected.
-        // The system also forces some apps like denylisted app to run at a lower refresh rate.
-        // @see android.R.array#config_highRefreshRateBlacklist
-        //
-        // When summarizing the votes and filtering the allowed display modes, these votes determine
-        // which mode id should be the base mode id to be sent to SurfaceFlinger:
-        // - APP_REQUEST_BASE_MODE_REFRESH_RATE is used to validate the vote summary. If a summary
-        //   includes a base mode refresh rate, but it is not in the refresh rate range, then the
-        //   summary is considered invalid so we could drop a lower priority vote and try again.
-        // - APP_REQUEST_SIZE is used to filter out display modes of a different size.
-        //
-        // The preferred refresh rate is set on the main surface of the app outside of
-        // DisplayModeDirector.
-        // @see com.android.server.wm.WindowState#updateFrameRateSelectionPriorityIfNeeded
-        public static final int PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE = 5;
-        public static final int PRIORITY_APP_REQUEST_SIZE = 6;
-
-        // SETTING_PEAK_RENDER_FRAME_RATE has a high priority and will restrict the bounds of the
-        // 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 = 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 = 11;
-
-        // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL.
-        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 = 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 = 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.
-
-        public static final int MIN_PRIORITY = PRIORITY_DEFAULT_RENDER_FRAME_RATE;
-        public static final int MAX_PRIORITY = PRIORITY_UDFPS;
-
-        // The cutoff for the app request refresh rate range. Votes with priorities lower than this
-        // value will not be considered when constructing the app request refresh rate range.
-        public static final int APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF =
-                PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE;
-
-        /**
-         * A value signifying an invalid width or height in a vote.
-         */
-        public static final int INVALID_SIZE = -1;
-
-        /**
-         * The requested width of the display in pixels, or INVALID_SIZE;
-         */
-        public final int width;
-        /**
-         * The requested height of the display in pixels, or INVALID_SIZE;
-         */
-        public final int height;
-        /**
-         * Information about the refresh rate frame rate ranges DM would like to set the display to.
-         */
-        public final RefreshRateRanges refreshRateRanges;
-
-        /**
-         * Whether refresh rate switching should be disabled (i.e. the refresh rate range is
-         * a single value).
-         */
-        public final boolean disableRefreshRateSwitching;
-
-        /**
-         * The preferred refresh rate selected by the app. It is used to validate that the summary
-         * refresh rate ranges include this value, and are not restricted by a lower priority vote.
-         */
-        public final float appRequestBaseModeRefreshRate;
-
-        public static Vote forPhysicalRefreshRates(float minRefreshRate, float maxRefreshRate) {
-            return new Vote(INVALID_SIZE, INVALID_SIZE, minRefreshRate, maxRefreshRate, 0,
-                    Float.POSITIVE_INFINITY,
-                    minRefreshRate == maxRefreshRate, 0f);
-        }
-
-        public static Vote forRenderFrameRates(float minFrameRate, float maxFrameRate) {
-            return new Vote(INVALID_SIZE, INVALID_SIZE, 0, Float.POSITIVE_INFINITY, minFrameRate,
-                    maxFrameRate,
-                    false, 0f);
-        }
-
-        public static Vote forSize(int width, int height) {
-            return new Vote(width, height, 0, Float.POSITIVE_INFINITY, 0, Float.POSITIVE_INFINITY,
-                    false,
-                    0f);
-        }
-
-        public static Vote forDisableRefreshRateSwitching() {
-            return new Vote(INVALID_SIZE, INVALID_SIZE, 0, Float.POSITIVE_INFINITY, 0,
-                    Float.POSITIVE_INFINITY, true,
-                    0f);
-        }
-
-        public static Vote forBaseModeRefreshRate(float baseModeRefreshRate) {
-            return new Vote(INVALID_SIZE, INVALID_SIZE, 0, Float.POSITIVE_INFINITY, 0,
-                    Float.POSITIVE_INFINITY, false,
-                    baseModeRefreshRate);
-        }
-
-        private Vote(int width, int height,
-                float minPhysicalRefreshRate,
-                float maxPhysicalRefreshRate,
-                float minRenderFrameRate,
-                float maxRenderFrameRate,
-                boolean disableRefreshRateSwitching,
-                float baseModeRefreshRate) {
-            this.width = width;
-            this.height = height;
-            this.refreshRateRanges = new RefreshRateRanges(
-                    new RefreshRateRange(minPhysicalRefreshRate, maxPhysicalRefreshRate),
-                    new RefreshRateRange(minRenderFrameRate, maxRenderFrameRate));
-            this.disableRefreshRateSwitching = disableRefreshRateSwitching;
-            this.appRequestBaseModeRefreshRate = baseModeRefreshRate;
-        }
-
-        public static String priorityToString(int priority) {
-            switch (priority) {
-                case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE:
-                    return "PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE";
-                case PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE:
-                    return "PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE";
-                case PRIORITY_APP_REQUEST_SIZE:
-                    return "PRIORITY_APP_REQUEST_SIZE";
-                case PRIORITY_DEFAULT_RENDER_FRAME_RATE:
-                    return "PRIORITY_DEFAULT_REFRESH_RATE";
-                case PRIORITY_FLICKER_REFRESH_RATE:
-                    return "PRIORITY_FLICKER_REFRESH_RATE";
-                case PRIORITY_FLICKER_REFRESH_RATE_SWITCH:
-                    return "PRIORITY_FLICKER_REFRESH_RATE_SWITCH";
-                case PRIORITY_HIGH_BRIGHTNESS_MODE:
-                    return "PRIORITY_HIGH_BRIGHTNESS_MODE";
-                case PRIORITY_PROXIMITY:
-                    return "PRIORITY_PROXIMITY";
-                case PRIORITY_LOW_POWER_MODE:
-                    return "PRIORITY_LOW_POWER_MODE";
-                case PRIORITY_SKIN_TEMPERATURE:
-                    return "PRIORITY_SKIN_TEMPERATURE";
-                case PRIORITY_UDFPS:
-                    return "PRIORITY_UDFPS";
-                case PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE:
-                    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";
-                case PRIORITY_LAYOUT_LIMITED_FRAME_RATE:
-                    return "PRIORITY_LAYOUT_LIMITED_FRAME_RATE";
-                default:
-                    return Integer.toString(priority);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "Vote{"
-                    + "width=" + width + ", height=" + height
-                    + ", refreshRateRanges=" + refreshRateRanges
-                    + ", disableRefreshRateSwitching=" + disableRefreshRateSwitching
-                    + ", appRequestBaseModeRefreshRate=" + appRequestBaseModeRefreshRate + "}";
-        }
-    }
-
-    @VisibleForTesting
     final class SettingsObserver extends ContentObserver {
-        private final Uri mSmoothDisplaySetting =
-                Settings.System.getUriFor(Settings.System.SMOOTH_DISPLAY);
-        private final Uri mForcePeakRefreshRateSetting =
-                Settings.System.getUriFor(Settings.System.FORCE_PEAK_REFRESH_RATE);
+        private final Uri mPeakRefreshRateSetting =
+                Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
+        private final Uri mMinRefreshRateSetting =
+                Settings.System.getUriFor(Settings.System.MIN_REFRESH_RATE);
         private final Uri mLowPowerModeSetting =
                 Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE);
         private final Uri mMatchContentFrameRateSetting =
@@ -1416,8 +1105,9 @@
 
         public void observe() {
             final ContentResolver cr = mContext.getContentResolver();
-            mInjector.registerSmoothDisplayObserver(cr, this);
-            mInjector.registerForcePeakRefreshRateObserver(cr, this);
+            mInjector.registerPeakRefreshRateObserver(cr, this);
+            cr.registerContentObserver(mMinRefreshRateSetting, false /*notifyDescendants*/, this,
+                    UserHandle.USER_SYSTEM);
             cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this,
                     UserHandle.USER_SYSTEM);
             cr.registerContentObserver(mMatchContentFrameRateSetting, false /*notifyDescendants*/,
@@ -1459,8 +1149,8 @@
         @Override
         public void onChange(boolean selfChange, Uri uri, int userId) {
             synchronized (mLock) {
-                if (mSmoothDisplaySetting.equals(uri)
-                        || mForcePeakRefreshRateSetting.equals(uri)) {
+                if (mPeakRefreshRateSetting.equals(uri)
+                        || mMinRefreshRateSetting.equals(uri)) {
                     updateRefreshRateSettingLocked();
                 } else if (mLowPowerModeSetting.equals(uri)) {
                     updateLowPowerModeSettingLocked();
@@ -1510,14 +1200,17 @@
             } else {
                 vote = null;
             }
-            updateVoteLocked(Vote.PRIORITY_LOW_POWER_MODE, vote);
+            mVotesStorage.updateGlobalVote(Vote.PRIORITY_LOW_POWER_MODE, vote);
             mBrightnessObserver.onLowPowerModeEnabledLocked(inLowPowerMode);
         }
 
         private void updateRefreshRateSettingLocked() {
-            updateRefreshRateSettingLocked(RefreshRateSettingsUtils.getMinRefreshRate(mContext),
-                    RefreshRateSettingsUtils.getPeakRefreshRate(mContext, mDefaultPeakRefreshRate),
-                    mDefaultRefreshRate);
+            final ContentResolver cr = mContext.getContentResolver();
+            float minRefreshRate = Settings.System.getFloatForUser(cr,
+                    Settings.System.MIN_REFRESH_RATE, 0f, cr.getUserId());
+            float peakRefreshRate = Settings.System.getFloatForUser(cr,
+                    Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate, cr.getUserId());
+            updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate);
         }
 
         private void updateRefreshRateSettingLocked(
@@ -1529,13 +1222,14 @@
             Vote peakVote = peakRefreshRate == 0f
                     ? null
                     : Vote.forRenderFrameRates(0f, Math.max(minRefreshRate, peakRefreshRate));
-            updateVoteLocked(Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE, peakVote);
-            updateVoteLocked(Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE,
+            mVotesStorage.updateGlobalVote(Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE,
+                    peakVote);
+            mVotesStorage.updateGlobalVote(Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE,
                     Vote.forRenderFrameRates(minRefreshRate, Float.POSITIVE_INFINITY));
             Vote defaultVote =
                     defaultRefreshRate == 0f
                             ? null : Vote.forRenderFrameRates(0f, defaultRefreshRate);
-            updateVoteLocked(Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE, defaultVote);
+            mVotesStorage.updateGlobalVote(Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE, defaultVote);
 
             float maxRefreshRate;
             if (peakRefreshRate == 0f && defaultRefreshRate == 0f) {
@@ -1619,9 +1313,9 @@
                 sizeVote = null;
             }
 
-            updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE,
+            mVotesStorage.updateVote(displayId, Vote.PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE,
                     baseModeRefreshRateVote);
-            updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);
+            mVotesStorage.updateVote(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);
         }
 
         private void setAppPreferredRefreshRateRangeLocked(int displayId,
@@ -1652,11 +1346,8 @@
                 mAppPreferredRefreshRateRangeByDisplay.remove(displayId);
                 vote = null;
             }
-            synchronized (mLock) {
-                updateVoteLocked(displayId,
-                        Vote.PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE,
-                        vote);
-            }
+            mVotesStorage.updateVote(displayId, Vote.PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE,
+                    vote);
         }
 
         private Display.Mode findModeByIdLocked(int displayId, int modeId) {
@@ -1696,12 +1387,12 @@
         // calling into us already holding its own lock.
         private final Context mContext;
         private final Handler mHandler;
-        private final BallotBox mBallotBox;
+        private final VotesStorage mVotesStorage;
 
-        DisplayObserver(Context context, Handler handler, BallotBox ballotBox) {
+        DisplayObserver(Context context, Handler handler, VotesStorage votesStorage) {
             mContext = context;
             mHandler = handler;
-            mBallotBox = ballotBox;
+            mVotesStorage = votesStorage;
         }
 
         public void observe() {
@@ -1750,17 +1441,18 @@
             updateLayoutLimitedFrameRate(displayId, displayInfo);
         }
 
+        @Nullable
         private DisplayInfo getDisplayInfo(int displayId) {
             DisplayInfo info = new DisplayInfo();
-            mInjector.getDisplayInfo(displayId, info);
-            return info;
+            // Display info might be invalid, in this case return null
+            return mInjector.getDisplayInfo(displayId, info) ? info : null;
         }
 
         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);
+            mVotesStorage.updateVote(displayId, Vote.PRIORITY_LAYOUT_LIMITED_FRAME_RATE, vote);
         }
 
         private void updateDisplayModes(int displayId, @Nullable DisplayInfo info) {
@@ -2082,8 +1774,8 @@
                 updateSensorStatus();
                 if (!changeable) {
                     // Revoke previous vote from BrightnessObserver
-                    updateVoteLocked(Vote.PRIORITY_FLICKER_REFRESH_RATE, null);
-                    updateVoteLocked(Vote.PRIORITY_FLICKER_REFRESH_RATE_SWITCH, null);
+                    mVotesStorage.updateGlobalVote(Vote.PRIORITY_FLICKER_REFRESH_RATE, null);
+                    mVotesStorage.updateGlobalVote(Vote.PRIORITY_FLICKER_REFRESH_RATE_SWITCH, null);
                 }
             }
         }
@@ -2408,8 +2100,9 @@
                 Slog.d(TAG, "Display brightness " + mBrightness + ", ambient lux " +  mAmbientLux
                         + ", Vote " + refreshRateVote);
             }
-            updateVoteLocked(Vote.PRIORITY_FLICKER_REFRESH_RATE, refreshRateVote);
-            updateVoteLocked(Vote.PRIORITY_FLICKER_REFRESH_RATE_SWITCH, refreshRateSwitchingVote);
+            mVotesStorage.updateGlobalVote(Vote.PRIORITY_FLICKER_REFRESH_RATE, refreshRateVote);
+            mVotesStorage.updateGlobalVote(Vote.PRIORITY_FLICKER_REFRESH_RATE_SWITCH,
+                    refreshRateSwitchingVote);
         }
 
         private boolean hasValidLowZone() {
@@ -2677,7 +2370,7 @@
             } else {
                 vote = null;
             }
-            DisplayModeDirector.this.updateVoteLocked(displayId, votePriority, vote);
+            mVotesStorage.updateVote(displayId, votePriority, vote);
         }
 
         void dumpLocked(PrintWriter pw) {
@@ -2703,7 +2396,7 @@
         private final String mProximitySensorName = null;
         private final String mProximitySensorType = Sensor.STRING_TYPE_PROXIMITY;
 
-        private final BallotBox mBallotBox;
+        private final VotesStorage mVotesStorage;
         private final Context mContext;
         private final Injector mInjector;
         @GuardedBy("mSensorObserverLock")
@@ -2715,9 +2408,9 @@
         @GuardedBy("mSensorObserverLock")
         private boolean mIsProxActive = false;
 
-        SensorObserver(Context context, BallotBox ballotBox, Injector injector) {
+        SensorObserver(Context context, VotesStorage votesStorage, Injector injector) {
             mContext = context;
-            mBallotBox = ballotBox;
+            mVotesStorage = votesStorage;
             mInjector = injector;
         }
 
@@ -2763,7 +2456,7 @@
                         vote = Vote.forPhysicalRefreshRates(rate.min, rate.max);
                     }
                 }
-                mBallotBox.vote(displayId, Vote.PRIORITY_PROXIMITY, vote);
+                mVotesStorage.updateVote(displayId, Vote.PRIORITY_PROXIMITY, vote);
             }
         }
 
@@ -2816,7 +2509,7 @@
      * DisplayManagerInternal but originate in the display-device-config file.
      */
     public class HbmObserver implements DisplayManager.DisplayListener {
-        private final BallotBox mBallotBox;
+        private final VotesStorage mVotesStorage;
         private final Handler mHandler;
         private final SparseIntArray mHbmMode = new SparseIntArray();
         private final SparseBooleanArray mHbmActive = new SparseBooleanArray();
@@ -2827,10 +2520,10 @@
 
         private DisplayManagerInternal mDisplayManagerInternal;
 
-        HbmObserver(Injector injector, BallotBox ballotBox, Handler handler,
+        HbmObserver(Injector injector, VotesStorage votesStorage, Handler handler,
                 DeviceConfigDisplaySettings displaySettings) {
             mInjector = injector;
-            mBallotBox = ballotBox;
+            mVotesStorage = votesStorage;
             mHandler = handler;
             mDeviceConfigDisplaySettings = displaySettings;
         }
@@ -2900,7 +2593,7 @@
 
         @Override
         public void onDisplayRemoved(int displayId) {
-            mBallotBox.vote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, null);
+            mVotesStorage.updateVote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, null);
             mHbmMode.delete(displayId);
             mHbmActive.delete(displayId);
         }
@@ -2967,7 +2660,7 @@
                 }
 
             }
-            mBallotBox.vote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, vote);
+            mVotesStorage.updateVote(displayId, Vote.PRIORITY_HIGH_BRIGHTNESS_MODE, vote);
         }
 
         void dumpLocked(PrintWriter pw) {
@@ -3150,17 +2843,12 @@
     }
 
     interface Injector {
-        Uri SMOOTH_DISPLAY_URI = Settings.System.getUriFor(Settings.System.SMOOTH_DISPLAY);
-        Uri FORCE_PEAK_REFRESH_RATE_URI =
-                Settings.System.getUriFor(Settings.System.FORCE_PEAK_REFRESH_RATE);
+        Uri PEAK_REFRESH_RATE_URI = Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
 
         @NonNull
         DeviceConfigInterface getDeviceConfig();
 
-        void registerSmoothDisplayObserver(@NonNull ContentResolver cr,
-                @NonNull ContentObserver observer);
-
-        void registerForcePeakRefreshRateObserver(@NonNull ContentResolver cr,
+        void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
                 @NonNull ContentObserver observer);
 
         void registerDisplayListener(@NonNull DisplayManager.DisplayListener listener,
@@ -3200,16 +2888,9 @@
         }
 
         @Override
-        public void registerSmoothDisplayObserver(@NonNull ContentResolver cr,
+        public void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
                 @NonNull ContentObserver observer) {
-            cr.registerContentObserver(SMOOTH_DISPLAY_URI, false /*notifyDescendants*/,
-                    observer, UserHandle.USER_SYSTEM);
-        }
-
-        @Override
-        public void registerForcePeakRefreshRateObserver(@NonNull ContentResolver cr,
-                @NonNull ContentObserver observer) {
-            cr.registerContentObserver(FORCE_PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/,
+            cr.registerContentObserver(PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/,
                     observer, UserHandle.USER_SYSTEM);
         }
 
@@ -3298,8 +2979,4 @@
                     ServiceManager.getService(Context.THERMAL_SERVICE));
         }
     }
-
-    interface BallotBox {
-        void vote(int displayId, int priority, Vote vote);
-    }
 }
diff --git a/services/core/java/com/android/server/display/mode/SkinThermalStatusObserver.java b/services/core/java/com/android/server/display/mode/SkinThermalStatusObserver.java
index 8a3b329..58e1550 100644
--- a/services/core/java/com/android/server/display/mode/SkinThermalStatusObserver.java
+++ b/services/core/java/com/android/server/display/mode/SkinThermalStatusObserver.java
@@ -37,7 +37,7 @@
         DisplayManager.DisplayListener {
     private static final String TAG = "SkinThermalStatusObserver";
 
-    private final DisplayModeDirector.BallotBox mBallotBox;
+    private final VotesStorage mVotesStorage;
     private final DisplayModeDirector.Injector mInjector;
 
     private boolean mLoggingEnabled;
@@ -52,15 +52,15 @@
             mThermalThrottlingByDisplay = new SparseArray<>();
 
     SkinThermalStatusObserver(DisplayModeDirector.Injector injector,
-            DisplayModeDirector.BallotBox ballotBox) {
-        this(injector, ballotBox, BackgroundThread.getHandler());
+            VotesStorage votesStorage) {
+        this(injector, votesStorage, BackgroundThread.getHandler());
     }
 
     @VisibleForTesting
     SkinThermalStatusObserver(DisplayModeDirector.Injector injector,
-            DisplayModeDirector.BallotBox ballotBox, Handler handler) {
+            VotesStorage votesStorage, Handler handler) {
         mInjector = injector;
-        mBallotBox = ballotBox;
+        mVotesStorage = votesStorage;
         mHandler = handler;
     }
 
@@ -112,8 +112,8 @@
     public void onDisplayRemoved(int displayId) {
         synchronized (mThermalObserverLock) {
             mThermalThrottlingByDisplay.remove(displayId);
-            mHandler.post(() -> mBallotBox.vote(displayId,
-                    DisplayModeDirector.Vote.PRIORITY_SKIN_TEMPERATURE, null));
+            mHandler.post(() -> mVotesStorage.updateVote(displayId,
+                    Vote.PRIORITY_SKIN_TEMPERATURE, null));
         }
         if (mLoggingEnabled) {
             Slog.d(TAG, "Display removed and voted: displayId=" + displayId);
@@ -218,11 +218,11 @@
         SurfaceControl.RefreshRateRange foundRange = findBestMatchingRefreshRateRange(currentStatus,
                 throttlingMap);
         // if status <= currentStatus not found in the map reset vote
-        DisplayModeDirector.Vote vote = null;
+        Vote vote = null;
         if (foundRange != null) { // otherwise vote with found range
-            vote = DisplayModeDirector.Vote.forRenderFrameRates(foundRange.min, foundRange.max);
+            vote = Vote.forRenderFrameRates(foundRange.min, foundRange.max);
         }
-        mBallotBox.vote(displayId, DisplayModeDirector.Vote.PRIORITY_SKIN_TEMPERATURE, vote);
+        mVotesStorage.updateVote(displayId, Vote.PRIORITY_SKIN_TEMPERATURE, vote);
         if (mLoggingEnabled) {
             Slog.d(TAG, "Voted: vote=" + vote + ", display =" + displayId);
         }
@@ -244,11 +244,11 @@
 
     private void fallbackReportThrottlingIfNeeded(int displayId,
             @Temperature.ThrottlingStatus int currentStatus) {
-        DisplayModeDirector.Vote vote = null;
+        Vote vote = null;
         if (currentStatus >= Temperature.THROTTLING_CRITICAL) {
-            vote = DisplayModeDirector.Vote.forRenderFrameRates(0f, 60f);
+            vote = Vote.forRenderFrameRates(0f, 60f);
         }
-        mBallotBox.vote(displayId, DisplayModeDirector.Vote.PRIORITY_SKIN_TEMPERATURE, vote);
+        mVotesStorage.updateVote(displayId, Vote.PRIORITY_SKIN_TEMPERATURE, vote);
         if (mLoggingEnabled) {
             Slog.d(TAG, "Voted(fallback): vote=" + vote + ", display =" + displayId);
         }
diff --git a/services/core/java/com/android/server/display/mode/Vote.java b/services/core/java/com/android/server/display/mode/Vote.java
new file mode 100644
index 0000000..a42d8f2
--- /dev/null
+++ b/services/core/java/com/android/server/display/mode/Vote.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.mode;
+
+import android.view.SurfaceControl;
+
+final class Vote {
+    // DEFAULT_RENDER_FRAME_RATE votes for render frame rate [0, DEFAULT]. As the lowest
+    // priority vote, it's overridden by all other considerations. It acts to set a default
+    // frame rate for a device.
+    static final int PRIORITY_DEFAULT_RENDER_FRAME_RATE = 0;
+
+    // PRIORITY_FLICKER_REFRESH_RATE votes for a single refresh rate like [60,60], [90,90] or
+    // null. It is used to set a preferred refresh rate value in case the higher priority votes
+    // result is a range.
+    static final int PRIORITY_FLICKER_REFRESH_RATE = 1;
+
+    // High-brightness-mode may need a specific range of refresh-rates to function properly.
+    static final int PRIORITY_HIGH_BRIGHTNESS_MODE = 2;
+
+    // SETTING_MIN_RENDER_FRAME_RATE is used to propose a lower bound of the render frame rate.
+    // It votes [minRefreshRate, Float.POSITIVE_INFINITY]
+    static final int PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE = 3;
+
+    // APP_REQUEST_RENDER_FRAME_RATE_RANGE is used to for internal apps to limit the render
+    // frame rate in certain cases, mostly to preserve power.
+    // @see android.view.WindowManager.LayoutParams#preferredMinRefreshRate
+    // @see android.view.WindowManager.LayoutParams#preferredMaxRefreshRate
+    // It votes to [preferredMinRefreshRate, preferredMaxRefreshRate].
+    static final int PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE = 4;
+
+    // We split the app request into different priorities in case we can satisfy one desire
+    // without the other.
+
+    // Application can specify preferred refresh rate with below attrs.
+    // @see android.view.WindowManager.LayoutParams#preferredRefreshRate
+    // @see android.view.WindowManager.LayoutParams#preferredDisplayModeId
+    //
+    // When the app specifies a LayoutParams#preferredDisplayModeId, in addition to the
+    // refresh rate, it also chooses a preferred size (resolution) as part of the selected
+    // mode id. The app preference is then translated to APP_REQUEST_BASE_MODE_REFRESH_RATE and
+    // optionally to APP_REQUEST_SIZE as well, if a mode id was selected.
+    // The system also forces some apps like denylisted app to run at a lower refresh rate.
+    // @see android.R.array#config_highRefreshRateBlacklist
+    //
+    // When summarizing the votes and filtering the allowed display modes, these votes determine
+    // which mode id should be the base mode id to be sent to SurfaceFlinger:
+    // - APP_REQUEST_BASE_MODE_REFRESH_RATE is used to validate the vote summary. If a summary
+    //   includes a base mode refresh rate, but it is not in the refresh rate range, then the
+    //   summary is considered invalid so we could drop a lower priority vote and try again.
+    // - APP_REQUEST_SIZE is used to filter out display modes of a different size.
+    //
+    // The preferred refresh rate is set on the main surface of the app outside of
+    // DisplayModeDirector.
+    // @see com.android.server.wm.WindowState#updateFrameRateSelectionPriorityIfNeeded
+    static final int PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE = 5;
+    static final int PRIORITY_APP_REQUEST_SIZE = 6;
+
+    // SETTING_PEAK_RENDER_FRAME_RATE has a high priority and will restrict the bounds of the
+    // rest of low priority voters. It votes [0, max(PEAK, MIN)]
+    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
+    static final int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 8;
+
+    // For concurrent displays we want to limit refresh rate on all displays
+    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.
+    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.
+    static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 11;
+
+    // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL.
+    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.
+    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.
+    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.
+
+    static final int MIN_PRIORITY = PRIORITY_DEFAULT_RENDER_FRAME_RATE;
+    static final int MAX_PRIORITY = PRIORITY_UDFPS;
+
+    // The cutoff for the app request refresh rate range. Votes with priorities lower than this
+    // value will not be considered when constructing the app request refresh rate range.
+    static final int APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF =
+            PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE;
+
+    /**
+     * A value signifying an invalid width or height in a vote.
+     */
+    static final int INVALID_SIZE = -1;
+
+    /**
+     * The requested width of the display in pixels, or INVALID_SIZE;
+     */
+    public final int width;
+    /**
+     * The requested height of the display in pixels, or INVALID_SIZE;
+     */
+    public final int height;
+    /**
+     * Information about the refresh rate frame rate ranges DM would like to set the display to.
+     */
+    public final SurfaceControl.RefreshRateRanges refreshRateRanges;
+
+    /**
+     * Whether refresh rate switching should be disabled (i.e. the refresh rate range is
+     * a single value).
+     */
+    public final boolean disableRefreshRateSwitching;
+
+    /**
+     * The preferred refresh rate selected by the app. It is used to validate that the summary
+     * refresh rate ranges include this value, and are not restricted by a lower priority vote.
+     */
+    public final float appRequestBaseModeRefreshRate;
+
+    static Vote forPhysicalRefreshRates(float minRefreshRate, float maxRefreshRate) {
+        return new Vote(INVALID_SIZE, INVALID_SIZE, minRefreshRate, maxRefreshRate, 0,
+                Float.POSITIVE_INFINITY,
+                minRefreshRate == maxRefreshRate, 0f);
+    }
+
+    static Vote forRenderFrameRates(float minFrameRate, float maxFrameRate) {
+        return new Vote(INVALID_SIZE, INVALID_SIZE, 0, Float.POSITIVE_INFINITY, minFrameRate,
+                maxFrameRate,
+                false, 0f);
+    }
+
+    static Vote forSize(int width, int height) {
+        return new Vote(width, height, 0, Float.POSITIVE_INFINITY, 0, Float.POSITIVE_INFINITY,
+                false,
+                0f);
+    }
+
+    static Vote forDisableRefreshRateSwitching() {
+        return new Vote(INVALID_SIZE, INVALID_SIZE, 0, Float.POSITIVE_INFINITY, 0,
+                Float.POSITIVE_INFINITY, true,
+                0f);
+    }
+
+    static Vote forBaseModeRefreshRate(float baseModeRefreshRate) {
+        return new Vote(INVALID_SIZE, INVALID_SIZE, 0, Float.POSITIVE_INFINITY, 0,
+                Float.POSITIVE_INFINITY, false,
+                baseModeRefreshRate);
+    }
+
+    private Vote(int width, int height,
+            float minPhysicalRefreshRate,
+            float maxPhysicalRefreshRate,
+            float minRenderFrameRate,
+            float maxRenderFrameRate,
+            boolean disableRefreshRateSwitching,
+            float baseModeRefreshRate) {
+        this.width = width;
+        this.height = height;
+        this.refreshRateRanges = new SurfaceControl.RefreshRateRanges(
+                new SurfaceControl.RefreshRateRange(minPhysicalRefreshRate, maxPhysicalRefreshRate),
+                new SurfaceControl.RefreshRateRange(minRenderFrameRate, maxRenderFrameRate));
+        this.disableRefreshRateSwitching = disableRefreshRateSwitching;
+        this.appRequestBaseModeRefreshRate = baseModeRefreshRate;
+    }
+
+    static String priorityToString(int priority) {
+        switch (priority) {
+            case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE:
+                return "PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE";
+            case PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE:
+                return "PRIORITY_APP_REQUEST_RENDER_FRAME_RATE_RANGE";
+            case PRIORITY_APP_REQUEST_SIZE:
+                return "PRIORITY_APP_REQUEST_SIZE";
+            case PRIORITY_DEFAULT_RENDER_FRAME_RATE:
+                return "PRIORITY_DEFAULT_REFRESH_RATE";
+            case PRIORITY_FLICKER_REFRESH_RATE:
+                return "PRIORITY_FLICKER_REFRESH_RATE";
+            case PRIORITY_FLICKER_REFRESH_RATE_SWITCH:
+                return "PRIORITY_FLICKER_REFRESH_RATE_SWITCH";
+            case PRIORITY_HIGH_BRIGHTNESS_MODE:
+                return "PRIORITY_HIGH_BRIGHTNESS_MODE";
+            case PRIORITY_PROXIMITY:
+                return "PRIORITY_PROXIMITY";
+            case PRIORITY_LOW_POWER_MODE:
+                return "PRIORITY_LOW_POWER_MODE";
+            case PRIORITY_SKIN_TEMPERATURE:
+                return "PRIORITY_SKIN_TEMPERATURE";
+            case PRIORITY_UDFPS:
+                return "PRIORITY_UDFPS";
+            case PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE:
+                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";
+            case PRIORITY_LAYOUT_LIMITED_FRAME_RATE:
+                return "PRIORITY_LAYOUT_LIMITED_FRAME_RATE";
+            default:
+                return Integer.toString(priority);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Vote: {"
+                + "width: " + width + ", height: " + height
+                + ", refreshRateRanges: " + refreshRateRanges
+                + ", disableRefreshRateSwitching: " + disableRefreshRateSwitching
+                + ", appRequestBaseModeRefreshRate: "  + appRequestBaseModeRefreshRate + "}";
+    }
+}
diff --git a/services/core/java/com/android/server/display/mode/VotesStorage.java b/services/core/java/com/android/server/display/mode/VotesStorage.java
new file mode 100644
index 0000000..dadcebe
--- /dev/null
+++ b/services/core/java/com/android/server/display/mode/VotesStorage.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 com.android.server.display.mode;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+
+class VotesStorage {
+    private static final String TAG = "VotesStorage";
+    // Special ID used to indicate that given vote is to be applied globally, rather than to a
+    // specific display.
+    private static final int GLOBAL_ID = -1;
+
+    private boolean mLoggingEnabled;
+
+    private final Listener mListener;
+
+    private final Object mStorageLock = new Object();
+    // 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.
+    @GuardedBy("mStorageLock")
+    private final SparseArray<SparseArray<Vote>> mVotesByDisplay = new SparseArray<>();
+
+    VotesStorage(@NonNull Listener listener) {
+        mListener = listener;
+    }
+    /** sets logging enabled/disabled for this class */
+    void setLoggingEnabled(boolean loggingEnabled) {
+        mLoggingEnabled = loggingEnabled;
+    }
+    /**
+     * gets all votes for specific display, note that global display votes are also added to result
+     */
+    @NonNull
+    SparseArray<Vote> getVotes(int displayId) {
+        SparseArray<Vote> votesLocal;
+        SparseArray<Vote> globalVotesLocal;
+        synchronized (mStorageLock) {
+            SparseArray<Vote> displayVotes = mVotesByDisplay.get(displayId);
+            votesLocal = displayVotes != null ? displayVotes.clone() : new SparseArray<>();
+            SparseArray<Vote> globalVotes = mVotesByDisplay.get(GLOBAL_ID);
+            globalVotesLocal = globalVotes != null ? globalVotes.clone() : new SparseArray<>();
+        }
+        for (int i = 0; i < globalVotesLocal.size(); i++) {
+            int priority = globalVotesLocal.keyAt(i);
+            if (!votesLocal.contains(priority)) {
+                votesLocal.put(priority, globalVotesLocal.valueAt(i));
+            }
+        }
+        return votesLocal;
+    }
+
+    /** updates vote storage for all displays */
+    void updateGlobalVote(int priority, @Nullable Vote vote) {
+        updateVote(GLOBAL_ID, priority, vote);
+    }
+
+    /** updates vote storage */
+    void updateVote(int displayId, int priority, @Nullable Vote vote) {
+        if (mLoggingEnabled) {
+            Slog.i(TAG, "updateVoteLocked(displayId=" + displayId
+                    + ", priority=" + Vote.priorityToString(priority)
+                    + ", vote=" + vote + ")");
+        }
+        if (priority < Vote.MIN_PRIORITY || priority > Vote.MAX_PRIORITY) {
+            Slog.w(TAG, "Received a vote with an invalid priority, ignoring:"
+                    + " priority=" + Vote.priorityToString(priority)
+                    + ", vote=" + vote);
+            return;
+        }
+        SparseArray<Vote> votes;
+        synchronized (mStorageLock) {
+            if (mVotesByDisplay.contains(displayId)) {
+                votes = mVotesByDisplay.get(displayId);
+            } else {
+                votes = new SparseArray<>();
+                mVotesByDisplay.put(displayId, votes);
+            }
+            if (vote != null) {
+                votes.put(priority, vote);
+            } else {
+                votes.remove(priority);
+            }
+        }
+        if (mLoggingEnabled) {
+            Slog.i(TAG, "Updated votes for display=" + displayId + " votes=" + votes);
+        }
+        mListener.onChanged();
+    }
+
+    /** dump class values, for debugging */
+    void dump(@NonNull PrintWriter pw) {
+        SparseArray<SparseArray<Vote>> votesByDisplayLocal = new SparseArray<>();
+        synchronized (mStorageLock) {
+            for (int i = 0; i < mVotesByDisplay.size(); i++) {
+                votesByDisplayLocal.put(mVotesByDisplay.keyAt(i),
+                        mVotesByDisplay.valueAt(i).clone());
+            }
+        }
+        pw.println("  mVotesByDisplay:");
+        for (int i = 0; i < votesByDisplayLocal.size(); i++) {
+            SparseArray<Vote> votes = votesByDisplayLocal.valueAt(i);
+            if (votes.size() == 0) {
+                continue;
+            }
+            pw.println("    " + votesByDisplayLocal.keyAt(i) + ":");
+            for (int p = Vote.MAX_PRIORITY; p >= Vote.MIN_PRIORITY; p--) {
+                Vote vote = votes.get(p);
+                if (vote == null) {
+                    continue;
+                }
+                pw.println("      " + Vote.priorityToString(p) + " -> " + vote);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    void injectVotesByDisplay(SparseArray<SparseArray<Vote>> votesByDisplay) {
+        synchronized (mStorageLock) {
+            mVotesByDisplay.clear();
+            for (int i = 0; i < votesByDisplay.size(); i++) {
+                mVotesByDisplay.put(votesByDisplay.keyAt(i), votesByDisplay.valueAt(i));
+            }
+        }
+    }
+
+    interface Listener {
+        void onChanged();
+    }
+}
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index de10b1b..6d70d21 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -345,6 +345,7 @@
         if (!mCurrentDream.mIsPreviewMode && !mSentStartBroadcast) {
             mContext.sendBroadcastAsUser(mDreamingStartedIntent, UserHandle.ALL,
                     null /* receiverPermission */, mDreamingStartedStoppedOptions);
+            mListener.onDreamStarted(mCurrentDream.mToken);
             mSentStartBroadcast = true;
         }
     }
@@ -353,6 +354,7 @@
      * Callback interface to be implemented by the {@link DreamManagerService}.
      */
     public interface Listener {
+        void onDreamStarted(Binder token);
         void onDreamStopped(Binder token);
     }
 
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 0e26d46..d2dcc50 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -84,6 +84,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
 
 /**
  * Service api for managing dreams.
@@ -341,10 +342,24 @@
     }
 
     private void reportKeepDreamingWhenUnpluggingChanged(boolean keepDreaming) {
+        notifyDreamStateListeners(
+                listener -> listener.onKeepDreamingWhenUnpluggingChanged(keepDreaming));
+    }
+
+    private void reportDreamingStarted() {
+        notifyDreamStateListeners(listener -> listener.onDreamingStarted());
+    }
+
+    private void reportDreamingStopped() {
+        notifyDreamStateListeners(listener -> listener.onDreamingStopped());
+    }
+
+    private void notifyDreamStateListeners(
+            Consumer<DreamManagerInternal.DreamManagerStateListener> notifier) {
         mHandler.post(() -> {
             for (DreamManagerInternal.DreamManagerStateListener listener
                     : mDreamManagerStateListeners) {
-                listener.onKeepDreamingWhenUnpluggingChanged(keepDreaming);
+                notifier.accept(listener);
             }
         });
     }
@@ -767,12 +782,23 @@
 
     private final DreamController.Listener mControllerListener = new DreamController.Listener() {
         @Override
+        public void onDreamStarted(Binder token) {
+            // Note that this event is distinct from DreamManagerService#startDreamLocked as it
+            // tracks the DreamService attach point from DreamController, closest to the broadcast
+            // of ACTION_DREAMING_STARTED.
+
+            reportDreamingStarted();
+        }
+
+        @Override
         public void onDreamStopped(Binder token) {
             synchronized (mLock) {
                 if (mCurrentDream != null && mCurrentDream.token == token) {
                     cleanupDreamLocked();
                 }
             }
+
+            reportDreamingStopped();
         }
     };
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index 220a438..b82129b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -35,6 +35,7 @@
             ERROR_DESTINATION,
             ERROR_PARAMETER,
             ERROR_PARAMETER_SHORT,
+            ERROR_PARAMETER_LONG,
     })
     public @interface ValidationResult {};
 
@@ -43,6 +44,7 @@
     static final int ERROR_DESTINATION = 2;
     static final int ERROR_PARAMETER = 3;
     static final int ERROR_PARAMETER_SHORT = 4;
+    static final int ERROR_PARAMETER_LONG = 5;
 
     interface ParameterValidator {
         /**
@@ -159,11 +161,13 @@
         addValidationInfo(Constants.MESSAGE_SET_MENU_LANGUAGE,
                 new AsciiValidator(3), DEST_BROADCAST);
 
-        ParameterValidator statusRequestValidator = new OneByteRangeValidator(0x01, 0x03);
+        ParameterValidator statusRequestValidator = new MinimumOneByteRangeValidator(0x01, 0x03);
         addValidationInfo(
-                Constants.MESSAGE_DECK_CONTROL, new OneByteRangeValidator(0x01, 0x04), DEST_DIRECT);
+                Constants.MESSAGE_DECK_CONTROL,
+                        new MinimumOneByteRangeValidator(0x01, 0x04), DEST_DIRECT);
         addValidationInfo(
-                Constants.MESSAGE_DECK_STATUS, new OneByteRangeValidator(0x11, 0x1F), DEST_DIRECT);
+                Constants.MESSAGE_DECK_STATUS,
+                        new MinimumOneByteRangeValidator(0x11, 0x1F), DEST_DIRECT);
         addValidationInfo(Constants.MESSAGE_GIVE_DECK_STATUS, statusRequestValidator, DEST_DIRECT);
         addValidationInfo(Constants.MESSAGE_PLAY, new PlayModeValidator(), DEST_DIRECT);
 
@@ -201,9 +205,11 @@
 
         // Messages for the Device Menu Control.
         addValidationInfo(
-                Constants.MESSAGE_MENU_REQUEST, new OneByteRangeValidator(0x00, 0x02), DEST_DIRECT);
+                Constants.MESSAGE_MENU_REQUEST,
+                        new MinimumOneByteRangeValidator(0x00, 0x02), DEST_DIRECT);
         addValidationInfo(
-                Constants.MESSAGE_MENU_STATUS, new OneByteRangeValidator(0x00, 0x01), DEST_DIRECT);
+                Constants.MESSAGE_MENU_STATUS,
+                        new MinimumOneByteRangeValidator(0x00, 0x01), DEST_DIRECT);
 
         // Messages for the Remote Control Passthrough.
         addValidationInfo(
@@ -214,7 +220,7 @@
         // Messages for the Power Status.
         addValidationInfo(
                 Constants.MESSAGE_REPORT_POWER_STATUS,
-                new OneByteRangeValidator(0x00, 0x03),
+                new MinimumOneByteRangeValidator(0x00, 0x03),
                 DEST_DIRECT | DEST_BROADCAST);
 
         // Messages for the General Protocol.
@@ -229,17 +235,17 @@
                 oneByteValidator, DEST_DIRECT);
         addValidationInfo(
                 Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE,
-                new OneByteRangeValidator(0x00, 0x01),
+                new MinimumOneByteRangeValidator(0x00, 0x01),
                 DEST_ALL);
         addValidationInfo(
                 Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS,
-                new OneByteRangeValidator(0x00, 0x01),
+                new SingleByteRangeValidator(0x00, 0x01),
                 DEST_DIRECT);
 
         // Messages for the Audio Rate Control.
         addValidationInfo(
                 Constants.MESSAGE_SET_AUDIO_RATE,
-                new OneByteRangeValidator(0x00, 0x06),
+                new MinimumOneByteRangeValidator(0x00, 0x06),
                 DEST_DIRECT);
 
         // Messages for Feature Discovery.
@@ -900,11 +906,14 @@
         }
     }
 
-    /** Check if the given parameters are one byte parameters and within range. */
-    private static class OneByteRangeValidator implements ParameterValidator {
+    /**
+     * Check if the given parameters are at least one byte parameters
+     * and the first byte is within range.
+     */
+    private static class MinimumOneByteRangeValidator implements ParameterValidator {
         private final int mMinValue, mMaxValue;
 
-        OneByteRangeValidator(int minValue, int maxValue) {
+        MinimumOneByteRangeValidator(int minValue, int maxValue) {
             mMinValue = minValue;
             mMaxValue = maxValue;
         }
@@ -918,6 +927,26 @@
         }
     }
 
+    /** Check if the given parameters are exactly one byte parameters and within range. */
+    private static class SingleByteRangeValidator implements ParameterValidator {
+        private final int mMinValue, mMaxValue;
+
+        SingleByteRangeValidator(int minValue, int maxValue) {
+            mMinValue = minValue;
+            mMaxValue = maxValue;
+        }
+
+        @Override
+        public int isValid(byte[] params) {
+            if (params.length < 1) {
+                return ERROR_PARAMETER_SHORT;
+            } else if (params.length > 1) {
+                return ERROR_PARAMETER_LONG;
+            }
+            return toErrorCode(isWithinRange(params[0], mMinValue, mMaxValue));
+        }
+    }
+
     /**
      * Check if the given Analogue Timer message parameters are valid. Valid parameters should
      * adhere to message description of Analogue Timer defined in CEC 1.4 Specification : Message
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 75fe63a..9cd5272 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1611,6 +1611,7 @@
         @HdmiCecMessageValidator.ValidationResult
         int validationResult = message.getValidationResult();
         if (validationResult == HdmiCecMessageValidator.ERROR_PARAMETER
+                || validationResult == HdmiCecMessageValidator.ERROR_PARAMETER_LONG
                 || !verifyPhysicalAddresses(message)) {
             return Constants.ABORT_INVALID_OPERAND;
         } else if (validationResult != HdmiCecMessageValidator.OK
diff --git a/services/core/java/com/android/server/infra/ServiceNameBaseResolver.java b/services/core/java/com/android/server/infra/ServiceNameBaseResolver.java
index 76ea05e..66ce5c7 100644
--- a/services/core/java/com/android/server/infra/ServiceNameBaseResolver.java
+++ b/services/core/java/com/android/server/infra/ServiceNameBaseResolver.java
@@ -268,7 +268,7 @@
             }
             if (enabled) {
                 Slog.i(TAG, "disabling default service for user " + userId);
-                mDefaultServicesDisabled.removeAt(userId);
+                mDefaultServicesDisabled.delete(userId);
             } else {
                 Slog.i(TAG, "enabling default service for user " + userId);
                 mDefaultServicesDisabled.put(userId, true);
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index 5b21669..153e9c1 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -52,25 +52,27 @@
         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()));
+                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) -> updateLongPressTimeout(reason)),
+                Map.entry(
+                        Settings.Global.getUriFor(
+                                Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH),
+                        (reason) -> updateMaximumObscuringOpacityForTouch()));
     }
 
     /**
@@ -151,8 +153,13 @@
         mNative.reloadPointerIcons();
     }
 
-    private void updateDeepPressStatus(String reason) {
-        // Not using ViewConfiguration.getLongPressTimeout here because it may return a stale value
+    private void updateLongPressTimeout(String reason) {
+        // Some key gesture timeouts are based on the long press timeout, so update key gesture
+        // timeouts when the value changes. See ViewConfiguration#getKeyRepeatTimeout().
+        mNative.notifyKeyGestureTimeoutsChanged();
+
+        // Update the deep press status.
+        // 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);
diff --git a/services/core/java/com/android/server/input/KeyboardBacklightController.java b/services/core/java/com/android/server/input/KeyboardBacklightController.java
index 048308e..48c346a 100644
--- a/services/core/java/com/android/server/input/KeyboardBacklightController.java
+++ b/services/core/java/com/android/server/input/KeyboardBacklightController.java
@@ -199,8 +199,11 @@
         }
         if (brightness.isPresent()) {
             int brightnessValue = Math.max(0, Math.min(MAX_BRIGHTNESS, brightness.getAsInt()));
-            int brightnessLevel = Arrays.binarySearch(BRIGHTNESS_VALUE_FOR_LEVEL, brightnessValue);
-            updateBacklightState(inputDevice.getId(), keyboardBacklight, brightnessLevel,
+            int index = Arrays.binarySearch(BRIGHTNESS_VALUE_FOR_LEVEL, brightnessValue);
+            if (index < 0) {
+                index = Math.min(NUM_BRIGHTNESS_CHANGE_STEPS, -(index + 1));
+            }
+            updateBacklightState(inputDevice.getId(), keyboardBacklight, index,
                     false /* isTriggeredByKeyPress */);
             if (DEBUG) {
                 Slog.d(TAG, "Restoring brightness level " + brightness.getAsInt());
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 72c7dad..d8716b3 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -16,6 +16,8 @@
 
 package com.android.server.input;
 
+import android.annotation.AnyThread;
+import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
@@ -99,6 +101,7 @@
     private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 2;
     private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 3;
     private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 4;
+    private static final int MSG_CURRENT_IME_INFO_CHANGED = 5;
 
     private final Context mContext;
     private final NativeInputManagerService mNative;
@@ -108,16 +111,17 @@
     private final Handler mHandler;
 
     // Connected keyboards with associated keyboard layouts (either auto-detected or manually
-    // selected layout). If the mapped value is null/empty, it means that no layout has been
-    // configured for the keyboard and user might need to manually configure it from the Settings.
-    private final SparseArray<Set<String>> mConfiguredKeyboards = new SparseArray<>();
+    // selected layout).
+    private final SparseArray<KeyboardConfiguration> mConfiguredKeyboards = new SparseArray<>();
     private Toast mSwitchedKeyboardLayoutToast;
 
     // This cache stores "best-matched" layouts so that we don't need to run the matching
     // algorithm repeatedly.
     @GuardedBy("mKeyboardLayoutCache")
     private final Map<String, String> mKeyboardLayoutCache = new ArrayMap<>();
+    private final Object mImeInfoLock = new Object();
     @Nullable
+    @GuardedBy("mImeInfoLock")
     private ImeInfo mCurrentImeInfo;
 
     KeyboardLayoutManager(Context context, NativeInputManagerService nativeService,
@@ -155,26 +159,32 @@
     }
 
     @Override
+    @MainThread
     public void onInputDeviceAdded(int deviceId) {
         onInputDeviceChanged(deviceId);
-        if (useNewSettingsUi()) {
-            // Force native callback to set up keyboard layout overlay for newly added keyboards
-            reloadKeyboardLayouts();
-        }
     }
 
     @Override
+    @MainThread
     public void onInputDeviceRemoved(int deviceId) {
         mConfiguredKeyboards.remove(deviceId);
         maybeUpdateNotification();
     }
 
     @Override
+    @MainThread
     public void onInputDeviceChanged(int deviceId) {
         final InputDevice inputDevice = getInputDevice(deviceId);
         if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
             return;
         }
+        KeyboardConfiguration config = mConfiguredKeyboards.get(deviceId);
+        if (config == null) {
+            config = new KeyboardConfiguration();
+            mConfiguredKeyboards.put(deviceId, config);
+        }
+
+        boolean needToShowNotification = false;
         if (!useNewSettingsUi()) {
             synchronized (mDataStore) {
                 String layout = getCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier());
@@ -182,54 +192,66 @@
                     layout = getDefaultKeyboardLayout(inputDevice);
                     if (layout != null) {
                         setCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier(), layout);
-                    } else {
-                        mConfiguredKeyboards.put(inputDevice.getId(), new HashSet<>());
                     }
                 }
+                config.setCurrentLayout(layout);
+                if (layout == null) {
+                    // In old settings show notification always until user manually selects a
+                    // layout in the settings.
+                    needToShowNotification = true;
+                }
             }
         } else {
             final InputDeviceIdentifier identifier = inputDevice.getIdentifier();
             final String key = getLayoutDescriptor(identifier);
             Set<String> selectedLayouts = new HashSet<>();
-            boolean needToShowMissingLayoutNotification = false;
             for (ImeInfo imeInfo : getImeInfoListForLayoutMapping()) {
                 // Check if the layout has been previously configured
                 String layout = getKeyboardLayoutForInputDeviceInternal(identifier,
                         new ImeInfo(imeInfo.mUserId, imeInfo.mImeSubtypeHandle,
                                 imeInfo.mImeSubtype));
                 if (layout == null) {
-                    needToShowMissingLayoutNotification = true;
-                    continue;
+                    // If even one layout not configured properly, we need to ask user to configure
+                    // the keyboard properly from the Settings.
+                    selectedLayouts.clear();
+                    break;
                 }
                 selectedLayouts.add(layout);
             }
 
-            if (needToShowMissingLayoutNotification) {
-                // If even one layout not configured properly we will show configuration
-                // notification allowing user to set the keyboard layout.
-                selectedLayouts.clear();
-            }
-
             if (DEBUG) {
                 Slog.d(TAG,
                         "Layouts selected for input device: " + identifier + " -> selectedLayouts: "
                                 + selectedLayouts);
             }
-            mConfiguredKeyboards.set(inputDevice.getId(), selectedLayouts);
+
+            config.setConfiguredLayouts(selectedLayouts);
+
+            // Update current layout: If there is a change then need to reload.
+            synchronized (mImeInfoLock) {
+                String layout = getKeyboardLayoutForInputDeviceInternal(
+                        inputDevice.getIdentifier(), mCurrentImeInfo);
+                if (!Objects.equals(layout, config.getCurrentLayout())) {
+                    config.setCurrentLayout(layout);
+                    mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS);
+                }
+            }
 
             synchronized (mDataStore) {
                 try {
-                    if (!mDataStore.setSelectedKeyboardLayouts(key, selectedLayouts)) {
-                        // No need to show the notification only if layout selection didn't change
+                    if (mDataStore.setSelectedKeyboardLayouts(key, selectedLayouts)) {
+                        // Need to show the notification only if layout selection changed
                         // from the previous configuration
-                        return;
+                        needToShowNotification = true;
                     }
                 } finally {
                     mDataStore.saveIfNeeded();
                 }
             }
         }
-        maybeUpdateNotification();
+        if (needToShowNotification) {
+            maybeUpdateNotification();
+        }
     }
 
     private String getDefaultKeyboardLayout(final InputDevice inputDevice) {
@@ -323,12 +345,14 @@
         reloadKeyboardLayouts();
     }
 
+    @AnyThread
     public KeyboardLayout[] getKeyboardLayouts() {
         final ArrayList<KeyboardLayout> list = new ArrayList<>();
         visitAllKeyboardLayouts((resources, keyboardLayoutResId, layout) -> list.add(layout));
         return list.toArray(new KeyboardLayout[0]);
     }
 
+    @AnyThread
     public KeyboardLayout[] getKeyboardLayoutsForInputDevice(
             final InputDeviceIdentifier identifier) {
         if (useNewSettingsUi()) {
@@ -375,6 +399,7 @@
                 KeyboardLayout[]::new);
     }
 
+    @AnyThread
     @Nullable
     public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) {
         Objects.requireNonNull(keyboardLayoutDescriptor,
@@ -543,6 +568,7 @@
         return key.toString();
     }
 
+    @AnyThread
     @Nullable
     public String getCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier) {
         if (useNewSettingsUi()) {
@@ -566,6 +592,7 @@
         }
     }
 
+    @AnyThread
     public void setCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
             String keyboardLayoutDescriptor) {
         if (useNewSettingsUi()) {
@@ -592,6 +619,7 @@
         }
     }
 
+    @AnyThread
     public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
         if (useNewSettingsUi()) {
             Slog.e(TAG, "getEnabledKeyboardLayoutsForInputDevice API not supported");
@@ -608,6 +636,7 @@
         }
     }
 
+    @AnyThread
     public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
             String keyboardLayoutDescriptor) {
         if (useNewSettingsUi()) {
@@ -635,6 +664,7 @@
         }
     }
 
+    @AnyThread
     public void removeKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
             String keyboardLayoutDescriptor) {
         if (useNewSettingsUi()) {
@@ -667,6 +697,7 @@
         }
     }
 
+    @AnyThread
     public void switchKeyboardLayout(int deviceId, int direction) {
         if (useNewSettingsUi()) {
             Slog.e(TAG, "switchKeyboardLayout API not supported");
@@ -675,7 +706,7 @@
         mHandler.obtainMessage(MSG_SWITCH_KEYBOARD_LAYOUT, deviceId, direction).sendToTarget();
     }
 
-    // Must be called on handler.
+    @MainThread
     private void handleSwitchKeyboardLayout(int deviceId, int direction) {
         final InputDevice device = getInputDevice(deviceId);
         if (device != null) {
@@ -713,23 +744,14 @@
     }
 
     @Nullable
+    @AnyThread
     public String[] getKeyboardLayoutOverlay(InputDeviceIdentifier identifier) {
         String keyboardLayoutDescriptor;
         if (useNewSettingsUi()) {
-            InputDevice inputDevice = getInputDevice(identifier);
-            if (inputDevice == null) {
-                // getKeyboardLayoutOverlay() called before input device added completely. Need
-                // to wait till the device is added which will call reloadKeyboardLayouts()
-                return null;
+            synchronized (mImeInfoLock) {
+                keyboardLayoutDescriptor = getKeyboardLayoutForInputDeviceInternal(identifier,
+                        mCurrentImeInfo);
             }
-            if (mCurrentImeInfo == null) {
-                // Haven't received onInputMethodSubtypeChanged() callback from IMMS. Will reload
-                // keyboard layouts once we receive the callback.
-                return null;
-            }
-
-            keyboardLayoutDescriptor = getKeyboardLayoutForInputDeviceInternal(identifier,
-                    mCurrentImeInfo);
         } else {
             keyboardLayoutDescriptor = getCurrentKeyboardLayoutForInputDevice(identifier);
         }
@@ -755,6 +777,7 @@
         return result;
     }
 
+    @AnyThread
     @Nullable
     public String getKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
             @UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
@@ -773,6 +796,7 @@
         return layout;
     }
 
+    @AnyThread
     public void setKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
             @UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
             @Nullable InputMethodSubtype imeSubtype,
@@ -783,8 +807,8 @@
         }
         Objects.requireNonNull(keyboardLayoutDescriptor,
                 "keyboardLayoutDescriptor must not be null");
-        String key = createLayoutKey(identifier, userId,
-                InputMethodSubtypeHandle.of(imeInfo, imeSubtype));
+        String key = createLayoutKey(identifier,
+                new ImeInfo(userId, InputMethodSubtypeHandle.of(imeInfo, imeSubtype), imeSubtype));
         synchronized (mDataStore) {
             try {
                 // Key for storing into data store = <device descriptor>,<userId>,<subtypeHandle>
@@ -803,6 +827,7 @@
         }
     }
 
+    @AnyThread
     public KeyboardLayout[] getKeyboardLayoutListForInputDevice(InputDeviceIdentifier identifier,
             @UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
             @Nullable InputMethodSubtype imeSubtype) {
@@ -815,8 +840,8 @@
     }
 
     private KeyboardLayout[] getKeyboardLayoutListForInputDeviceInternal(
-            InputDeviceIdentifier identifier, ImeInfo imeInfo) {
-        String key = createLayoutKey(identifier, imeInfo.mUserId, imeInfo.mImeSubtypeHandle);
+            InputDeviceIdentifier identifier, @Nullable ImeInfo imeInfo) {
+        String key = createLayoutKey(identifier, imeInfo);
 
         // Fetch user selected layout and always include it in layout list.
         String userSelectedLayout;
@@ -826,7 +851,7 @@
 
         final ArrayList<KeyboardLayout> potentialLayouts = new ArrayList<>();
         String imeLanguageTag;
-        if (imeInfo.mImeSubtype == null) {
+        if (imeInfo == null || imeInfo.mImeSubtype == null) {
             imeLanguageTag = "";
         } else {
             ULocale imeLocale = imeInfo.mImeSubtype.getPhysicalKeyboardHintLanguageTag();
@@ -866,6 +891,7 @@
         return potentialLayouts.toArray(new KeyboardLayout[0]);
     }
 
+    @AnyThread
     public void onInputMethodSubtypeChanged(@UserIdInt int userId,
             @Nullable InputMethodSubtypeHandle subtypeHandle,
             @Nullable InputMethodSubtype subtype) {
@@ -879,25 +905,45 @@
             }
             return;
         }
-        if (mCurrentImeInfo == null || !subtypeHandle.equals(mCurrentImeInfo.mImeSubtypeHandle)
-                || mCurrentImeInfo.mUserId != userId) {
-            mCurrentImeInfo = new ImeInfo(userId, subtypeHandle, subtype);
-            mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS);
-            if (DEBUG) {
-                Slog.d(TAG, "InputMethodSubtype changed: userId=" + userId
-                        + " subtypeHandle=" + subtypeHandle);
+        synchronized (mImeInfoLock) {
+            if (mCurrentImeInfo == null || !subtypeHandle.equals(mCurrentImeInfo.mImeSubtypeHandle)
+                    || mCurrentImeInfo.mUserId != userId) {
+                mCurrentImeInfo = new ImeInfo(userId, subtypeHandle, subtype);
+                mHandler.sendEmptyMessage(MSG_CURRENT_IME_INFO_CHANGED);
+                if (DEBUG) {
+                    Slog.d(TAG, "InputMethodSubtype changed: userId=" + userId
+                            + " subtypeHandle=" + subtypeHandle);
+                }
+            }
+        }
+    }
+
+    @MainThread
+    private void onCurrentImeInfoChanged() {
+        synchronized (mImeInfoLock) {
+            for (int i = 0; i < mConfiguredKeyboards.size(); i++) {
+                InputDevice inputDevice = Objects.requireNonNull(
+                        getInputDevice(mConfiguredKeyboards.keyAt(i)));
+                String layout = getKeyboardLayoutForInputDeviceInternal(inputDevice.getIdentifier(),
+                        mCurrentImeInfo);
+                KeyboardConfiguration config = mConfiguredKeyboards.valueAt(i);
+                if (!Objects.equals(layout, config.getCurrentLayout())) {
+                    config.setCurrentLayout(layout);
+                    mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS);
+                    return;
+                }
             }
         }
     }
 
     @Nullable
     private String getKeyboardLayoutForInputDeviceInternal(InputDeviceIdentifier identifier,
-            ImeInfo imeInfo) {
+            @Nullable ImeInfo imeInfo) {
         InputDevice inputDevice = getInputDevice(identifier);
         if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
             return null;
         }
-        String key = createLayoutKey(identifier, imeInfo.mUserId, imeInfo.mImeSubtypeHandle);
+        String key = createLayoutKey(identifier, imeInfo);
         String layout;
         synchronized (mDataStore) {
             layout = mDataStore.getKeyboardLayout(getLayoutDescriptor(identifier), key);
@@ -923,11 +969,7 @@
 
     @Nullable
     private static String getDefaultKeyboardLayoutBasedOnImeInfo(InputDevice inputDevice,
-            ImeInfo imeInfo, KeyboardLayout[] layoutList) {
-        if (imeInfo.mImeSubtypeHandle == null) {
-            return null;
-        }
-
+            @Nullable ImeInfo imeInfo, KeyboardLayout[] layoutList) {
         Arrays.sort(layoutList);
 
         // Check <VendorID, ProductID> matching for explicitly declared custom KCM files.
@@ -961,12 +1003,12 @@
             }
         }
 
-        InputMethodSubtype subtype = imeInfo.mImeSubtype;
-        // Can't auto select layout based on IME if subtype or language tag is null
-        if (subtype == null) {
+        if (imeInfo == null || imeInfo.mImeSubtypeHandle == null || imeInfo.mImeSubtype == null) {
+            // Can't auto select layout based on IME info is null
             return null;
         }
 
+        InputMethodSubtype subtype = imeInfo.mImeSubtype;
         // Check layout type, language tag information from IME for matching
         ULocale pkLocale = subtype.getPhysicalKeyboardHintLanguageTag();
         String pkLanguageTag =
@@ -1043,6 +1085,7 @@
         mNative.reloadKeyboardLayouts();
     }
 
+    @MainThread
     private void maybeUpdateNotification() {
         if (mConfiguredKeyboards.size() == 0) {
             hideKeyboardLayoutNotification();
@@ -1051,7 +1094,7 @@
         for (int i = 0; i < mConfiguredKeyboards.size(); i++) {
             // If we have a keyboard with no selected layouts, we should always show missing
             // layout notification even if there are other keyboards that are configured properly.
-            if (mConfiguredKeyboards.valueAt(i).isEmpty()) {
+            if (!mConfiguredKeyboards.valueAt(i).hasConfiguredLayouts()) {
                 showMissingKeyboardLayoutNotification();
                 return;
             }
@@ -1059,7 +1102,7 @@
         showConfiguredKeyboardLayoutNotification();
     }
 
-    // Must be called on handler.
+    @MainThread
     private void showMissingKeyboardLayoutNotification() {
         final Resources r = mContext.getResources();
         final String missingKeyboardLayoutNotificationContent = r.getString(
@@ -1084,6 +1127,7 @@
         }
     }
 
+    @MainThread
     private void showKeyboardLayoutNotification(@NonNull String intentTitle,
             @NonNull String intentContent, @Nullable InputDevice targetDevice) {
         final NotificationManager notificationManager = mContext.getSystemService(
@@ -1119,7 +1163,7 @@
                 notification, UserHandle.ALL);
     }
 
-    // Must be called on handler.
+    @MainThread
     private void hideKeyboardLayoutNotification() {
         NotificationManager notificationManager = mContext.getSystemService(
                 NotificationManager.class);
@@ -1132,6 +1176,7 @@
                 UserHandle.ALL);
     }
 
+    @MainThread
     private void showConfiguredKeyboardLayoutNotification() {
         final Resources r = mContext.getResources();
 
@@ -1144,8 +1189,8 @@
         }
 
         final InputDevice inputDevice = getInputDevice(mConfiguredKeyboards.keyAt(0));
-        final Set<String> selectedLayouts = mConfiguredKeyboards.valueAt(0);
-        if (inputDevice == null || selectedLayouts == null || selectedLayouts.isEmpty()) {
+        final KeyboardConfiguration config = mConfiguredKeyboards.valueAt(0);
+        if (inputDevice == null || !config.hasConfiguredLayouts()) {
             return;
         }
 
@@ -1153,10 +1198,11 @@
                 r.getString(
                         R.string.keyboard_layout_notification_selected_title,
                         inputDevice.getName()),
-                createConfiguredNotificationText(mContext, selectedLayouts),
+                createConfiguredNotificationText(mContext, config.getConfiguredLayouts()),
                 inputDevice);
     }
 
+    @MainThread
     private String createConfiguredNotificationText(@NonNull Context context,
             @NonNull Set<String> selectedLayouts) {
         final Resources r = context.getResources();
@@ -1199,6 +1245,9 @@
             case MSG_UPDATE_KEYBOARD_LAYOUTS:
                 updateKeyboardLayouts();
                 return true;
+            case MSG_CURRENT_IME_INFO_CHANGED:
+                onCurrentImeInfoChanged();
+                return true;
             default:
                 return false;
         }
@@ -1252,17 +1301,19 @@
         return imeInfoList;
     }
 
-    private String createLayoutKey(InputDeviceIdentifier identifier, int userId,
-            @NonNull InputMethodSubtypeHandle subtypeHandle) {
-        Objects.requireNonNull(subtypeHandle, "subtypeHandle must not be null");
-        return "layoutDescriptor:" + getLayoutDescriptor(identifier) + ",userId:" + userId
-                + ",subtypeHandle:" + subtypeHandle.toStringHandle();
+    private String createLayoutKey(InputDeviceIdentifier identifier, @Nullable ImeInfo imeInfo) {
+        if (imeInfo == null) {
+            return getLayoutDescriptor(identifier);
+        }
+        Objects.requireNonNull(imeInfo.mImeSubtypeHandle, "subtypeHandle must not be null");
+        return "layoutDescriptor:" + getLayoutDescriptor(identifier) + ",userId:" + imeInfo.mUserId
+                + ",subtypeHandle:" + imeInfo.mImeSubtypeHandle.toStringHandle();
     }
 
     private static boolean isLayoutCompatibleWithLanguageTag(KeyboardLayout layout,
             @NonNull String languageTag) {
         LocaleList layoutLocales = layout.getLocales();
-        if (layoutLocales.isEmpty()) {
+        if (layoutLocales.isEmpty() || TextUtils.isEmpty(languageTag)) {
             // KCM file doesn't have an associated language tag. This can be from
             // a 3rd party app so need to include it as a potential layout.
             return true;
@@ -1350,6 +1401,39 @@
         }
     }
 
+    private static class KeyboardConfiguration {
+        // If null or empty, it means no layout is configured for the device. And user needs to
+        // manually set up the device.
+        @Nullable
+        private Set<String> mConfiguredLayouts;
+
+        // If null, it means no layout is selected for the device.
+        @Nullable
+        private String mCurrentLayout;
+
+        private boolean hasConfiguredLayouts() {
+            return mConfiguredLayouts != null && !mConfiguredLayouts.isEmpty();
+        }
+
+        @Nullable
+        private Set<String> getConfiguredLayouts() {
+            return mConfiguredLayouts;
+        }
+
+        private void setConfiguredLayouts(Set<String> configuredLayouts) {
+            mConfiguredLayouts = configuredLayouts;
+        }
+
+        @Nullable
+        private String getCurrentLayout() {
+            return mCurrentLayout;
+        }
+
+        private void setCurrentLayout(String currentLayout) {
+            mCurrentLayout = currentLayout;
+        }
+    }
+
     private interface KeyboardLayoutVisitor {
         void visitKeyboardLayout(Resources resources,
                 int keyboardLayoutResId, KeyboardLayout layout);
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index aeb2477..363bc94 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -28,6 +28,7 @@
 import android.view.InputEvent;
 import android.view.PointerIcon;
 import android.view.VerifiedInputEvent;
+import android.view.ViewConfiguration;
 
 import java.util.List;
 
@@ -198,8 +199,6 @@
 
     void changeKeyboardLayoutAssociation();
 
-    void notifyPointerDisplayIdChanged();
-
     void setDisplayEligibilityForPointerCapture(int displayId, boolean enabled);
 
     void setMotionClassifierEnabled(boolean enabled);
@@ -243,6 +242,15 @@
      */
     void sysfsNodeChanged(String sysfsNodePath);
 
+    /**
+     * Notify there is a change in any of the key gesture timeouts, such as the key
+     * repeat timeout or key repeat delay.
+     *
+     * @see ViewConfiguration#getKeyRepeatTimeout()
+     * @see ViewConfiguration#getKeyRepeatDelay()
+     */
+    void notifyKeyGestureTimeoutsChanged();
+
     /** The native implementation of InputManagerService methods. */
     class NativeImpl implements NativeInputManagerService {
         /** Pointer to native input manager service object, used by native code. */
@@ -452,9 +460,6 @@
         public native void changeKeyboardLayoutAssociation();
 
         @Override
-        public native void notifyPointerDisplayIdChanged();
-
-        @Override
         public native void setDisplayEligibilityForPointerCapture(int displayId, boolean enabled);
 
         @Override
@@ -493,5 +498,8 @@
 
         @Override
         public native void sysfsNodeChanged(String sysfsNodePath);
+
+        @Override
+        public native void notifyKeyGestureTimeoutsChanged();
     }
 }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index c70d555..57f8d14 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -856,13 +856,15 @@
     @GuardedBy("ImfLock.class")
     private final WeakHashMap<IBinder, IBinder> mImeTargetWindowMap = new WeakHashMap<>();
 
-    private static final class SoftInputShowHideHistory {
+    @VisibleForTesting
+    static final class SoftInputShowHideHistory {
         private final Entry[] mEntries = new Entry[16];
         private int mNextIndex = 0;
         private static final AtomicInteger sSequenceNumber = new AtomicInteger(0);
 
-        private static final class Entry {
+        static final class Entry {
             final int mSequenceNumber = sSequenceNumber.getAndIncrement();
+            @Nullable
             final ClientState mClientState;
             @SoftInputModeFlags
             final int mFocusedWindowSoftInputMode;
@@ -874,7 +876,7 @@
             final boolean mInFullscreenMode;
             @NonNull
             final String mFocusedWindowName;
-            @NonNull
+            @Nullable
             final EditorInfo mEditorInfo;
             @NonNull
             final String mRequestWindowName;
@@ -953,9 +955,13 @@
 
                 pw.print(prefix);
                 pw.print(" editorInfo: ");
-                pw.print(" inputType=" + entry.mEditorInfo.inputType);
-                pw.print(" privateImeOptions=" + entry.mEditorInfo.privateImeOptions);
-                pw.println(" fieldId (viewId)=" + entry.mEditorInfo.fieldId);
+                if (entry.mEditorInfo != null) {
+                    pw.print(" inputType=" + entry.mEditorInfo.inputType);
+                    pw.print(" privateImeOptions=" + entry.mEditorInfo.privateImeOptions);
+                    pw.println(" fieldId (viewId)=" + entry.mEditorInfo.fieldId);
+                } else {
+                    pw.println("null");
+                }
 
                 pw.print(prefix);
                 pw.println(" focusedWindowSoftInputMode=" + InputMethodDebug.softInputModeToString(
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 2d3b97b..20d7dfa 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -285,8 +285,20 @@
                         ? routeListingPreference.getLinkedItemComponentName()
                         : null;
         if (linkedItemLandingComponent != null) {
+            int callingUid = Binder.getCallingUid();
             MediaServerUtils.enforcePackageName(
-                    linkedItemLandingComponent.getPackageName(), Binder.getCallingUid());
+                    linkedItemLandingComponent.getPackageName(), callingUid);
+            if (!MediaServerUtils.isValidActivityComponentName(
+                    mContext,
+                    linkedItemLandingComponent,
+                    RouteListingPreference.ACTION_TRANSFER_MEDIA,
+                    Binder.getCallingUserHandle())) {
+                throw new IllegalArgumentException(
+                        "Unable to resolve "
+                                + linkedItemLandingComponent
+                                + " to a valid activity for "
+                                + RouteListingPreference.ACTION_TRANSFER_MEDIA);
+            }
         }
 
         final long token = Binder.clearCallingIdentity();
@@ -764,7 +776,7 @@
                         userRecord.mHandler, routerRecord));
 
         Slog.i(TAG, TextUtils.formatSimple(
-                "registerRouter2 | package: %s, uid: %d, pid: %d, router: %d",
+                "registerRouter2 | package: %s, uid: %d, pid: %d, router id: %d",
                 packageName, uid, pid, routerRecord.mRouterId));
     }
 
@@ -776,10 +788,11 @@
             return;
         }
 
-        Slog.i(TAG, TextUtils.formatSimple(
-                "unregisterRouter2 | package: %s, router: %d",
-                routerRecord.mPackageName,
-                routerRecord.mRouterId));
+        Slog.i(
+                TAG,
+                TextUtils.formatSimple(
+                        "unregisterRouter2 | package: %s, router id: %d",
+                        routerRecord.mPackageName, routerRecord.mRouterId));
 
         UserRecord userRecord = routerRecord.mUserRecord;
         userRecord.mRouterRecords.remove(routerRecord);
@@ -806,9 +819,14 @@
             return;
         }
 
-        Slog.i(TAG, TextUtils.formatSimple(
-                "setDiscoveryRequestWithRouter2 | router: %d, discovery request: %s",
-                routerRecord.mRouterId, discoveryRequest.toString()));
+        Slog.i(
+                TAG,
+                TextUtils.formatSimple(
+                        "setDiscoveryRequestWithRouter2 | router: %s(id: %d), discovery request:"
+                            + " %s",
+                        routerRecord.mPackageName,
+                        routerRecord.mRouterId,
+                        discoveryRequest.toString()));
 
         routerRecord.mDiscoveryPreference = discoveryRequest;
         routerRecord.mUserRecord.mHandler.sendMessage(
@@ -832,10 +850,12 @@
                                 .collect(Collectors.joining(","))
                         : null;
 
-        Slog.i(TAG, TextUtils.formatSimple(
-                "setRouteListingPreference | router: %d, route listing preference: [%s]",
-                routerRecord.mRouterId,
-                routeListingAsString));
+        Slog.i(
+                TAG,
+                TextUtils.formatSimple(
+                        "setRouteListingPreference | router: %s(id: %d), route listing preference:"
+                            + " [%s]",
+                        routerRecord.mPackageName, routerRecord.mRouterId, routeListingAsString));
 
         routerRecord.mUserRecord.mHandler.sendMessage(
                 obtainMessage(
@@ -851,9 +871,11 @@
         RouterRecord routerRecord = mAllRouterRecords.get(binder);
 
         if (routerRecord != null) {
-            Slog.i(TAG, TextUtils.formatSimple(
-                    "setRouteVolumeWithRouter2 | router: %d, volume: %d",
-                    routerRecord.mRouterId, volume));
+            Slog.i(
+                    TAG,
+                    TextUtils.formatSimple(
+                            "setRouteVolumeWithRouter2 | router: %s(id: %d), volume: %d",
+                            routerRecord.mPackageName, routerRecord.mRouterId, volume));
 
             routerRecord.mUserRecord.mHandler.sendMessage(
                     obtainMessage(UserHandler::setRouteVolumeOnHandler,
@@ -935,9 +957,11 @@
             return;
         }
 
-        Slog.i(TAG, TextUtils.formatSimple(
-                "selectRouteWithRouter2 | router: %d, route: %s",
-                routerRecord.mRouterId, route.getId()));
+        Slog.i(
+                TAG,
+                TextUtils.formatSimple(
+                        "selectRouteWithRouter2 | router: %s(id: %d), route: %s",
+                        routerRecord.mPackageName, routerRecord.mRouterId, route.getId()));
 
         routerRecord.mUserRecord.mHandler.sendMessage(
                 obtainMessage(UserHandler::selectRouteOnHandler,
@@ -954,9 +978,11 @@
             return;
         }
 
-        Slog.i(TAG, TextUtils.formatSimple(
-                "deselectRouteWithRouter2 | router: %d, route: %s",
-                routerRecord.mRouterId, route.getId()));
+        Slog.i(
+                TAG,
+                TextUtils.formatSimple(
+                        "deselectRouteWithRouter2 | router: %s(id: %d), route: %s",
+                        routerRecord.mPackageName, routerRecord.mRouterId, route.getId()));
 
         routerRecord.mUserRecord.mHandler.sendMessage(
                 obtainMessage(UserHandler::deselectRouteOnHandler,
@@ -973,9 +999,11 @@
             return;
         }
 
-        Slog.i(TAG, TextUtils.formatSimple(
-                "transferToRouteWithRouter2 | router: %d, route: %s",
-                routerRecord.mRouterId, route.getId()));
+        Slog.i(
+                TAG,
+                TextUtils.formatSimple(
+                        "transferToRouteWithRouter2 | router: %s(id: %d), route: %s",
+                        routerRecord.mPackageName, routerRecord.mRouterId, route.getId()));
 
         String defaultRouteId =
                 routerRecord.mUserRecord.mHandler.mSystemProvider.getDefaultRoute().getId();
@@ -1002,9 +1030,14 @@
             return;
         }
 
-        Slog.i(TAG, TextUtils.formatSimple(
-                "setSessionVolumeWithRouter2 | router: %d, session: %s, volume: %d",
-                routerRecord.mRouterId,  uniqueSessionId, volume));
+        Slog.i(
+                TAG,
+                TextUtils.formatSimple(
+                        "setSessionVolumeWithRouter2 | router: %s(id: %d), session: %s, volume: %d",
+                        routerRecord.mPackageName,
+                        routerRecord.mRouterId,
+                        uniqueSessionId,
+                        volume));
 
         routerRecord.mUserRecord.mHandler.sendMessage(
                 obtainMessage(UserHandler::setSessionVolumeOnHandler,
@@ -1021,9 +1054,11 @@
             return;
         }
 
-        Slog.i(TAG, TextUtils.formatSimple(
-                "releaseSessionWithRouter2 | router: %d, session: %s",
-                routerRecord.mRouterId,  uniqueSessionId));
+        Slog.i(
+                TAG,
+                TextUtils.formatSimple(
+                        "releaseSessionWithRouter2 | router: %s(id: %d), session: %s",
+                        routerRecord.mPackageName, routerRecord.mRouterId, uniqueSessionId));
 
         routerRecord.mUserRecord.mHandler.sendMessage(
                 obtainMessage(UserHandler::releaseSessionOnHandler,
diff --git a/services/core/java/com/android/server/media/MediaServerUtils.java b/services/core/java/com/android/server/media/MediaServerUtils.java
index a4a99af..60592fe 100644
--- a/services/core/java/com/android/server/media/MediaServerUtils.java
+++ b/services/core/java/com/android/server/media/MediaServerUtils.java
@@ -16,9 +16,13 @@
 
 package com.android.server.media;
 
+import android.annotation.NonNull;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.ResolveInfo;
 import android.os.Binder;
 import android.os.Process;
 import android.os.UserHandle;
@@ -27,11 +31,27 @@
 import com.android.server.LocalServices;
 
 import java.io.PrintWriter;
+import java.util.List;
 
-/**
- * Util class for media server.
- */
-class MediaServerUtils {
+/** Util class for media server. */
+/* package */ class MediaServerUtils {
+
+    /**
+     * Returns whether the provided {@link ComponentName} and {@code action} resolve to a valid
+     * activity for the user defined by {@code userHandle}.
+     */
+    public static boolean isValidActivityComponentName(
+            @NonNull Context context,
+            @NonNull ComponentName componentName,
+            @NonNull String action,
+            @NonNull UserHandle userHandle) {
+        Intent intent = new Intent(action);
+        intent.setComponent(componentName);
+        List<ResolveInfo> resolveInfos =
+                context.getPackageManager()
+                        .queryIntentActivitiesAsUser(intent, /* flags= */ 0, userHandle);
+        return !resolveInfos.isEmpty();
+    }
 
     /**
      * Throws if the given {@code packageName} does not correspond to the given {@code uid}.
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 94d5aab..377b8cf 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -19,9 +19,19 @@
 import static android.Manifest.permission.MANAGE_MEDIA_PROJECTION;
 import static android.app.ActivityManagerInternal.MEDIA_PROJECTION_TOKEN_EVENT_CREATED;
 import static android.app.ActivityManagerInternal.MEDIA_PROJECTION_TOKEN_EVENT_DESTROYED;
+import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.media.projection.IMediaProjectionManager.EXTRA_PACKAGE_REUSING_GRANTED_CONSENT;
+import static android.media.projection.IMediaProjectionManager.EXTRA_USER_REVIEW_GRANTED_CONSENT;
+import static android.media.projection.ReviewGrantedConsentResult.RECORD_CANCEL;
+import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_DISPLAY;
+import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_TASK;
+import static android.media.projection.ReviewGrantedConsentResult.UNKNOWN;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 
 import android.Manifest;
+import android.annotation.EnforcePermission;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManagerInternal;
@@ -30,7 +40,9 @@
 import android.app.compat.CompatChanges;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledSince;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -45,11 +57,13 @@
 import android.media.projection.IMediaProjectionWatcherCallback;
 import android.media.projection.MediaProjectionInfo;
 import android.media.projection.MediaProjectionManager;
+import android.media.projection.ReviewGrantedConsentResult;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.PermissionEnforcer;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -57,6 +71,7 @@
 import android.util.Slog;
 import android.view.ContentRecordingSession;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
@@ -69,6 +84,7 @@
 import java.io.PrintWriter;
 import java.time.Duration;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * Manages MediaProjection sessions.
@@ -161,10 +177,9 @@
         }
     }
 
-
     @Override
     public void onStart() {
-        publishBinderService(Context.MEDIA_PROJECTION_SERVICE, new BinderService(),
+        publishBinderService(Context.MEDIA_PROJECTION_SERVICE, new BinderService(mContext),
                 false /*allowIsolated*/);
         mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY, mMediaRouterCallback,
                 MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY);
@@ -305,6 +320,10 @@
                 }
                 return false;
             }
+            if (mProjectionGrant != null) {
+                // Cache the session details.
+                mProjectionGrant.mSession = incomingSession;
+            }
             return true;
         }
     }
@@ -323,9 +342,8 @@
         }
     }
 
-
     /**
-     * Reshows the permisison dialog for the user to review consent they've already granted in
+     * Re-shows the permission dialog for the user to review consent they've already granted in
      * the given projection instance.
      *
      * <p>Preconditions:
@@ -337,18 +355,111 @@
      * <p>Returns immediately but waits to start recording until user has reviewed their consent.
      */
     @VisibleForTesting
-    void requestConsentForInvalidProjection(IMediaProjection projection) {
+    void requestConsentForInvalidProjection() {
         synchronized (mLock) {
             Slog.v(TAG, "Reusing token: Reshow dialog for due to invalid projection.");
-            // TODO(b/274790702): Trigger the permission dialog again in SysUI.
+            // Trigger the permission dialog again in SysUI
+            // Do not handle the result; SysUI will update us when the user has consented.
+            mContext.startActivityAsUser(buildReviewGrantedConsentIntent(),
+                    UserHandle.getUserHandleForUid(mProjectionGrant.uid));
+        }
+    }
+
+    /**
+     * Returns an intent to re-show the consent dialog in SysUI. Should only be used for the
+     * scenario where the host app has re-used the consent token.
+     *
+     * <p>Consent dialog result handled in
+     * {@link BinderService#setUserReviewGrantedConsentResult(int)}.
+     */
+    private Intent buildReviewGrantedConsentIntent() {
+        final String permissionDialogString = mContext.getResources().getString(
+                R.string.config_mediaProjectionPermissionDialogComponent);
+        final ComponentName mediaProjectionPermissionDialogComponent =
+                ComponentName.unflattenFromString(permissionDialogString);
+        // We can use mProjectionGrant since we already checked that it matches the given token.
+        return new Intent().setComponent(mediaProjectionPermissionDialogComponent)
+                .putExtra(EXTRA_USER_REVIEW_GRANTED_CONSENT, true)
+                .putExtra(EXTRA_PACKAGE_REUSING_GRANTED_CONSENT, mProjectionGrant.packageName)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+    }
+
+    /**
+     * Handles result of dialog shown from {@link BinderService#buildReviewGrantedConsentIntent()}.
+     *
+     * <p>Tears down session if user did not consent, or starts mirroring if user did consent.
+     */
+    @VisibleForTesting
+    void setUserReviewGrantedConsentResult(@ReviewGrantedConsentResult int consentResult,
+            @Nullable IMediaProjection projection) {
+        synchronized (mLock) {
+            final boolean consentGranted =
+                    consentResult == RECORD_CONTENT_DISPLAY || consentResult == RECORD_CONTENT_TASK;
+            if (consentGranted && !isCurrentProjection(
+                    projection == null ? null : projection.asBinder())) {
+                Slog.v(TAG, "Reusing token: Ignore consent result of " + consentResult + " for a "
+                        + "token that isn't current");
+                return;
+            }
+            if (mProjectionGrant == null) {
+                Slog.w(TAG, "Reusing token: Can't review consent with no ongoing projection.");
+                return;
+            }
+            if (mProjectionGrant.mSession == null
+                    || !mProjectionGrant.mSession.isWaitingToRecord()) {
+                Slog.w(TAG, "Reusing token: Ignore consent result " + consentResult
+                        + " if not waiting for the result.");
+                return;
+            }
+            Slog.v(TAG, "Reusing token: Handling user consent result " + consentResult);
+            switch (consentResult) {
+                case UNKNOWN:
+                case RECORD_CANCEL:
+                    // Pass in null to stop mirroring.
+                    setReviewedConsentSessionLocked(/* session= */ null);
+                    // The grant may now be null if setting the session failed.
+                    if (mProjectionGrant != null) {
+                        // Always stop the projection.
+                        mProjectionGrant.stop();
+                    }
+                    break;
+                case RECORD_CONTENT_DISPLAY:
+                    // TODO(270118861) The app may have specified a particular id in the virtual
+                    //  display config. However - below will always return INVALID since it checks
+                    //  that window manager mirroring is not enabled (it is always enabled for MP).
+                    setReviewedConsentSessionLocked(ContentRecordingSession.createDisplaySession(
+                            DEFAULT_DISPLAY));
+                    break;
+                case RECORD_CONTENT_TASK:
+                    setReviewedConsentSessionLocked(ContentRecordingSession.createTaskSession(
+                            mProjectionGrant.getLaunchCookie()));
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Updates the session after the user has reviewed consent. There must be a current session.
+     *
+     * @param session The new session details, or {@code null} to stop recording.
+     */
+    private void setReviewedConsentSessionLocked(@Nullable ContentRecordingSession session) {
+        if (session != null) {
+            session.setWaitingToRecord(false);
+            session.setVirtualDisplayId(mProjectionGrant.mVirtualDisplayId);
+        }
+
+        Slog.v(TAG, "Reusing token: Processed consent so set the session " + session);
+        if (!setContentRecordingSession(session)) {
+            Slog.e(TAG, "Reusing token: Failed to set session for reused consent, so stop");
+            // Do not need to invoke stop; updating the session does it for us.
         }
     }
 
     // TODO(b/261563516): Remove internal method and test aidl directly, here and elsewhere.
     @VisibleForTesting
     MediaProjection createProjectionInternal(int uid, String packageName, int type,
-            boolean isPermanentGrant, UserHandle callingUser,
-            boolean packageAttemptedReusingGrantedConsent) {
+            boolean isPermanentGrant, UserHandle callingUser) {
         MediaProjection projection;
         ApplicationInfo ai;
         try {
@@ -371,6 +482,34 @@
         return projection;
     }
 
+    // TODO(b/261563516): Remove internal method and test aidl directly, here and elsewhere.
+    @VisibleForTesting
+    MediaProjection getProjectionInternal(int uid, String packageName) {
+        final long callingToken = Binder.clearCallingIdentity();
+        try {
+            // Supposedly the package has re-used the user's consent; confirm the provided details
+            // against the current projection token before re-using the current projection.
+            if (mProjectionGrant == null || mProjectionGrant.mSession == null
+                    || !mProjectionGrant.mSession.isWaitingToRecord()) {
+                Slog.e(TAG, "Reusing token: Not possible to reuse the current projection "
+                        + "instance");
+                return null;
+            }
+                // The package matches, go ahead and re-use the token for this request.
+            if (mProjectionGrant.uid == uid
+                    && Objects.equals(mProjectionGrant.packageName, packageName)) {
+                Slog.v(TAG, "Reusing token: getProjection can reuse the current projection");
+                return mProjectionGrant;
+            } else {
+                Slog.e(TAG, "Reusing token: Not possible to reuse the current projection "
+                        + "instance due to package details mismatching");
+                return null;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(callingToken);
+        }
+    }
+
     @VisibleForTesting
     MediaProjectionInfo getActiveProjectionInfo() {
         synchronized (mLock) {
@@ -395,6 +534,10 @@
 
     private final class BinderService extends IMediaProjectionManager.Stub {
 
+        BinderService(Context context) {
+            super(PermissionEnforcer.fromContext(context));
+        }
+
         @Override // Binder call
         public boolean hasProjectionPermission(int uid, String packageName) {
             final long token = Binder.clearCallingIdentity();
@@ -424,7 +567,25 @@
             }
             final UserHandle callingUser = Binder.getCallingUserHandle();
             return createProjectionInternal(uid, packageName, type, isPermanentGrant,
-                    callingUser, false);
+                    callingUser);
+        }
+
+        @Override // Binder call
+        @EnforcePermission(MANAGE_MEDIA_PROJECTION)
+        public IMediaProjection getProjection(int uid, String packageName) {
+            getProjection_enforcePermission();
+            if (packageName == null || packageName.isEmpty()) {
+                throw new IllegalArgumentException("package name must not be empty");
+            }
+
+            MediaProjection projection;
+            final long callingToken = Binder.clearCallingIdentity();
+            try {
+                projection = getProjectionInternal(uid, packageName);
+            } finally {
+                Binder.restoreCallingIdentity(callingToken);
+            }
+            return projection;
         }
 
         @Override // Binder call
@@ -562,7 +723,7 @@
         }
 
         @Override
-        public void requestConsentForInvalidProjection(IMediaProjection projection) {
+        public void requestConsentForInvalidProjection(@NonNull IMediaProjection projection) {
             if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
                     != PackageManager.PERMISSION_GRANTED) {
                 throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION to check if the given"
@@ -577,7 +738,22 @@
             // Remove calling app identity before performing any privileged operations.
             final long token = Binder.clearCallingIdentity();
             try {
-                MediaProjectionManagerService.this.requestConsentForInvalidProjection(projection);
+                MediaProjectionManagerService.this.requestConsentForInvalidProjection();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override // Binder call
+        @EnforcePermission(MANAGE_MEDIA_PROJECTION)
+        public void setUserReviewGrantedConsentResult(@ReviewGrantedConsentResult int consentResult,
+                @Nullable IMediaProjection projection) {
+            setUserReviewGrantedConsentResult_enforcePermission();
+            // Remove calling app identity before performing any privileged operations.
+            final long token = Binder.clearCallingIdentity();
+            try {
+                MediaProjectionManagerService.this.setUserReviewGrantedConsentResult(consentResult,
+                        projection);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -594,7 +770,6 @@
             }
         }
 
-
         private boolean checkPermission(String packageName, String permission) {
             return mContext.getPackageManager().checkPermission(permission, packageName)
                     == PackageManager.PERMISSION_GRANTED;
@@ -630,6 +805,8 @@
         // Set if MediaProjection#createVirtualDisplay has been invoked previously (it
         // should only be called once).
         private int mVirtualDisplayId = INVALID_DISPLAY;
+        // The associated session details already sent to WindowManager.
+        private ContentRecordingSession mSession;
 
         MediaProjection(int type, int uid, String packageName, int targetSdkVersion,
                 boolean isPrivileged) {
@@ -883,6 +1060,18 @@
             }
             synchronized (mLock) {
                 mVirtualDisplayId = displayId;
+
+                // If prior session was does not have a valid display id, then update the display
+                // so recording can start.
+                if (mSession != null && mSession.getVirtualDisplayId() == INVALID_DISPLAY) {
+                    Slog.v(TAG, "Virtual display now created, so update session with the virtual "
+                            + "display id");
+                    mSession.setVirtualDisplayId(mVirtualDisplayId);
+                    if (!setContentRecordingSession(mSession)) {
+                        Slog.e(TAG, "Failed to set session for virtual display id");
+                        // Do not need to invoke stop; updating the session does it for us.
+                    }
+                }
             }
         }
 
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index a3d89e7..b708269 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -28,6 +28,7 @@
 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
 import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
 import static android.app.ActivityManager.isProcStateConsideredInteraction;
+import static android.app.ActivityManager.printCapabilitiesSummary;
 import static android.app.ActivityManager.procStateToString;
 import static android.app.PendingIntent.FLAG_IMMUTABLE;
 import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
@@ -1133,6 +1134,7 @@
                 if (!callbackInfo.isPending) {
                     mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, callbackInfo)
                             .sendToTarget();
+                    callbackInfo.isPending = true;
                 }
             }
         }
@@ -1156,6 +1158,19 @@
             this.procStateSeq = procStateSeq;
             this.capability = capability;
         }
+
+        @Override
+        public String toString() {
+            final StringBuilder sb = new StringBuilder();
+            sb.append("{");
+            sb.append("uid=").append(uid).append(",");
+            sb.append("proc_state=").append(procStateToString(procState)).append(",");
+            sb.append("seq=").append(procStateSeq).append(",");
+            sb.append("cap="); printCapabilitiesSummary(sb, capability); sb.append(",");
+            sb.append("pending=").append(isPending);
+            sb.append("}");
+            return sb.toString();
+        }
     }
 
     final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
@@ -3982,31 +3997,31 @@
                 synchronized (mUidBlockedState) {
                     collectKeys(mUidBlockedState, knownUids);
                 }
+                synchronized (mUidStateCallbackInfos) {
+                    collectKeys(mUidStateCallbackInfos, knownUids);
+                }
 
                 fout.println("Status for all known UIDs:");
                 fout.increaseIndent();
                 size = knownUids.size();
                 for (int i = 0; i < size; i++) {
                     final int uid = knownUids.keyAt(i);
-                    fout.print("UID=");
-                    fout.print(uid);
+                    fout.print("UID", uid);
 
                     final UidState uidState = mUidState.get(uid);
-                    if (uidState == null) {
-                        fout.print(" state={null}");
-                    } else {
-                        fout.print(" state=");
-                        fout.print(uidState.toString());
-                    }
+                    fout.print("state", uidState);
 
                     synchronized (mUidBlockedState) {
                         final UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
-                        if (uidBlockedState == null) {
-                            fout.print(" blocked_state={null}");
-                        } else {
-                            fout.print(" blocked_state=");
-                            fout.print(uidBlockedState);
-                        }
+                        fout.print("blocked_state", uidBlockedState);
+                    }
+
+                    synchronized (mUidStateCallbackInfos) {
+                        final UidStateCallbackInfo callbackInfo = mUidStateCallbackInfos.get(uid);
+                        fout.println();
+                        fout.increaseIndent();
+                        fout.print("callback_info", callbackInfo);
+                        fout.decreaseIndent();
                     }
                     fout.println();
                 }
@@ -4052,27 +4067,49 @@
     }
 
     @VisibleForTesting
-    boolean isUidForeground(int uid) {
-        synchronized (mUidRulesFirstLock) {
-            return isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid));
+    @GuardedBy("mUidRulesFirstLock")
+    boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
+        final UidState uidState = mUidState.get(uid);
+        if (isProcStateAllowedWhileOnRestrictBackground(uidState)) {
+            return true;
         }
+        // Check if there is any pending state change.
+        synchronized (mUidStateCallbackInfos) {
+            final UidStateCallbackInfo callbackInfo = mUidStateCallbackInfos.get(uid);
+            final long prevProcStateSeq = uidState != null ? uidState.procStateSeq : -1;
+            if (callbackInfo != null && callbackInfo.isPending
+                    && callbackInfo.procStateSeq >= prevProcStateSeq) {
+                return isProcStateAllowedWhileOnRestrictBackground(callbackInfo.procState,
+                        callbackInfo.capability);
+            }
+        }
+        return false;
     }
 
+    @VisibleForTesting
     @GuardedBy("mUidRulesFirstLock")
-    private boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
+    boolean isUidForegroundOnRestrictPowerUL(int uid) {
         final UidState uidState = mUidState.get(uid);
-        return isProcStateAllowedWhileOnRestrictBackground(uidState);
-    }
-
-    @GuardedBy("mUidRulesFirstLock")
-    private boolean isUidForegroundOnRestrictPowerUL(int uid) {
-        final UidState uidState = mUidState.get(uid);
-        return isProcStateAllowedWhileIdleOrPowerSaveMode(uidState);
+        if (isProcStateAllowedWhileIdleOrPowerSaveMode(uidState)) {
+            return true;
+        }
+        // Check if there is any pending state change.
+        synchronized (mUidStateCallbackInfos) {
+            final UidStateCallbackInfo callbackInfo = mUidStateCallbackInfos.get(uid);
+            final long prevProcStateSeq = uidState != null ? uidState.procStateSeq : -1;
+            if (callbackInfo != null && callbackInfo.isPending
+                    && callbackInfo.procStateSeq >= prevProcStateSeq) {
+                return isProcStateAllowedWhileIdleOrPowerSaveMode(callbackInfo.procState,
+                        callbackInfo.capability);
+            }
+        }
+        return false;
     }
 
     @GuardedBy("mUidRulesFirstLock")
     private boolean isUidTop(int uid) {
         final UidState uidState = mUidState.get(uid);
+        // TODO: Consider taking pending uid state change into account.
         return isProcStateAllowedWhileInLowPowerStandby(uidState);
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d1d6f5f..f0ab815 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -124,6 +124,7 @@
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES;
 import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
 import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
 import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
@@ -277,7 +278,6 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-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;
@@ -306,7 +306,6 @@
 import com.android.server.IoThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
-import com.android.server.UiThread;
 import com.android.server.job.JobSchedulerInternal;
 import com.android.server.lights.LightsManager;
 import com.android.server.lights.LogicalLight;
@@ -317,7 +316,6 @@
 import com.android.server.notification.toast.ToastRecord;
 import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.UserManagerInternal;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.policy.PermissionPolicyInternal;
 import com.android.server.powerstats.StatsPullAtomCallbackImpl;
 import com.android.server.statusbar.StatusBarManagerInternal;
@@ -560,10 +558,10 @@
     private PermissionHelper mPermissionHelper;
     private UsageStatsManagerInternal mUsageStatsManagerInternal;
     private TelecomManager mTelecomManager;
+    private PostNotificationTrackerFactory mPostNotificationTrackerFactory;
 
     final IBinder mForegroundToken = new Binder();
     private WorkerHandler mHandler;
-    private Handler mUiHandler;
     private final HandlerThread mRankingThread = new HandlerThread("ranker",
             Process.THREAD_PRIORITY_BACKGROUND);
 
@@ -572,7 +570,6 @@
 
     private boolean mUseAttentionLight;
     boolean mHasLight = true;
-    boolean mLightEnabled;
     boolean mSystemReady;
 
     private boolean mDisableNotificationEffects;
@@ -629,7 +626,6 @@
     ArrayList<String> mLights = new ArrayList<>();
 
     private AppOpsManager mAppOps;
-    private IAppOpsService mAppOpsService;
     private UsageStatsManagerInternal mAppUsageStats;
     private DevicePolicyManagerInternal mDpm;
     private StatsManager mStatsManager;
@@ -926,7 +922,7 @@
         if (oldFlags != flags) {
             summary.getSbn().getNotification().flags = flags;
             mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground,
-                    SystemClock.elapsedRealtime()));
+                    mPostNotificationTrackerFactory.newTracker()));
         }
     }
 
@@ -1459,7 +1455,8 @@
                         // Force isAppForeground true here, because for sysui's purposes we
                         // want to adjust the flag behaviour.
                         mHandler.post(new EnqueueNotificationRunnable(r.getUser().getIdentifier(),
-                                r, true /* isAppForeground*/, SystemClock.elapsedRealtime()));
+                                r, true /* isAppForeground*/,
+                                mPostNotificationTrackerFactory.newTracker()));
                     }
                 }
             }
@@ -1489,7 +1486,8 @@
                         // want to be able to adjust the flag behaviour.
                         mHandler.post(
                                 new EnqueueNotificationRunnable(r.getUser().getIdentifier(), r,
-                                        true /* isAppForeground */, SystemClock.elapsedRealtime()));
+                                        /* foreground= */ true,
+                                        mPostNotificationTrackerFactory.newTracker()));
                     }
                 }
             }
@@ -2173,11 +2171,6 @@
     }
 
     @VisibleForTesting
-    void setPackageManager(IPackageManager packageManager) {
-        mPackageManager = packageManager;
-    }
-
-    @VisibleForTesting
     void setRankingHelper(RankingHelper rankingHelper) {
         mRankingHelper = rankingHelper;
     }
@@ -2231,15 +2224,15 @@
             ActivityManager activityManager, GroupHelper groupHelper, IActivityManager am,
             ActivityTaskManagerInternal atm, UsageStatsManagerInternal appUsageStats,
             DevicePolicyManagerInternal dpm, IUriGrantsManager ugm,
-            UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, IAppOpsService iAppOps,
-            UserManager userManager,
+            UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, UserManager userManager,
             NotificationHistoryManager historyManager, StatsManager statsManager,
             TelephonyManager telephonyManager, ActivityManagerInternal ami,
             MultiRateLimiter toastRateLimiter, PermissionHelper permissionHelper,
             UsageStatsManagerInternal usageStatsManagerInternal,
             TelecomManager telecomManager, NotificationChannelLogger channelLogger,
             SystemUiSystemPropertiesFlags.FlagResolver flagResolver,
-            PermissionManager permissionManager) {
+            PermissionManager permissionManager,
+            PostNotificationTrackerFactory postNotificationTrackerFactory) {
         mHandler = handler;
         Resources resources = getContext().getResources();
         mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
@@ -2261,7 +2254,6 @@
         mUmInternal = LocalServices.getService(UserManagerInternal.class);
         mUsageStatsManagerInternal = usageStatsManagerInternal;
         mAppOps = appOps;
-        mAppOpsService = iAppOps;
         mAppUsageStats = appUsageStats;
         mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
         mCompanionManager = companionManager;
@@ -2271,11 +2263,11 @@
         mDpm = dpm;
         mUm = userManager;
         mTelecomManager = telecomManager;
+        mPostNotificationTrackerFactory = postNotificationTrackerFactory;
         mPlatformCompat = IPlatformCompat.Stub.asInterface(
                 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
 
         mStrongAuthTracker = new StrongAuthTracker(getContext());
-        mUiHandler = new Handler(UiThread.get().getLooper());
         String[] extractorNames;
         try {
             extractorNames = resources.getStringArray(R.array.config_notificationSignalExtractors);
@@ -2560,20 +2552,20 @@
                 UriGrantsManager.getService(),
                 LocalServices.getService(UriGrantsManagerInternal.class),
                 getContext().getSystemService(AppOpsManager.class),
-                IAppOpsService.Stub.asInterface(ServiceManager.getService(Context.APP_OPS_SERVICE)),
                 getContext().getSystemService(UserManager.class),
                 new NotificationHistoryManager(getContext(), handler),
                 mStatsManager = (StatsManager) getContext().getSystemService(
                         Context.STATS_MANAGER),
                 getContext().getSystemService(TelephonyManager.class),
                 LocalServices.getService(ActivityManagerInternal.class),
-                createToastRateLimiter(), new PermissionHelper(LocalServices.getService(
-                        PermissionManagerServiceInternal.class), AppGlobals.getPackageManager(),
+                createToastRateLimiter(), new PermissionHelper(getContext(),
+                        AppGlobals.getPackageManager(),
                         AppGlobals.getPermissionManager()),
                 LocalServices.getService(UsageStatsManagerInternal.class),
                 getContext().getSystemService(TelecomManager.class),
                 new NotificationChannelLoggerImpl(), SystemUiSystemPropertiesFlags.getResolver(),
-                getContext().getSystemService(PermissionManager.class));
+                getContext().getSystemService(PermissionManager.class),
+                new PostNotificationTrackerFactory() {});
 
         publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
                 DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL);
@@ -2689,7 +2681,7 @@
                     final boolean isAppForeground =
                             mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
                     mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
-                            SystemClock.elapsedRealtime()));
+                            mPostNotificationTrackerFactory.newTracker()));
                 }
             }
 
@@ -6562,6 +6554,26 @@
     void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
             final int callingPid, final String tag, final int id, final Notification notification,
             int incomingUserId, boolean postSilently) {
+        PostNotificationTracker tracker = mPostNotificationTrackerFactory.newTracker();
+        boolean enqueued = false;
+        try {
+            enqueued = enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id,
+                    notification, incomingUserId, postSilently, tracker);
+        } finally {
+            if (!enqueued) {
+                tracker.cancel();
+            }
+        }
+    }
+
+    /**
+     * @return True if we successfully processed the notification and handed off the task of
+     * enqueueing it to a background thread; false otherwise.
+     */
+    private boolean enqueueNotificationInternal(final String pkg, final String opPkg,
+            final int callingUid, final int callingPid, final String tag, final int id,
+            final Notification notification, int incomingUserId, boolean postSilently,
+            PostNotificationTracker tracker) {
         if (DBG) {
             Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
                     + " notification=" + notification);
@@ -6610,7 +6622,7 @@
                 throw new SecurityException("Invalid FGS notification", e);
             }
             Slog.e(TAG, "Cannot fix notification", e);
-            return;
+            return false;
         }
 
         if (policy == ServiceNotificationPolicy.UPDATE_ONLY) {
@@ -6619,7 +6631,7 @@
             // handling.
             if (!isNotificationShownInternal(pkg, tag, id, userId)) {
                 reportForegroundServiceUpdate(false, notification, id, pkg, userId);
-                return;
+                return false;
             }
         }
 
@@ -6660,7 +6672,7 @@
                         "Failed to post notification on channel \"" + channelId + "\"\n" +
                         "See log for more details");
             }
-            return;
+            return false;
         }
 
         final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
@@ -6707,7 +6719,7 @@
 
         if (!checkDisqualifyingFeatures(userId, notificationUid, id, tag, r,
                 r.getSbn().getOverrideGroupKey() != null)) {
-            return;
+            return false;
         }
 
         if (info != null) {
@@ -6748,8 +6760,8 @@
         } finally {
             Binder.restoreCallingIdentity(token);
         }
-        mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
-                SystemClock.elapsedRealtime()));
+        mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground, tracker));
+        return true;
     }
 
     private void onConversationRemovedInternal(String pkg, int uid, Set<String> shortcuts) {
@@ -7069,7 +7081,7 @@
                             mHandler.post(
                                     new NotificationManagerService.EnqueueNotificationRunnable(
                                             r.getUser().getIdentifier(), r, isAppForeground,
-                                            SystemClock.elapsedRealtime()));
+                                            mPostNotificationTrackerFactory.newTracker()));
                         }
                     }
                 }
@@ -7213,12 +7225,12 @@
         }
 
         if (n.isStyle(Notification.CallStyle.class)) {
-            boolean isForegroundService = (n.flags & FLAG_FOREGROUND_SERVICE) != 0;
             boolean hasFullScreenIntent = n.fullScreenIntent != null;
-            if (!isForegroundService && !hasFullScreenIntent) {
+            boolean requestedFullScreenIntent = (n.flags & FLAG_FSI_REQUESTED_BUT_DENIED) != 0;
+            if (!n.isFgsOrUij() && !hasFullScreenIntent && !requestedFullScreenIntent) {
                 throw new IllegalArgumentException(r.getKey() + " Not posted."
-                        + " CallStyle notifications must either be for a foreground Service or"
-                        + " use a fullScreenIntent.");
+                        + " CallStyle notifications must be for a foreground service or"
+                        + " user initated job or use a fullScreenIntent.");
             }
         }
 
@@ -7410,7 +7422,6 @@
             } else {
                 Log.w(TAG, "Cannot snooze " + r.getKey() + ": too many snoozed notifications");
             }
-
         }
 
         @GuardedBy("mNotificationLock")
@@ -7429,14 +7440,25 @@
             cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null,
                     SystemClock.elapsedRealtime());
             updateLightsLocked();
-            if (mSnoozeCriterionId != null) {
-                mAssistants.notifyAssistantSnoozedLocked(r, mSnoozeCriterionId);
-                mSnoozeHelper.snooze(r, mSnoozeCriterionId);
-            } else {
-                mSnoozeHelper.snooze(r, mDuration);
+            if (isSnoozable(r)) {
+                if (mSnoozeCriterionId != null) {
+                    mAssistants.notifyAssistantSnoozedLocked(r, mSnoozeCriterionId);
+                    mSnoozeHelper.snooze(r, mSnoozeCriterionId);
+                } else {
+                    mSnoozeHelper.snooze(r, mDuration);
+                }
+                r.recordSnoozed();
+                handleSavePolicyFile();
             }
-            r.recordSnoozed();
-            handleSavePolicyFile();
+        }
+
+        /**
+         * Autogroup summaries are not snoozable
+         * They will be recreated as needed when the group children are unsnoozed
+         */
+        private boolean isSnoozable(NotificationRecord record) {
+            return !(record.getNotification().isGroupSummary() && GroupHelper.AUTOGROUP_KEY.equals(
+                    record.getNotification().getGroup()));
         }
     }
 
@@ -7607,28 +7629,43 @@
         private final NotificationRecord r;
         private final int userId;
         private final boolean isAppForeground;
-        private final long enqueueElapsedTimeMs;
+        private final PostNotificationTracker mTracker;
 
         EnqueueNotificationRunnable(int userId, NotificationRecord r, boolean foreground,
-                @ElapsedRealtimeLong long enqueueElapsedTimeMs) {
+                PostNotificationTracker tracker) {
             this.userId = userId;
             this.r = r;
             this.isAppForeground = foreground;
-            this.enqueueElapsedTimeMs = enqueueElapsedTimeMs;
+            this.mTracker = checkNotNull(tracker);
         }
 
         @Override
         public void run() {
+            boolean enqueued = false;
+            try {
+                enqueued = enqueueNotification();
+            } finally {
+                if (!enqueued) {
+                    mTracker.cancel();
+                }
+            }
+        }
+
+        /**
+         * @return True if we successfully enqueued the notification and handed off the task of
+         * posting it to a background thread; false otherwise.
+         */
+        private boolean enqueueNotification() {
             synchronized (mNotificationLock) {
-                final Long snoozeAt =
+                final long snoozeAt =
                         mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
                                 r.getUser().getIdentifier(),
                                 r.getSbn().getPackageName(), r.getSbn().getKey());
                 final long currentTime = System.currentTimeMillis();
-                if (snoozeAt.longValue() > currentTime) {
+                if (snoozeAt > currentTime) {
                     (new SnoozeNotificationRunnable(r.getSbn().getKey(),
-                            snoozeAt.longValue() - currentTime, null)).snoozeLocked(r);
-                    return;
+                            snoozeAt - currentTime, null)).snoozeLocked(r);
+                    return false;
                 }
 
                 final String contextId =
@@ -7638,7 +7675,7 @@
                 if (contextId != null) {
                     (new SnoozeNotificationRunnable(r.getSbn().getKey(),
                             0, contextId)).snoozeLocked(r);
-                    return;
+                    return false;
                 }
 
                 mEnqueuedNotifications.add(r);
@@ -7689,12 +7726,14 @@
                     mAssistants.onNotificationEnqueuedLocked(r);
                     mHandler.postDelayed(
                             new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                                    r.getUid(), enqueueElapsedTimeMs),
+                                    r.getUid(), mTracker),
                             DELAY_FOR_ASSISTANT_TIME);
                 } else {
-                    mHandler.post(new PostNotificationRunnable(r.getKey(),
-                            r.getSbn().getPackageName(), r.getUid(), enqueueElapsedTimeMs));
+                    mHandler.post(
+                            new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+                                    r.getUid(), mTracker));
                 }
+                return true;
             }
         }
     }
@@ -7716,22 +7755,37 @@
 
     protected class PostNotificationRunnable implements Runnable {
         private final String key;
-        private final long postElapsedTimeMs;
         private final String pkg;
         private final int uid;
+        private final PostNotificationTracker mTracker;
 
-        PostNotificationRunnable(String key, String pkg, int uid,
-                @ElapsedRealtimeLong long postElapsedTimeMs) {
+        PostNotificationRunnable(String key, String pkg, int uid, PostNotificationTracker tracker) {
             this.key = key;
             this.pkg = pkg;
             this.uid = uid;
-            this.postElapsedTimeMs = postElapsedTimeMs;
+            this.mTracker = checkNotNull(tracker);
         }
 
         @Override
         public void run() {
+            boolean posted = false;
+            try {
+                posted = postNotification();
+            } finally {
+                if (!posted) {
+                    mTracker.cancel();
+                }
+            }
+        }
+
+        /**
+         * @return True if we successfully processed the notification and handed off the task of
+         * notifying all listeners to a background thread; false otherwise.
+         */
+        private boolean postNotification() {
             boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
             boolean isCallNotification = isCallNotification(pkg, uid);
+            boolean posted = false;
             synchronized (mNotificationLock) {
                 try {
                     NotificationRecord r = null;
@@ -7745,7 +7799,7 @@
                     }
                     if (r == null) {
                         Slog.i(TAG, "Cannot find enqueued record for key: " + key);
-                        return;
+                        return false;
                     }
 
                     final StatusBarNotification n = r.getSbn();
@@ -7759,7 +7813,7 @@
                         if (DBG) {
                             Slog.e(TAG, "Suppressing notification from package " + pkg);
                         }
-                        return;
+                        return false;
                     }
 
                     final boolean isPackageSuspended =
@@ -7782,7 +7836,7 @@
                         mNotificationList.add(r);
                         mUsageStats.registerPostedByApp(r);
                         mUsageStatsManagerInternal.reportNotificationPosted(r.getSbn().getOpPkg(),
-                                r.getSbn().getUser(), postElapsedTimeMs);
+                                r.getSbn().getUser(), mTracker.getStartTime());
                         final boolean isInterruptive = isVisuallyInterruptive(null, r);
                         r.setInterruptive(isInterruptive);
                         r.setTextChanged(isInterruptive);
@@ -7791,7 +7845,7 @@
                         mNotificationList.set(index, r);
                         mUsageStats.registerUpdatedByApp(r, old);
                         mUsageStatsManagerInternal.reportNotificationUpdated(r.getSbn().getOpPkg(),
-                                r.getSbn().getUser(), postElapsedTimeMs);
+                                r.getSbn().getUser(), mTracker.getStartTime());
                         // Make sure we don't lose the foreground service state.
                         notification.flags |=
                                 old.getNotification().flags & FLAG_FOREGROUND_SERVICE;
@@ -7818,8 +7872,14 @@
                     }
 
                     if (notification.getSmallIcon() != null) {
+                        mTracker.setReport(
+                                mNotificationRecordLogger.prepareToLogNotificationPosted(r, old,
+                                        position, buzzBeepBlinkLoggingCode,
+                                        getGroupInstanceId(r.getSbn().getGroupKey())));
+                        notifyListenersPostedAndLogLocked(r, old, mTracker);
+                        posted = true;
+
                         StatusBarNotification oldSbn = (old != null) ? old.getSbn() : null;
-                        mListeners.notifyPostedLocked(r, old);
                         if (oldSbn == null
                                 || !Objects.equals(oldSbn.getGroup(), n.getGroup())
                                 || oldSbn.getNotification().flags != n.getNotification().flags) {
@@ -7860,10 +7920,6 @@
                     maybeRecordInterruptionLocked(r);
                     maybeRegisterMessageSent(r);
                     maybeReportForegroundServiceUpdate(r, true);
-
-                    // Log event to statsd
-                    mNotificationRecordLogger.maybeLogNotificationPosted(r, old, position,
-                            buzzBeepBlinkLoggingCode, getGroupInstanceId(r.getSbn().getGroupKey()));
                 } finally {
                     int N = mEnqueuedNotifications.size();
                     for (int i = 0; i < N; i++) {
@@ -7875,6 +7931,7 @@
                     }
                 }
             }
+            return posted;
         }
     }
 
@@ -10790,6 +10847,34 @@
         }
     }
 
+    /**
+     * Asynchronously notify all listeners about a posted (new or updated) notification. This
+     * should be called from {@link PostNotificationRunnable} to "complete" the post (since SysUI is
+     * one of the NLSes, and will display it to the user).
+     *
+     * <p>This method will call {@link PostNotificationTracker#finish} on the supplied tracker
+     * when every {@link NotificationListenerService} has received the news.
+     *
+     * <p>Also takes care of removing a notification that has been visible to a listener before,
+     * but isn't anymore.
+     */
+    @GuardedBy("mNotificationLock")
+    private void notifyListenersPostedAndLogLocked(NotificationRecord r, NotificationRecord old,
+            @NonNull PostNotificationTracker tracker) {
+        List<Runnable> listenerCalls = mListeners.prepareNotifyPostedLocked(r, old, true);
+        mHandler.post(() -> {
+            for (Runnable listenerCall : listenerCalls) {
+                listenerCall.run();
+            }
+
+            tracker.finish();
+            NotificationRecordLogger.NotificationReported report = tracker.getReport();
+            if (report != null) {
+                mNotificationRecordLogger.logNotificationPosted(report);
+            }
+        });
+    }
+
     public class NotificationListeners extends ManagedServices {
         static final String TAG_ENABLED_NOTIFICATION_LISTENERS = "enabled_listeners";
         static final String TAG_REQUESTED_LISTENERS = "request_listeners";
@@ -11160,28 +11245,59 @@
         }
 
         /**
-         * asynchronously notify all listeners about a new notification
+         * Asynchronously notify all listeners about a new or updated notification. Note that the
+         * notification is new or updated from the point of view of the NLS, but might not be
+         * "strictly new" <em>from the point of view of NMS itself</em> -- for example, this method
+         * is also invoked after exiting lockdown mode.
          *
          * <p>
          * Also takes care of removing a notification that has been visible to a listener before,
          * but isn't anymore.
          */
+        @VisibleForTesting
         @GuardedBy("mNotificationLock")
-        public void notifyPostedLocked(NotificationRecord r, NotificationRecord old) {
+        void notifyPostedLocked(NotificationRecord r, NotificationRecord old) {
             notifyPostedLocked(r, old, true);
         }
 
         /**
+         * Asynchronously notify all listeners about a new or updated notification. Note that the
+         * notification is new or updated from the point of view of the NLS, but might not be
+         * "strictly new" <em>from the point of view of NMS itself</em> -- for example, this method
+         * is invoked after exiting lockdown mode.
+         *
          * @param notifyAllListeners notifies all listeners if true, else only notifies listeners
-         *                           targetting <= O_MR1
+         *                           targeting <= O_MR1
          */
+        @VisibleForTesting
         @GuardedBy("mNotificationLock")
         void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
                 boolean notifyAllListeners) {
+            for (Runnable listenerCall : prepareNotifyPostedLocked(r, old, notifyAllListeners)) {
+                mHandler.post(listenerCall);
+            }
+        }
+
+        /**
+         * "Prepares" to notify all listeners about the posted notification.
+         *
+         * <p>This method <em>does not invoke</em> the listeners; the caller should post each
+         * returned {@link Runnable} on a suitable thread to do so.
+         *
+         * @param notifyAllListeners notifies all listeners if true, else only notifies listeners
+         *                           targeting <= O_MR1
+         * @return A list of {@link Runnable} operations to notify all listeners about the posted
+         * notification.
+         */
+        @VisibleForTesting
+        @GuardedBy("mNotificationLock")
+        List<Runnable> prepareNotifyPostedLocked(NotificationRecord r,
+                NotificationRecord old, boolean notifyAllListeners) {
             if (isInLockDownMode(r.getUser().getIdentifier())) {
-                return;
+                return new ArrayList<>();
             }
 
+            ArrayList<Runnable> listenerCalls = new ArrayList<>();
             try {
                 // Lazily initialized snapshots of the notification.
                 StatusBarNotification sbn = r.getSbn();
@@ -11215,7 +11331,7 @@
                     // This notification became invisible -> remove the old one.
                     if (oldSbnVisible && !sbnVisible) {
                         final StatusBarNotification oldSbnLightClone = oldSbn.cloneLight();
-                        mHandler.post(() -> notifyRemoved(
+                        listenerCalls.add(() -> notifyRemoved(
                                 info, oldSbnLightClone, update, null, REASON_USER_STOPPED));
                         continue;
                     }
@@ -11231,11 +11347,12 @@
                             false /* direct */, false /* retainOnUpdate */);
 
                     final StatusBarNotification sbnToPost = trimCache.ForListener(info);
-                    mHandler.post(() -> notifyPosted(info, sbnToPost, update));
+                    listenerCalls.add(() -> notifyPosted(info, sbnToPost, update));
                 }
             } catch (Exception e) {
                 Slog.e(TAG, "Could not notify listeners for " + r.getKey(), e);
             }
+            return listenerCalls;
         }
 
         /**
@@ -11417,7 +11534,7 @@
             int numChangedNotifications = changedNotifications.size();
             for (int i = 0; i < numChangedNotifications; i++) {
                 NotificationRecord rec = changedNotifications.get(i);
-                mListeners.notifyPostedLocked(rec, rec, false);
+                notifyPostedLocked(rec, rec, false);
             }
         }
 
@@ -11481,6 +11598,8 @@
             StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
             try {
                 listener.onNotificationPosted(sbnHolder, rankingUpdate);
+            } catch (android.os.DeadObjectException ex) {
+                Slog.wtf(TAG, "unable to notify listener (posted): " + info, ex);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "unable to notify listener (posted): " + info, ex);
             }
@@ -11502,6 +11621,8 @@
                     reason = REASON_LISTENER_CANCEL;
                 }
                 listener.onNotificationRemoved(sbnHolder, rankingUpdate, stats, reason);
+            } catch (android.os.DeadObjectException ex) {
+                Slog.wtf(TAG, "unable to notify listener (removed): " + info, ex);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "unable to notify listener (removed): " + info, ex);
             }
@@ -11512,6 +11633,8 @@
             final INotificationListener listener = (INotificationListener) info.service;
             try {
                 listener.onNotificationRankingUpdate(rankingUpdate);
+            } catch (android.os.DeadObjectException ex) {
+                Slog.wtf(TAG, "unable to notify listener (ranking update): " + info, ex);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "unable to notify listener (ranking update): " + info, ex);
             }
@@ -12016,4 +12139,76 @@
                     && !CompatChanges.isChangeEnabled(NOTIFICATION_TRAMPOLINE_BLOCK, uid);
         }
     }
+
+    interface PostNotificationTrackerFactory {
+        default PostNotificationTracker newTracker() {
+            return new PostNotificationTracker();
+        }
+    }
+
+    static class PostNotificationTracker {
+        @ElapsedRealtimeLong private final long mStartTime;
+        @Nullable private NotificationRecordLogger.NotificationReported mReport;
+        private boolean mOngoing;
+
+        @VisibleForTesting
+        PostNotificationTracker() {
+            // TODO(b/275044361): (Conditionally) receive a wakelock.
+            mStartTime = SystemClock.elapsedRealtime();
+            mOngoing = true;
+            if (DBG) {
+                Slog.d(TAG, "PostNotification: Started");
+            }
+        }
+
+        void setReport(@Nullable NotificationRecordLogger.NotificationReported report) {
+            mReport = report;
+        }
+
+        NotificationRecordLogger.NotificationReported getReport() {
+            return mReport;
+        }
+
+        @ElapsedRealtimeLong
+        long getStartTime() {
+            return mStartTime;
+        }
+
+        @VisibleForTesting
+        boolean isOngoing() {
+            return mOngoing;
+        }
+
+        void cancel() {
+            if (!isOngoing()) {
+                Log.wtfStack(TAG, "cancel() called on already-finished tracker");
+                return;
+            }
+            mOngoing = false;
+
+            // TODO(b/275044361): Release wakelock.
+
+            if (DBG) {
+                long elapsedTime = SystemClock.elapsedRealtime() - mStartTime;
+                Slog.d(TAG, TextUtils.formatSimple("PostNotification: Abandoned after %d ms",
+                        elapsedTime));
+            }
+        }
+
+        void finish() {
+            if (!isOngoing()) {
+                Log.wtfStack(TAG, "finish() called on already-finished tracker");
+                return;
+            }
+            mOngoing = false;
+
+            // TODO(b/275044361): Release wakelock.
+
+            long elapsedTime = SystemClock.elapsedRealtime() - mStartTime;
+            if (DBG) {
+                Slog.d(TAG,
+                        TextUtils.formatSimple("PostNotification: Finished in %d ms", elapsedTime));
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index 25d619d..71ebf7a 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -42,26 +42,45 @@
  * in production.  Use NotificationRecordLoggerFake for testing.
  * @hide
  */
-public interface NotificationRecordLogger {
+interface NotificationRecordLogger {
 
     // The high-level interface used by clients.
 
     /**
-     * May log a NotificationReported atom reflecting the posting or update of a notification.
-     * @param r The new NotificationRecord. If null, no action is taken.
-     * @param old The previous NotificationRecord.  Null if there was no previous record.
+     * Prepare to log an atom reflecting the posting or update of a notification.
+     *
+     * The returned {@link NotificationReported} object, if any, should be supplied to
+     * {@link #logNotificationPosted}. Because only some updates are considered "interesting
+     * enough" to log, this method may return {@code null}. In that case, the follow-up call
+     * should not be performed.
+     *
+     * @param r The new {@link NotificationRecord}.
+     * @param old The previous {@link NotificationRecord}. Null if there was no previous record.
      * @param position The position at which this notification is ranked.
      * @param buzzBeepBlink Logging code reflecting whether this notification alerted the user.
-     * @param groupId The instance Id of the group summary notification, or null.
+     * @param groupId The {@link InstanceId} of the group summary notification, or null.
      */
-    void maybeLogNotificationPosted(@Nullable NotificationRecord r,
+    @Nullable
+    default NotificationReported prepareToLogNotificationPosted(@Nullable NotificationRecord r,
             @Nullable NotificationRecord old,
             int position, int buzzBeepBlink,
-            InstanceId groupId);
+            InstanceId groupId) {
+        NotificationRecordPair p = new NotificationRecordPair(r, old);
+        if (!p.shouldLogReported(buzzBeepBlink)) {
+            return null;
+        }
+        return new NotificationReported(p, NotificationReportedEvent.fromRecordPair(p), position,
+                buzzBeepBlink, groupId);
+    }
+
+    /**
+     * Log a NotificationReported atom reflecting the posting or update of a notification.
+     */
+    void logNotificationPosted(NotificationReported nr);
 
     /**
      * Logs a NotificationReported atom reflecting an adjustment to a notification.
-     * Unlike maybeLogNotificationPosted, this method is guaranteed to log a notification update,
+     * Unlike for posted notifications, this method is guaranteed to log a notification update,
      * so the caller must take responsibility for checking that that logging update is necessary,
      * and that the notification is meaningfully changed.
      * @param r The NotificationRecord. If null, no action is taken.
@@ -125,7 +144,7 @@
 
         public static NotificationReportedEvent fromRecordPair(NotificationRecordPair p) {
             return (p.old != null) ? NotificationReportedEvent.NOTIFICATION_UPDATED :
-                            NotificationReportedEvent.NOTIFICATION_POSTED;
+                    NotificationReportedEvent.NOTIFICATION_POSTED;
         }
     }
 
@@ -450,6 +469,68 @@
 
     }
 
+    /** Data object corresponding to a NotificationReported atom.
+     *
+     * Fields must be kept in sync with frameworks/proto_logging/stats/atoms.proto.
+     */
+    class NotificationReported {
+        final int event_id;
+        final int uid;
+        final String package_name;
+        final int instance_id;
+        final int notification_id_hash;
+        final int channel_id_hash;
+        final int group_id_hash;
+        final int group_instance_id;
+        final boolean is_group_summary;
+        final String category;
+        final int style;
+        final int num_people;
+        final int position;
+        final int importance;
+        final int alerting;
+        final int importance_source;
+        final int importance_initial;
+        final int importance_initial_source;
+        final int importance_asst;
+        final int assistant_hash;
+        final float assistant_ranking_score;
+        final boolean is_ongoing;
+        final boolean is_foreground_service;
+        final long timeout_millis;
+        final boolean is_non_dismissible;
+
+        NotificationReported(NotificationRecordPair p,
+                NotificationReportedEvent eventType, int position, int buzzBeepBlink,
+                InstanceId groupId) {
+            this.event_id = eventType.getId();
+            this.uid = p.r.getUid();
+            this.package_name = p.r.getSbn().getPackageName();
+            this.instance_id = p.getInstanceId();
+            this.notification_id_hash = p.getNotificationIdHash();
+            this.channel_id_hash = p.getChannelIdHash();
+            this.group_id_hash = p.getGroupIdHash();
+            this.group_instance_id = (groupId == null) ? 0 : groupId.getId();
+            this.is_group_summary = p.r.getSbn().getNotification().isGroupSummary();
+            this.category = p.r.getSbn().getNotification().category;
+            this.style = p.getStyle();
+            this.num_people = p.getNumPeople();
+            this.position = position;
+            this.importance = NotificationRecordLogger.getLoggingImportance(p.r);
+            this.alerting = buzzBeepBlink;
+            this.importance_source = p.r.getImportanceExplanationCode();
+            this.importance_initial = p.r.getInitialImportance();
+            this.importance_initial_source = p.r.getInitialImportanceExplanationCode();
+            this.importance_asst = p.r.getAssistantImportance();
+            this.assistant_hash = p.getAssistantHash();
+            this.assistant_ranking_score = p.r.getRankingScore();
+            this.is_ongoing = p.r.getSbn().isOngoing();
+            this.is_foreground_service = NotificationRecordLogger.isForegroundService(p.r);
+            this.timeout_millis = p.r.getSbn().getNotification().getTimeoutAfter();
+            this.is_non_dismissible = NotificationRecordLogger.isNonDismissible(p.r);
+        }
+    }
+
     /**
      * @param r NotificationRecord
      * @return Logging importance of record, taking important conversation channels into account.
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index 9a1f19d..cd457b7 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -27,20 +27,13 @@
  * Standard implementation of NotificationRecordLogger interface.
  * @hide
  */
-public class NotificationRecordLoggerImpl implements NotificationRecordLogger {
+class NotificationRecordLoggerImpl implements NotificationRecordLogger {
 
     private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
 
     @Override
-    public void maybeLogNotificationPosted(NotificationRecord r, NotificationRecord old,
-            int position, int buzzBeepBlink,
-            InstanceId groupId) {
-        NotificationRecordPair p = new NotificationRecordPair(r, old);
-        if (!p.shouldLogReported(buzzBeepBlink)) {
-            return;
-        }
-        writeNotificationReportedAtom(p, NotificationReportedEvent.fromRecordPair(p),
-                position, buzzBeepBlink, groupId);
+    public void logNotificationPosted(NotificationReported nr) {
+        writeNotificationReportedAtom(nr);
     }
 
     @Override
@@ -48,48 +41,40 @@
             int position, int buzzBeepBlink,
             InstanceId groupId) {
         NotificationRecordPair p = new NotificationRecordPair(r, null);
-        writeNotificationReportedAtom(p, NotificationReportedEvent.NOTIFICATION_ADJUSTED,
-                position, buzzBeepBlink, groupId);
+        writeNotificationReportedAtom(
+                new NotificationReported(p, NotificationReportedEvent.NOTIFICATION_ADJUSTED,
+                        position, buzzBeepBlink, groupId));
     }
 
-    private void writeNotificationReportedAtom(NotificationRecordPair p,
-            NotificationReportedEvent eventType, int position, int buzzBeepBlink,
-            InstanceId groupId) {
-        FrameworkStatsLog.write(FrameworkStatsLog.NOTIFICATION_REPORTED,
-                /* int32 event_id = 1 */ eventType.getId(),
-                /* int32 uid = 2 */ p.r.getUid(),
-                /* string package_name = 3 */ p.r.getSbn().getPackageName(),
-                /* int32 instance_id = 4 */ p.getInstanceId(),
-                /* int32 notification_id_hash = 5 */ p.getNotificationIdHash(),
-                /* int32 channel_id_hash = 6 */ p.getChannelIdHash(),
-                /* string group_id_hash = 7 */ p.getGroupIdHash(),
-                /* int32 group_instance_id = 8 */ (groupId == null) ? 0 : groupId.getId(),
-                /* bool is_group_summary = 9 */ p.r.getSbn().getNotification().isGroupSummary(),
-                /* string category = 10 */ p.r.getSbn().getNotification().category,
-                /* int32 style = 11 */ p.getStyle(),
-                /* int32 num_people = 12 */ p.getNumPeople(),
-                /* int32 position = 13 */ position,
-                /* android.stats.sysui.NotificationImportance importance = 14 */
-                NotificationRecordLogger.getLoggingImportance(p.r),
-                /* int32 alerting = 15 */ buzzBeepBlink,
-                /* NotificationImportanceExplanation importance_source = 16 */
-                p.r.getImportanceExplanationCode(),
-                /* android.stats.sysui.NotificationImportance importance_initial = 17 */
-                p.r.getInitialImportance(),
-                /* NotificationImportanceExplanation importance_initial_source = 18 */
-                p.r.getInitialImportanceExplanationCode(),
-                /* android.stats.sysui.NotificationImportance importance_asst = 19 */
-                p.r.getAssistantImportance(),
-                /* int32 assistant_hash = 20 */ p.getAssistantHash(),
-                /* float assistant_ranking_score = 21 */ p.r.getRankingScore(),
-                /* bool is_ongoing = 22 */ p.r.getSbn().isOngoing(),
-                /* bool is_foreground_service = 23 */
-                NotificationRecordLogger.isForegroundService(p.r),
-                /* optional int64 timeout_millis = 24 */
-                p.r.getSbn().getNotification().getTimeoutAfter(),
-                /* bool is_nondismissible = 25 */
-                NotificationRecordLogger.isNonDismissible(p.r)
-        );
+    private void writeNotificationReportedAtom(
+            NotificationReported notificationReported) {
+        FrameworkStatsLog.write(
+                FrameworkStatsLog.NOTIFICATION_REPORTED,
+                notificationReported.event_id,
+                notificationReported.uid,
+                notificationReported.package_name,
+                notificationReported.instance_id,
+                notificationReported.notification_id_hash,
+                notificationReported.channel_id_hash,
+                notificationReported.group_id_hash,
+                notificationReported.group_instance_id,
+                notificationReported.is_group_summary,
+                notificationReported.category,
+                notificationReported.style,
+                notificationReported.num_people,
+                notificationReported.position,
+                notificationReported.importance,
+                notificationReported.alerting,
+                notificationReported.importance_source,
+                notificationReported.importance_initial,
+                notificationReported.importance_initial_source,
+                notificationReported.importance_asst,
+                notificationReported.assistant_hash,
+                notificationReported.assistant_ranking_score,
+                notificationReported.is_ongoing,
+                notificationReported.is_foreground_service,
+                notificationReported.timeout_millis,
+                notificationReported.is_non_dismissible);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index b6fd822..93c83e1 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -25,6 +25,7 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
+import android.content.Context;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -37,7 +38,6 @@
 import android.util.Slog;
 
 import com.android.internal.util.ArrayUtils;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.util.Collections;
 import java.util.HashSet;
@@ -53,13 +53,13 @@
 
     private static final String NOTIFICATION_PERMISSION = Manifest.permission.POST_NOTIFICATIONS;
 
-    private final PermissionManagerServiceInternal mPmi;
+    private final Context mContext;
     private final IPackageManager mPackageManager;
     private final IPermissionManager mPermManager;
 
-    public PermissionHelper(PermissionManagerServiceInternal pmi, IPackageManager packageManager,
+    public PermissionHelper(Context context, IPackageManager packageManager,
             IPermissionManager permManager) {
-        mPmi = pmi;
+        mContext = context;
         mPackageManager = packageManager;
         mPermManager = permManager;
     }
@@ -71,7 +71,7 @@
     public boolean hasPermission(int uid) {
         final long callingId = Binder.clearCallingIdentity();
         try {
-            return mPmi.checkUidPermission(uid, NOTIFICATION_PERMISSION) == PERMISSION_GRANTED;
+            return mContext.checkPermission(NOTIFICATION_PERMISSION, -1, uid) == PERMISSION_GRANTED;
         } finally {
             Binder.restoreCallingIdentity(callingId);
         }
@@ -193,8 +193,8 @@
                 return;
             }
 
-            boolean currentlyGranted = mPmi.checkPermission(packageName, NOTIFICATION_PERMISSION,
-                    userId) != PackageManager.PERMISSION_DENIED;
+            int uid = mPackageManager.getPackageUid(packageName, 0, userId);
+            boolean currentlyGranted = hasPermission(uid);
             if (grant && !currentlyGranted) {
                 mPermManager.grantRuntimePermission(packageName, NOTIFICATION_PERMISSION, userId);
             } else if (!grant && currentlyGranted) {
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index f733199..2460ce5 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -48,6 +48,7 @@
 import android.content.pm.ParceledListSlice;
 import android.content.pm.UserInfo;
 import android.metrics.LogMaker;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
 import android.os.UserHandle;
@@ -60,6 +61,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.IntArray;
+import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
@@ -387,7 +389,8 @@
                 NotificationChannel channel = new NotificationChannel(
                         id, channelName, channelImportance);
                 if (forRestore) {
-                    channel.populateFromXmlForRestore(parser, mContext);
+                    final boolean pkgInstalled = r.uid != UNKNOWN_UID;
+                    channel.populateFromXmlForRestore(parser, pkgInstalled, mContext);
                 } else {
                     channel.populateFromXml(parser);
                 }
@@ -2412,6 +2415,21 @@
                         mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId));
                         synchronized (mPackagePreferences) {
                             mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r);
+
+                            // Try to restore any unrestored sound resources
+                            for (NotificationChannel channel : r.channels.values()) {
+                                if (!channel.isSoundRestored()) {
+                                    Uri uri = channel.getSound();
+                                    Uri restoredUri = channel.restoreSoundUri(mContext, uri, true);
+                                    if (Settings.System.DEFAULT_NOTIFICATION_URI.equals(
+                                            restoredUri)) {
+                                        Log.w(TAG,
+                                                "Could not restore sound: " + uri + " for channel: "
+                                                        + channel);
+                                    }
+                                    channel.setSound(restoredUri, channel.getAudioAttributes());
+                                }
+                            }
                         }
                         if (r.migrateToPm) {
                             try {
diff --git a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
index 48ee64f..8a28888 100644
--- a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
+++ b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
@@ -437,6 +437,16 @@
                     .addCategory(Intent.CATEGORY_DEFAULT)
                     .build();
 
+    private static final DefaultCrossProfileIntentFilter CLONE_TO_PARENT_PHOTOPICKER_SELECTION =
+            new DefaultCrossProfileIntentFilter.Builder(
+                    DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
+                    /* flags= */ 0x00000018, // 0x00000018 means FLAG_IS_PACKAGE_FOR_FILTER
+                    // and FLAG_ALLOW_CHAINED_RESOLUTION set
+                    /* letsPersonalDataIntoProfile= */ false)
+                    .addAction(MediaStore.ACTION_USER_SELECT_IMAGES_FOR_APP)
+                    .addCategory(Intent.CATEGORY_DEFAULT)
+                    .build();
+
     /*
      Allowing send action from clone to parent profile to share content from clone apps to parent
      apps
@@ -611,7 +621,8 @@
                 CLONE_TO_PARENT_VIEW_ACTION,
                 CLONE_TO_PARENT_PICK_INSERT_ACTION,
                 CLONE_TO_PARENT_DIAL_DATA,
-                CLONE_TO_PARENT_SMS_MMS
+                CLONE_TO_PARENT_SMS_MMS,
+                CLONE_TO_PARENT_PHOTOPICKER_SELECTION
         );
     }
 }
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index 064be7c..39cd888 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -745,6 +745,9 @@
         applyPackageFilter(snapshot, remainingPredicate, result, remainingPkgSettings, sortTemp,
                 packageManagerService);
 
+        // Make sure the system server isn't in the result, because it can never be dexopted here.
+        result.removeIf(pkgSetting -> PLATFORM_PACKAGE_NAME.equals(pkgSetting.getPackageName()));
+
         if (debug) {
             Log.i(TAG, "Packages to be dexopted: " + packagesToString(result));
             Log.i(TAG, "Packages skipped from dexopt: " + packagesToString(remainingPkgSettings));
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 1e0c95c..a267e8a 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -118,6 +118,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
+import android.content.pm.ResolveInfo;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.Signature;
 import android.content.pm.SigningDetails;
@@ -3975,6 +3976,24 @@
                 mPm.mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true);
             }
         }
+
+        // If this is a system app we hadn't seen before, and this is a first boot or OTA,
+        // we need to unstop it if it doesn't have a launcher entry.
+        if (mPm.mShouldStopSystemPackagesByDefault && scanResult.mRequest.mPkgSetting == null
+                && ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0)
+                && ((scanFlags & SCAN_AS_SYSTEM) != 0)) {
+            final Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
+            launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            launcherIntent.setPackage(parsedPackage.getPackageName());
+            final List<ResolveInfo> launcherActivities =
+                    mPm.snapshotComputer().queryIntentActivitiesInternal(launcherIntent, null,
+                            PackageManager.MATCH_DIRECT_BOOT_AWARE
+                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 0);
+            if (launcherActivities.isEmpty()) {
+                scanResult.mPkgSetting.setStopped(false, 0);
+            }
+        }
+
         if (mIncrementalManager != null && isIncrementalPath(parsedPackage.getPath())) {
             if (scanResult.mPkgSetting != null && scanResult.mPkgSetting.isLoading()) {
                 // Continue monitoring loading progress of active incremental packages
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 402fb30..9b1a80be 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -1120,12 +1120,12 @@
                     return shortcutOverridesInfo;
                 }
 
-                List<String> packagesToOverride =
+                Map<String, String> packagesToOverride =
                         DevicePolicyCache.getInstance().getLauncherShortcutOverrides();
-                for (String packageName : packagesToOverride) {
+                for (Map.Entry<String, String> packageNames : packagesToOverride.entrySet()) {
                     Intent intent = new Intent(Intent.ACTION_MAIN)
                             .addCategory(Intent.CATEGORY_LAUNCHER)
-                            .setPackage(packageName);
+                            .setPackage(packageNames.getValue());
 
                     List<LauncherActivityInfoInternal> possibleShortcutOverrides =
                             queryIntentLauncherActivities(
@@ -1135,7 +1135,8 @@
                             );
 
                     if (!possibleShortcutOverrides.isEmpty()) {
-                        shortcutOverridesInfo.put(packageName, possibleShortcutOverrides.get(0));
+                        shortcutOverridesInfo.put(packageNames.getKey(),
+                                possibleShortcutOverrides.get(0));
                     }
                 }
                 return shortcutOverridesInfo;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 006d7c8..29c5ada 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1148,8 +1148,13 @@
             info.userId = userId;
             info.installerPackageName = mInstallSource.mInstallerPackageName;
             info.installerAttributionTag = mInstallSource.mInstallerAttributionTag;
-            info.resolvedBaseCodePath = (mResolvedBaseFile != null) ?
-                    mResolvedBaseFile.getAbsolutePath() : null;
+            if (mContext.checkCallingOrSelfPermission(
+                    Manifest.permission.READ_INSTALLED_SESSION_PATHS)
+                            == PackageManager.PERMISSION_GRANTED && mResolvedBaseFile != null) {
+                info.resolvedBaseCodePath = mResolvedBaseFile.getAbsolutePath();
+            } else {
+                info.resolvedBaseCodePath = null;
+            }
             info.progress = progress;
             info.sealed = mSealed;
             info.isCommitted = isCommitted();
@@ -2754,11 +2759,6 @@
                         : PackageInstaller.ACTION_CONFIRM_INSTALL);
         intent.setPackage(mPm.getPackageInstallerPackageName());
         intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
-        synchronized (mLock) {
-            intent.putExtra(PackageInstaller.EXTRA_RESOLVED_BASE_PATH,
-                    mResolvedBaseFile != null ? mResolvedBaseFile.getAbsolutePath() : null);
-        }
-
         sendOnUserActionRequired(mContext, target, sessionId, intent);
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index eea6720..f78b611 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -24,6 +24,7 @@
 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
 
 import static com.android.server.LocalManagerRegistry.ManagerNotFoundException;
+import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import android.accounts.IAccountManager;
 import android.annotation.NonNull;
@@ -927,6 +928,7 @@
         boolean showUid = false;
         boolean showVersionCode = false;
         boolean listApexOnly = false;
+        boolean showStopped = false;
         int uid = -1;
         int defaultUserId = UserHandle.USER_ALL;
         try {
@@ -984,6 +986,9 @@
                     case "--match-libraries":
                         getFlags |= PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES;
                         break;
+                    case "--show-stopped":
+                        showStopped = true;
+                        break;
                     default:
                         pw.println("Error: Unknown option: " + opt);
                         return -1;
@@ -1076,6 +1081,12 @@
                         stringBuilder.append(info.getLongVersionCode());
                     }
                 }
+                if (showStopped) {
+                    stringBuilder.append(" stopped=");
+                    stringBuilder.append(
+                            ((info.applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0)
+                            ? "true" : "false");
+                }
                 if (listInstaller) {
                     stringBuilder.append("  installer=");
                     stringBuilder.append(mInterface.getInstallerPackageName(info.packageName));
@@ -1954,6 +1965,8 @@
         List<String> packageNames = null;
         if (allPackages) {
             packageNames = mInterface.getAllPackages();
+            // Compiling the system server is only supported from odrefresh, so skip it.
+            packageNames.removeIf(packageName -> PLATFORM_PACKAGE_NAME.equals(packageName));
         } else {
             String packageName = getNextArg();
             if (packageName == null) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index e8f89d3..e0dbcbf 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4293,10 +4293,23 @@
 
                 // Non-Apex system apps, that are not included in the allowlist in
                 // initialNonStoppedSystemPackages, should be marked as stopped by default.
-                final boolean shouldBeStopped = service.mShouldStopSystemPackagesByDefault
+                boolean shouldBeStopped = service.mShouldStopSystemPackagesByDefault
                         && ps.isSystem()
                         && !ps.isApex()
                         && !service.mInitialNonStoppedSystemPackages.contains(ps.getPackageName());
+                if (shouldBeStopped) {
+                    final Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
+                    launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+                    launcherIntent.setPackage(ps.getPackageName());
+                    final List<ResolveInfo> launcherActivities =
+                            service.snapshotComputer().queryIntentActivitiesInternal(launcherIntent,
+                                    null,
+                                    PackageManager.MATCH_DIRECT_BOOT_AWARE
+                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 0);
+                    if (launcherActivities.isEmpty()) {
+                        shouldBeStopped = false;
+                    }
+                }
                 ps.setStopped(shouldBeStopped, userHandle);
 
                 // If userTypeInstallablePackages is the *only* reason why we're not installing,
@@ -4922,6 +4935,8 @@
             date.setTime(ps.getLoadingCompletedTime());
             pw.print(prefix); pw.println("  loadingCompletedTime=" + sdf.format(date));
         }
+        pw.print(prefix); pw.print("  appMetadataFilePath=");
+        pw.println(ps.getAppMetadataFilePath());
         if (ps.getVolumeUuid() != null) {
             pw.print(prefix); pw.print("  volumeUuid=");
                     pw.println(ps.getVolumeUuid());
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index b669ba2..2f0cea3 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -93,7 +93,6 @@
 import android.text.TextUtils;
 import android.text.format.TimeMigrationUtils;
 import android.util.ArraySet;
-import android.util.AtomicFile;
 import android.util.KeyValueListParser;
 import android.util.Log;
 import android.util.Slog;
@@ -149,6 +148,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 import java.util.regex.Pattern;
@@ -321,8 +321,7 @@
     private final ArrayList<LauncherApps.ShortcutChangeCallback> mShortcutChangeCallbacks =
             new ArrayList<>(1);
 
-    @GuardedBy("mLock")
-    private long mRawLastResetTime;
+    private final AtomicLong mRawLastResetTime = new AtomicLong(0);
 
     /**
      * User ID -> UserShortcuts
@@ -756,10 +755,15 @@
     }
 
     /** Return the base state file name */
-    private AtomicFile getBaseStateFile() {
-        final File path = new File(injectSystemDataPath(), FILENAME_BASE_STATE);
-        path.mkdirs();
-        return new AtomicFile(path);
+    final ResilientAtomicFile getBaseStateFile() {
+        File mainFile = new File(injectSystemDataPath(), FILENAME_BASE_STATE);
+        File temporaryBackup = new File(injectSystemDataPath(),
+                FILENAME_BASE_STATE + ".backup");
+        File reserveCopy = new File(injectSystemDataPath(),
+                FILENAME_BASE_STATE + ".reservecopy");
+        int fileMode = FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH;
+        return new ResilientAtomicFile(mainFile, temporaryBackup, reserveCopy, fileMode,
+                "base shortcut", null);
     }
 
     /**
@@ -976,80 +980,91 @@
         writeAttr(out, name, intent.toUri(/* flags =*/ 0));
     }
 
-    @GuardedBy("mLock")
     @VisibleForTesting
-    void saveBaseStateLocked() {
-        final AtomicFile file = getBaseStateFile();
-        if (DEBUG || DEBUG_REBOOT) {
-            Slog.d(TAG, "Saving to " + file.getBaseFile());
-        }
+    void saveBaseState() {
+        try (ResilientAtomicFile file = getBaseStateFile()) {
+            if (DEBUG || DEBUG_REBOOT) {
+                Slog.d(TAG, "Saving to " + file.getBaseFile());
+            }
 
-        FileOutputStream outs = null;
-        try {
-            outs = file.startWrite();
+            FileOutputStream outs = null;
+            try {
+                synchronized (mLock) {
+                    outs = file.startWrite();
+                }
 
-            // Write to XML
-            TypedXmlSerializer out = Xml.resolveSerializer(outs);
-            out.startDocument(null, true);
-            out.startTag(null, TAG_ROOT);
+                // Write to XML
+                TypedXmlSerializer out = Xml.resolveSerializer(outs);
+                out.startDocument(null, true);
+                out.startTag(null, TAG_ROOT);
 
-            // Body.
-            writeTagValue(out, TAG_LAST_RESET_TIME, mRawLastResetTime);
+                // Body.
+                // No locking required. Ok to add lock later if we save more data.
+                writeTagValue(out, TAG_LAST_RESET_TIME, mRawLastResetTime.get());
 
-            // Epilogue.
-            out.endTag(null, TAG_ROOT);
-            out.endDocument();
+                // Epilogue.
+                out.endTag(null, TAG_ROOT);
+                out.endDocument();
 
-            // Close.
-            file.finishWrite(outs);
-        } catch (IOException e) {
-            Slog.e(TAG, "Failed to write to file " + file.getBaseFile(), e);
-            file.failWrite(outs);
+                // Close.
+                file.finishWrite(outs);
+            } catch (IOException e) {
+                Slog.e(TAG, "Failed to write to file " + file.getBaseFile(), e);
+                file.failWrite(outs);
+            }
         }
     }
 
     @GuardedBy("mLock")
     private void loadBaseStateLocked() {
-        mRawLastResetTime = 0;
+        mRawLastResetTime.set(0);
 
-        final AtomicFile file = getBaseStateFile();
-        if (DEBUG || DEBUG_REBOOT) {
-            Slog.d(TAG, "Loading from " + file.getBaseFile());
-        }
-        try (FileInputStream in = file.openRead()) {
-            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;
-                    }
-                    continue;
-                }
-                // Assume depth == 2
-                switch (tag) {
-                    case TAG_LAST_RESET_TIME:
-                        mRawLastResetTime = parseLongAttribute(parser, ATTR_VALUE);
-                        break;
-                    default:
-                        Slog.e(TAG, "Invalid tag: " + tag);
-                        break;
-                }
+        try (ResilientAtomicFile file = getBaseStateFile()) {
+            if (DEBUG || DEBUG_REBOOT) {
+                Slog.d(TAG, "Loading from " + file.getBaseFile());
             }
-        } catch (FileNotFoundException e) {
-            // Use the default
-        } catch (IOException | XmlPullParserException e) {
-            Slog.e(TAG, "Failed to read file " + file.getBaseFile(), e);
+            FileInputStream in = null;
+            try {
+                in = file.openRead();
+                if (in == null) {
+                    throw new FileNotFoundException(file.getBaseFile().getAbsolutePath());
+                }
 
-            mRawLastResetTime = 0;
+                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;
+                        }
+                        continue;
+                    }
+                    // Assume depth == 2
+                    switch (tag) {
+                        case TAG_LAST_RESET_TIME:
+                            mRawLastResetTime.set(parseLongAttribute(parser, ATTR_VALUE));
+                            break;
+                        default:
+                            Slog.e(TAG, "Invalid tag: " + tag);
+                            break;
+                    }
+                }
+            } catch (FileNotFoundException e) {
+                // Use the default
+            } catch (IOException | XmlPullParserException e) {
+                // Remove corrupted file and retry.
+                file.failRead(in, e);
+                loadBaseStateLocked();
+                return;
+            }
         }
         // Adjust the last reset time.
         getLastResetTimeLocked();
@@ -1067,8 +1082,7 @@
                 "user shortcut", null);
     }
 
-    @GuardedBy("mLock")
-    private void saveUserLocked(@UserIdInt int userId) {
+    private void saveUser(@UserIdInt int userId) {
         try (ResilientAtomicFile file = getUserFile(userId)) {
             FileOutputStream os = null;
             try {
@@ -1076,9 +1090,10 @@
                     Slog.d(TAG, "Saving to " + file);
                 }
 
-                os = file.startWrite();
-
-                saveUserInternalLocked(userId, os, /* forBackup= */ false);
+                synchronized (mLock) {
+                    os = file.startWrite();
+                    saveUserInternalLocked(userId, os, /* forBackup= */ false);
+                }
 
                 file.finishWrite(os);
 
@@ -1215,16 +1230,19 @@
         }
         try {
             Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "shortcutSaveDirtyInfo");
+            List<Integer> dirtyUserIds = new ArrayList<>();
             synchronized (mLock) {
-                for (int i = mDirtyUserIds.size() - 1; i >= 0; i--) {
-                    final int userId = mDirtyUserIds.get(i);
-                    if (userId == UserHandle.USER_NULL) { // USER_NULL for base state.
-                        saveBaseStateLocked();
-                    } else {
-                        saveUserLocked(userId);
-                    }
+                List<Integer> tmp = mDirtyUserIds;
+                mDirtyUserIds = dirtyUserIds;
+                dirtyUserIds = tmp;
+            }
+            for (int i = dirtyUserIds.size() - 1; i >= 0; i--) {
+                final int userId = dirtyUserIds.get(i);
+                if (userId == UserHandle.USER_NULL) { // USER_NULL for base state.
+                    saveBaseState();
+                } else {
+                    saveUser(userId);
                 }
-                mDirtyUserIds.clear();
             }
         } catch (Exception e) {
             wtf("Exception in saveDirtyInfo", e);
@@ -1237,14 +1255,14 @@
     @GuardedBy("mLock")
     long getLastResetTimeLocked() {
         updateTimesLocked();
-        return mRawLastResetTime;
+        return mRawLastResetTime.get();
     }
 
     /** Return the next reset time. */
     @GuardedBy("mLock")
     long getNextResetTimeLocked() {
         updateTimesLocked();
-        return mRawLastResetTime + mResetInterval;
+        return mRawLastResetTime.get() + mResetInterval;
     }
 
     static boolean isClockValid(long time) {
@@ -1259,25 +1277,26 @@
 
         final long now = injectCurrentTimeMillis();
 
-        final long prevLastResetTime = mRawLastResetTime;
+        final long prevLastResetTime = mRawLastResetTime.get();
+        long newLastResetTime = prevLastResetTime;
 
-        if (mRawLastResetTime == 0) { // first launch.
+        if (newLastResetTime == 0) { // first launch.
             // TODO Randomize??
-            mRawLastResetTime = now;
-        } else if (now < mRawLastResetTime) {
+            newLastResetTime = now;
+        } else if (now < newLastResetTime) {
             // Clock rewound.
             if (isClockValid(now)) {
                 Slog.w(TAG, "Clock rewound");
                 // TODO Randomize??
-                mRawLastResetTime = now;
+                newLastResetTime = now;
             }
-        } else {
-            if ((mRawLastResetTime + mResetInterval) <= now) {
-                final long offset = mRawLastResetTime % mResetInterval;
-                mRawLastResetTime = ((now / mResetInterval) * mResetInterval) + offset;
-            }
+        } else if ((newLastResetTime + mResetInterval) <= now) {
+            final long offset = newLastResetTime % mResetInterval;
+            newLastResetTime = ((now / mResetInterval) * mResetInterval) + offset;
         }
-        if (prevLastResetTime != mRawLastResetTime) {
+
+        mRawLastResetTime.set(newLastResetTime);
+        if (prevLastResetTime != newLastResetTime) {
             scheduleSaveBaseState();
         }
     }
@@ -1716,6 +1735,11 @@
         if (si == null) {
             return;
         }
+
+        if (isCallerSystem()) {
+            return; // no check
+        }
+
         if (!Objects.equals(callerPackage, si.getPackage())) {
             android.util.EventLog.writeEvent(0x534e4554, "109824443", -1, "");
             throw new SecurityException("Shortcut package name mismatch");
@@ -2700,9 +2724,7 @@
     }
 
     void resetAllThrottlingInner() {
-        synchronized (mLock) {
-            mRawLastResetTime = injectCurrentTimeMillis();
-        }
+        mRawLastResetTime.set(injectCurrentTimeMillis());
         scheduleSaveBaseState();
         Slog.i(TAG, "ShortcutManager: throttling counter reset for all users");
     }
@@ -2720,8 +2742,8 @@
             }
             getPackageShortcutsLocked(packageName, userId)
                     .resetRateLimitingForCommandLineNoSaving();
-            saveUserLocked(userId);
         }
+        saveUser(userId);
     }
 
     // We override this method in unit tests to do a simpler check.
@@ -4500,8 +4522,8 @@
                 dumpCurrentTime(pw);
                 pw.println();
             });
-            saveUserLocked(userId);
         }
+        saveUser(userId);
     }
 
     // === Dump ===
@@ -4712,9 +4734,9 @@
                 pw.print(formatTime(now));
 
                 pw.print("  Raw last reset: [");
-                pw.print(mRawLastResetTime);
+                pw.print(mRawLastResetTime.get());
                 pw.print("] ");
-                pw.print(formatTime(mRawLastResetTime));
+                pw.print(formatTime(mRawLastResetTime.get()));
 
                 final long last = getLastResetTimeLocked();
                 pw.print("  Last reset: [");
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index aeadcd5..79eed64 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1004,7 +1004,7 @@
             return;
         }
 
-        final boolean interactive = Display.isOnState(mDefaultDisplay.getState());
+        final boolean interactive = mDefaultDisplayPolicy.isAwake();
 
         Slog.d(TAG, "powerPress: eventTime=" + eventTime + " interactive=" + interactive
                 + " count=" + count + " beganFromNonInteractive=" + beganFromNonInteractive
@@ -2186,12 +2186,6 @@
                     Intent.EXTRA_DOCK_STATE_UNDOCKED));
         }
 
-        // register for dream-related broadcasts
-        filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_DREAMING_STARTED);
-        filter.addAction(Intent.ACTION_DREAMING_STOPPED);
-        mContext.registerReceiver(mDreamReceiver, filter);
-
         // register for multiuser-relevant broadcasts
         filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
         mContext.registerReceiver(mMultiuserReceiver, filter);
@@ -2207,8 +2201,10 @@
 
         // Match current screen state.
         if (!mPowerManager.isInteractive()) {
-            startedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
-            finishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+            startedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP,
+                    PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+            finishedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP,
+                    PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
         }
 
         mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
@@ -2993,6 +2989,7 @@
                 }
                 break;
             case KeyEvent.KEYCODE_H:
+            case KeyEvent.KEYCODE_ENTER:
                 if (event.isMetaPressed()) {
                     return handleHomeShortcuts(displayId, focusedToken, event);
                 }
@@ -4100,7 +4097,7 @@
 
         // This could prevent some wrong state in multi-displays environment,
         // the default display may turned off but interactive is true.
-        final boolean isDefaultDisplayOn = Display.isOnState(mDefaultDisplay.getState());
+        final boolean isDefaultDisplayOn = mDefaultDisplayPolicy.isAwake();
         final boolean interactiveAndOn = interactive && isDefaultDisplayOn;
         if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
             handleKeyGesture(event, interactiveAndOn);
@@ -4785,21 +4782,6 @@
         }
     };
 
-    BroadcastReceiver mDreamReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_DREAMING_STARTED.equals(intent.getAction())) {
-                if (mKeyguardDelegate != null) {
-                    mKeyguardDelegate.onDreamingStarted();
-                }
-            } else if (Intent.ACTION_DREAMING_STOPPED.equals(intent.getAction())) {
-                if (mKeyguardDelegate != null) {
-                    mKeyguardDelegate.onDreamingStopped();
-                }
-            }
-        }
-    };
-
     BroadcastReceiver mMultiuserReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -4815,17 +4797,40 @@
         }
     };
 
+    @Override
+    public void startedWakingUpGlobal(@WakeReason int reason) {
+
+    }
+
+    @Override
+    public void finishedWakingUpGlobal(@WakeReason int reason) {
+
+    }
+
+    @Override
+    public void startedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) {
+        mDeviceGoingToSleep = true;
+    }
+
+    @Override
+    public void finishedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) {
+        mDeviceGoingToSleep = false;
+    }
+
     // Called on the PowerManager's Notifier thread.
     @Override
-    public void startedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
+    public void startedGoingToSleep(int displayGroupId,
+            @PowerManager.GoToSleepReason int pmSleepReason) {
         if (DEBUG_WAKEUP) {
-            Slog.i(TAG, "Started going to sleep... (why="
+            Slog.i(TAG, "Started going to sleep... (groupId=" + displayGroupId + " why="
                     + WindowManagerPolicyConstants.offReasonToString(
                             WindowManagerPolicyConstants.translateSleepReasonToOffReason(
                                     pmSleepReason)) + ")");
         }
+        if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
+            return;
+        }
 
-        mDeviceGoingToSleep = true;
         mRequestedOrSleepingDefaultDisplay = true;
 
         if (mKeyguardDelegate != null) {
@@ -4835,17 +4840,20 @@
 
     // Called on the PowerManager's Notifier thread.
     @Override
-    public void finishedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
+    public void finishedGoingToSleep(int displayGroupId,
+            @PowerManager.GoToSleepReason int pmSleepReason) {
+        if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
+            return;
+        }
         EventLogTags.writeScreenToggled(0);
         if (DEBUG_WAKEUP) {
-            Slog.i(TAG, "Finished going to sleep... (why="
+            Slog.i(TAG, "Finished going to sleep... (groupId=" + displayGroupId + " why="
                     + WindowManagerPolicyConstants.offReasonToString(
                             WindowManagerPolicyConstants.translateSleepReasonToOffReason(
                                     pmSleepReason)) + ")");
         }
         MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
 
-        mDeviceGoingToSleep = false;
         mRequestedOrSleepingDefaultDisplay = false;
         mDefaultDisplayPolicy.setAwake(false);
 
@@ -4870,26 +4878,18 @@
 
     // Called on the PowerManager's Notifier thread.
     @Override
-    public void onPowerGroupWakefulnessChanged(int groupId, int wakefulness,
-            @PowerManager.GoToSleepReason int pmSleepReason, int globalWakefulness) {
-        if (wakefulness != globalWakefulness
-                && wakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE
-                && groupId == Display.DEFAULT_DISPLAY_GROUP
-                && mKeyguardDelegate != null) {
-            mKeyguardDelegate.doKeyguardTimeout(null);
-        }
-    }
-
-    // Called on the PowerManager's Notifier thread.
-    @Override
-    public void startedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
-        EventLogTags.writeScreenToggled(1);
+    public void startedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) {
         if (DEBUG_WAKEUP) {
-            Slog.i(TAG, "Started waking up... (why="
+            Slog.i(TAG, "Started waking up... (groupId=" + displayGroupId + " why="
                     + WindowManagerPolicyConstants.onReasonToString(
-                            WindowManagerPolicyConstants.translateWakeReasonToOnReason(
-                                    pmWakeReason)) + ")");
+                    WindowManagerPolicyConstants.translateWakeReasonToOnReason(
+                            pmWakeReason)) + ")");
         }
+        if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
+            return;
+        }
+        EventLogTags.writeScreenToggled(1);
+
 
         mDefaultDisplayPolicy.setAwake(true);
 
@@ -4912,13 +4912,16 @@
 
     // Called on the PowerManager's Notifier thread.
     @Override
-    public void finishedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
+    public void finishedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) {
         if (DEBUG_WAKEUP) {
-            Slog.i(TAG, "Finished waking up... (why="
+            Slog.i(TAG, "Finished waking up... (groupId=" + displayGroupId + " why="
                     + WindowManagerPolicyConstants.onReasonToString(
                             WindowManagerPolicyConstants.translateWakeReasonToOnReason(
                                     pmWakeReason)) + ")");
         }
+        if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
+            return;
+        }
 
         if (mKeyguardDelegate != null) {
             mKeyguardDelegate.onFinishedWakingUp();
@@ -5007,11 +5010,11 @@
 
     // Called on the DisplayManager's DisplayPowerController thread.
     @Override
-    public void screenTurnedOff(int displayId) {
+    public void screenTurnedOff(int displayId, boolean isSwappingDisplay) {
         if (DEBUG_WAKEUP) Slog.i(TAG, "Display" + displayId + " turned off...");
 
         if (displayId == DEFAULT_DISPLAY) {
-            updateScreenOffSleepToken(true);
+            updateScreenOffSleepToken(true, isSwappingDisplay);
             mRequestedOrSleepingDefaultDisplay = false;
             mDefaultDisplayPolicy.screenTurnedOff();
             synchronized (mLock) {
@@ -5062,7 +5065,7 @@
         if (displayId == DEFAULT_DISPLAY) {
             Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn",
                     0 /* cookie */);
-            updateScreenOffSleepToken(false);
+            updateScreenOffSleepToken(false /* acquire */, false /* isSwappingDisplay */);
             mDefaultDisplayPolicy.screenTurnedOn(screenOnListener);
             mBootAnimationDismissable = false;
 
@@ -5398,8 +5401,8 @@
             }
         }
         mSideFpsEventHandler.onFingerprintSensorReady();
-        startedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
-        finishedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
+        startedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN);
+        finishedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN);
 
         int defaultDisplayState = mDisplayManager.getDisplay(DEFAULT_DISPLAY).getState();
         boolean defaultDisplayOn = defaultDisplayState == Display.STATE_ON;
@@ -5581,9 +5584,9 @@
     }
 
     // TODO (multidisplay): Support multiple displays in WindowManagerPolicy.
-    private void updateScreenOffSleepToken(boolean acquire) {
+    private void updateScreenOffSleepToken(boolean acquire, boolean isSwappingDisplay) {
         if (acquire) {
-            mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY);
+            mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY, isSwappingDisplay);
         } else {
             mScreenOffSleepTokenAcquirer.release(DEFAULT_DISPLAY);
         }
diff --git a/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java b/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
index 92f00113..9c3b38a 100644
--- a/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
+++ b/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java
@@ -395,7 +395,7 @@
 
     private class KeyHandler extends Handler {
         KeyHandler() {
-            super(Looper.getMainLooper());
+            super(Looper.myLooper());
         }
 
         @Override
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 5d558e9..887f946 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -67,10 +67,12 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.companion.virtual.VirtualDevice;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.hardware.display.VirtualDisplay;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.PowerManager;
@@ -762,50 +764,84 @@
     void setAllowLockscreenWhenOn(int displayId, boolean allow);
 
     /**
+     * Called when the global wakefulness is becoming awake.
+     *
+     * @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
+     */
+    void startedWakingUpGlobal(@PowerManager.WakeReason int reason);
+
+    /**
+     * Called when the global wakefulness has finished becoming awake.
+     *
+     * @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
+     */
+    void finishedWakingUpGlobal(@PowerManager.WakeReason int reason);
+
+    /**
+     * Called when the global wakefulness has started going to sleep.
+     *
+     * @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
+     */
+    void startedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason);
+
+    /**
+     * Called when the global wakefulness has finished going to sleep.
+     *
+     * @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
+     */
+    void finishedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason);
+
+    /**
      * Called when the device has started waking up.
      *
-     * @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason we're
-     * waking up, such as WAKE_REASON_POWER_BUTTON or WAKE_REASON_GESTURE.
+     * @param displayGroupId The id of the display group that has started waking up. This will often
+     *                       be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is possible for other
+     *                       display groups to exist, for example when there is a
+     *                       {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
+     * @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason this
+     *                     display group is waking up, such as WAKE_REASON_POWER_BUTTON or
+     *                     WAKE_REASON_GESTURE.
      */
-    void startedWakingUp(@PowerManager.WakeReason int pmWakeReason);
+    void startedWakingUp(int displayGroupId, @PowerManager.WakeReason int pmWakeReason);
 
     /**
      * Called when the device has finished waking up.
      *
-     * @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason we're
-     * waking up, such as WAKE_REASON_POWER_BUTTON or WAKE_REASON_GESTURE.
+     * @param displayGroupId The id of the display group that has finished waking. This will often
+     *                       be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is possible for other
+     *                       display groups to exist, for example when there is a
+     *                       {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
+     * @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason this
+     *                     display group is waking up, such as WAKE_REASON_POWER_BUTTON or
+     *                     WAKE_REASON_GESTURE.
      */
-    void finishedWakingUp(@PowerManager.WakeReason int pmWakeReason);
+    void finishedWakingUp(int displayGroupId, @PowerManager.WakeReason int pmWakeReason);
 
     /**
      * Called when the device has started going to sleep.
      *
+     * @param displayGroupId The id of the display group that has started going to sleep. This
+     *                       will often be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is
+     *                       possible for other display groups to exist, for example when there is a
+     *                       {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
      * @param pmSleepReason One of PowerManager.GO_TO_SLEEP_REASON_*, detailing the specific reason
-     * we're going to sleep, such as GO_TO_SLEEP_REASON_POWER_BUTTON or GO_TO_SLEEP_REASON_TIMEOUT.
+     *                      this display group is going to sleep, such as
+     *                      GO_TO_SLEEP_REASON_POWER_BUTTON or GO_TO_SLEEP_REASON_TIMEOUT.
      */
-    public void startedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason);
+    void startedGoingToSleep(int displayGroupId, @PowerManager.GoToSleepReason int pmSleepReason);
 
     /**
      * Called when the device has finished going to sleep.
      *
+     * @param displayGroupId The id of the display group that has finished going to sleep. This
+     *                       will often be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is
+     *                       possible for other display groups to exist, for example when there is a
+     *                       {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
      * @param pmSleepReason One of PowerManager.GO_TO_SLEEP_REASON_*, detailing the specific reason
-     * we're going to sleep, such as GO_TO_SLEEP_REASON_POWER_BUTTON or GO_TO_SLEEP_REASON_TIMEOUT.
+     *                      we're going to sleep, such as GO_TO_SLEEP_REASON_POWER_BUTTON or
+     *                      GO_TO_SLEEP_REASON_TIMEOUT.
      */
-    public void finishedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason);
-
-    /**
-     * Called when a particular PowerGroup has changed wakefulness.
-     *
-     * @param groupId The id of the PowerGroup.
-     * @param wakefulness One of PowerManagerInternal.WAKEFULNESS_* indicating the wake state for
-     * the group
-     * @param pmSleepReason One of PowerManager.GO_TO_SLEEP_REASON_*, detailing the reason this
-     * group is going to sleep.
-     * @param globalWakefulness The global wakefulness, which may or may not match that of this
-     * group. One of PowerManagerInternal.WAKEFULNESS_*
-     */
-    void onPowerGroupWakefulnessChanged(int groupId, int wakefulness,
-            @PowerManager.GoToSleepReason int pmSleepReason, int globalWakefulness);
+    void finishedGoingToSleep(int displayGroupId, @PowerManager.GoToSleepReason int pmSleepReason);
 
     /**
      * Called when the display is about to turn on to show content.
@@ -835,8 +871,10 @@
 
     /**
      * Called when the display has turned off.
+     * @param displayId The display to apply to.
+     * @param isSwappingDisplay Whether the display is swapping to another physical display.
      */
-    public void screenTurnedOff(int displayId);
+    void screenTurnedOff(int displayId, boolean isSwappingDisplay);
 
     public interface ScreenOnListener {
         void onScreenOn();
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 646dc4e..495e239 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -18,6 +18,7 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.service.dreams.DreamManagerInternal;
 import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
@@ -27,6 +28,7 @@
 import com.android.internal.policy.IKeyguardDrawnCallback;
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardService;
+import com.android.server.LocalServices;
 import com.android.server.UiThread;
 import com.android.server.policy.WindowManagerPolicy.OnKeyguardExitResult;
 import com.android.server.wm.EventLogTags;
@@ -60,6 +62,19 @@
 
     private DrawnListener mDrawnListenerWhenConnect;
 
+    private final DreamManagerInternal.DreamManagerStateListener mDreamManagerStateListener =
+            new DreamManagerInternal.DreamManagerStateListener() {
+                @Override
+                public void onDreamingStarted() {
+                    KeyguardServiceDelegate.this.onDreamingStarted();
+                }
+
+                @Override
+                public void onDreamingStopped() {
+                    KeyguardServiceDelegate.this.onDreamingStopped();
+                }
+            };
+
     private static final class KeyguardState {
         KeyguardState() {
             reset();
@@ -158,6 +173,11 @@
         } else {
             if (DEBUG) Log.v(TAG, "*** Keyguard started");
         }
+
+        final DreamManagerInternal dreamManager =
+                LocalServices.getService(DreamManagerInternal.class);
+
+        dreamManager.registerDreamManagerStateListener(mDreamManagerStateListener);
     }
 
     private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index d0ed9bf..9bc0ee22 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -51,6 +51,7 @@
 import android.telephony.TelephonyManager;
 import android.util.EventLog;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.view.WindowManagerPolicyConstants;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -87,7 +88,7 @@
  * tell the system when we go to sleep so that it can lock the keyguard if needed.
  * </p>
  */
-@VisibleForTesting
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
 public class Notifier {
     private static final String TAG = "PowerManagerNotifier";
 
@@ -150,14 +151,21 @@
     // begins charging wirelessly
     private final boolean mShowWirelessChargingAnimationConfig;
 
-    // The current interactive state.  This is set as soon as an interactive state
+    // Encapsulates interactivity information about a particular display group.
+    private static class Interactivity {
+        public boolean isInteractive = true;
+        public int changeReason;
+        public long changeStartTime; // In SystemClock.uptimeMillis()
+        public boolean isChanging;
+    }
+
+    private final SparseArray<Interactivity> mInteractivityByGroupId = new SparseArray<>();
+
+    // The current global interactive state.  This is set as soon as an interactive state
     // transition begins so as to capture the reason that it happened.  At some point
     // this state will propagate to the pending state then eventually to the
     // broadcasted state over the course of reporting the transition asynchronously.
-    private boolean mInteractive = true;
-    private int mInteractiveChangeReason;
-    private long mInteractiveChangeStartTime; // In SystemClock.uptimeMillis()
-    private boolean mInteractiveChanging;
+    private Interactivity mGlobalInteractivity = new Interactivity();
 
     // The pending interactive state that we will eventually want to broadcast.
     // This is designed so that we can collapse redundant sequences of awake/sleep
@@ -438,7 +446,8 @@
      * which case it will assume that the state did not fully converge before the
      * next transition began and will recover accordingly.
      */
-    public void onWakefulnessChangeStarted(final int wakefulness, int reason, long eventTime) {
+    public void onGlobalWakefulnessChangeStarted(final int wakefulness, int reason,
+            long eventTime) {
         final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
         if (DEBUG) {
             Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
@@ -456,10 +465,10 @@
 
         // Handle any early interactive state changes.
         // Finish pending incomplete ones from a previous cycle.
-        if (mInteractive != interactive) {
+        if (mGlobalInteractivity.isInteractive != interactive) {
             // Finish up late behaviors if needed.
-            if (mInteractiveChanging) {
-                handleLateInteractiveChange();
+            if (mGlobalInteractivity.isChanging) {
+                handleLateGlobalInteractiveChange();
             }
 
             // Start input as soon as we start waking up or going to sleep.
@@ -475,11 +484,11 @@
                             FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__OFF);
 
             // Handle early behaviors.
-            mInteractive = interactive;
-            mInteractiveChangeReason = reason;
-            mInteractiveChangeStartTime = eventTime;
-            mInteractiveChanging = true;
-            handleEarlyInteractiveChange();
+            mGlobalInteractivity.isInteractive = interactive;
+            mGlobalInteractivity.isChanging = true;
+            mGlobalInteractivity.changeReason = reason;
+            mGlobalInteractivity.changeStartTime = eventTime;
+            handleEarlyGlobalInteractiveChange();
         }
     }
 
@@ -490,10 +499,34 @@
         if (DEBUG) {
             Slog.d(TAG, "onWakefulnessChangeFinished");
         }
+        for (int i = 0; i < mInteractivityByGroupId.size(); i++) {
+            int groupId = mInteractivityByGroupId.keyAt(i);
+            Interactivity interactivity = mInteractivityByGroupId.valueAt(i);
+            if (interactivity.isChanging) {
+                interactivity.isChanging = false;
+                handleLateInteractiveChange(groupId);
+            }
+        }
+        if (mGlobalInteractivity.isChanging) {
+            mGlobalInteractivity.isChanging = false;
+            handleLateGlobalInteractiveChange();
+        }
+    }
 
-        if (mInteractiveChanging) {
-            mInteractiveChanging = false;
-            handleLateInteractiveChange();
+
+    private void handleEarlyInteractiveChange(int groupId) {
+        synchronized (mLock) {
+            Interactivity interactivity = mInteractivityByGroupId.get(groupId);
+            if (interactivity == null) {
+                Slog.e(TAG, "no Interactivity entry for groupId:" + groupId);
+                return;
+            }
+            final int changeReason = interactivity.changeReason;
+            if (interactivity.isInteractive) {
+                mHandler.post(() -> mPolicy.startedWakingUp(groupId, changeReason));
+            } else {
+                mHandler.post(() -> mPolicy.startedGoingToSleep(groupId, changeReason));
+            }
         }
     }
 
@@ -501,13 +534,13 @@
      * Handle early interactive state changes such as getting applications or the lock
      * screen running and ready for the user to see (such as when turning on the screen).
      */
-    private void handleEarlyInteractiveChange() {
+    private void handleEarlyGlobalInteractiveChange() {
         synchronized (mLock) {
-            if (mInteractive) {
+            if (mGlobalInteractivity.isInteractive) {
                 // Waking up...
                 mHandler.post(() -> {
-                    mPolicy.startedWakingUp(mInteractiveChangeReason);
                     mDisplayManagerInternal.onEarlyInteractivityChange(true /*isInteractive*/);
+                    mPolicy.startedWakingUpGlobal(mGlobalInteractivity.changeReason);
                 });
 
                 // Send interactive broadcast.
@@ -516,37 +549,36 @@
                 updatePendingBroadcastLocked();
             } else {
                 // Going to sleep...
-                // Tell the policy that we started going to sleep.
                 mHandler.post(() -> {
-                    mPolicy.startedGoingToSleep(mInteractiveChangeReason);
                     mDisplayManagerInternal.onEarlyInteractivityChange(false /*isInteractive*/);
+                    mPolicy.startedGoingToSleepGlobal(mGlobalInteractivity.changeReason);
                 });
             }
         }
     }
 
     /**
-     * Handle late interactive state changes once they are finished so that the system can
-     * finish pending transitions (such as turning the screen off) before causing
-     * applications to change state visibly.
+     * Handle late global interactive state changes. Also see
+     * {@link #handleLateInteractiveChange(int)}.
      */
-    private void handleLateInteractiveChange() {
+    private void handleLateGlobalInteractiveChange() {
         synchronized (mLock) {
             final int interactiveChangeLatency =
-                    (int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime);
-            if (mInteractive) {
+                    (int) (SystemClock.uptimeMillis() - mGlobalInteractivity.changeStartTime);
+            if (mGlobalInteractivity.isInteractive) {
                 // Finished waking up...
                 mHandler.post(() -> {
                     LogMaker log = new LogMaker(MetricsEvent.SCREEN);
                     log.setType(MetricsEvent.TYPE_OPEN);
                     log.setSubtype(WindowManagerPolicyConstants.translateWakeReasonToOnReason(
-                            mInteractiveChangeReason));
+                            mGlobalInteractivity.changeReason));
                     log.setLatency(interactiveChangeLatency);
-                    log.addTaggedData(
-                            MetricsEvent.FIELD_SCREEN_WAKE_REASON, mInteractiveChangeReason);
+                    log.addTaggedData(MetricsEvent.FIELD_SCREEN_WAKE_REASON,
+                            mGlobalInteractivity.changeReason);
                     MetricsLogger.action(log);
                     EventLogTags.writePowerScreenState(1, 0, 0, 0, interactiveChangeLatency);
-                    mPolicy.finishedWakingUp(mInteractiveChangeReason);
+
+                    mPolicy.finishedWakingUpGlobal(mGlobalInteractivity.changeReason);
                 });
             } else {
                 // Finished going to sleep...
@@ -563,18 +595,19 @@
 
                 // Tell the policy we finished going to sleep.
                 final int offReason = WindowManagerPolicyConstants.translateSleepReasonToOffReason(
-                        mInteractiveChangeReason);
+                        mGlobalInteractivity.changeReason);
                 mHandler.post(() -> {
                     LogMaker log = new LogMaker(MetricsEvent.SCREEN);
                     log.setType(MetricsEvent.TYPE_CLOSE);
                     log.setSubtype(offReason);
                     log.setLatency(interactiveChangeLatency);
-                    log.addTaggedData(
-                            MetricsEvent.FIELD_SCREEN_SLEEP_REASON, mInteractiveChangeReason);
+                    log.addTaggedData(MetricsEvent.FIELD_SCREEN_SLEEP_REASON,
+                            mGlobalInteractivity.changeReason);
                     MetricsLogger.action(log);
                     EventLogTags.writePowerScreenState(
                             0, offReason, 0, 0, interactiveChangeLatency);
-                    mPolicy.finishedGoingToSleep(mInteractiveChangeReason);
+
+                    mPolicy.finishedGoingToSleepGlobal(mGlobalInteractivity.changeReason);
                 });
 
                 // Send non-interactive broadcast.
@@ -586,12 +619,62 @@
     }
 
     /**
+     * Handle late interactive state changes once they are finished so that the system can
+     * finish pending transitions (such as turning the screen off) before causing
+     * applications to change state visibly.
+     */
+    private void handleLateInteractiveChange(int groupId) {
+        synchronized (mLock) {
+            Interactivity interactivity = mInteractivityByGroupId.get(groupId);
+            if (interactivity == null) {
+                Slog.e(TAG, "no Interactivity entry for groupId:" + groupId);
+                return;
+            }
+            final int changeReason = interactivity.changeReason;
+            if (interactivity.isInteractive) {
+                mHandler.post(() -> mPolicy.finishedWakingUp(groupId, changeReason));
+            } else {
+                mHandler.post(() -> mPolicy.finishedGoingToSleep(groupId, changeReason));
+            }
+        }
+    }
+
+    /**
      * Called when an individual PowerGroup changes wakefulness.
      */
-    public void onPowerGroupWakefulnessChanged(int groupId, int groupWakefulness, int changeReason,
-            int globalWakefulness) {
-        mHandler.post(() -> mPolicy.onPowerGroupWakefulnessChanged(groupId, groupWakefulness,
-                changeReason, globalWakefulness));
+    public void onGroupWakefulnessChangeStarted(int groupId, int wakefulness, int changeReason,
+            long eventTime) {
+        final boolean isInteractive = PowerManagerInternal.isInteractive(wakefulness);
+
+        boolean isNewGroup = false;
+        Interactivity interactivity = mInteractivityByGroupId.get(groupId);
+        if (interactivity == null) {
+            isNewGroup = true;
+            interactivity = new Interactivity();
+            mInteractivityByGroupId.put(groupId, interactivity);
+        }
+        if (isNewGroup || interactivity.isInteractive != isInteractive) {
+            // Finish up late behaviors if needed.
+            if (interactivity.isChanging) {
+                handleLateInteractiveChange(groupId);
+            }
+
+            // Handle early behaviors.
+            interactivity.isInteractive = isInteractive;
+            interactivity.changeReason = changeReason;
+            interactivity.changeStartTime = eventTime;
+            interactivity.isChanging = true;
+            handleEarlyInteractiveChange(groupId);
+        }
+    }
+
+    /**
+     * Called when a PowerGroup has been removed.
+     *
+     * @param groupId which group was removed
+     */
+    public void onGroupRemoved(int groupId) {
+        mInteractivityByGroupId.remove(groupId);
     }
 
     /**
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index e392c24..9ff98be 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -686,6 +686,8 @@
         @Override
         public void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime,
                 int reason, int uid, int opUid, String opPackageName, String details) {
+            mWakefulnessChanging = true;
+            mDirty |= DIRTY_WAKEFULNESS;
             if (wakefulness == WAKEFULNESS_AWAKE) {
                 // Kick user activity to prevent newly awake group from timing out instantly.
                 // The dream may end without user activity if the dream app crashes / is updated,
@@ -696,9 +698,8 @@
                         PowerManager.USER_ACTIVITY_EVENT_OTHER, flags, uid);
             }
             mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
+            mNotifier.onGroupWakefulnessChangeStarted(groupId, wakefulness, reason, eventTime);
             updateGlobalWakefulnessLocked(eventTime, reason, uid, opUid, opPackageName, details);
-            mNotifier.onPowerGroupWakefulnessChanged(groupId, wakefulness, reason,
-                    getGlobalWakefulnessLocked());
             updatePowerStateLocked();
         }
     }
@@ -2152,7 +2153,7 @@
             mDozeStartInProgress &= (newWakefulness == WAKEFULNESS_DOZING);
 
             if (mNotifier != null) {
-                mNotifier.onWakefulnessChangeStarted(newWakefulness, reason, eventTime);
+                mNotifier.onGlobalWakefulnessChangeStarted(newWakefulness, reason, eventTime);
             }
             mAttentionDetector.onWakefulnessChangeStarted(newWakefulness);
 
@@ -2163,15 +2164,6 @@
                     if (sQuiescent) {
                         mDirty |= DIRTY_QUIESCENT;
                     }
-                    PowerGroup defaultGroup = mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP);
-                    if (defaultGroup.getWakefulnessLocked() == WAKEFULNESS_DOZING) {
-                        // Workaround for b/187231320 where the AOD can get stuck in a "half on /
-                        // half off" state when a non-default-group VirtualDisplay causes the global
-                        // wakefulness to change to awake, even though the default display is
-                        // dozing. We set sandman summoned to restart dreaming to get it unstuck.
-                        // TODO(b/255688811) - fix this so that AOD never gets interrupted at all.
-                        defaultGroup.setSandmanSummonedLocked(true);
-                    }
                     break;
 
                 case WAKEFULNESS_ASLEEP:
@@ -2248,6 +2240,8 @@
 
     @GuardedBy("mLock")
     void onPowerGroupEventLocked(int event, PowerGroup powerGroup) {
+        mWakefulnessChanging = true;
+        mDirty |= DIRTY_WAKEFULNESS;
         final int groupId = powerGroup.getGroupId();
         if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) {
             mPowerGroups.delete(groupId);
@@ -2260,6 +2254,11 @@
             // Kick user activity to prevent newly added group from timing out instantly.
             userActivityNoUpdateLocked(powerGroup, mClock.uptimeMillis(),
                     PowerManager.USER_ACTIVITY_EVENT_OTHER, /* flags= */ 0, Process.SYSTEM_UID);
+            mNotifier.onGroupWakefulnessChangeStarted(groupId,
+                    powerGroup.getWakefulnessLocked(), WAKE_REASON_DISPLAY_GROUP_ADDED,
+                    mClock.uptimeMillis());
+        } else if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) {
+            mNotifier.onGroupRemoved(groupId);
         }
 
         if (oldWakefulness != newWakefulness) {
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index f971db9..e796275 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -161,7 +161,13 @@
                     mDisplayTrustGrantedMessage = (flags & FLAG_GRANT_TRUST_DISPLAY_MESSAGE) != 0;
                     if ((flags & FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) != 0) {
                         mWaitingForTrustableDowngrade = true;
-                        setSecurityWindowTimer();
+                        resultCallback.thenAccept(result -> {
+                            if (result.getStatus() == GrantTrustResult.STATUS_UNLOCKED_BY_GRANT) {
+                                // if we are not unlocked by grantTrust, then we don't need to
+                                // have the timer for the security window
+                                setSecurityWindowTimer();
+                            }
+                        });
                     } else {
                         mWaitingForTrustableDowngrade = false;
                     }
@@ -562,6 +568,7 @@
      * @see android.service.trust.TrustAgentService#onDeviceLocked()
      */
     public void onDeviceLocked() {
+        mWithinSecurityLockdownWindow = false;
         try {
             if (mTrustAgentService != null) mTrustAgentService.onDeviceLocked();
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 8786005..1ab9823 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -393,6 +393,23 @@
                 true /* overrideHardTimeout */);
     }
 
+    private void cancelBothTrustableAlarms(int userId) {
+        TrustableTimeoutAlarmListener idleTimeout =
+                mIdleTrustableTimeoutAlarmListenerForUser.get(
+                        userId);
+        TrustableTimeoutAlarmListener trustableTimeout =
+                mTrustableTimeoutAlarmListenerForUser.get(
+                        userId);
+        if (idleTimeout != null && idleTimeout.isQueued()) {
+            idleTimeout.setQueued(false);
+            mAlarmManager.cancel(idleTimeout);
+        }
+        if (trustableTimeout != null && trustableTimeout.isQueued()) {
+            trustableTimeout.setQueued(false);
+            mAlarmManager.cancel(trustableTimeout);
+        }
+    }
+
     private void handleScheduleTrustedTimeout(int userId, boolean shouldOverride) {
         long when = SystemClock.elapsedRealtime() + TRUST_TIMEOUT_IN_MILLIS;
         TrustedTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
@@ -657,6 +674,11 @@
                 resultCallback.complete(new GrantTrustResult(STATUS_UNLOCKED_BY_GRANT));
             }
         }
+
+        if ((wasTrusted || wasTrustable) && pendingTrustState == TrustState.UNTRUSTED) {
+            if (DEBUG) Slog.d(TAG, "Trust was revoked, destroy trustable alarms");
+            cancelBothTrustableAlarms(userId);
+        }
     }
 
     private void updateTrustUsuallyManaged(int userId, boolean managed) {
@@ -1908,7 +1930,11 @@
                     handleScheduleTrustTimeout(shouldOverride, timeoutType);
                     break;
                 case MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH:
-                    refreshTrustableTimers(msg.arg1);
+                    TrustableTimeoutAlarmListener trustableAlarm =
+                            mTrustableTimeoutAlarmListenerForUser.get(msg.arg1);
+                    if (trustableAlarm != null && trustableAlarm.isQueued()) {
+                        refreshTrustableTimers(msg.arg1);
+                    }
                     break;
             }
         }
@@ -2160,7 +2186,7 @@
             TrustedTimeoutAlarmListener otherAlarm;
             boolean otherAlarmPresent;
             if (ENABLE_ACTIVE_UNLOCK_FLAG) {
-                cancelBothTrustableAlarms();
+                cancelBothTrustableAlarms(mUserId);
                 otherAlarm = mTrustTimeoutAlarmListenerForUser.get(mUserId);
                 otherAlarmPresent = (otherAlarm != null) && otherAlarm.isQueued();
                 if (otherAlarmPresent) {
@@ -2172,23 +2198,6 @@
             }
         }
 
-        private void cancelBothTrustableAlarms() {
-            TrustableTimeoutAlarmListener idleTimeout =
-                    mIdleTrustableTimeoutAlarmListenerForUser.get(
-                            mUserId);
-            TrustableTimeoutAlarmListener trustableTimeout =
-                    mTrustableTimeoutAlarmListenerForUser.get(
-                            mUserId);
-            if (idleTimeout != null && idleTimeout.isQueued()) {
-                idleTimeout.setQueued(false);
-                mAlarmManager.cancel(idleTimeout);
-            }
-            if (trustableTimeout != null && trustableTimeout.isQueued()) {
-                trustableTimeout.setQueued(false);
-                mAlarmManager.cancel(trustableTimeout);
-            }
-        }
-
         private void disableRenewableTrustWhileNonrenewableTrustIsPresent() {
             // if non-renewable trust is running, we need to temporarily prevent
             // renewable trust from being used
diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java
index b6ab351..4bbca33 100644
--- a/services/core/java/com/android/server/tv/TvInputHal.java
+++ b/services/core/java/com/android/server/tv/TvInputHal.java
@@ -27,9 +27,6 @@
 import android.util.SparseIntArray;
 import android.view.Surface;
 
-import java.util.LinkedList;
-import java.util.Queue;
-
 /**
  * Provides access to the low-level TV input hardware abstraction layer.
  */
@@ -64,6 +61,8 @@
     private static native TvStreamConfig[] nativeGetStreamConfigs(long ptr, int deviceId,
             int generation);
     private static native void nativeClose(long ptr);
+    private static native int nativeSetTvMessageEnabled(long ptr, int deviceId, int streamId,
+            int type, boolean enabled);
 
     private final Object mLock = new Object();
     private long mPtr = 0;
@@ -100,6 +99,25 @@
         }
     }
 
+    public int setTvMessageEnabled(int deviceId, TvStreamConfig streamConfig, int type,
+            boolean enabled) {
+        synchronized (mLock) {
+            if (mPtr == 0) {
+                return ERROR_NO_INIT;
+            }
+            int generation = mStreamConfigGenerations.get(deviceId, 0);
+            if (generation != streamConfig.getGeneration()) {
+                return ERROR_STALE_CONFIG;
+            }
+            if (nativeSetTvMessageEnabled(mPtr, deviceId, streamConfig.getStreamId(), type,
+                    enabled) == 0) {
+                return SUCCESS;
+            } else {
+                return ERROR_UNKNOWN;
+            }
+        }
+    }
+
     public int removeStream(int deviceId, TvStreamConfig streamConfig) {
         synchronized (mLock) {
             if (mPtr == 0) {
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 98dfb00..077f8d5 100755
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -459,9 +459,11 @@
 
     private int findDeviceIdForInputIdLocked(String inputId) {
         for (int i = 0; i < mConnections.size(); ++i) {
-            Connection connection = mConnections.get(i);
-            if (connection.getInfoLocked().getId().equals(inputId)) {
-                return i;
+            int key = mConnections.keyAt(i);
+            Connection connection = mConnections.get(key);
+            if (connection != null && connection.getInfoLocked() != null
+                    && connection.getInfoLocked().getId().equals(inputId)) {
+                return key;
             }
         }
         return -1;
@@ -489,6 +491,27 @@
         return configsList;
     }
 
+    public boolean setTvMessageEnabled(String inputId, int type,
+            boolean enabled) {
+        synchronized (mLock) {
+            int deviceId = findDeviceIdForInputIdLocked(inputId);
+            if (deviceId < 0) {
+                Slog.e(TAG, "Invalid inputId : " + inputId);
+                return false;
+            }
+
+            Connection connection = mConnections.get(deviceId);
+            boolean success = true;
+            for (TvStreamConfig config : connection.getConfigsLocked()) {
+                success = success
+                        && mHal.setTvMessageEnabled(deviceId, config, type, enabled)
+                        == TvInputHal.SUCCESS;
+            }
+
+            return success;
+        }
+    }
+
     /**
      * Take a snapshot of the given TV input into the provided Surface.
      */
@@ -764,6 +787,7 @@
                     + " mHardwareInfo: " + mHardwareInfo
                     + ", mInfo: " + mInfo
                     + ", mCallback: " + mCallback
+                    + ", mHardware: " + mHardware
                     + ", mConfigs: " + Arrays.toString(mConfigs)
                     + ", mCallingUid: " + mCallingUid
                     + ", mResolvedUserId: " + mResolvedUserId
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index fd203bb..88c9042 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -2154,6 +2154,9 @@
             try {
                 synchronized (mLock) {
                     try {
+                        final String inputId =
+                                getSessionStateLocked(sessionToken, callingUid, userId).inputId;
+                        mTvInputHardwareManager.setTvMessageEnabled(inputId, type, enabled);
                         getSessionLocked(sessionToken, callingUid, resolvedUserId)
                                 .setTvMessageEnabled(type, enabled);
                     } catch (RemoteException | SessionNotFoundException e) {
@@ -2711,7 +2714,10 @@
                         .audioAddress("0")
                         .hdmiPortId(0)
                         .build();
-            mTvInputHardwareManager.onDeviceAvailable(info, null);
+            TvStreamConfig[] configs = {
+                    new TvStreamConfig.Builder().streamId(19001)
+                            .generation(1).maxHeight(600).maxWidth(800).type(1).build()};
+            mTvInputHardwareManager.onDeviceAvailable(info, configs);
         }
 
         /**
diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
index fb400da..80cb085 100644
--- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
+++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
@@ -2340,6 +2340,10 @@
 
         @Override
         public void binderDied() {
+            synchronized (mLock) {
+                mSession = null;
+                clearSessionAndNotifyClientLocked(this);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 51872b3..9020cb3 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -803,6 +803,20 @@
     protected WallpaperData mLastLockWallpaper;
     private IWallpaperManagerCallback mKeyguardListener;
     private boolean mWaitingForUnlock;
+
+    /**
+     * Flag set to true after reboot if the home wallpaper is waiting for the device to be unlocked.
+     * This happens for wallpapers that are not direct-boot aware; they can only be rendered after
+     * the user unlocks the device for the first time after a reboot. In the meantime, the default
+     * wallpaper is shown instead.
+     */
+    private boolean mHomeWallpaperWaitingForUnlock;
+
+    /**
+     * Flag set to true after reboot if the lock wallpaper is waiting for the device to be unlocked.
+     */
+    private boolean mLockWallpaperWaitingForUnlock;
+
     private boolean mShuttingDown;
 
     /**
@@ -1339,9 +1353,6 @@
 
         void complete() {
             // Only changes from home+lock to just home or lock need attention
-            // If setting the wallpaper fails, this callback will be called
-            // when the wallpaper is detached, in which case wallpapers may have
-            // already changed. Make sure we're not overwriting a more recent wallpaper.
             if (mNewWallpaper.mSystemWasBoth) {
                 if (DEBUG) {
                     Slog.v(TAG, "Handling change from system+lock wallpaper");
@@ -1364,7 +1375,8 @@
                                     mOriginalSystem.wallpaperComponent;
                             lockWp.connection = mOriginalSystem.connection;
                             lockWp.connection.mWallpaper = lockWp;
-                            updateEngineFlags(mOriginalSystem, FLAG_LOCK);
+                            mOriginalSystem.mWhich = FLAG_LOCK;
+                            updateEngineFlags(mOriginalSystem);
                             notifyWallpaperColorsChanged(lockWp, FLAG_LOCK);
                         } else {
                             // Failed rename, use current system wp for both
@@ -1373,7 +1385,7 @@
                             }
                             WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId);
                             currentSystem.mWhich = FLAG_SYSTEM | FLAG_LOCK;
-                            updateEngineFlags(currentSystem, FLAG_SYSTEM | FLAG_LOCK);
+                            updateEngineFlags(currentSystem);
                             mLockWallpaperMap.remove(mNewWallpaper.userId);
                         }
                     } else {
@@ -1382,7 +1394,7 @@
                             Slog.v(TAG, "live system+lock to system success");
                         }
                         mOriginalSystem.mWhich = FLAG_LOCK;
-                        updateEngineFlags(mOriginalSystem, FLAG_LOCK);
+                        updateEngineFlags(mOriginalSystem);
                         mLockWallpaperMap.put(mNewWallpaper.userId, mOriginalSystem);
                         mLastLockWallpaper = mOriginalSystem;
                         notifyWallpaperColorsChanged(mOriginalSystem, FLAG_LOCK);
@@ -1395,7 +1407,7 @@
                     WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId);
                     if (currentSystem.wallpaperId == mOriginalSystem.wallpaperId) {
                         currentSystem.mWhich = FLAG_SYSTEM;
-                        updateEngineFlags(currentSystem, FLAG_SYSTEM);
+                        updateEngineFlags(currentSystem);
                     }
                 }
             }
@@ -1408,24 +1420,6 @@
                 Slog.v(TAG, "new lastLockWp: " + mLastLockWallpaper);
             }
         }
-
-        private void updateEngineFlags(WallpaperData wallpaper, @SetWallpaperFlags int which) {
-            if (wallpaper.connection == null) {
-                return;
-            }
-            wallpaper.connection.forEachDisplayConnector(
-                    connector -> {
-                        try {
-                            if (connector.mEngine != null) {
-                                connector.mEngine.setWallpaperFlags(which);
-                                mWindowManagerInternal.setWallpaperShowWhenLocked(
-                                        connector.mToken, (which & FLAG_LOCK) != 0);
-                            }
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Failed to update wallpaper engine flags", e);
-                        }
-                    });
-        }
     }
 
     class MyPackageMonitor extends PackageMonitor {
@@ -1790,7 +1784,23 @@
     public void onUnlockUser(final int userId) {
         synchronized (mLock) {
             if (mCurrentUserId == userId) {
-                if (mWaitingForUnlock) {
+                if (mIsLockscreenLiveWallpaperEnabled) {
+                    if (mHomeWallpaperWaitingForUnlock) {
+                        final WallpaperData systemWallpaper =
+                                getWallpaperSafeLocked(userId, FLAG_SYSTEM);
+                        switchWallpaper(systemWallpaper, null);
+                        // TODO(b/278261563): call notifyCallbacksLocked inside switchWallpaper
+                        notifyCallbacksLocked(systemWallpaper);
+                    }
+                    if (mLockWallpaperWaitingForUnlock) {
+                        final WallpaperData lockWallpaper =
+                                getWallpaperSafeLocked(userId, FLAG_LOCK);
+                        switchWallpaper(lockWallpaper, null);
+                        notifyCallbacksLocked(lockWallpaper);
+                    }
+                }
+
+                if (mWaitingForUnlock && !mIsLockscreenLiveWallpaperEnabled) {
                     // the desired wallpaper is not direct-boot aware, load it now
                     final WallpaperData systemWallpaper =
                             getWallpaperSafeLocked(userId, FLAG_SYSTEM);
@@ -1845,13 +1855,23 @@
                 }
                 mCurrentUserId = userId;
                 systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
-                final WallpaperData tmpLockWallpaper = mLockWallpaperMap.get(userId);
-                lockWallpaper = tmpLockWallpaper == null ? systemWallpaper : tmpLockWallpaper;
+
+                if (mIsLockscreenLiveWallpaperEnabled) {
+                    lockWallpaper = systemWallpaper.mWhich == (FLAG_LOCK | FLAG_SYSTEM)
+                            ? systemWallpaper : getWallpaperSafeLocked(userId, FLAG_LOCK);
+                } else {
+                    final WallpaperData tmpLockWallpaper = mLockWallpaperMap.get(userId);
+                    lockWallpaper = tmpLockWallpaper == null ? systemWallpaper : tmpLockWallpaper;
+                }
+
                 // Not started watching yet, in case wallpaper data was loaded for other reasons.
                 if (systemWallpaper.wallpaperObserver == null) {
                     systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
                     systemWallpaper.wallpaperObserver.startWatching();
                 }
+                if (mIsLockscreenLiveWallpaperEnabled && lockWallpaper != systemWallpaper)  {
+                    switchWallpaper(lockWallpaper, null);
+                }
                 switchWallpaper(systemWallpaper, reply);
             }
 
@@ -1870,6 +1890,11 @@
     void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
         synchronized (mLock) {
             mWaitingForUnlock = false;
+            if (mIsLockscreenLiveWallpaperEnabled) {
+                if ((wallpaper.mWhich & FLAG_SYSTEM) != 0) mHomeWallpaperWaitingForUnlock = false;
+                if ((wallpaper.mWhich & FLAG_LOCK) != 0) mLockWallpaperWaitingForUnlock = false;
+            }
+
             final ComponentName cname = wallpaper.wallpaperComponent != null ?
                     wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
             if (!bindWallpaperComponentLocked(cname, true, false, wallpaper, reply)) {
@@ -1882,6 +1907,11 @@
                 } catch (RemoteException ignored) {
                 }
 
+                if (mIsLockscreenLiveWallpaperEnabled) {
+                    onSwitchWallpaperFailLocked(wallpaper, reply, si);
+                    return;
+                }
+
                 if (si == null) {
                     Slog.w(TAG, "Failure starting previous wallpaper; clearing");
                     clearWallpaperLocked(false, FLAG_SYSTEM, wallpaper.userId, reply);
@@ -1899,6 +1929,43 @@
         }
     }
 
+    /**
+     * Fallback method if a wallpaper fails to load on boot or after a user switch.
+     * Only called if mIsLockscreenLiveWallpaperEnabled is true.
+     */
+    private void onSwitchWallpaperFailLocked(
+            WallpaperData wallpaper, IRemoteCallback reply, ServiceInfo serviceInfo) {
+
+        if (serviceInfo == null) {
+            Slog.w(TAG, "Failure starting previous wallpaper; clearing");
+
+            if (wallpaper.mWhich == (FLAG_LOCK | FLAG_SYSTEM)) {
+                clearWallpaperLocked(false, FLAG_SYSTEM, wallpaper.userId, null);
+                clearWallpaperLocked(false, FLAG_LOCK, wallpaper.userId, reply);
+            } else {
+                clearWallpaperLocked(false, wallpaper.mWhich, wallpaper.userId, reply);
+            }
+            return;
+        }
+        Slog.w(TAG, "Wallpaper isn't direct boot aware; using fallback until unlocked");
+        // We might end up persisting the current wallpaper data
+        // while locked, so pretend like the component was actually
+        // bound into place
+        wallpaper.wallpaperComponent = wallpaper.nextWallpaperComponent;
+        final WallpaperData fallback = new WallpaperData(wallpaper.userId, wallpaper.mWhich);
+
+        // files from the previous static wallpaper may still be stored in memory.
+        // delete them in order to show the default wallpaper.
+        if (wallpaper.wallpaperFile.exists()) {
+            wallpaper.wallpaperFile.delete();
+            wallpaper.cropFile.delete();
+        }
+
+        bindWallpaperComponentLocked(mImageWallpaper, true, false, fallback, reply);
+        if ((wallpaper.mWhich & FLAG_SYSTEM) != 0) mHomeWallpaperWaitingForUnlock = true;
+        if ((wallpaper.mWhich & FLAG_LOCK) != 0) mLockWallpaperWaitingForUnlock = true;
+    }
+
     @Override
     public void clearWallpaper(String callingPackage, int which, int userId) {
         if (DEBUG) Slog.v(TAG, "clearWallpaper");
@@ -3008,6 +3075,9 @@
                                 newWallpaper.userId);
                         if (lockedWallpaper != null) {
                             detachWallpaperLocked(lockedWallpaper);
+                            if (same) {
+                                updateEngineFlags(newWallpaper);
+                            }
                         }
                         mLockWallpaperMap.remove(newWallpaper.userId);
                     }
@@ -3343,6 +3413,27 @@
         }
     }
 
+    // Updates the given wallpaper's Engine so that its destination flags are the same as those of
+    // the wallpaper, e.g., after a wallpaper has been changed from displaying on home+lock to home
+    // or lock only.
+    private void updateEngineFlags(WallpaperData wallpaper) {
+        if (wallpaper.connection == null) {
+            return;
+        }
+        wallpaper.connection.forEachDisplayConnector(
+                connector -> {
+                    try {
+                        if (connector.mEngine != null) {
+                            connector.mEngine.setWallpaperFlags(wallpaper.mWhich);
+                            mWindowManagerInternal.setWallpaperShowWhenLocked(
+                                    connector.mToken, (wallpaper.mWhich & FLAG_LOCK) != 0);
+                        }
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Failed to update wallpaper engine flags", e);
+                    }
+                });
+    }
+
     private void clearWallpaperComponentLocked(WallpaperData wallpaper) {
         wallpaper.wallpaperComponent = null;
         detachWallpaperLocked(wallpaper);
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index 32f7b96..5c929a9 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -239,7 +239,17 @@
             }
             return null;
         }
-        source.getBounds(mTmpRect);
+        mTmpRect.setEmpty();
+        if (source.mTransitionController.inFinishingTransition(source)) {
+            final Transition.ChangeInfo changeInfo = source.mTransitionController
+                    .mFinishingTransition.mChanges.get(source);
+            if (changeInfo != null) {
+                mTmpRect.set(changeInfo.mAbsoluteBounds);
+            }
+        }
+        if (mTmpRect.isEmpty()) {
+            source.getBounds(mTmpRect);
+        }
         mTmpRect.offsetTo(0, 0);
         SurfaceControl[] excludeLayers;
         final WindowState imeWindow = source.getDisplayContent().mInputMethodWindow;
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 8bbcd27..c40d72c 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -807,11 +807,8 @@
                 if (under != null) {
                     under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
                 }
-                // Create a transition if the activity is playing in case the current activity
-                // didn't commit invisible. That's because if this activity has changed its
-                // visibility while playing transition, there won't able to commit visibility until
-                // the running transition finish.
-                final Transition transition = r.mTransitionController.inPlayingTransition(r)
+                // Create a transition to make sure the activity change is collected.
+                final Transition transition = r.mTransitionController.isShellTransitionsEnabled()
                         && !r.mTransitionController.isCollecting()
                         ? r.mTransitionController.createTransition(TRANSIT_TO_FRONT) : null;
                 final boolean changed = r.setOccludesParent(false);
diff --git a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
index d844c6f..9647a62 100644
--- a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
+++ b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
@@ -84,6 +84,7 @@
             PERMISSION_POLICY_ORDERED_ID,
             VIRTUAL_DEVICE_SERVICE_ORDERED_ID,
             DREAM_MANAGER_ORDERED_ID,
+            PRODUCT_ORDERED_ID,
             SYSTEM_LAST_ORDERED_ID, // Update this when adding new ids
             // Order Ids for mainline module services
             MAINLINE_FIRST_ORDERED_ID,
@@ -119,11 +120,18 @@
     int DREAM_MANAGER_ORDERED_ID = 4;
 
     /**
+     * The identifier for an interceptor which is specific to the type of android product like
+     * automotive, wear, TV etc.
+     * @hide
+     */
+    int PRODUCT_ORDERED_ID = 5;
+
+    /**
      * The final id, used by the framework to determine the valid range of ids. Update this when
      * adding new ids.
      * @hide
      */
-    int SYSTEM_LAST_ORDERED_ID = DREAM_MANAGER_ORDERED_ID;
+    int SYSTEM_LAST_ORDERED_ID = PRODUCT_ORDERED_ID;
 
     /**
      * The first mainline module id, used by the framework to determine the valid range of ids
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c6a2e0e..25e5dac 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5220,6 +5220,11 @@
         }
         logAppCompatState();
         if (!visible) {
+            final InputTarget imeInputTarget = mDisplayContent.getImeInputTarget();
+            mLastImeShown = imeInputTarget != null && imeInputTarget.getWindowState() != null
+                    && imeInputTarget.getWindowState().mActivityRecord == this
+                    && mDisplayContent.mInputMethodWindow != null
+                    && mDisplayContent.mInputMethodWindow.isVisible();
             finishOrAbortReplacingWindow();
         }
         return true;
@@ -5296,6 +5301,10 @@
             if (isCollecting) {
                 mTransitionController.collect(this);
             } else {
+                // Failsafe to make sure that we show any activities that were incorrectly hidden
+                // during a transition. If this vis-change is a result of finishing, ignore it.
+                // Finish should only ever commit visibility=false, so we can check full containment
+                // rather than just direct membership.
                 inFinishingTransition = mTransitionController.inFinishingTransition(this);
                 if (!inFinishingTransition && !mDisplayContent.isSleeping()) {
                     Slog.e(TAG, "setVisibility=" + visible
@@ -5396,7 +5405,9 @@
             return;
         }
         if (inFinishingTransition) {
-            // Let the finishing transition commit the visibility.
+            // Let the finishing transition commit the visibility, but let the controller know
+            // about it so that we can recover from degenerate cases.
+            mTransitionController.mValidateCommitVis.add(this);
             return;
         }
         // If we are preparing an app transition, then delay changing
@@ -5603,11 +5614,6 @@
         }
 
         if (!visible) {
-            final InputTarget imeInputTarget = mDisplayContent.getImeInputTarget();
-            mLastImeShown = imeInputTarget != null && imeInputTarget.getWindowState() != null
-                    && imeInputTarget.getWindowState().mActivityRecord == this
-                    && mDisplayContent.mInputMethodWindow != null
-                    && mDisplayContent.mInputMethodWindow.isVisible();
             mImeInsetsFrozenUntilStartInput = true;
         }
 
@@ -8525,6 +8531,16 @@
         return inTransitionSelfOrParent();
     }
 
+    boolean isDisplaySleepingAndSwapping() {
+        for (int i = mDisplayContent.mAllSleepTokens.size() - 1; i >= 0; i--) {
+            RootWindowContainer.SleepToken sleepToken = mDisplayContent.mAllSleepTokens.get(i);
+            if (sleepToken.isDisplaySwapping()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed
      * orientation then aspect ratio restrictions are also already respected.
@@ -10551,8 +10567,8 @@
     }
 
     @Override
-    boolean isSyncFinished() {
-        if (!super.isSyncFinished()) return false;
+    boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
+        if (!super.isSyncFinished(group)) return false;
         if (mDisplayContent != null && mDisplayContent.mUnknownAppVisibilityController
                 .isVisibilityUnknown(this)) {
             return false;
@@ -10572,11 +10588,14 @@
     }
 
     @Override
-    void finishSync(Transaction outMergedTransaction, boolean cancel) {
+    void finishSync(Transaction outMergedTransaction, BLASTSyncEngine.SyncGroup group,
+            boolean cancel) {
         // This override is just for getting metrics. allFinished needs to be checked before
         // finish because finish resets all the states.
+        final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup();
+        if (syncGroup != null && group != getSyncGroup()) return;
         mLastAllReadyAtSync = allSyncFinished();
-        super.finishSync(outMergedTransaction, cancel);
+        super.finishSync(outMergedTransaction, group, cancel);
     }
 
     @Nullable
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index a27f3e4..19a12f2 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1468,9 +1468,8 @@
         // transition based on a sub-action.
         // Only do the create here (and defer requestStart) since startActivityInner might abort.
         final TransitionController transitionController = r.mTransitionController;
-        Transition newTransition = (!transitionController.isCollecting()
-                && transitionController.getTransitionPlayer() != null)
-                ? transitionController.createTransition(TRANSIT_OPEN) : null;
+        Transition newTransition = transitionController.isShellTransitionsEnabled()
+                ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null;
         RemoteTransition remoteTransition = r.takeRemoteTransition();
         try {
             mService.deferWindowLayout();
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index bfb735d..3f4a775 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -144,6 +144,13 @@
         void acquire(int displayId);
 
         /**
+         * Acquires a sleep token.
+         * @param displayId The display to apply to.
+         * @param isSwappingDisplay Whether the display is swapping to another physical display.
+         */
+        void acquire(int displayId, boolean isSwappingDisplay);
+
+        /**
          * Releases the sleep token.
          * @param displayId The display to apply to.
          */
@@ -465,7 +472,7 @@
     public abstract boolean attachApplication(WindowProcessController wpc) throws RemoteException;
 
     /** @see IActivityManager#notifyLockedProfile(int) */
-    public abstract void notifyLockedProfile(@UserIdInt int userId, int currentUserId);
+    public abstract void notifyLockedProfile(@UserIdInt int userId);
 
     /** @see IActivityManager#startConfirmDeviceCredentialIntent(Intent, Bundle) */
     public abstract void startConfirmDeviceCredentialIntent(Intent intent, Bundle options);
@@ -748,4 +755,10 @@
 
     /** Unregister a task stack listener so that it stops receiving callbacks. */;
     public abstract void unregisterTaskStackListener(ITaskStackListener listener);
+
+    /**
+     * Gets the id of the display the activity was launched on.
+     * @param token The activity token.
+     */
+    public abstract int getDisplayId(IBinder token);
 }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index ea0731a..1f4606b 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -241,6 +241,7 @@
 import android.window.TaskSnapshot;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.ProcessMap;
@@ -2953,6 +2954,7 @@
                     mKeyguardController.setKeyguardShown(displayContent.getDisplayId(),
                             keyguardShowing, aodShowing);
                 });
+                maybeHideLockedProfileActivityLocked();
             } finally {
                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 Binder.restoreCallingIdentity(ident);
@@ -2966,6 +2968,26 @@
         });
     }
 
+    /**
+     * Hides locked profile activity by going to home screen to avoid showing the user two lock
+     * screens in a row.
+     */
+    @GuardedBy("mGlobalLock")
+    private void maybeHideLockedProfileActivityLocked() {
+        if (!mKeyguardController.isKeyguardLocked(DEFAULT_DISPLAY)
+                || mLastResumedActivity == null) {
+            return;
+        }
+        var userInfo = mUserManager.getUserInfo(mLastResumedActivity.mUserId);
+        if (userInfo == null || !userInfo.isManagedProfile()) {
+            return;
+        }
+        if (mAmInternal.shouldConfirmCredentials(mLastResumedActivity.mUserId)) {
+            mInternal.startHomeActivity(
+                    mAmInternal.getCurrentUserId(), "maybeHideLockedProfileActivityLocked");
+        }
+    }
+
     // The caller MUST NOT hold the global lock.
     public void onScreenAwakeChanged(boolean isAwake) {
         mH.post(() -> {
@@ -4822,10 +4844,16 @@
 
         @Override
         public void acquire(int displayId) {
+            acquire(displayId, false /* isSwappingDisplay */);
+        }
+
+        @Override
+        public void acquire(int displayId, boolean isSwappingDisplay) {
             synchronized (mGlobalLock) {
                 if (!mSleepTokens.contains(displayId)) {
                     mSleepTokens.append(displayId,
-                            mRootWindowContainer.createSleepToken(mTag, displayId));
+                            mRootWindowContainer.createSleepToken(mTag, displayId,
+                                    isSwappingDisplay));
                     updateSleepIfNeededLocked();
                 }
             }
@@ -5788,6 +5816,18 @@
         }
 
         @Override
+        public int getDisplayId(IBinder token) {
+            synchronized (mGlobalLock) {
+                ActivityRecord r = ActivityRecord.forTokenLocked(token);
+                if (r == null) {
+                    throw new IllegalArgumentException(
+                            "setFocusedActivity: No activity record matching token=" + token);
+                }
+                return r.getDisplayId();
+            }
+        }
+
+        @Override
         public void registerScreenObserver(ScreenObserver observer) {
             mScreenObservers.add(observer);
         }
@@ -6368,7 +6408,7 @@
         }
 
         @Override
-        public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
+        public void notifyLockedProfile(@UserIdInt int userId) {
             try {
                 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
                     throw new SecurityException("Only privileged app can call notifyLockedProfile");
@@ -6381,10 +6421,7 @@
                 final long ident = Binder.clearCallingIdentity();
                 try {
                     if (mAmInternal.shouldConfirmCredentials(userId)) {
-                        if (mKeyguardController.isKeyguardLocked(DEFAULT_DISPLAY)) {
-                            // Showing launcher to avoid user entering credential twice.
-                            startHomeActivity(currentUserId, "notifyLockedProfile");
-                        }
+                        maybeHideLockedProfileActivityLocked();
                         mRootWindowContainer.lockAllProfileTasks(userId);
                     }
                 } finally {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 7d220df..0121513 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -188,6 +188,9 @@
     // How long we can hold the launch wake lock before giving up.
     private static final int LAUNCH_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
 
+    // How long we delay processing the stopping and finishing activities.
+    private static final int SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS = 200;
+
     /** How long we wait until giving up on the activity telling us it released the top state. */
     private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT = 500;
 
@@ -2181,13 +2184,15 @@
             boolean processPausingActivities, String reason) {
         // Stop any activities that are scheduled to do so but have been waiting for the transition
         // animation to finish.
+        boolean displaySwapping = false;
         ArrayList<ActivityRecord> readyToStopActivities = null;
         for (int i = 0; i < mStoppingActivities.size(); i++) {
             final ActivityRecord s = mStoppingActivities.get(i);
             final boolean animating = s.isInTransition();
+            displaySwapping |= s.isDisplaySleepingAndSwapping();
             ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
                     + "finishing=%s", s, s.nowVisible, animating, s.finishing);
-            if (!animating || mService.mShuttingDown) {
+            if ((!animating && !displaySwapping) || mService.mShuttingDown) {
                 if (!processPausingActivities && s.isState(PAUSING)) {
                     // Defer processing pausing activities in this iteration and reschedule
                     // a delayed idle to reprocess it again
@@ -2207,6 +2212,16 @@
             }
         }
 
+        // Stopping activities are deferred processing if the display is swapping. Check again
+        // later to ensure the stopping activities can be stopped after display swapped.
+        if (displaySwapping) {
+            mHandler.postDelayed(() -> {
+                synchronized (mService.mGlobalLock) {
+                    scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
+                }
+            }, SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS);
+        }
+
         final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
         for (int i = 0; i < numReadyStops; i++) {
             final ActivityRecord r = readyToStopActivities.get(i);
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 7a11120..7e78393 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -267,7 +267,12 @@
             op.mDrawTransaction = null;
             if (DEBUG) Slog.d(TAG, "finishOp merge transaction " + windowToken.getTopChild());
         }
-        if (op.mAction == Operation.ACTION_FADE) {
+        if (op.mAction == Operation.ACTION_TOGGLE_IME) {
+            if (DEBUG) Slog.d(TAG, "finishOp fade-in IME " + windowToken.getTopChild());
+            fadeWindowToken(true /* show */, windowToken, ANIMATION_TYPE_TOKEN_TRANSFORM,
+                    (type, anim) -> mDisplayContent.getInsetsStateController()
+                            .getImeSourceProvider().reportImeDrawnForOrganizer());
+        } else if (op.mAction == Operation.ACTION_FADE) {
             if (DEBUG) Slog.d(TAG, "finishOp fade-in " + windowToken.getTopChild());
             // The previous animation leash will be dropped when preparing fade-in animation, so
             // simply apply new animation without restoring the transformation.
@@ -344,7 +349,7 @@
         for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
             final WindowToken windowToken = mTargetWindowTokens.keyAt(i);
             final Operation op = mTargetWindowTokens.valueAt(i);
-            if (op.mAction == Operation.ACTION_FADE) {
+            if (op.mAction == Operation.ACTION_FADE || op.mAction == Operation.ACTION_TOGGLE_IME) {
                 fadeWindowToken(false /* show */, windowToken, ANIMATION_TYPE_TOKEN_TRANSFORM);
                 op.mLeash = windowToken.getAnimationLeash();
                 if (DEBUG) Slog.d(TAG, "Start fade-out " + windowToken.getTopChild());
@@ -374,17 +379,19 @@
                 WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION);
     }
 
-    /** Hides the window immediately until it is drawn in new rotation. */
-    void hideImmediately(WindowToken windowToken) {
-        if (isTargetToken(windowToken)) return;
+    /** Hides the IME window immediately until it is drawn in new rotation. */
+    void hideImeImmediately() {
+        if (mDisplayContent.mInputMethodWindow == null) return;
+        final WindowToken imeWindowToken = mDisplayContent.mInputMethodWindow.mToken;
+        if (isTargetToken(imeWindowToken)) return;
         final boolean original = mHideImmediately;
         mHideImmediately = true;
-        final Operation op = new Operation(Operation.ACTION_FADE);
-        mTargetWindowTokens.put(windowToken, op);
-        fadeWindowToken(false /* show */, windowToken, ANIMATION_TYPE_TOKEN_TRANSFORM);
-        op.mLeash = windowToken.getAnimationLeash();
+        final Operation op = new Operation(Operation.ACTION_TOGGLE_IME);
+        mTargetWindowTokens.put(imeWindowToken, op);
+        fadeWindowToken(false /* show */, imeWindowToken, ANIMATION_TYPE_TOKEN_TRANSFORM);
+        op.mLeash = imeWindowToken.getAnimationLeash();
         mHideImmediately = original;
-        if (DEBUG) Slog.d(TAG, "hideImmediately " + windowToken.getTopChild());
+        if (DEBUG) Slog.d(TAG, "hideImeImmediately " + imeWindowToken.getTopChild());
     }
 
     /** Returns {@code true} if the window will rotate independently. */
@@ -586,11 +593,13 @@
     /** The operation to control the rotation appearance associated with window token. */
     private static class Operation {
         @Retention(RetentionPolicy.SOURCE)
-        @IntDef(value = { ACTION_SEAMLESS, ACTION_FADE })
+        @IntDef(value = { ACTION_SEAMLESS, ACTION_FADE, ACTION_TOGGLE_IME })
         @interface Action {}
 
         static final int ACTION_SEAMLESS = 1;
         static final int ACTION_FADE = 2;
+        /** The action to toggle the IME window appearance */
+        static final int ACTION_TOGGLE_IME = 3;
         final @Action int mAction;
         /** The leash of window token. It can be animation leash or the token itself. */
         SurfaceControl mLeash;
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index 7ecc083..778951a 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -27,7 +27,6 @@
 import android.os.Trace;
 import android.util.ArraySet;
 import android.util.Slog;
-import android.util.SparseArray;
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -61,6 +60,26 @@
  * This works primarily by setting-up state and then watching/waiting for the registered subtrees
  * to enter into a "finished" state (either by receiving drawn content or by disappearing). This
  * checks the subtrees during surface-placement.
+ *
+ * By default, all Syncs will be serialized (and it is an error to start one while another is
+ * active). However, a sync can be explicitly started in "parallel". This does not guarantee that
+ * it will run in parallel; however, it will run in parallel as long as it's watched hierarchy
+ * doesn't overlap with any other syncs' watched hierarchies.
+ *
+ * Currently, a sync that is started as "parallel" implicitly ignores the subtree below it's
+ * direct members unless those members are activities (WindowStates are considered "part of" the
+ * activity). This allows "stratified" parallelism where, eg, a sync that is only at Task-level
+ * can run in parallel with another sync that includes only the task's activities.
+ *
+ * If, at any time, a container is added to a parallel sync that *is* watched by another sync, it
+ * will be forced to serialize with it. This is done by adding a dependency. A sync will only
+ * finish if it has no active dependencies. At this point it is effectively not parallel anymore.
+ *
+ * To avoid dependency cycles, if a sync B ultimately depends on a sync A and a container is added
+ * to A which is watched by B, that container will, instead, be moved from B to A instead of
+ * creating a cyclic dependency.
+ *
+ * When syncs overlap, this will attempt to finish everything in the order they were started.
  */
 class BLASTSyncEngine {
     private static final String TAG = "BLASTSyncEngine";
@@ -104,6 +123,18 @@
         private SurfaceControl.Transaction mOrphanTransaction = null;
         private String mTraceName;
 
+        private static final ArrayList<SyncGroup> NO_DEPENDENCIES = new ArrayList<>();
+
+        /**
+         * When `true`, this SyncGroup will only wait for mRootMembers to draw; otherwise,
+         * it waits for the whole subtree(s) rooted at the mRootMembers.
+         */
+        boolean mIgnoreIndirectMembers = false;
+
+        /** List of SyncGroups that must finish before this one can. */
+        @NonNull
+        ArrayList<SyncGroup> mDependencies = NO_DEPENDENCIES;
+
         private SyncGroup(TransactionReadyListener listener, int id, String name) {
             mSyncId = id;
             mListener = listener;
@@ -133,19 +164,43 @@
             return mOrphanTransaction;
         }
 
-        private void tryFinish() {
-            if (!mReady) return;
+        /**
+         * Check if the sync-group ignores a particular container. This is used to allow syncs at
+         * different levels to run in parallel. The primary example is Recents while an activity
+         * sync is happening.
+         */
+        boolean isIgnoring(WindowContainer wc) {
+            // Some heuristics to avoid unnecessary work:
+            // 1. For now, require an explicit acknowledgement of potential "parallelism" across
+            //    hierarchy levels (horizontal).
+            if (!mIgnoreIndirectMembers) return false;
+            // 2. Don't check WindowStates since they are below the relevant abstraction level (
+            //    anything activity/token and above).
+            if (wc.asWindowState() != null) return false;
+            // Obviously, don't ignore anything that is directly part of this group.
+            return wc.mSyncGroup != this;
+        }
+
+        /** @return `true` if it finished. */
+        private boolean tryFinish() {
+            if (!mReady) return false;
             ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: onSurfacePlacement checking %s",
                     mSyncId, mRootMembers);
+            if (!mDependencies.isEmpty()) {
+                ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d:  Unfinished dependencies: %s",
+                        mSyncId, mDependencies);
+                return false;
+            }
             for (int i = mRootMembers.size() - 1; i >= 0; --i) {
                 final WindowContainer wc = mRootMembers.valueAt(i);
-                if (!wc.isSyncFinished()) {
+                if (!wc.isSyncFinished(this)) {
                     ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d:  Unfinished container: %s",
                             mSyncId, wc);
-                    return;
+                    return false;
                 }
             }
             finishNow();
+            return true;
         }
 
         private void finishNow() {
@@ -158,7 +213,7 @@
                 merged.merge(mOrphanTransaction);
             }
             for (WindowContainer wc : mRootMembers) {
-                wc.finishSync(merged, false /* cancel */);
+                wc.finishSync(merged, this, false /* cancel */);
             }
 
             final ArraySet<WindowContainer> wcAwaitingCommit = new ArraySet<>();
@@ -204,7 +259,7 @@
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionReady");
             mListener.onTransactionReady(mSyncId, merged);
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-            mActiveSyncs.remove(mSyncId);
+            mActiveSyncs.remove(this);
             mHandler.removeCallbacks(mOnTimeout);
 
             // Immediately start the next pending sync-transaction if there is one.
@@ -230,54 +285,115 @@
             }
         }
 
-        private void setReady(boolean ready) {
+        /** returns true if readiness changed. */
+        private boolean setReady(boolean ready) {
             if (mReady == ready) {
-                return;
+                return false;
             }
             ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Set ready %b", mSyncId, ready);
             mReady = ready;
-            if (!ready) return;
-            mWm.mWindowPlacerLocked.requestTraversal();
+            if (ready) {
+                mWm.mWindowPlacerLocked.requestTraversal();
+            }
+            return true;
         }
 
         private void addToSync(WindowContainer wc) {
-            if (!mRootMembers.add(wc)) {
+            if (mRootMembers.contains(wc)) {
                 return;
             }
             ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Adding to group: %s", mSyncId, wc);
-            wc.setSyncGroup(this);
+            final SyncGroup dependency = wc.getSyncGroup();
+            if (dependency != null && dependency != this && !dependency.isIgnoring(wc)) {
+                // This syncgroup now conflicts with another one, so the whole group now must
+                // wait on the other group.
+                Slog.w(TAG, "SyncGroup " + mSyncId + " conflicts with " + dependency.mSyncId
+                        + ": Making " + mSyncId + " depend on " + dependency.mSyncId);
+                if (mDependencies.contains(dependency)) {
+                    // nothing, it's already a dependency.
+                } else if (dependency.dependsOn(this)) {
+                    Slog.w(TAG, " Detected dependency cycle between " + mSyncId + " and "
+                            + dependency.mSyncId + ": Moving " + wc + " to " + mSyncId);
+                    // Since dependency already depends on this, make this now `wc`'s watcher
+                    if (wc.mSyncGroup == null) {
+                        wc.setSyncGroup(this);
+                    } else {
+                        // Explicit replacement.
+                        wc.mSyncGroup.mRootMembers.remove(wc);
+                        mRootMembers.add(wc);
+                        wc.mSyncGroup = this;
+                    }
+                } else {
+                    if (mDependencies == NO_DEPENDENCIES) {
+                        mDependencies = new ArrayList<>();
+                    }
+                    mDependencies.add(dependency);
+                }
+            } else {
+                mRootMembers.add(wc);
+                wc.setSyncGroup(this);
+            }
             wc.prepareSync();
             if (mReady) {
                 mWm.mWindowPlacerLocked.requestTraversal();
             }
         }
 
+        private boolean dependsOn(SyncGroup group) {
+            if (mDependencies.isEmpty()) return false;
+            // BFS search with membership check. We don't expect cycle here (since this is
+            // explicitly called to avoid cycles) but just to be safe.
+            final ArrayList<SyncGroup> fringe = mTmpFringe;
+            fringe.clear();
+            fringe.add(this);
+            for (int head = 0; head < fringe.size(); ++head) {
+                final SyncGroup next = fringe.get(head);
+                if (next == group) {
+                    fringe.clear();
+                    return true;
+                }
+                for (int i = 0; i < next.mDependencies.size(); ++i) {
+                    if (fringe.contains(next.mDependencies.get(i))) continue;
+                    fringe.add(next.mDependencies.get(i));
+                }
+            }
+            fringe.clear();
+            return false;
+        }
+
         void onCancelSync(WindowContainer wc) {
             mRootMembers.remove(wc);
         }
 
         private void onTimeout() {
-            if (!mActiveSyncs.contains(mSyncId)) return;
+            if (!mActiveSyncs.contains(this)) return;
             boolean allFinished = true;
             for (int i = mRootMembers.size() - 1; i >= 0; --i) {
                 final WindowContainer<?> wc = mRootMembers.valueAt(i);
-                if (!wc.isSyncFinished()) {
+                if (!wc.isSyncFinished(this)) {
                     allFinished = false;
                     Slog.i(TAG, "Unfinished container: " + wc);
                 }
             }
+            for (int i = mDependencies.size() - 1; i >= 0; --i) {
+                allFinished = false;
+                Slog.i(TAG, "Unfinished dependency: " + mDependencies.get(i).mSyncId);
+            }
             if (allFinished && !mReady) {
                 Slog.w(TAG, "Sync group " + mSyncId + " timed-out because not ready. If you see "
                         + "this, please file a bug.");
             }
             finishNow();
+            removeFromDependencies(this);
         }
     }
 
     private final WindowManagerService mWm;
     private final Handler mHandler;
     private int mNextSyncId = 0;
-    private final SparseArray<SyncGroup> mActiveSyncs = new SparseArray<>();
+
+    /** Currently active syncs. Intentionally ordered by start time. */
+    private final ArrayList<SyncGroup> mActiveSyncs = new ArrayList<>();
 
     /**
      * A queue of pending sync-sets waiting for their turn to run.
@@ -288,6 +404,9 @@
 
     private final ArrayList<Runnable> mOnIdleListeners = new ArrayList<>();
 
+    private final ArrayList<SyncGroup> mTmpFinishQueue = new ArrayList<>();
+    private final ArrayList<SyncGroup> mTmpFringe = new ArrayList<>();
+
     BLASTSyncEngine(WindowManagerService wms) {
         this(wms, wms.mH);
     }
@@ -306,32 +425,39 @@
         return new SyncGroup(listener, mNextSyncId++, name);
     }
 
-    int startSyncSet(TransactionReadyListener listener, long timeoutMs, String name) {
+    int startSyncSet(TransactionReadyListener listener, long timeoutMs, String name,
+            boolean parallel) {
         final SyncGroup s = prepareSyncSet(listener, name);
-        startSyncSet(s, timeoutMs);
+        startSyncSet(s, timeoutMs, parallel);
         return s.mSyncId;
     }
 
     void startSyncSet(SyncGroup s) {
-        startSyncSet(s, BLAST_TIMEOUT_DURATION);
+        startSyncSet(s, BLAST_TIMEOUT_DURATION, false /* parallel */);
     }
 
-    void startSyncSet(SyncGroup s, long timeoutMs) {
-        if (mActiveSyncs.size() != 0) {
-            // We currently only support one sync at a time, so start a new SyncGroup when there is
-            // another may cause issue.
+    void startSyncSet(SyncGroup s, long timeoutMs, boolean parallel) {
+        final boolean alreadyRunning = mActiveSyncs.size() > 0;
+        if (!parallel && alreadyRunning) {
+            // We only support overlapping syncs when explicitly declared `parallel`.
             Slog.e(TAG, "SyncGroup " + s.mSyncId
                     + ": Started when there is other active SyncGroup");
         }
-        mActiveSyncs.put(s.mSyncId, s);
-        ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Started for listener: %s",
-                s.mSyncId, s.mListener);
+        mActiveSyncs.add(s);
+        // For now, parallel implies this.
+        s.mIgnoreIndirectMembers = parallel;
+        ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Started %sfor listener: %s",
+                s.mSyncId, (parallel && alreadyRunning ? "(in parallel) " : ""), s.mListener);
         scheduleTimeout(s, timeoutMs);
     }
 
     @Nullable
     SyncGroup getSyncSet(int id) {
-        return mActiveSyncs.get(id);
+        for (int i = 0; i < mActiveSyncs.size(); ++i) {
+            if (mActiveSyncs.get(i).mSyncId != id) continue;
+            return mActiveSyncs.get(i);
+        }
+        return null;
     }
 
     boolean hasActiveSync() {
@@ -356,8 +482,8 @@
         syncGroup.mSyncMethod = method;
     }
 
-    void setReady(int id, boolean ready) {
-        getSyncGroup(id).setReady(ready);
+    boolean setReady(int id, boolean ready) {
+        return getSyncGroup(id).setReady(ready);
     }
 
     void setReady(int id) {
@@ -372,21 +498,68 @@
      * Aborts the sync (ie. it doesn't wait for ready or anything to finish)
      */
     void abort(int id) {
-        getSyncGroup(id).finishNow();
+        final SyncGroup group = getSyncGroup(id);
+        group.finishNow();
+        removeFromDependencies(group);
     }
 
     private SyncGroup getSyncGroup(int id) {
-        final SyncGroup syncGroup = mActiveSyncs.get(id);
+        final SyncGroup syncGroup = getSyncSet(id);
         if (syncGroup == null) {
             throw new IllegalStateException("SyncGroup is not started yet id=" + id);
         }
         return syncGroup;
     }
 
+    /**
+     * Just removes `group` from any dependency lists. Does not try to evaluate anything. However,
+     * it will schedule traversals if any groups were changed in a way that could make them ready.
+     */
+    private void removeFromDependencies(SyncGroup group) {
+        boolean anyChange = false;
+        for (int i = 0; i < mActiveSyncs.size(); ++i) {
+            final SyncGroup active = mActiveSyncs.get(i);
+            if (!active.mDependencies.remove(group)) continue;
+            if (!active.mDependencies.isEmpty()) continue;
+            anyChange = true;
+        }
+        if (!anyChange) return;
+        mWm.mWindowPlacerLocked.requestTraversal();
+    }
+
     void onSurfacePlacement() {
-        // backwards since each state can remove itself if finished
-        for (int i = mActiveSyncs.size() - 1; i >= 0; --i) {
-            mActiveSyncs.valueAt(i).tryFinish();
+        if (mActiveSyncs.isEmpty()) return;
+        // queue in-order since we want interdependent syncs to become ready in the same order they
+        // started in.
+        mTmpFinishQueue.addAll(mActiveSyncs);
+        // There shouldn't be any dependency cycles or duplicates, but add an upper-bound just
+        // in case. Assuming absolute worst case, each visit will try and revisit everything
+        // before it, so n + (n-1) + (n-2) ... = (n+1)*n/2
+        int visitBounds = ((mActiveSyncs.size() + 1) * mActiveSyncs.size()) / 2;
+        while (!mTmpFinishQueue.isEmpty()) {
+            if (visitBounds <= 0) {
+                Slog.e(TAG, "Trying to finish more syncs than theoretically possible. This "
+                        + "should never happen. Most likely a dependency cycle wasn't detected.");
+            }
+            --visitBounds;
+            final SyncGroup group = mTmpFinishQueue.remove(0);
+            final int grpIdx = mActiveSyncs.indexOf(group);
+            // Skip if it's already finished:
+            if (grpIdx < 0) continue;
+            if (!group.tryFinish()) continue;
+            // Finished, so update dependencies of any prior groups and retry if unblocked.
+            int insertAt = 0;
+            for (int i = 0; i < mActiveSyncs.size(); ++i) {
+                final SyncGroup active = mActiveSyncs.get(i);
+                if (!active.mDependencies.remove(group)) continue;
+                // Anything afterwards is already in queue.
+                if (i >= grpIdx) continue;
+                if (!active.mDependencies.isEmpty()) continue;
+                // `active` became unblocked so it can finish, since it started earlier, it should
+                // be checked next to maintain order.
+                mTmpFinishQueue.add(insertAt, mActiveSyncs.get(i));
+                insertAt += 1;
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index e447049..1a3d673 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -452,6 +452,9 @@
         // If we are here, it means all exemptions not based on PI sender failed, so we'll block
         // unless resultIfPiSenderAllowsBal is an allow and the PI sender allows BAL
 
+        String realCallingPackage = callingUid == realCallingUid ? callingPackage :
+                mService.mContext.getPackageManager().getNameForUid(realCallingUid);
+
         String stateDumpLog = " [callingPackage: " + callingPackage
                 + "; callingUid: " + callingUid
                 + "; appSwitchState: " + appSwitchState
@@ -460,6 +463,7 @@
                         ActivityManager.class, "PROCESS_STATE_", callingUidProcState)
                 + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
                 + "; balAllowedByPiSender: " + balAllowedByPiSender
+                + "; realCallingPackage: " + realCallingPackage
                 + "; realCallingUid: " + realCallingUid
                 + "; realCallingUidHasAnyVisibleWindow: " + realCallingUidHasAnyVisibleWindow
                 + "; realCallingUidProcState: " + DebugUtils.valueToString(
diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java
index a41dcc6..040da88 100644
--- a/services/core/java/com/android/server/wm/ContentRecordingController.java
+++ b/services/core/java/com/android/server/wm/ContentRecordingController.java
@@ -80,7 +80,7 @@
         }
         // Invalid scenario: ignore identical incoming session.
         if (ContentRecordingSession.isProjectionOnSameDisplay(mSession, incomingSession)) {
-            // TODO(242833866) if incoming session is no longer waiting to record, allow
+            // TODO(242833866): if incoming session is no longer waiting to record, allow
             //  the update through.
 
             ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
@@ -99,7 +99,7 @@
             incomingDisplayContent = wmService.mRoot.getDisplayContentOrCreate(
                     incomingSession.getVirtualDisplayId());
             incomingDisplayContent.setContentRecordingSession(incomingSession);
-            // TODO(b/270118861) When user grants consent to re-use, explicitly ask ContentRecorder
+            // TODO(b/270118861): When user grants consent to re-use, explicitly ask ContentRecorder
             //  to update, since no config/display change arrives. Mark recording as black.
         }
         // Takeover and stopping scenario: stop recording on the pre-existing session.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 76d6951..57812c1 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1755,7 +1755,7 @@
     }
 
     @Override
-    boolean isSyncFinished() {
+    boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
         // Do not consider children because if they are requested to be synced, they should be
         // added to sync group explicitly.
         return !mRemoteDisplayChangeController.isWaitingForRemoteDisplayChange();
@@ -1896,7 +1896,12 @@
             case SOFT_INPUT_STATE_HIDDEN:
                 return false;
         }
-        return r.mLastImeShown;
+        final boolean useIme = r.getWindow(
+                w -> WindowManager.LayoutParams.mayUseInputMethod(w.mAttrs.flags)) != null;
+        if (!useIme) {
+            return false;
+        }
+        return r.mLastImeShown || (r.mStartingData != null && r.mStartingData.hasImeSurface());
     }
 
     /** Returns {@code true} if the top activity is transformed with the new rotation of display. */
@@ -2190,6 +2195,14 @@
         }
 
         mWmService.mDisplayManagerInternal.performTraversal(transaction);
+        if (shellTransitions) {
+            // Before setDisplayProjection is applied by the start transaction of transition,
+            // set the transform hint to avoid using surface in old rotation.
+            getPendingTransaction().setFixedTransformHint(mSurfaceControl, rotation);
+            // The sync transaction should already contains setDisplayProjection, so unset the
+            // hint to restore the natural state when the transaction is applied.
+            transaction.unsetFixedTransformHint(mSurfaceControl);
+        }
         scheduleAnimation();
 
         mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation);
@@ -2267,6 +2280,12 @@
         if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) {
             return WmDisplayCutout.NO_CUTOUT;
         }
+        if (displayWidth == displayHeight) {
+            Slog.w(TAG, "Ignore cutout because display size is square: " + displayWidth);
+            // Avoid UnsupportedOperationException because DisplayCutout#computeSafeInsets doesn't
+            // support square size.
+            return WmDisplayCutout.NO_CUTOUT;
+        }
         if (rotation == ROTATION_0) {
             return WmDisplayCutout.computeSafeInsets(
                     cutout, displayWidth, displayHeight);
@@ -3087,13 +3106,9 @@
 
         mIsSizeForced = mInitialDisplayWidth != width || mInitialDisplayHeight != height;
         if (mIsSizeForced) {
-            // Set some sort of reasonable bounds on the size of the display that we will try
-            // to emulate.
-            final int minSize = 200;
-            final int maxScale = 3;
-            final int maxSize = Math.max(mInitialDisplayWidth, mInitialDisplayHeight) * maxScale;
-            width = Math.min(Math.max(width, minSize), maxSize);
-            height = Math.min(Math.max(height, minSize), maxSize);
+            final Point size = getValidForcedSize(width, height);
+            width = size.x;
+            height = size.y;
         }
 
         Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
@@ -3108,6 +3123,16 @@
         mWmService.mDisplayWindowSettings.setForcedSize(this, width, height);
     }
 
+    /** Returns a reasonable size for setting forced display size. */
+    Point getValidForcedSize(int w, int h) {
+        final int minSize = 200;
+        final int maxScale = 3;
+        final int maxSize = Math.max(mInitialDisplayWidth, mInitialDisplayHeight) * maxScale;
+        w = Math.min(Math.max(w, minSize), maxSize);
+        h = Math.min(Math.max(h, minSize), maxSize);
+        return new Point(w, h);
+    }
+
     DisplayCutout loadDisplayCutout(int displayWidth, int displayHeight) {
         if (mDisplayPolicy == null || mInitialDisplayCutout == null) {
             return null;
@@ -4199,7 +4224,7 @@
             // Hide the window until the rotation is done to avoid intermediate artifacts if the
             // parent surface of IME container is changed.
             if (mAsyncRotationController != null) {
-                mAsyncRotationController.hideImmediately(mInputMethodWindow.mToken);
+                mAsyncRotationController.hideImeImmediately();
             }
         }
     }
@@ -6025,7 +6050,7 @@
     static boolean alwaysCreateRootTask(int windowingMode, int activityType) {
         // Always create a root task for fullscreen, freeform, and multi windowing
         // modes so that we can manage visual ordering and return types correctly.
-        return activityType == ACTIVITY_TYPE_STANDARD
+        return (activityType == ACTIVITY_TYPE_STANDARD || activityType == ACTIVITY_TYPE_RECENTS)
                 && (windowingMode == WINDOWING_MODE_FULLSCREEN
                 || windowingMode == WINDOWING_MODE_FREEFORM
                 || windowingMode == WINDOWING_MODE_PINNED
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 747819e9..ce43628 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1882,6 +1882,12 @@
 
         static final int DECOR_TYPES = Type.displayCutout() | Type.navigationBars();
 
+        /**
+         * The types that may affect display configuration. This excludes cutout because it is
+         * known from display info.
+         */
+        static final int CONFIG_TYPES = Type.statusBars() | Type.navigationBars();
+
         private final DisplayContent mDisplayContent;
         private final Info[] mInfoForRotation = new Info[4];
         final Info mTmpInfo = new Info();
@@ -1921,7 +1927,7 @@
         final DecorInsets.Info newInfo = mDecorInsets.mTmpInfo;
         newInfo.update(mDisplayContent, rotation, dw, dh);
         final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh);
-        if (newInfo.mNonDecorFrame.equals(currentInfo.mNonDecorFrame)) {
+        if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)) {
             return false;
         }
         mDecorInsets.invalidate();
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 20048ce..a3d233d 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -123,6 +123,7 @@
 
     public final boolean isDefaultDisplay;
     private final boolean mSupportAutoRotation;
+    private final boolean mAllowRotationResolver;
     private final int mLidOpenRotation;
     private final int mCarDockRotation;
     private final int mDeskDockRotation;
@@ -272,6 +273,8 @@
 
         mSupportAutoRotation =
                 mContext.getResources().getBoolean(R.bool.config_supportAutoRotation);
+        mAllowRotationResolver =
+                mContext.getResources().getBoolean(R.bool.config_allowRotationResolver);
         mLidOpenRotation = readRotation(R.integer.config_lidOpenRotation);
         mCarDockRotation = readRotation(R.integer.config_carDockRotation);
         mDeskDockRotation = readRotation(R.integer.config_deskDockRotation);
@@ -946,6 +949,10 @@
     }
 
     void freezeRotation(int rotation) {
+        if (mDeviceStateController.shouldReverseRotationDirectionAroundZAxis()) {
+            rotation = RotationUtils.reverseRotationDirectionAroundZAxis(rotation);
+        }
+
         rotation = (rotation == -1) ? mRotation : rotation;
         setUserRotation(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation);
     }
@@ -2037,7 +2044,8 @@
 
         @Override
         public boolean isRotationResolverEnabled() {
-            return mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
+            return mAllowRotationResolver
+                    && mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
                     && mCameraRotationMode == CAMERA_ROTATION_ENABLED
                     && !mService.mPowerManager.isPowerSaveMode();
         }
diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
index 1fb97f9..2fb9869 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
@@ -114,7 +114,7 @@
      * @see DisplayWindowPolicyController#keepActivityOnWindowFlagsChanged(ActivityInfo, int, int)
      */
     boolean keepActivityOnWindowFlagsChanged(ActivityInfo aInfo, int flagChanges,
-            int privateFlagChanges) {
+            int privateFlagChanges, int flagValues, int privateFlagValues) {
         if (mDisplayWindowPolicyController == null) {
             return true;
         }
@@ -125,7 +125,7 @@
         }
 
         return mDisplayWindowPolicyController.keepActivityOnWindowFlagsChanged(
-                aInfo, flagChanges, privateFlagChanges);
+                aInfo, flagValues, privateFlagValues);
     }
 
     /** Update the top activity and the uids of non-finishing activity */
diff --git a/services/core/java/com/android/server/wm/FadeAnimationController.java b/services/core/java/com/android/server/wm/FadeAnimationController.java
index 561a070..7af67e6 100644
--- a/services/core/java/com/android/server/wm/FadeAnimationController.java
+++ b/services/core/java/com/android/server/wm/FadeAnimationController.java
@@ -57,14 +57,21 @@
         return AnimationUtils.loadAnimation(mContext, R.anim.fade_out);
     }
 
+    /** Run the fade in/out animation for a window token. */
+    public void fadeWindowToken(boolean show, WindowToken windowToken, int animationType) {
+        fadeWindowToken(show, windowToken, animationType, null);
+    }
+
     /**
      * Run the fade in/out animation for a window token.
      *
      * @param show true for fade-in, otherwise for fade-out.
      * @param windowToken the window token to run the animation.
      * @param animationType the animation type defined in SurfaceAnimator.
+     * @param finishedCallback the callback after the animation finished.
      */
-    public void fadeWindowToken(boolean show, WindowToken windowToken, int animationType) {
+    public void fadeWindowToken(boolean show, WindowToken windowToken, int animationType,
+            SurfaceAnimator.OnAnimationFinishedCallback finishedCallback) {
         if (windowToken == null || windowToken.getParent() == null) {
             return;
         }
@@ -75,9 +82,8 @@
         if (animationAdapter == null) {
             return;
         }
-
         windowToken.startAnimation(windowToken.getPendingTransaction(), animationAdapter,
-                show /* hidden */, animationType, null /* finishedCallback */);
+                show /* hidden */, animationType, finishedCallback);
     }
 
     protected FadeAnimationAdapter createAdapter(LocalAnimationAdapter.AnimationSpec animationSpec,
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index b4dffdc..ff2985c 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -145,18 +145,44 @@
         }
         boolean changed = super.updateClientVisibility(caller);
         if (changed && caller.isRequestedVisible(mSource.getType())) {
-            reportImeDrawnForOrganizer(caller);
+            reportImeDrawnForOrganizerIfNeeded(caller);
         }
         changed |= mDisplayContent.onImeInsetsClientVisibilityUpdate();
         return changed;
     }
 
-    private void reportImeDrawnForOrganizer(InsetsControlTarget caller) {
-        if (caller.getWindow() != null && caller.getWindow().getTask() != null) {
-            if (caller.getWindow().getTask().isOrganized()) {
-                mWindowContainer.mWmService.mAtmService.mTaskOrganizerController
-                        .reportImeDrawnOnTask(caller.getWindow().getTask());
-            }
+    private void reportImeDrawnForOrganizerIfNeeded(@NonNull InsetsControlTarget caller) {
+        final WindowState callerWindow = caller.getWindow();
+        if (callerWindow == null) {
+            return;
+        }
+        WindowToken imeToken = mWindowContainer.asWindowState() != null
+                ? mWindowContainer.asWindowState().mToken : null;
+        if (mDisplayContent.getAsyncRotationController() != null
+                && mDisplayContent.getAsyncRotationController().isTargetToken(imeToken)) {
+            // Skip reporting IME drawn state when the control target is in fixed
+            // rotation, AsyncRotationController will report after the animation finished.
+            return;
+        }
+        reportImeDrawnForOrganizer(caller);
+    }
+
+    private void reportImeDrawnForOrganizer(@NonNull InsetsControlTarget caller) {
+        final WindowState callerWindow = caller.getWindow();
+        if (callerWindow == null || callerWindow.getTask() == null) {
+            return;
+        }
+        if (callerWindow.getTask().isOrganized()) {
+            mWindowContainer.mWmService.mAtmService.mTaskOrganizerController
+                    .reportImeDrawnOnTask(caller.getWindow().getTask());
+        }
+    }
+
+    /** Report the IME has drawn on the current IME control target for its task organizer */
+    void reportImeDrawnForOrganizer() {
+        final InsetsControlTarget imeControlTarget = getControlTarget();
+        if (imeControlTarget != null) {
+            reportImeDrawnForOrganizer(imeControlTarget);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index f5079d3..e47787e 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -33,6 +33,7 @@
 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.MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 
@@ -209,7 +210,8 @@
     private final PointerEventListener mListener = new PointerEventListener() {
         @Override
         public void onPointerEvent(MotionEvent ev) {
-            if (!mFreezeTaskListReordering || ev.getAction() != MotionEvent.ACTION_DOWN) {
+            if (!mFreezeTaskListReordering || ev.getAction() != MotionEvent.ACTION_DOWN
+                    || ev.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE) {
                 // Skip if we aren't freezing or starting a gesture
                 return;
             }
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index b879d1a..eb639b6 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -362,15 +362,8 @@
 
     private void invokeAnimationCancelled(String reason) {
         ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "cancelAnimation(): reason=%s", reason);
-        final boolean isKeyguardOccluded = mDisplayContent.isKeyguardOccluded();
-
         try {
-            EventLogTags.writeWmSetKeyguardOccluded(
-                    isKeyguardOccluded ? 1 : 0,
-                    0 /* animate */,
-                    0 /* transit */,
-                    "onAnimationCancelled");
-            mRemoteAnimationAdapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
+            mRemoteAnimationAdapter.getRunner().onAnimationCancelled();
         } catch (RemoteException e) {
             Slog.e(TAG, "Failed to notify cancel", e);
         }
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index cd4b3c5..d3edeae 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2601,6 +2601,10 @@
     }
 
     SleepToken createSleepToken(String tag, int displayId) {
+        return createSleepToken(tag, displayId, false /* isSwappingDisplay */);
+    }
+
+    SleepToken createSleepToken(String tag, int displayId, boolean isSwappingDisplay) {
         final DisplayContent display = getDisplayContent(displayId);
         if (display == null) {
             throw new IllegalArgumentException("Invalid display: " + displayId);
@@ -2609,7 +2613,7 @@
         final int tokenKey = makeSleepTokenKey(tag, displayId);
         SleepToken token = mSleepTokens.get(tokenKey);
         if (token == null) {
-            token = new SleepToken(tag, displayId);
+            token = new SleepToken(tag, displayId, isSwappingDisplay);
             mSleepTokens.put(tokenKey, token);
             display.mAllSleepTokens.add(token);
             ProtoLog.d(WM_DEBUG_STATES, "Create sleep token: tag=%s, displayId=%d", tag, displayId);
@@ -3235,7 +3239,7 @@
             if (task.getActivity(activity -> !activity.finishing && activity.mUserId == userId)
                     != null) {
                 mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
-                        task.getTaskInfo());
+                        task.getTaskInfo(), userId);
             }
         }, true /* traverseTopToBottom */);
     }
@@ -3518,18 +3522,34 @@
         private final String mTag;
         private final long mAcquireTime;
         private final int mDisplayId;
+        private final boolean mIsSwappingDisplay;
         final int mHashKey;
 
-        SleepToken(String tag, int displayId) {
+        // The display could remain in sleep after the physical display swapped, adding a 1
+        // seconds display swap timeout to prevent activities staying in PAUSED state.
+        // Otherwise, the sleep token should be removed once display turns back on after swapped.
+        private static final long DISPLAY_SWAP_TIMEOUT = 1000;
+
+        SleepToken(String tag, int displayId, boolean isSwappingDisplay) {
             mTag = tag;
             mDisplayId = displayId;
             mAcquireTime = SystemClock.uptimeMillis();
+            mIsSwappingDisplay = isSwappingDisplay;
             mHashKey = makeSleepTokenKey(mTag, mDisplayId);
         }
 
+        public boolean isDisplaySwapping() {
+            long now = SystemClock.uptimeMillis();
+            if (now - mAcquireTime > DISPLAY_SWAP_TIMEOUT) {
+                return false;
+            }
+            return mIsSwappingDisplay;
+        }
+
         @Override
         public String toString() {
             return "{\"" + mTag + "\", display " + mDisplayId
+                    + (mIsSwappingDisplay ? " is swapping " : "")
                     + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
         }
 
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index b5df3e0..bbb8563 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -193,6 +193,7 @@
                                 .setSourceCrop(new Rect(0, 0, width, height))
                                 .setAllowProtected(true)
                                 .setCaptureSecureLayers(true)
+                                .setHintForSeamlessTransition(true)
                                 .build();
                 screenshotBuffer = ScreenCapture.captureDisplay(captureArgs);
             } else {
@@ -202,6 +203,7 @@
                                 .setCaptureSecureLayers(true)
                                 .setAllowProtected(true)
                                 .setSourceCrop(new Rect(0, 0, width, height))
+                                .setHintForSeamlessTransition(true)
                                 .build();
                 screenshotBuffer = ScreenCapture.captureLayers(captureArgs);
             }
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 49d064f..9324e29 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -144,7 +144,7 @@
     };
 
     private final TaskStackConsumer mNotifyTaskProfileLocked = (l, m) -> {
-        l.onTaskProfileLocked((RunningTaskInfo) m.obj);
+        l.onTaskProfileLocked((RunningTaskInfo) m.obj, m.arg1);
     };
 
     private final TaskStackConsumer mNotifyTaskSnapshotChanged = (l, m) -> {
@@ -467,9 +467,9 @@
      * Notify listeners that the task has been put in a locked state because one or more of the
      * activities inside it belong to a managed profile user that has been locked.
      */
-    void notifyTaskProfileLocked(ActivityManager.RunningTaskInfo taskInfo) {
+    void notifyTaskProfileLocked(RunningTaskInfo taskInfo, int userId) {
         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG,
-                taskInfo);
+                userId, 0, taskInfo);
         forAllLocalListeners(mNotifyTaskProfileLocked, msg);
         msg.sendToTarget();
     }
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 3f7ab14..c6c3b14 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -2547,8 +2547,8 @@
     }
 
     @Override
-    boolean isSyncFinished() {
-        return super.isSyncFinished() && isReadyToTransit();
+    boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
+        return super.isSyncFinished(group) && isReadyToTransit();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 5626aa7..cdb4ad6 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -18,6 +18,9 @@
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.TaskInfo.cameraCompatControlStateToString;
+import static android.window.StartingWindowRemovalInfo.DEFER_MODE_NONE;
+import static android.window.StartingWindowRemovalInfo.DEFER_MODE_NORMAL;
+import static android.window.StartingWindowRemovalInfo.DEFER_MODE_ROTATION;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
 import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission;
@@ -686,8 +689,19 @@
         final boolean playShiftUpAnimation = !task.inMultiWindowMode();
         final ActivityRecord topActivity = task.topActivityContainsStartingWindow();
         if (topActivity != null) {
-            removalInfo.deferRemoveForIme = topActivity.mDisplayContent
-                    .mayImeShowOnLaunchingActivity(topActivity);
+            // Set defer remove mode for IME
+            final DisplayContent dc = topActivity.getDisplayContent();
+            final WindowState imeWindow = dc.mInputMethodWindow;
+            if (topActivity.isVisibleRequested() && imeWindow != null
+                    && dc.mayImeShowOnLaunchingActivity(topActivity)
+                    && dc.isFixedRotationLaunchingApp(topActivity)) {
+                removalInfo.deferRemoveForImeMode = DEFER_MODE_ROTATION;
+            } else if (dc.mayImeShowOnLaunchingActivity(topActivity)) {
+                removalInfo.deferRemoveForImeMode = DEFER_MODE_NORMAL;
+            } else {
+                removalInfo.deferRemoveForImeMode = DEFER_MODE_NONE;
+            }
+
             final WindowState mainWindow =
                     topActivity.findMainWindow(false/* includeStartingApp */);
             // No app window for this activity, app might be crashed.
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 452bd6d..7bd3b32 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -55,6 +55,7 @@
 import static android.window.TransitionInfo.FLAG_TASK_LAUNCHING_BEHIND;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 import static android.window.TransitionInfo.FLAG_WILL_IME_SHOWN;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_PENDING_INTENT;
 
 import static com.android.server.wm.ActivityRecord.State.RESUMED;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
@@ -65,12 +66,14 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ActivityOptions;
 import android.app.IApplicationThread;
 import android.content.pm.ActivityInfo;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
@@ -85,6 +88,7 @@
 import android.view.WindowManager;
 import android.window.ScreenCapture;
 import android.window.TransitionInfo;
+import android.window.WindowContainerTransaction;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
@@ -107,6 +111,11 @@
  * Represents a logical transition. This keeps track of all the changes associated with a logical
  * WM state -> state transition.
  * @see TransitionController
+ *
+ * In addition to tracking individual container changes, this also tracks ordering-changes (just
+ * on-top for now). However, since order is a "global" property, the mechanics of order-change
+ * detection/reporting is non-trivial when transitions are collecting in parallel. See
+ * {@link #collectOrderChanges} for more details.
  */
 class Transition implements BLASTSyncEngine.TransactionReadyListener {
     private static final String TAG = "Transition";
@@ -180,7 +189,7 @@
     final ArraySet<WindowContainer> mParticipants = new ArraySet<>();
 
     /** The final animation targets derived from participants after promotion. */
-    private ArrayList<ChangeInfo> mTargets;
+    ArrayList<ChangeInfo> mTargets;
 
     /** The displays that this transition is running on. */
     private final ArrayList<DisplayContent> mTargetDisplays = new ArrayList<>();
@@ -192,6 +201,12 @@
     private final ArrayList<Task> mOnTopTasksStart = new ArrayList<>();
 
     /**
+     * The (non alwaysOnTop) tasks which were on-top of their display when this transition became
+     * ready (via setReady, not animation-ready).
+     */
+    private final ArrayList<Task> mOnTopTasksAtReady = new ArrayList<>();
+
+    /**
      * Set of participating windowtokens (activity/wallpaper) which are visible at the end of
      * the transition animation.
      */
@@ -233,6 +248,16 @@
     private IContainerFreezer mContainerFreezer = null;
     private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
 
+    /**
+     * {@code true} if some other operation may have caused the originally-recorded state (in
+     * mChanges) to be dirty. This is usually due to finishTransition being called mid-collect;
+     * and, the reason that finish can alter the "start" state of other transitions is because
+     * setVisible(false) is deferred until then.
+     * Instead of adding this conditional, we could re-check always; but, this situation isn't
+     * common so it'd be wasted work.
+     */
+    boolean mPriorVisibilityMightBeDirty = false;
+
     final TransitionController.Logger mLogger = new TransitionController.Logger();
 
     /** Whether this transition was forced to play early (eg for a SLEEP signal). */
@@ -244,6 +269,41 @@
      */
     boolean mIsPlayerEnabled = true;
 
+    /** This transition doesn't run in parallel. */
+    static final int PARALLEL_TYPE_NONE = 0;
+
+    /** Any 2 transitions of this type can run in parallel with each other. Used for testing. */
+    static final int PARALLEL_TYPE_MUTUAL = 1;
+
+    /** This is a recents transition. */
+    static final int PARALLEL_TYPE_RECENTS = 2;
+
+
+    @IntDef(prefix = { "PARALLEL_TYPE_" }, value = {
+            PARALLEL_TYPE_NONE,
+            PARALLEL_TYPE_MUTUAL,
+            PARALLEL_TYPE_RECENTS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface ParallelType {}
+
+    /**
+     * What category of parallel-collect support this transition has. The value of this is used
+     * by {@link TransitionController} to determine which transitions can collect in parallel. If
+     * a transition can collect in parallel, it means that it will start collecting as soon as the
+     * prior collecting transition is {@link #isPopulated}. This is a shortcut for supporting
+     * a couple specific situations before we have full-fledged support for parallel transitions.
+     */
+    @ParallelType int mParallelCollectType = PARALLEL_TYPE_NONE;
+
+    /**
+     * A "Track" is a set of animations which must cooperate with each other to play smoothly. If
+     * animations can play independently of each other, then they can be in different tracks. If
+     * a transition must cooperate with transitions in >1 other track, then it must be marked
+     * FLAG_SYNC and it will end-up flushing all animations before it starts.
+     */
+    int mAnimationTrack = 0;
+
     Transition(@TransitionType int type, @TransitionFlags int flags,
             TransitionController controller, BLASTSyncEngine syncEngine) {
         mType = type;
@@ -277,6 +337,21 @@
         mFlags |= flag;
     }
 
+    void calcParallelCollectType(WindowContainerTransaction wct) {
+        for (int i = 0; i < wct.getHierarchyOps().size(); ++i) {
+            final WindowContainerTransaction.HierarchyOp hop = wct.getHierarchyOps().get(i);
+            if (hop.getType() != HIERARCHY_OP_TYPE_PENDING_INTENT) continue;
+            final Bundle b = hop.getLaunchOptions();
+            if (b == null || b.isEmpty()) continue;
+            final boolean transientLaunch = b.getBoolean(ActivityOptions.KEY_TRANSIENT_LAUNCH);
+            if (transientLaunch) {
+                ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
+                        "Starting a Recents transition which can be parallel.");
+                mParallelCollectType = PARALLEL_TYPE_RECENTS;
+            }
+        }
+    }
+
     /** Records an activity as transient-launch. This activity must be already collected. */
     void setTransientLaunch(@NonNull ActivityRecord activity, @Nullable Task restoreBelow) {
         if (mTransientLaunches == null) {
@@ -329,6 +404,10 @@
         return false;
     }
 
+    boolean hasTransientLaunch() {
+        return mTransientLaunches != null && !mTransientLaunches.isEmpty();
+    }
+
     boolean isTransientLaunch(@NonNull ActivityRecord activity) {
         return mTransientLaunches != null && mTransientLaunches.containsKey(activity);
     }
@@ -447,7 +526,8 @@
             throw new IllegalStateException("Attempting to re-use a transition");
         }
         mState = STATE_COLLECTING;
-        mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG);
+        mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG,
+                mParallelCollectType != PARALLEL_TYPE_NONE);
         mSyncEngine.setSyncMethod(mSyncId, TransitionController.SYNC_METHOD);
 
         mLogger.mSyncId = mSyncId;
@@ -718,8 +798,15 @@
         final boolean ready = mReadyTracker.allReady();
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                 "Set transition ready=%b %d", ready, mSyncId);
-        mSyncEngine.setReady(mSyncId, ready);
-        if (ready) mLogger.mReadyTimeNs = SystemClock.elapsedRealtimeNanos();
+        boolean changed = mSyncEngine.setReady(mSyncId, ready);
+        if (changed && ready) {
+            mLogger.mReadyTimeNs = SystemClock.elapsedRealtimeNanos();
+            mOnTopTasksAtReady.clear();
+            for (int i = 0; i < mTargetDisplays.size(); ++i) {
+                addOnTopTasks(mTargetDisplays.get(i), mOnTopTasksAtReady);
+            }
+            mController.onTransitionPopulated(this);
+        }
     }
 
     /**
@@ -737,6 +824,11 @@
         return mReadyTracker.allReady();
     }
 
+    /** This transition has all of its expected participants. */
+    boolean isPopulated() {
+        return mState >= STATE_STARTED && mReadyTracker.allReady();
+    }
+
     /**
      * Build a transaction that "resets" all the re-parenting and layer changes. This is
      * intended to be applied at the end of the transition but before the finish callback. This
@@ -811,6 +903,13 @@
             if (c.getSnapshot() != null) {
                 t.reparent(c.getSnapshot(), null);
             }
+            // The fixed transform hint was set in DisplayContent#applyRotation(). Make sure to
+            // clear the hint in case the start transaction is not applied.
+            if (c.hasFlags(FLAG_IS_DISPLAY) && c.getStartRotation() != c.getEndRotation()
+                    && c.getContainer() != null) {
+                t.unsetFixedTransformHint(WindowContainer.fromBinder(c.getContainer().asBinder())
+                        .asDisplayContent().mSurfaceControl);
+            }
         }
         for (int i = info.getRootCount() - 1; i >= 0; --i) {
             final SurfaceControl leash = info.getRoot(i).getLeash();
@@ -905,28 +1004,37 @@
         mController.mFinishingTransition = this;
 
         if (mTransientHideTasks != null && !mTransientHideTasks.isEmpty()) {
-            // Record all the now-hiding activities so that they are committed after
-            // recalculating visibilities. We just use mParticipants because we can and it will
-            // ensure proper reporting of `isInFinishTransition`.
-            for (int i = 0; i < mTransientHideTasks.size(); ++i) {
-                mTransientHideTasks.get(i).forAllActivities(r -> {
-                    // Only check leaf-tasks that were collected
-                    if (!mParticipants.contains(r.getTask())) return;
-                    // Only concern ourselves with anything that can become invisible
-                    if (!r.isVisible()) return;
-                    mParticipants.add(r);
-                });
-            }
             // The transient hide tasks could be occluded now, e.g. returning to home. So trigger
             // the update to make the activities in the tasks invisible-requested, then the next
             // step can continue to commit the visibility.
             mController.mAtm.mRootWindowContainer.ensureActivitiesVisible(null /* starting */,
                     0 /* configChanges */, true /* preserveWindows */);
+            // Record all the now-hiding activities so that they are committed. Just use
+            // mParticipants because we can avoid a new list this way.
+            for (int i = 0; i < mTransientHideTasks.size(); ++i) {
+                final Task rootTask = mTransientHideTasks.get(i);
+                rootTask.forAllActivities(r -> {
+                    // Only check leaf-tasks that were collected
+                    if (!mParticipants.contains(r.getTask())) return;
+                    if (rootTask.isVisibleRequested()) {
+                        // This transient-hide didn't hide, so don't commit anything (otherwise we
+                        // could prematurely commit invisible on unrelated activities). To be safe,
+                        // though, notify the controller to prevent degenerate cases.
+                        if (!r.isVisibleRequested()) {
+                            mController.mValidateCommitVis.add(r);
+                        }
+                        return;
+                    }
+                    // This did hide: commit immediately so that other transitions know about it.
+                    mParticipants.add(r);
+                });
+            }
         }
 
         boolean hasParticipatedDisplay = false;
         boolean hasVisibleTransientLaunch = false;
         boolean enterAutoPip = false;
+        boolean committedSomeInvisible = false;
         // Commit all going-invisible containers
         for (int i = 0; i < mParticipants.size(); ++i) {
             final WindowContainer<?> participant = mParticipants.valueAt(i);
@@ -962,6 +1070,7 @@
                         }
                         ar.commitVisibility(false /* visible */, false /* performLayout */,
                                 true /* fromTransition */);
+                        committedSomeInvisible = true;
                     } else {
                         enterAutoPip = true;
                     }
@@ -1020,6 +1129,9 @@
                 }
             }
         }
+        if (committedSomeInvisible) {
+            mController.onCommittedInvisibles();
+        }
 
         if (hasVisibleTransientLaunch) {
             // Notify the change about the transient-below task if entering auto-pip.
@@ -1211,7 +1323,7 @@
                 : mController.mAtm.mRootWindowContainer.getDefaultDisplay();
 
         if (mState == STATE_ABORT) {
-            mController.abort(this);
+            mController.onAbort(this);
             primaryDisplay.getPendingTransaction().merge(transaction);
             mSyncId = -1;
             mOverrideOptions = null;
@@ -1222,20 +1334,28 @@
         mState = STATE_PLAYING;
         mStartTransaction = transaction;
         mFinishTransaction = mController.mAtm.mWindowManager.mTransactionFactory.get();
-        mController.moveToPlaying(this);
 
         // Flags must be assigned before calculateTransitionInfo. Otherwise it won't take effect.
         if (primaryDisplay.isKeyguardLocked()) {
             mFlags |= TRANSIT_FLAG_KEYGUARD_LOCKED;
         }
-        collectOrderChanges();
 
+        // This is the only (or last) transition that is collecting, so we need to report any
+        // leftover order changes.
+        collectOrderChanges(mController.mWaitingTransitions.isEmpty());
+
+        if (mPriorVisibilityMightBeDirty) {
+            updatePriorVisibility();
+        }
         // Resolve the animating targets from the participants.
         mTargets = calculateTargets(mParticipants, mChanges);
         // Check whether the participants were animated from back navigation.
         mController.mAtm.mBackNavigationController.onTransactionReady(this, mTargets);
         final TransitionInfo info = calculateTransitionInfo(mType, mFlags, mTargets, transaction);
         info.setDebugId(mSyncId);
+        mController.assignTrack(this, info);
+
+        mController.moveToPlaying(this);
 
         // Repopulate the displays based on the resolved targets.
         mTargetDisplays.clear();
@@ -1383,24 +1503,70 @@
         info.releaseAnimSurfaces();
     }
 
-    /** Collect tasks which moved-to-top but didn't change otherwise. */
+    /**
+     * Collect tasks which moved-to-top as part of this transition. This also updates the
+     * controller's latest-reported when relevant.
+     *
+     * This is a non-trivial operation because transition can collect in parallel; however, it can
+     * be made tenable by acknowledging that the "setup" part of collection (phase 1) is still
+     * globally serial; so, we can build some reasonable rules around it.
+     *
+     * First, we record the "start" on-top state (to compare against). Then, when this becomes
+     * ready (via allReady, NOT onTransactionReady), we also record the "onReady" on-top state
+     * -- the idea here is that upon "allReady", all the actual WM changes should be done and we
+     * are now just waiting for window content to become ready (finish drawing).
+     *
+     * Then, in this function (during onTransactionReady), we compare the two orders and include
+     * any changes to the order in the reported transition-info. Unfortunately, because of parallel
+     * collection, the order can change in unexpected ways by now. To resolve this, we ALSO keep a
+     * global "latest reported order" in TransitionController and use that to make decisions.
+     */
     @VisibleForTesting
-    void collectOrderChanges() {
+    void collectOrderChanges(boolean reportCurrent) {
         if (mOnTopTasksStart.isEmpty()) return;
-        final ArrayList<Task> onTopTasksEnd = new ArrayList<>();
-        for (int i = 0; i < mTargetDisplays.size(); ++i) {
-            addOnTopTasks(mTargetDisplays.get(i), onTopTasksEnd);
-        }
-        for (int i = 0; i < onTopTasksEnd.size(); ++i) {
-            final Task task = onTopTasksEnd.get(i);
+        boolean includesOrderChange = false;
+        for (int i = 0; i < mOnTopTasksAtReady.size(); ++i) {
+            final Task task = mOnTopTasksAtReady.get(i);
             if (mOnTopTasksStart.contains(task)) continue;
-            mParticipants.add(task);
-            int changeIdx = mChanges.indexOfKey(task);
-            if (changeIdx < 0) {
-                mChanges.put(task, new ChangeInfo(task));
-                changeIdx = mChanges.indexOfKey(task);
+            includesOrderChange = true;
+            break;
+        }
+        if (!includesOrderChange && !reportCurrent) {
+            // This transition doesn't include an order change, so if it isn't required to report
+            // the current focus (eg. it's the last of a cluster of transitions), then don't
+            // report.
+            return;
+        }
+        // The transition included an order change, but it may not be up-to-date, so grab the
+        // latest state and compare with the last reported state (or our start state if no
+        // reported state exists).
+        ArrayList<Task> onTopTasksEnd = new ArrayList<>();
+        for (int d = 0; d < mTargetDisplays.size(); ++d) {
+            addOnTopTasks(mTargetDisplays.get(d), onTopTasksEnd);
+            final int displayId = mTargetDisplays.get(d).mDisplayId;
+            ArrayList<Task> reportedOnTop = mController.mLatestOnTopTasksReported.get(displayId);
+            for (int i = onTopTasksEnd.size() - 1; i >= 0; --i) {
+                final Task task = onTopTasksEnd.get(i);
+                if (task.getDisplayId() != displayId) continue;
+                // If it didn't change since last report, don't report
+                if (reportedOnTop == null) {
+                    if (mOnTopTasksStart.contains(task)) continue;
+                } else if (reportedOnTop.contains(task)) {
+                    continue;
+                }
+                // Need to report it.
+                mParticipants.add(task);
+                int changeIdx = mChanges.indexOfKey(task);
+                if (changeIdx < 0) {
+                    mChanges.put(task, new ChangeInfo(task));
+                    changeIdx = mChanges.indexOfKey(task);
+                }
+                mChanges.valueAt(changeIdx).mFlags |= ChangeInfo.FLAG_CHANGE_MOVED_TO_TOP;
             }
-            mChanges.valueAt(changeIdx).mFlags |= ChangeInfo.FLAG_CHANGE_MOVED_TO_TOP;
+            // Swap in the latest on-top tasks.
+            mController.mLatestOnTopTasksReported.put(displayId, onTopTasksEnd);
+            onTopTasksEnd = reportedOnTop != null ? reportedOnTop : new ArrayList<>();
+            onTopTasksEnd.clear();
         }
     }
 
@@ -1694,6 +1860,20 @@
         }
     }
 
+    private void updatePriorVisibility() {
+        for (int i = 0; i < mChanges.size(); ++i) {
+            final ChangeInfo chg = mChanges.valueAt(i);
+            // For task/activity, recalculate the current "real" visibility.
+            if (chg.mContainer.asActivityRecord() == null && chg.mContainer.asTask() == null) {
+                continue;
+            }
+            // This ONLY works in the visible -> invisible case (and is only needed for this case)
+            // because commitVisible(false) is deferred until finish.
+            if (!chg.mVisible) continue;
+            chg.mVisible = chg.mContainer.isVisible();
+        }
+    }
+
     /**
      * Under some conditions (eg. all visible targets within a parent container are transitioning
      * the same way) the transition can be "promoted" to the parent container. This means an
@@ -2819,11 +2999,14 @@
 
             Rect cropBounds = new Rect(bounds);
             cropBounds.offsetTo(0, 0);
+            final boolean isDisplayRotation = wc.asDisplayContent() != null
+                    && wc.asDisplayContent().isRotationChanging();
             ScreenCapture.LayerCaptureArgs captureArgs =
                     new ScreenCapture.LayerCaptureArgs.Builder(wc.getSurfaceControl())
                             .setSourceCrop(cropBounds)
                             .setCaptureSecureLayers(true)
                             .setAllowProtected(true)
+                            .setHintForSeamlessTransition(isDisplayRotation)
                             .build();
             ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
                     ScreenCapture.captureLayers(captureArgs);
@@ -2834,8 +3017,6 @@
                 Slog.w(TAG, "Failed to capture screenshot for " + wc);
                 return false;
             }
-            final boolean isDisplayRotation = wc.asDisplayContent() != null
-                    && wc.asDisplayContent().isRotationChanging();
             // Some tests may check the name "RotationLayer" to detect display rotation.
             final String name = isDisplayRotation ? "RotationLayer" : "transition snapshot: " + wc;
             SurfaceControl snapshotSurface = wc.makeAnimationLeash()
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index e8e4792..7cb6b46 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -39,6 +39,7 @@
 import android.os.SystemProperties;
 import android.util.ArrayMap;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl;
@@ -60,7 +61,34 @@
 import java.util.function.LongConsumer;
 
 /**
- * Handles all the aspects of recording and synchronizing transitions.
+ * Handles all the aspects of recording (collecting) and synchronizing transitions. This is only
+ * concerned with the WM changes. The actual animations are handled by the Player.
+ *
+ * Currently, only 1 transition can be the primary "collector" at a time. This is because WM changes
+ * are still performed in a "global" manner. However, collecting can actually be broken into
+ * two phases:
+ *    1. Actually making WM changes and recording the participating containers.
+ *    2. Waiting for the participating containers to become ready (eg. redrawing content).
+ * Because (2) takes most of the time AND doesn't change WM, we can actually have multiple
+ * transitions in phase (2) concurrently with one in phase (1). We refer to this arrangement as
+ * "parallel" collection even though there is still only ever 1 transition actually able to gain
+ * participants.
+ *
+ * Parallel collection happens when the "primary collector" has finished "setup" (phase 1) and is
+ * just waiting. At this point, another transition can start collecting. When this happens, the
+ * first transition is moved to a "waiting" list and the new transition becomes the "primary
+ * collector". If at any time, the "primary collector" moves to playing before one of the waiting
+ * transitions, then the first waiting transition will move back to being the "primary collector".
+ * This maintains the "global"-like abstraction that the rest of WM currently expects.
+ *
+ * When a transition move-to-playing, we check it against all other playing transitions. If it
+ * doesn't overlap with them, it can also animate in parallel. In this case it will be assigned a
+ * new "track". "tracks" are a way to communicate to the player about which transitions need to be
+ * played serially with each-other. So, if we find that a transition overlaps with other transitions
+ * in one track, the transition will be assigned to that track. If, however, the transition overlaps
+ * with transition in >1 track, we will actually just mark it as SYNC meaning it can't actually
+ * play until all prior transition animations finish. This is heavy-handed because it is a fallback
+ * situation and supporting something fancier would be unnecessarily complicated.
  */
 class TransitionController {
     private static final String TAG = "TransitionController";
@@ -105,10 +133,18 @@
     final ArrayList<Runnable> mStateValidators = new ArrayList<>();
 
     /**
+     * List of activity-records whose visibility changed outside the main/tracked part of a
+     * transition (eg. in the finish-transaction). These will be checked when idle to recover from
+     * degenerate states.
+     */
+    final ArrayList<ActivityRecord> mValidateCommitVis = new ArrayList<>();
+
+    /**
      * Currently playing transitions (in the order they were started). When finished, records are
      * removed from this list.
      */
     private final ArrayList<Transition> mPlayingTransitions = new ArrayList<>();
+    int mTrackCount = 0;
 
     /** The currently finishing transition. */
     Transition mFinishingTransition;
@@ -143,10 +179,26 @@
 
     private final ArrayList<QueuedTransition> mQueuedTransitions = new ArrayList<>();
 
-    /** The transition currently being constructed (collecting participants). */
+    /**
+     * The transition currently being constructed (collecting participants). Unless interrupted,
+     * all WM changes will go into this.
+     */
     private Transition mCollectingTransition = null;
 
     /**
+     * The transitions that are complete but still waiting for participants to become ready
+     */
+    final ArrayList<Transition> mWaitingTransitions = new ArrayList<>();
+
+    /**
+     * The (non alwaysOnTop) tasks which were reported as on-top of their display most recently
+     * within a cluster of simultaneous transitions. If tasks are nested, all the tasks that are
+     * parents of the on-top task are also included. This is used to decide which transitions
+     * report which on-top changes.
+     */
+    final SparseArray<ArrayList<Task>> mLatestOnTopTasksReported = new SparseArray<>();
+
+    /**
      * `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
      * calculate the layers for the finishTransaction. So, when assigning layers into the finish
@@ -199,6 +251,11 @@
             mPlayingTransitions.get(i).cleanUpOnFailure();
         }
         mPlayingTransitions.clear();
+        // Clean up waiting transitions first since they technically started first.
+        for (int i = 0; i < mWaitingTransitions.size(); ++i) {
+            mWaitingTransitions.get(i).abort();
+        }
+        mWaitingTransitions.clear();
         if (mCollectingTransition != null) {
             mCollectingTransition.abort();
         }
@@ -223,8 +280,9 @@
             throw new IllegalStateException("Shell Transitions not enabled");
         }
         if (mCollectingTransition != null) {
-            throw new IllegalStateException("Simultaneous transition collection not supported"
-                    + " yet. Use {@link #createPendingTransition} for explicit queueing.");
+            throw new IllegalStateException("Trying to directly start transition collection while "
+                    + " collection is already ongoing. Use {@link #startCollectOrQueue} if"
+                    + " possible.");
         }
         Transition transit = new Transition(type, flags, this, mSyncEngine);
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Creating Transition: %s", transit);
@@ -318,7 +376,12 @@
      *                      This is {@code false} once a transition is playing.
      */
     boolean isCollecting(@NonNull WindowContainer wc) {
-        return mCollectingTransition != null && mCollectingTransition.mParticipants.contains(wc);
+        if (mCollectingTransition == null) return false;
+        if (mCollectingTransition.mParticipants.contains(wc)) return true;
+        for (int i = 0; i < mWaitingTransitions.size(); ++i) {
+            if (mWaitingTransitions.get(i).mParticipants.contains(wc)) return true;
+        }
+        return false;
     }
 
     /**
@@ -327,7 +390,11 @@
      */
     boolean inCollectingTransition(@NonNull WindowContainer wc) {
         if (!isCollecting()) return false;
-        return mCollectingTransition.isInTransition(wc);
+        if (mCollectingTransition.isInTransition(wc)) return true;
+        for (int i = 0; i < mWaitingTransitions.size(); ++i) {
+            if (mWaitingTransitions.get(i).isInTransition(wc)) return true;
+        }
+        return false;
     }
 
     /**
@@ -348,9 +415,9 @@
         return false;
     }
 
-    /** Returns {@code true} if the `wc` is a participant of the finishing transition. */
+    /** Returns {@code true} if the finishing transition contains `wc`. */
     boolean inFinishingTransition(WindowContainer<?> wc) {
-        return mFinishingTransition != null && mFinishingTransition.mParticipants.contains(wc);
+        return mFinishingTransition != null && mFinishingTransition.isInTransition(wc);
     }
 
     /** @return {@code true} if a transition is running */
@@ -369,6 +436,9 @@
         if (mCollectingTransition != null && mCollectingTransition.isOnDisplay(dc)) {
             return true;
         }
+        for (int i = mWaitingTransitions.size() - 1; i >= 0; --i) {
+            if (mWaitingTransitions.get(i).isOnDisplay(dc)) return true;
+        }
         for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
             if (mPlayingTransitions.get(i).isOnDisplay(dc)) return true;
         }
@@ -379,6 +449,9 @@
         if (mCollectingTransition != null && mCollectingTransition.isInTransientHide(task)) {
             return true;
         }
+        for (int i = mWaitingTransitions.size() - 1; i >= 0; --i) {
+            if (mWaitingTransitions.get(i).isInTransientHide(task)) return true;
+        }
         for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
             if (mPlayingTransitions.get(i).isInTransientHide(task)) return true;
         }
@@ -754,7 +827,20 @@
         mRunningLock.doNotifyLocked();
         // Run state-validation checks when no transitions are active anymore.
         if (!inTransition()) {
+            // Can reset track-count now that everything is idle.
+            mTrackCount = 0;
             validateStates();
+            mAtm.mWindowManager.onAnimationFinished();
+        }
+    }
+
+    /** Called by {@link Transition#finishTransition} if it committed invisible to any activities */
+    void onCommittedInvisibles() {
+        if (mCollectingTransition != null) {
+            mCollectingTransition.mPriorVisibilityMightBeDirty = true;
+        }
+        for (int i = mWaitingTransitions.size() - 1; i >= 0; --i) {
+            mWaitingTransitions.get(i).mPriorVisibilityMightBeDirty = true;
         }
     }
 
@@ -769,6 +855,35 @@
             }
         }
         mStateValidators.clear();
+        for (int i = 0; i < mValidateCommitVis.size(); ++i) {
+            final ActivityRecord ar = mValidateCommitVis.get(i);
+            if (!ar.isVisibleRequested() && ar.isVisible()) {
+                Slog.e(TAG, "Uncommitted visibility change: " + ar);
+                ar.commitVisibility(ar.isVisibleRequested(), false /* layout */,
+                        false /* fromTransition */);
+            }
+        }
+        mValidateCommitVis.clear();
+    }
+
+    /**
+     * Called when the transition has a complete set of participants for its operation. In other
+     * words, it is when the transition is "ready" but is still waiting for participants to draw.
+     */
+    void onTransitionPopulated(Transition transition) {
+        tryStartCollectFromQueue();
+    }
+
+    private boolean canStartCollectingNow(@Nullable Transition queued) {
+        if (mCollectingTransition == null) return true;
+        // Population (collect until ready) is still serialized, so always wait for that.
+        if (!mCollectingTransition.isPopulated()) return false;
+        // Check if queued *can* be independent with all collecting/waiting transitions.
+        if (!getCanBeIndependent(mCollectingTransition, queued)) return false;
+        for (int i = 0; i < mWaitingTransitions.size(); ++i) {
+            if (!getCanBeIndependent(mWaitingTransitions.get(i), queued)) return false;
+        }
+        return true;
     }
 
     void tryStartCollectFromQueue() {
@@ -776,7 +891,16 @@
         // Only need to try the next one since, even when transition can collect in parallel,
         // they still need to serialize on readiness.
         final QueuedTransition queued = mQueuedTransitions.get(0);
-        if (mCollectingTransition != null || mSyncEngine.hasActiveSync()) {
+        if (mCollectingTransition != null) {
+            // If it's a legacy sync, then it needs to wait until there is no collecting transition.
+            if (queued.mTransition == null) return;
+            if (!canStartCollectingNow(queued.mTransition)) return;
+            ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS_MIN, "Moving #%d from collecting"
+                    + " to waiting.", mCollectingTransition.getSyncId());
+            mWaitingTransitions.add(mCollectingTransition);
+            mCollectingTransition = null;
+        } else if (mSyncEngine.hasActiveSync()) {
+            // A legacy transition is on-going, so we must wait.
             return;
         }
         mQueuedTransitions.remove(0);
@@ -797,16 +921,151 @@
     }
 
     void moveToPlaying(Transition transition) {
-        if (transition != mCollectingTransition) {
-            throw new IllegalStateException("Trying to move non-collecting transition to playing");
+        if (transition == mCollectingTransition) {
+            mCollectingTransition = null;
+            if (!mWaitingTransitions.isEmpty()) {
+                mCollectingTransition = mWaitingTransitions.remove(0);
+            }
+            if (mCollectingTransition == null) {
+                // nothing collecting anymore, so clear order records.
+                mLatestOnTopTasksReported.clear();
+            }
+        } else {
+            if (!mWaitingTransitions.remove(transition)) {
+                throw new IllegalStateException("Trying to move non-collecting transition to"
+                        + "playing " + transition.getSyncId());
+            }
         }
-        mCollectingTransition = null;
         mPlayingTransitions.add(transition);
         updateRunningRemoteAnimation(transition, true /* isPlaying */);
         mTransitionTracer.logState(transition);
         // Sync engine should become idle after this, so the idle listener will check the queue.
     }
 
+    /**
+     * Checks if the `queued` transition has the potential to run independently of the
+     * `collecting` transition. It may still ultimately block in sync-engine or become dependent
+     * in {@link #getIsIndependent} later.
+     */
+    boolean getCanBeIndependent(Transition collecting, @Nullable Transition queued) {
+        // For tests
+        if (queued != null && queued.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL
+                && collecting.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL) {
+            return true;
+        }
+        // For recents
+        if (queued != null && queued.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
+            if (collecting.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
+                // Must serialize with itself.
+                return false;
+            }
+            // allow this if `collecting` only has activities
+            for (int i = 0; i < collecting.mParticipants.size(); ++i) {
+                final WindowContainer wc = collecting.mParticipants.valueAt(i);
+                final ActivityRecord ar = wc.asActivityRecord();
+                if (ar == null && wc.asWindowState() == null && wc.asWindowToken() == null) {
+                    // Is task or above, so can't be independent
+                    return false;
+                }
+                if (ar != null && ar.isActivityTypeHomeOrRecents()) {
+                    // It's a recents or home type, so it conflicts.
+                    return false;
+                }
+            }
+            return true;
+        } else if (collecting.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
+            // We can collect simultaneously with recents if it is populated. This is because
+            // we know that recents will not collect/trampoline any more stuff. If anything in the
+            // queued transition overlaps, it will end up just waiting in sync-queue anyways.
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Checks if `incoming` transition can run independently of `running` transition assuming that
+     * `running` is playing based on its current state.
+     */
+    static boolean getIsIndependent(Transition running, Transition incoming) {
+        // For tests
+        if (running.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL
+                && incoming.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL) {
+            return true;
+        }
+        // For now there's only one mutually-independent pair: an all activity-level transition and
+        // a transient-launch where none of the activities are part of the transient-launch task,
+        // so the following logic is hard-coded specifically for this.
+        // Also, we currently restrict valid transient-launches to just recents.
+        final Transition recents;
+        final Transition other;
+        if (running.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS
+                && running.hasTransientLaunch()) {
+            if (incoming.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
+                // Recents can't be independent from itself.
+                return false;
+            }
+            recents = running;
+            other = incoming;
+        } else if (incoming.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS
+                && incoming.hasTransientLaunch()) {
+            recents = incoming;
+            other = running;
+        } else {
+            return false;
+        }
+        // Check against *targets* because that is the post-promotion set of containers that are
+        // actually animating.
+        for (int i = 0; i < other.mTargets.size(); ++i) {
+            final WindowContainer wc = other.mTargets.get(i).mContainer;
+            final ActivityRecord ar = wc.asActivityRecord();
+            if (ar == null && wc.asWindowState() == null && wc.asWindowToken() == null) {
+                // Is task or above, so for now don't let them be independent.
+                return false;
+            }
+            if (ar != null && recents.isTransientLaunch(ar)) {
+                // Change overlaps with recents, so serialize.
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void assignTrack(Transition transition, TransitionInfo info) {
+        int track = -1;
+        boolean sync = false;
+        for (int i = 0; i < mPlayingTransitions.size(); ++i) {
+            // ignore ourself obviously
+            if (mPlayingTransitions.get(i) == transition) continue;
+            if (getIsIndependent(mPlayingTransitions.get(i), transition)) continue;
+            if (track >= 0) {
+                // At this point, transition overlaps with multiple tracks, so just wait for
+                // everything
+                sync = true;
+                break;
+            }
+            track = mPlayingTransitions.get(i).mAnimationTrack;
+        }
+        if (sync) {
+            track = 0;
+        }
+        if (track < 0) {
+            // Didn't overlap with anything, so give it its own track
+            track = mTrackCount;
+            if (track > 0) {
+                ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Playing #%d in parallel on "
+                        + "track #%d", transition.getSyncId(), track);
+            }
+        }
+        if (sync) {
+            info.setFlags(info.getFlags() | TransitionInfo.FLAG_SYNC);
+            ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Marking #%d animation as SYNC.",
+                    transition.getSyncId());
+        }
+        transition.mAnimationTrack = track;
+        info.setTrack(track);
+        mTrackCount = Math.max(mTrackCount, track + 1);
+    }
+
     void updateAnimatingState(SurfaceControl.Transaction t) {
         final boolean animatingState = !mPlayingTransitions.isEmpty()
                     || (mCollectingTransition != null && mCollectingTransition.isStarted());
@@ -842,14 +1101,27 @@
         mRemotePlayer.update(delegate, isPlaying, true /* predict */);
     }
 
-    void abort(Transition transition) {
+    /** Called when a transition is aborted. This should only be called by {@link Transition} */
+    void onAbort(Transition transition) {
         if (transition != mCollectingTransition) {
-            throw new IllegalStateException("Too late to abort.");
+            int waitingIdx = mWaitingTransitions.indexOf(transition);
+            if (waitingIdx < 0) {
+                throw new IllegalStateException("Too late for abort.");
+            }
+            mWaitingTransitions.remove(waitingIdx);
+        } else {
+            mCollectingTransition = null;
+            if (!mWaitingTransitions.isEmpty()) {
+                mCollectingTransition = mWaitingTransitions.remove(0);
+            }
+            if (mCollectingTransition == null) {
+                // nothing collecting anymore, so clear order records.
+                mLatestOnTopTasksReported.clear();
+            }
         }
-        transition.abort();
-        mCollectingTransition = null;
         mTransitionTracer.logState(transition);
-        // abort will call through the normal finish paths and thus check the queue.
+        // This is called during Transition.abort whose codepath will eventually check the queue
+        // via sync-engine idle.
     }
 
     /**
@@ -956,7 +1228,19 @@
             return false;
         }
         if (mSyncEngine.hasActiveSync()) {
-            if (!isCollecting()) {
+            if (isCollecting()) {
+                // Check if we can run in parallel here.
+                if (canStartCollectingNow(transit)) {
+                    // start running in parallel.
+                    ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS_MIN, "Moving #%d from"
+                            + " collecting to waiting.", mCollectingTransition.getSyncId());
+                    mWaitingTransitions.add(mCollectingTransition);
+                    mCollectingTransition = null;
+                    moveToCollecting(transit);
+                    onStartCollect.onCollectStarted(false /* deferred */);
+                    return true;
+                }
+            } else {
                 Slog.w(TAG, "Ongoing Sync outside of transition.");
             }
             queueTransition(transit, onStartCollect);
@@ -967,6 +1251,44 @@
         return true;
     }
 
+    /**
+     * This will create and start collecting for a transition if possible. If there's no way to
+     * start collecting for `parallelType` now, then this returns null.
+     *
+     * WARNING: ONLY use this if the transition absolutely cannot be deferred!
+     */
+    @NonNull
+    Transition createAndStartCollecting(int type) {
+        if (mTransitionPlayer == null) {
+            return null;
+        }
+        if (!mQueuedTransitions.isEmpty()) {
+            // There is a queue, so it's not possible to start immediately
+            return null;
+        }
+        if (mSyncEngine.hasActiveSync()) {
+            if (isCollecting()) {
+                // Check if we can run in parallel here.
+                if (canStartCollectingNow(null /* transit */)) {
+                    // create and collect in parallel.
+                    ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS_MIN, "Moving #%d from"
+                            + " collecting to waiting.", mCollectingTransition.getSyncId());
+                    mWaitingTransitions.add(mCollectingTransition);
+                    mCollectingTransition = null;
+                    Transition transit = new Transition(type, 0 /* flags */, this, mSyncEngine);
+                    moveToCollecting(transit);
+                    return transit;
+                }
+            } else {
+                Slog.w(TAG, "Ongoing Sync outside of transition.");
+            }
+            return null;
+        }
+        Transition transit = new Transition(type, 0 /* flags */, this, mSyncEngine);
+        moveToCollecting(transit);
+        return transit;
+    }
+
     /** Returns {@code true} if it started collecting, {@code false} if it was queued. */
     boolean startLegacySyncOrQueue(BLASTSyncEngine.SyncGroup syncGroup, Runnable applySync) {
         if (!mQueuedTransitions.isEmpty() || mSyncEngine.hasActiveSync()) {
diff --git a/services/core/java/com/android/server/wm/TransitionTracer.java b/services/core/java/com/android/server/wm/TransitionTracer.java
index 6597d4c..6aac81b 100644
--- a/services/core/java/com/android/server/wm/TransitionTracer.java
+++ b/services/core/java/com/android/server/wm/TransitionTracer.java
@@ -21,6 +21,7 @@
 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.REAL_TO_ELAPSED_TIME_OFFSET_NANOS;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -37,6 +38,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Helper class to collect and dump transition traces.
@@ -395,6 +397,10 @@
         try {
             ProtoOutputStream proto = new ProtoOutputStream();
             proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
+            long timeOffsetNs =
+                    TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis())
+                            - SystemClock.elapsedRealtimeNanos();
+            proto.write(REAL_TO_ELAPSED_TIME_OFFSET_NANOS, timeOffsetNs);
             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/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index cf6efd2..a5cdd0b 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -3594,8 +3594,11 @@
                 && !mTransitionController.useShellTransitionsRotation()) {
             if (deltaRotation != Surface.ROTATION_0) {
                 updateSurfaceRotation(t, deltaRotation, null /* positionLeash */);
+                t.setFixedTransformHint(mSurfaceControl,
+                        getWindowConfiguration().getDisplayRotation());
             } else if (deltaRotation != mLastDeltaRotation) {
                 t.setMatrix(mSurfaceControl, 1, 0, 0, 1);
+                t.unsetFixedTransformHint(mSurfaceControl);
             }
         }
         mLastDeltaRotation = deltaRotation;
@@ -3835,13 +3838,12 @@
 
     void setSyncGroup(@NonNull BLASTSyncEngine.SyncGroup group) {
         ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "setSyncGroup #%d on %s", group.mSyncId, this);
-        if (group != null) {
-            if (mSyncGroup != null && mSyncGroup != group) {
-                // This can still happen if WMCore starts a new transition when there is ongoing
-                // sync transaction from Shell. Please file a bug if it happens.
-                throw new IllegalStateException("Can't sync on 2 engines simultaneously"
-                        + " currentSyncId=" + mSyncGroup.mSyncId + " newSyncId=" + group.mSyncId);
-            }
+        if (mSyncGroup != null && mSyncGroup != group) {
+            // This can still happen if WMCore starts a new transition when there is ongoing
+            // sync transaction from Shell. Please file a bug if it happens.
+            throw new IllegalStateException("Can't sync on 2 groups simultaneously"
+                    + " currentSyncId=" + mSyncGroup.mSyncId + " newSyncId=" + group.mSyncId
+                    + " wc=" + this);
         }
         mSyncGroup = group;
     }
@@ -3883,12 +3885,16 @@
      * @param cancel If true, this is being finished because it is leaving the sync group rather
      *               than due to the sync group completing.
      */
-    void finishSync(Transaction outMergedTransaction, boolean cancel) {
+    void finishSync(Transaction outMergedTransaction, BLASTSyncEngine.SyncGroup group,
+            boolean cancel) {
         if (mSyncState == SYNC_STATE_NONE) return;
+        final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup();
+        // If it's null, then we need to clean-up anyways.
+        if (syncGroup != null && group != syncGroup) return;
         ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "finishSync cancel=%b for %s", cancel, this);
         outMergedTransaction.merge(mSyncTransaction);
         for (int i = mChildren.size() - 1; i >= 0; --i) {
-            mChildren.get(i).finishSync(outMergedTransaction, cancel);
+            mChildren.get(i).finishSync(outMergedTransaction, group, cancel);
         }
         if (cancel && mSyncGroup != null) mSyncGroup.onCancelSync(this);
         mSyncState = SYNC_STATE_NONE;
@@ -3903,7 +3909,7 @@
      *
      * @return {@code true} if this subtree is finished waiting for sync participants.
      */
-    boolean isSyncFinished() {
+    boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
         if (!isVisibleRequested()) {
             return true;
         }
@@ -3917,7 +3923,7 @@
         // Loop from top-down.
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer child = mChildren.get(i);
-            final boolean childFinished = child.isSyncFinished();
+            final boolean childFinished = group.isIgnoring(child) || child.isSyncFinished(group);
             if (childFinished && child.isVisibleRequested() && child.fillsParent()) {
                 // Any lower children will be covered-up, so we can consider this finished.
                 return true;
@@ -3968,11 +3974,11 @@
                 // This is getting removed.
                 if (oldParent.mSyncState != SYNC_STATE_NONE) {
                     // In order to keep the transaction in sync, merge it into the parent.
-                    finishSync(oldParent.mSyncTransaction, true /* cancel */);
+                    finishSync(oldParent.mSyncTransaction, getSyncGroup(), true /* cancel */);
                 } else if (mSyncGroup != null) {
                     // This is watched directly by the sync-group, so merge this transaction into
                     // into the sync-group so it isn't lost
-                    finishSync(mSyncGroup.getOrphanTransaction(), true /* cancel */);
+                    finishSync(mSyncGroup.getOrphanTransaction(), mSyncGroup, true /* cancel */);
                 } else {
                     throw new IllegalStateException("This container is in sync mode without a sync"
                             + " group: " + this);
@@ -3981,7 +3987,7 @@
             } else if (mSyncGroup == null) {
                 // This is being reparented out of the sync-group. To prevent ordering issues on
                 // this container, immediately apply/cancel sync on it.
-                finishSync(getPendingTransaction(), true /* cancel */);
+                finishSync(getPendingTransaction(), getSyncGroup(), true /* cancel */);
                 return;
             }
             // Otherwise this is the "root" of a synced subtree, so continue on to preparation.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8822193..f9b6fc1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1831,7 +1831,7 @@
 
             boolean needToSendNewConfiguration =
                     win.isVisibleRequestedOrAdding() && displayContent.updateOrientation();
-            if (win.providesNonDecorInsets()) {
+            if (win.providesDisplayDecorInsets()) {
                 needToSendNewConfiguration |= displayPolicy.updateDecorInsetsInfo();
             }
             if (needToSendNewConfiguration) {
@@ -2274,7 +2274,7 @@
                         & WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED) != 0) {
                     win.mLayoutNeeded = true;
                 }
-                if (layoutChanged && win.providesNonDecorInsets()) {
+                if (layoutChanged && win.providesDisplayDecorInsets()) {
                     configChanged = displayPolicy.updateDecorInsetsInfo();
                 }
                 if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0
@@ -2290,14 +2290,24 @@
                     winAnimator.setColorSpaceAgnosticLocked((win.mAttrs.privateFlags
                             & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
                 }
-                if (win.mActivityRecord != null
-                        && !displayContent.mDwpcHelper.keepActivityOnWindowFlagsChanged(
-                                win.mActivityRecord.info, flagChanges, privateFlagChanges)) {
-                    mH.sendMessage(mH.obtainMessage(H.REPARENT_TASK_TO_DEFAULT_DISPLAY,
-                            win.mActivityRecord.getTask()));
-                    Slog.w(TAG_WM, "Activity " + win.mActivityRecord + " window flag changed,"
-                            + " can't remain on display " + displayContent.getDisplayId());
-                    return 0;
+                // See if the DisplayWindowPolicyController wants to keep the activity on the window
+                if (displayContent.mDwpcHelper.hasController()
+                        && win.mActivityRecord != null && (!win.mRelayoutCalled || flagChanges != 0
+                        || privateFlagChanges != 0)) {
+                    int newOrChangedFlags = !win.mRelayoutCalled ? win.mAttrs.flags : flagChanges;
+                    int newOrChangedPrivateFlags =
+                            !win.mRelayoutCalled ? win.mAttrs.privateFlags : privateFlagChanges;
+
+                    if (!displayContent.mDwpcHelper.keepActivityOnWindowFlagsChanged(
+                            win.mActivityRecord.info, newOrChangedFlags, newOrChangedPrivateFlags,
+                            win.mAttrs.flags,
+                            win.mAttrs.privateFlags)) {
+                        mH.sendMessage(mH.obtainMessage(H.REPARENT_TASK_TO_DEFAULT_DISPLAY,
+                                win.mActivityRecord.getTask()));
+                        Slog.w(TAG_WM, "Activity " + win.mActivityRecord + " window flag changed,"
+                                + " can't remain on display " + displayContent.getDisplayId());
+                        return 0;
+                    }
                 }
             }
 
@@ -5780,10 +5790,12 @@
         if (sizeStr != null && sizeStr.length() > 0) {
             final int pos = sizeStr.indexOf(',');
             if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
-                int width, height;
                 try {
-                    width = Integer.parseInt(sizeStr.substring(0, pos));
-                    height = Integer.parseInt(sizeStr.substring(pos + 1));
+                    final Point size = displayContent.getValidForcedSize(
+                            Integer.parseInt(sizeStr.substring(0, pos)),
+                            Integer.parseInt(sizeStr.substring(pos + 1)));
+                    final int width = size.x;
+                    final int height = size.y;
                     if (displayContent.mBaseDisplayWidth != width
                             || displayContent.mBaseDisplayHeight != height) {
                         ProtoLog.i(WM_ERROR, "FORCED DISPLAY SIZE: %dx%d", width, height);
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index cd42528..d5aa520 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -299,6 +299,7 @@
                     final boolean needsSetReady = t != null;
                     final Transition nextTransition = new Transition(type, 0 /* flags */,
                             mTransitionController, mService.mWindowManager.mSyncEngine);
+                    nextTransition.calcParallelCollectType(wct);
                     mTransitionController.startCollectOrQueue(nextTransition,
                             (deferred) -> {
                                 nextTransition.start();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a299592..032f08a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1834,13 +1834,13 @@
         return (mPolicyVisibility & POLICY_VISIBILITY_ALL) == POLICY_VISIBILITY_ALL;
     }
 
-    boolean providesNonDecorInsets() {
+    boolean providesDisplayDecorInsets() {
         if (mInsetsSourceProviders == null) {
             return false;
         }
         for (int i = mInsetsSourceProviders.size() - 1; i >= 0; i--) {
             final InsetsSource source = mInsetsSourceProviders.valueAt(i).getSource();
-            if (source.getType() == WindowInsets.Type.navigationBars()) {
+            if ((source.getType() & DisplayPolicy.DecorInsets.CONFIG_TYPES) != 0) {
                 return true;
             }
         }
@@ -1980,19 +1980,16 @@
 
     /**
      * Like isOnScreen(), but we don't return true if the window is part
-     * of a transition but has not yet started animating.
+     * of a transition that has not yet been started.
      */
     boolean isReadyForDisplay() {
-        if (!mHasSurface || mDestroying || !isVisibleByPolicy()) {
-            return false;
-        }
-        if (mToken.waitingToShow && getDisplayContent().mAppTransition.isTransitionSet()
-                && !isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_APP_TRANSITION)) {
+        if (mToken.waitingToShow && getDisplayContent().mAppTransition.isTransitionSet()) {
             return false;
         }
         final boolean parentAndClientVisible = !isParentWindowHidden()
                 && mViewVisibility == View.VISIBLE && mToken.isVisible();
-        return parentAndClientVisible || isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_ALL);
+        return mHasSurface && isVisibleByPolicy() && !mDestroying
+                && (parentAndClientVisible || isAnimating(TRANSITION | PARENTS));
     }
 
     boolean isFullyTransparent() {
@@ -2507,13 +2504,13 @@
             }
 
             // Check if window provides non decor insets before clearing its provided insets.
-            final boolean windowProvidesNonDecorInsets = providesNonDecorInsets();
+            final boolean windowProvidesDisplayDecorInsets = providesDisplayDecorInsets();
 
             removeImmediately();
             // Removing a visible window may affect the display orientation so just update it if
             // needed. Also recompute configuration if it provides screen decor insets.
             boolean needToSendNewConfiguration = wasVisible && displayContent.updateOrientation();
-            if (windowProvidesNonDecorInsets) {
+            if (windowProvidesDisplayDecorInsets) {
                 needToSendNewConfiguration |=
                         displayContent.getDisplayPolicy().updateDecorInsetsInfo();
             }
@@ -5634,7 +5631,7 @@
     private void dropBufferFrom(Transaction t) {
         SurfaceControl viewSurface = getClientViewRootSurface();
         if (viewSurface == null) return;
-        t.setBuffer(viewSurface, (android.hardware.HardwareBuffer) null);
+        t.unsetBuffer(viewSurface);
     }
 
     @Override
@@ -5678,7 +5675,7 @@
     }
 
     @Override
-    boolean isSyncFinished() {
+    boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
         if (!isVisibleRequested() || isFullyTransparent()) {
             // Don't wait for invisible windows. However, we don't alter the state in case the
             // window becomes visible while the sync group is still active.
@@ -5689,11 +5686,14 @@
             // Complete the sync state immediately for a drawn window that doesn't need to redraw.
             onSyncFinishedDrawing();
         }
-        return super.isSyncFinished();
+        return super.isSyncFinished(group);
     }
 
     @Override
-    void finishSync(Transaction outMergedTransaction, boolean cancel) {
+    void finishSync(Transaction outMergedTransaction, BLASTSyncEngine.SyncGroup group,
+            boolean cancel) {
+        final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup();
+        if (syncGroup != null && group != syncGroup) return;
         mPrepareSyncSeqId = 0;
         if (cancel) {
             // This is leaving sync so any buffers left in the sync have a chance of
@@ -5701,7 +5701,7 @@
             // window. To prevent this, drop the buffer.
             dropBufferFrom(mSyncTransaction);
         }
-        super.finishSync(outMergedTransaction, cancel);
+        super.finishSync(outMergedTransaction, group, cancel);
     }
 
     boolean finishDrawing(SurfaceControl.Transaction postDrawTransaction, int syncSeqId) {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index da54b15..4c5efef 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -596,6 +596,7 @@
                 .build();
         t.setPosition(leash, mLastSurfacePosition.x, mLastSurfacePosition.y);
         t.reparent(getSurfaceControl(), leash);
+        t.setFixedTransformHint(leash, getWindowConfiguration().getDisplayRotation());
         mFixedRotationTransformLeash = leash;
         updateSurfaceRotation(t, rotation, mFixedRotationTransformLeash);
         return mFixedRotationTransformLeash;
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index cf57b33..369c974 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -2567,6 +2567,11 @@
     im->setStylusPointerIconEnabled(enabled);
 }
 
+static void nativeNotifyKeyGestureTimeoutsChanged(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
+    im->getInputManager()->getDispatcher().requestRefreshConfiguration();
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gInputManagerMethods[] = {
@@ -2663,6 +2668,7 @@
          (void*)nativeSetStylusButtonMotionEventsEnabled},
         {"getMouseCursorPosition", "()[F", (void*)nativeGetMouseCursorPosition},
         {"setStylusPointerIconEnabled", "(Z)V", (void*)nativeSetStylusPointerIconEnabled},
+        {"notifyKeyGestureTimeoutsChanged", "()V", (void*)nativeNotifyKeyGestureTimeoutsChanged},
 };
 
 #define FIND_CLASS(var, className) \
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index a8d2f4e..a8806b5 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -84,23 +84,26 @@
     return result;
 }
 
+static int nativeSetTvMessageEnabled(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId,
+                                     jint streamId, jint type, jboolean enabled) {
+    JTvInputHal* tvInputHal = (JTvInputHal*)ptr;
+    return tvInputHal->setTvMessageEnabled(deviceId, streamId, type, enabled);
+}
+
 static void nativeClose(JNIEnv* env, jclass clazz, jlong ptr) {
     JTvInputHal* tvInputHal = (JTvInputHal*)ptr;
     delete tvInputHal;
 }
 
 static const JNINativeMethod gTvInputHalMethods[] = {
-    /* name, signature, funcPtr */
-    { "nativeOpen", "(Landroid/os/MessageQueue;)J",
-            (void*) nativeOpen },
-    { "nativeAddOrUpdateStream", "(JIILandroid/view/Surface;)I",
-            (void*) nativeAddOrUpdateStream },
-    { "nativeRemoveStream", "(JII)I",
-            (void*) nativeRemoveStream },
-    { "nativeGetStreamConfigs", "(JII)[Landroid/media/tv/TvStreamConfig;",
-            (void*) nativeGetStreamConfigs },
-    { "nativeClose", "(J)V",
-            (void*) nativeClose },
+        /* name, signature, funcPtr */
+        {"nativeOpen", "(Landroid/os/MessageQueue;)J", (void*)nativeOpen},
+        {"nativeAddOrUpdateStream", "(JIILandroid/view/Surface;)I", (void*)nativeAddOrUpdateStream},
+        {"nativeRemoveStream", "(JII)I", (void*)nativeRemoveStream},
+        {"nativeGetStreamConfigs", "(JII)[Landroid/media/tv/TvStreamConfig;",
+         (void*)nativeGetStreamConfigs},
+        {"nativeSetTvMessageEnabled", "(JIIIZ)I", (void*)nativeSetTvMessageEnabled},
+        {"nativeClose", "(J)V", (void*)nativeClose},
 };
 
 #define FIND_CLASS(var, className) \
diff --git a/services/core/jni/tvinput/JTvInputHal.cpp b/services/core/jni/tvinput/JTvInputHal.cpp
index 98e6b19..6bb5217 100644
--- a/services/core/jni/tvinput/JTvInputHal.cpp
+++ b/services/core/jni/tvinput/JTvInputHal.cpp
@@ -144,6 +144,17 @@
     return NO_ERROR;
 }
 
+int JTvInputHal::setTvMessageEnabled(int deviceId, int streamId, int type, bool enabled) {
+    Mutex::Autolock autoLock(&mLock);
+    if (!mTvInput->setTvMessageEnabled(deviceId, streamId,
+                                       static_cast<AidlTvMessageEventType>(type), enabled)
+                 .isOk()) {
+        ALOGE("Error in setTvMessageEnabled. device id:%d stream id:%d", deviceId, streamId);
+        return BAD_VALUE;
+    }
+    return NO_ERROR;
+}
+
 const std::vector<AidlTvStreamConfig> JTvInputHal::getStreamConfigs(int deviceId) {
     std::vector<AidlTvStreamConfig> list;
     ::ndk::ScopedAStatus status = mTvInput->getStreamConfigurations(deviceId, &list);
@@ -384,4 +395,15 @@
     }
 }
 
+::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::setTvMessageEnabled(int32_t deviceId,
+                                                                       int32_t streamId,
+                                                                       TvMessageEventType in_type,
+                                                                       bool enabled) {
+    if (mIsHidl) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    } else {
+        return mAidlTvInput->setTvMessageEnabled(deviceId, streamId, in_type, enabled);
+    }
+}
+
 } // namespace android
diff --git a/services/core/jni/tvinput/JTvInputHal.h b/services/core/jni/tvinput/JTvInputHal.h
index 984407a..e29da79 100644
--- a/services/core/jni/tvinput/JTvInputHal.h
+++ b/services/core/jni/tvinput/JTvInputHal.h
@@ -44,6 +44,8 @@
 using ::aidl::android::hardware::tv::input::CableConnectionStatus;
 using ::aidl::android::hardware::tv::input::TvInputEventType;
 using ::aidl::android::hardware::tv::input::TvInputType;
+using ::aidl::android::hardware::tv::input::TvMessageEvent;
+using ::aidl::android::hardware::tv::input::TvMessageEventType;
 
 using AidlAudioDevice = ::aidl::android::media::audio::common::AudioDevice;
 using AidlAudioDeviceAddress = ::aidl::android::media::audio::common::AudioDeviceAddress;
@@ -53,6 +55,7 @@
 using AidlTvInputDeviceInfo = ::aidl::android::hardware::tv::input::TvInputDeviceInfo;
 using AidlTvInputEvent = ::aidl::android::hardware::tv::input::TvInputEvent;
 using AidlTvMessageEvent = ::aidl::android::hardware::tv::input::TvMessageEvent;
+using AidlTvMessageEventType = ::aidl::android::hardware::tv::input::TvMessageEventType;
 using AidlTvStreamConfig = ::aidl::android::hardware::tv::input::TvStreamConfig;
 
 extern gTvInputHalClassInfoType gTvInputHalClassInfo;
@@ -69,6 +72,7 @@
     static JTvInputHal* createInstance(JNIEnv* env, jobject thiz, const sp<Looper>& looper);
 
     int addOrUpdateStream(int deviceId, int streamId, const sp<Surface>& surface);
+    int setTvMessageEnabled(int deviceId, int streamId, int type, bool enabled);
     int removeStream(int deviceId, int streamId);
     const std::vector<AidlTvStreamConfig> getStreamConfigs(int deviceId);
 
@@ -150,6 +154,8 @@
         ::ndk::ScopedAStatus openStream(int32_t in_deviceId, int32_t in_streamId,
                                         AidlNativeHandle* _aidl_return);
         ::ndk::ScopedAStatus closeStream(int32_t in_deviceId, int32_t in_streamId);
+        ::ndk::ScopedAStatus setTvMessageEnabled(int32_t deviceId, int32_t streamId,
+                                                 TvMessageEventType in_type, bool enabled);
 
     private:
         ::ndk::ScopedAStatus hidlSetCallback(const std::shared_ptr<TvInputCallback>& in_callback);
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 981844c..f96ca58 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -153,12 +153,6 @@
                 <xs:annotation name="nullable"/>
                 <xs:annotation name="final"/>
             </xs:element>
-            <!-- The highest (most severe) thermal status at which high-brightness-mode is allowed
-                 to operate. -->
-            <xs:element name="thermalStatusLimit" type="thermalStatus" minOccurs="0" maxOccurs="1">
-                <xs:annotation name="nonnull"/>
-                <xs:annotation name="final"/>
-            </xs:element>
             <xs:element name="allowInLowPowerMode" type="xs:boolean" minOccurs="0" maxOccurs="1">
                 <xs:annotation name="nonnull"/>
                 <xs:annotation name="final"/>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 8cb4837..ad6434e 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -156,7 +156,6 @@
     method @NonNull public final java.math.BigDecimal getMinimumLux_all();
     method @Nullable public final com.android.server.display.config.RefreshRateRange getRefreshRate_all();
     method @Nullable public final com.android.server.display.config.SdrHdrRatioMap getSdrHdrRatioMap_all();
-    method @NonNull public final com.android.server.display.config.ThermalStatus getThermalStatusLimit_all();
     method public com.android.server.display.config.HbmTiming getTiming_all();
     method @NonNull public final java.math.BigDecimal getTransitionPoint_all();
     method public final void setAllowInLowPowerMode_all(@NonNull boolean);
@@ -165,7 +164,6 @@
     method public final void setMinimumLux_all(@NonNull java.math.BigDecimal);
     method public final void setRefreshRate_all(@Nullable com.android.server.display.config.RefreshRateRange);
     method public final void setSdrHdrRatioMap_all(@Nullable com.android.server.display.config.SdrHdrRatioMap);
-    method public final void setThermalStatusLimit_all(@NonNull com.android.server.display.config.ThermalStatus);
     method public void setTiming_all(com.android.server.display.config.HbmTiming);
     method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal);
   }
diff --git a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
index 19a0c5e..04ecd6e 100644
--- a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
@@ -67,7 +67,7 @@
                 .createNewSession(mContext, mUserId, providerInfo,
                         this, remoteCredentialService);
         if (providerClearSession != null) {
-            Slog.d(TAG, "In startProviderSession - provider session created "
+            Slog.i(TAG, "Provider session created "
                     + "and being added for: " + providerInfo.getComponentName());
             mProviders.put(providerClearSession.getComponentName().flattenToString(),
                     providerClearSession);
@@ -78,12 +78,12 @@
     @Override // from provider session
     public void onProviderStatusChanged(ProviderSession.Status status,
             ComponentName componentName, ProviderSession.CredentialsSource source) {
-        Slog.d(TAG, "in onStatusChanged with status: " + status + ", and source: " + source);
+        Slog.i(TAG, "Provider changed with status: " + status + ", and source: " + source);
         if (ProviderSession.isTerminatingStatus(status)) {
-            Slog.d(TAG, "in onProviderStatusChanged terminating status");
+            Slog.i(TAG, "Provider terminating status");
             onProviderTerminated(componentName);
         } else if (ProviderSession.isCompletionStatus(status)) {
-            Slog.d(TAG, "in onProviderStatusChanged isCompletionStatus status");
+            Slog.i(TAG, "Provider has completion status");
             onProviderResponseComplete(componentName);
         }
     }
diff --git a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
index fc7fd1a..4b32062 100644
--- a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
@@ -79,7 +79,7 @@
                 .createNewSession(mContext, mUserId, providerInfo,
                         this, remoteCredentialService);
         if (providerCreateSession != null) {
-            Slog.d(TAG, "In initiateProviderSession - provider session created and "
+            Slog.i(TAG, "Provider session created and "
                     + "being added for: " + providerInfo.getComponentName());
             mProviders.put(providerCreateSession.getComponentName().flattenToString(),
                     providerCreateSession);
@@ -98,7 +98,9 @@
                             mRequestId, mClientRequest,
                             mClientAppInfo.getPackageName(),
                             PermissionUtils.hasPermission(mContext, mClientAppInfo.getPackageName(),
-                                    Manifest.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS)),
+                                    Manifest.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS),
+                            // TODO(b/279480457): populate
+                            /*defaultProviderId=*/new ArrayList<>()),
                     providerDataList);
             mClientCallback.onPendingIntent(mPendingIntent);
         } catch (RemoteException e) {
@@ -125,7 +127,7 @@
     @Override
     public void onFinalResponseReceived(ComponentName componentName,
             @Nullable CreateCredentialResponse response) {
-        Slog.d(TAG, "onFinalCredentialReceived from: " + componentName.flattenToString());
+        Slog.i(TAG, "Final credential received from: " + componentName.flattenToString());
         mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime());
         mRequestSessionMetric.collectChosenMetricViaCandidateTransfer(mProviders.get(
                 componentName.flattenToString()).mProviderSessionMetric
@@ -168,13 +170,13 @@
     @Override
     public void onProviderStatusChanged(ProviderSession.Status status,
             ComponentName componentName, ProviderSession.CredentialsSource source) {
-        Slog.d(TAG, "in onStatusChanged with status: " + status + ", and source: " + source);
+        Slog.i(TAG, "Provider status changed: " + status + ", and source: " + source);
         // If all provider responses have been received, we can either need the UI,
         // or we need to respond with error. The only other case is the entry being
         // selected after the UI has been invoked which has a separate code path.
         if (!isAnyProviderPending()) {
             if (isUiInvocationNeeded()) {
-                Slog.d(TAG, "in onProviderStatusChanged - isUiInvocationNeeded");
+                Slog.i(TAG, "Provider status changed - ui invocation is needed");
                 getProviderDataAndInitiateUi();
             } else {
                 respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREATE_OPTIONS,
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index 06b96eb..7f95e05 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -58,7 +58,6 @@
 import android.service.credentials.CallingAppInfo;
 import android.service.credentials.CredentialProviderInfoFactory;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -437,7 +436,7 @@
                 IGetCredentialCallback callback,
                 final String callingPackage) {
             final long timestampBegan = System.nanoTime();
-            Slog.d(TAG, "starting executeGetCredential with callingPackage: "
+            Slog.i(TAG, "starting executeGetCredential with callingPackage: "
                     + callingPackage);
             ICancellationSignal cancelTransport = CancellationSignal.createTransport();
 
@@ -472,7 +471,7 @@
                             GetCredentialException.TYPE_NO_CREDENTIAL,
                             "No credentials available on this device.");
                 } catch (RemoteException e) {
-                    Log.i(
+                    Slog.e(
                             TAG,
                             "Issue invoking onError on IGetCredentialCallback "
                                     + "callback: "
@@ -528,7 +527,7 @@
                                     false, null,
                                     false, false, null));
                 } catch (RemoteException e) {
-                    Log.i(
+                    Slog.e(
                             TAG,
                             "Issue invoking onError on IGetCredentialCallback "
                                     + "callback: "
@@ -607,7 +606,7 @@
                 ICreateCredentialCallback callback,
                 String callingPackage) {
             final long timestampBegan = System.nanoTime();
-            Slog.d(TAG, "starting executeCreateCredential with callingPackage: "
+            Slog.i(TAG, "starting executeCreateCredential with callingPackage: "
                     + callingPackage);
             ICancellationSignal cancelTransport = CancellationSignal.createTransport();
 
@@ -673,7 +672,7 @@
                 MetricUtilities.logApiCalledInitialPhase(initMetric,
                         session.mRequestSessionMetric.returnIncrementSequence());
             } catch (Exception e) {
-                Log.w(TAG, "Unexpected error during metric logging: ", e);
+                Slog.i(TAG, "Unexpected error during metric logging: ", e);
             }
         }
 
@@ -706,7 +705,7 @@
                     Settings.Secure.CREDENTIAL_SERVICE,
                     storedValue,
                     userId)) {
-                Log.e(TAG, "Failed to store setting containing enabled providers");
+                Slog.e(TAG, "Failed to store setting containing enabled providers");
                 try {
                     callback.onError(
                             "failed_setting_store",
@@ -733,7 +732,7 @@
         @Override
         public boolean isEnabledCredentialProviderService(
                 ComponentName componentName, String callingPackage) {
-            Slog.d(TAG, "isEnabledCredentialProviderService with componentName: "
+            Slog.i(TAG, "isEnabledCredentialProviderService with componentName: "
                     + componentName.flattenToString());
 
             // TODO(253157366): Check additional set of services.
@@ -829,7 +828,7 @@
                 IClearCredentialStateCallback callback,
                 String callingPackage) {
             final long timestampBegan = System.nanoTime();
-            Slog.d(TAG, "starting clearCredentialState with callingPackage: "
+            Slog.i(TAG, "starting clearCredentialState with callingPackage: "
                     + callingPackage);
             final int userId = UserHandle.getCallingUserId();
             int callingUid = Binder.getCallingUid();
@@ -882,7 +881,7 @@
         public void registerCredentialDescription(
                 RegisterCredentialDescriptionRequest request, String callingPackage)
                 throws IllegalArgumentException, NonCredentialProviderCallerException {
-            Slog.d(TAG, "registerCredentialDescription with callingPackage: " + callingPackage);
+            Slog.i(TAG, "registerCredentialDescription with callingPackage: " + callingPackage);
 
             if (!isCredentialDescriptionApiEnabled()) {
                 throw new UnsupportedOperationException();
@@ -900,7 +899,7 @@
         public void unregisterCredentialDescription(
                 UnregisterCredentialDescriptionRequest request, String callingPackage)
                 throws IllegalArgumentException {
-            Slog.d(TAG, "unregisterCredentialDescription with callingPackage: "
+            Slog.i(TAG, "unregisterCredentialDescription with callingPackage: "
                     + callingPackage);
 
 
@@ -962,7 +961,6 @@
         @Override
         @GuardedBy("mLock")
         public void onFinishRequestSession(@UserIdInt int userId, IBinder token) {
-            Log.i(TAG, "In onFinishRequestSession");
             if (mRequestSessions.get(userId) != null) {
                 mRequestSessions.get(userId).remove(token);
             }
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
index 91be2a7..808fdae 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
@@ -48,7 +48,7 @@
             @NonNull Object lock, int userId, String serviceName)
             throws PackageManager.NameNotFoundException {
         super(master, lock, userId);
-        Slog.d(TAG, "CredentialManagerServiceImpl constructed for: " + serviceName);
+        Slog.i(TAG, "CredentialManagerServiceImpl constructed for: " + serviceName);
         synchronized (mLock) {
             newServiceInfoLocked(ComponentName.unflattenFromString(serviceName));
         }
@@ -63,7 +63,7 @@
             @NonNull CredentialManagerService master,
             @NonNull Object lock, int userId, CredentialProviderInfo providerInfo) {
         super(master, lock, userId);
-        Slog.d(TAG, "CredentialManagerServiceImpl constructed for: "
+        Slog.i(TAG, "CredentialManagerServiceImpl constructed for: "
                 + providerInfo.getServiceInfo().getComponentName().flattenToString());
         mInfo = providerInfo;
     }
@@ -74,11 +74,11 @@
             throws PackageManager.NameNotFoundException {
         // TODO : Test update flows with multiple providers
         if (mInfo != null) {
-            Slog.d(TAG, "newServiceInfoLocked, mInfo not null : "
+            Slog.i(TAG, "newServiceInfoLocked, mInfo not null : "
                     + mInfo.getServiceInfo().getComponentName().flattenToString() + " , "
                     + serviceComponent.flattenToString());
         } else {
-            Slog.d(TAG, "newServiceInfoLocked, mInfo null, "
+            Slog.i(TAG, "newServiceInfoLocked, mInfo null, "
                     + serviceComponent.flattenToString());
         }
         mInfo = CredentialProviderInfoFactory.create(
@@ -95,11 +95,11 @@
     public ProviderSession initiateProviderSessionForRequestLocked(
             RequestSession requestSession, List<String> requestOptions) {
         if (!requestOptions.isEmpty() && !isServiceCapableLocked(requestOptions)) {
-            Slog.d(TAG, "Service does not have the required capabilities");
+            Slog.i(TAG, "Service does not have the required capabilities");
             return null;
         }
         if (mInfo == null) {
-            Slog.w(TAG, "in initiateProviderSessionForRequest in CredManServiceImpl, "
+            Slog.w(TAG, "Initiating provider session for request "
                     + "but mInfo is null. This shouldn't happen");
             return null;
         }
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index 0271727..1503410 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -72,7 +72,7 @@
                 .createNewSession(mContext, mUserId, providerInfo,
                         this, remoteCredentialService);
         if (providerGetSession != null) {
-            Slog.d(TAG, "In startProviderSession - provider session created and "
+            Slog.i(TAG, "Provider session created and "
                     + "being added for: " + providerInfo.getComponentName());
             mProviders.put(providerGetSession.getComponentName().flattenToString(),
                     providerGetSession);
@@ -114,7 +114,7 @@
     @Override
     public void onFinalResponseReceived(ComponentName componentName,
             @Nullable GetCredentialResponse response) {
-        Slog.d(TAG, "onFinalResponseReceived from: " + componentName.flattenToString());
+        Slog.i(TAG, "onFinalResponseReceived from: " + componentName.flattenToString());
         mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime());
         mRequestSessionMetric.collectChosenMetricViaCandidateTransfer(
                 mProviders.get(componentName.flattenToString())
@@ -158,7 +158,7 @@
     @Override
     public void onProviderStatusChanged(ProviderSession.Status status,
             ComponentName componentName, ProviderSession.CredentialsSource source) {
-        Slog.d(TAG, "in onStatusChanged for: " + componentName + ", with status: "
+        Slog.i(TAG, "Status changed for: " + componentName + ", with status: "
                 + status + ", and source: " + source);
 
         // Auth entry was selected, and it did not have any underlying credentials
@@ -172,7 +172,7 @@
             // or we need to respond with error. The only other case is the entry being
             // selected after the UI has been invoked which has a separate code path.
             if (isUiInvocationNeeded()) {
-                Slog.d(TAG, "in onProviderStatusChanged - isUiInvocationNeeded");
+                Slog.i(TAG, "Provider status changed - ui invocation is needed");
                 getProviderDataAndInitiateUi();
             } else {
                 respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
diff --git a/services/credentials/java/com/android/server/credentials/MetricUtilities.java b/services/credentials/java/com/android/server/credentials/MetricUtilities.java
index 50e5163..47502c2 100644
--- a/services/credentials/java/com/android/server/credentials/MetricUtilities.java
+++ b/services/credentials/java/com/android/server/credentials/MetricUtilities.java
@@ -19,7 +19,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.util.Log;
+import android.util.Slog;
 
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.credentials.metrics.ApiName;
@@ -27,6 +27,7 @@
 import com.android.server.credentials.metrics.CandidateBrowsingPhaseMetric;
 import com.android.server.credentials.metrics.CandidatePhaseMetric;
 import com.android.server.credentials.metrics.ChosenProviderFinalPhaseMetric;
+import com.android.server.credentials.metrics.EntryEnum;
 import com.android.server.credentials.metrics.InitialPhaseMetric;
 
 import java.util.List;
@@ -35,6 +36,7 @@
 /**
  * For all future metric additions, this will contain their names for local usage after importing
  * from {@link com.android.internal.util.FrameworkStatsLog}.
+ * TODO(b/271135048) - Emit all atoms, including all V4 atoms (specifically the rest of track 1).
  */
 public class MetricUtilities {
     private static final boolean LOG_FLAG = true;
@@ -68,7 +70,7 @@
                     componentName.getPackageName(),
                     PackageManager.ApplicationInfoFlags.of(0)).uid;
         } catch (Throwable t) {
-            Log.i(TAG, "Couldn't find required uid");
+            Slog.i(TAG, "Couldn't find required uid");
         }
         return sessUid;
     }
@@ -146,28 +148,28 @@
                             .getFinalFinishTimeNanoseconds()),
                     /* chosen_provider_status */ finalPhaseMetric.getChosenProviderStatus(),
                     /* chosen_provider_has_exception */ finalPhaseMetric.isHasException(),
-                    /* chosen_provider_available_entries */ finalPhaseMetric.getAvailableEntries()
-                            .stream().mapToInt(i -> i).toArray(),
-                    /* chosen_provider_action_entry_count */ finalPhaseMetric.getActionEntryCount(),
-                    /* chosen_provider_credential_entry_count */
-                    finalPhaseMetric.getCredentialEntryCount(),
-                    /* chosen_provider_credential_entry_type_count */
-                    finalPhaseMetric.getCredentialEntryTypeCount(),
-                    /* chosen_provider_remote_entry_count */
-                    finalPhaseMetric.getRemoteEntryCount(),
-                    /* chosen_provider_authentication_entry_count */
-                    finalPhaseMetric.getAuthenticationEntryCount(),
+                    /* chosen_provider_available_entries (deprecated) */ DEFAULT_REPEATED_INT_32,
+                    /* chosen_provider_action_entry_count (deprecated) */ DEFAULT_INT_32,
+                    /* chosen_provider_credential_entry_count (deprecated)*/DEFAULT_INT_32,
+                    /* chosen_provider_credential_entry_type_count (deprecated) */ DEFAULT_INT_32,
+                    /* chosen_provider_remote_entry_count (deprecated) */ DEFAULT_INT_32,
+                    /* chosen_provider_authentication_entry_count (deprecated) */ DEFAULT_INT_32,
                     /* clicked_entries */ browsedClickedEntries,
                     /* provider_of_clicked_entry */ browsedProviderUid,
                     /* api_status */ apiStatus,
-                    DEFAULT_REPEATED_INT_32,
-                    DEFAULT_REPEATED_INT_32,
-                    DEFAULT_REPEATED_STR,
-                    DEFAULT_REPEATED_INT_32,
+                    /* unique_entries */
+                    finalPhaseMetric.getResponseCollective().getUniqueEntries(),
+                    /* per_entry_counts */
+                    finalPhaseMetric.getResponseCollective().getUniqueEntryCounts(),
+                    /* unique_response_classtypes */
+                    finalPhaseMetric.getResponseCollective().getUniqueResponseStrings(),
+                    /* per_classtype_counts */
+                    finalPhaseMetric.getResponseCollective().getUniqueResponseCounts(),
+                    /* framework_exception_unique_classtypes */
                     DEFAULT_STRING
             );
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.w(TAG, "Unexpected error during final provider uid emit: " + e);
         }
     }
 
@@ -222,12 +224,18 @@
                                 metric.getQueryFinishTimeNanoseconds());
                 candidateStatusList[index] = metric.getProviderQueryStatus();
                 candidateHasExceptionList[index] = metric.isHasException();
-                candidateTotalEntryCountList[index] = metric.getNumEntriesTotal();
-                candidateCredentialEntryCountList[index] = metric.getCredentialEntryCount();
-                candidateCredentialTypeCountList[index] = metric.getCredentialEntryTypeCount();
-                candidateActionEntryCountList[index] = metric.getActionEntryCount();
-                candidateAuthEntryCountList[index] = metric.getAuthenticationEntryCount();
-                candidateRemoteEntryCountList[index] = metric.getRemoteEntryCount();
+                candidateTotalEntryCountList[index] = metric.getResponseCollective()
+                        .getNumEntriesTotal();
+                candidateCredentialEntryCountList[index] = metric.getResponseCollective()
+                        .getCountForEntry(EntryEnum.CREDENTIAL_ENTRY);
+                candidateCredentialTypeCountList[index] = metric.getResponseCollective()
+                        .getUniqueResponseStrings().length;
+                candidateActionEntryCountList[index] = metric.getResponseCollective()
+                        .getCountForEntry(EntryEnum.ACTION_ENTRY);
+                candidateAuthEntryCountList[index] = metric.getResponseCollective()
+                        .getCountForEntry(EntryEnum.AUTHENTICATION_ENTRY);
+                candidateRemoteEntryCountList[index] = metric.getResponseCollective()
+                        .getCountForEntry(EntryEnum.REMOTE_ENTRY);
                 frameworkExceptionList[index] = metric.getFrameworkException();
                 index++;
             }
@@ -261,7 +269,7 @@
                     initialPhaseMetric.getUniqueRequestCounts()
             );
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.w(TAG, "Unexpected error during candidate provider uid metric emit: " + e);
         }
     }
 
@@ -297,7 +305,7 @@
                     DEFAULT_INT_32,
                     /* chosen_provider_status */ DEFAULT_INT_32);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.w(TAG, "Unexpected error during metric logging: " + e);
         }
     }
 
@@ -330,7 +338,7 @@
                     initialPhaseMetric.isOriginSpecified()
             );
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.w(TAG, "Unexpected error during initial metric emit: " + e);
         }
     }
 }
diff --git a/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
index 441c87b..36bc8ba 100644
--- a/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
@@ -66,7 +66,7 @@
     @Override
     public void onProviderStatusChanged(ProviderSession.Status status, ComponentName componentName,
             ProviderSession.CredentialsSource source) {
-        Slog.d(TAG, "in onProviderStatusChanged with status: " + status + ", and "
+        Slog.i(TAG, "Provider Status changed with status: " + status + ", and "
                 + "source: " + source);
 
         switch (source) {
diff --git a/services/credentials/java/com/android/server/credentials/ProviderClearSession.java b/services/credentials/java/com/android/server/credentials/ProviderClearSession.java
index 8af6b56..c1fb92d 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderClearSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderClearSession.java
@@ -80,7 +80,7 @@
 
     @Override
     public void onProviderResponseSuccess(@Nullable Void response) {
-        Slog.d(TAG, "Remote provider responded with a valid response: " + mComponentName);
+        Slog.i(TAG, "Remote provider responded with a valid response: " + mComponentName);
         mProviderResponseSet = true;
         updateStatusAndInvokeCallback(Status.COMPLETE,
                 /*source=*/ CredentialsSource.REMOTE_PROVIDER);
diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
index 520b937..4cdc6f4 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
@@ -75,7 +75,8 @@
         CreateCredentialRequest providerCreateRequest =
                 createProviderRequest(providerInfo.getCapabilities(),
                         createRequestSession.mClientRequest,
-                        createRequestSession.mClientAppInfo);
+                        createRequestSession.mClientAppInfo,
+                        providerInfo.isSystemProvider());
         if (providerCreateRequest != null) {
             return new ProviderCreateSession(
                     context,
@@ -92,7 +93,7 @@
                     createRequestSession.mHybridService
             );
         }
-        Slog.d(TAG, "Unable to create provider session for: "
+        Slog.i(TAG, "Unable to create provider session for: "
                 + providerInfo.getComponentName());
         return null;
     }
@@ -114,9 +115,16 @@
     }
 
     @Nullable
-    private static CreateCredentialRequest createProviderRequest(List<String> providerCapabilities,
+    private static CreateCredentialRequest createProviderRequest(
+            List<String> providerCapabilities,
             android.credentials.CreateCredentialRequest clientRequest,
-            CallingAppInfo callingAppInfo) {
+            CallingAppInfo callingAppInfo,
+            boolean isSystemProvider) {
+        if (clientRequest.isSystemProviderRequired() && !isSystemProvider) {
+            // Request requires system provider but this session does not correspond to a
+            // system service
+            return null;
+        }
         String capability = clientRequest.getType();
         if (providerCapabilities.contains(capability)) {
             return new CreateCredentialRequest(callingAppInfo, capability,
@@ -145,7 +153,7 @@
     @Override
     public void onProviderResponseSuccess(
             @Nullable BeginCreateCredentialResponse response) {
-        Slog.d(TAG, "Remote provider responded with a valid response: " + mComponentName);
+        Slog.i(TAG, "Remote provider responded with a valid response: " + mComponentName);
         onSetInitialRemoteResponse(response);
     }
 
@@ -200,7 +208,7 @@
     protected CreateCredentialProviderData prepareUiData()
             throws IllegalArgumentException {
         if (!ProviderSession.isUiInvokingStatus(getStatus())) {
-            Slog.d(TAG, "No data for UI from: " + mComponentName.flattenToString());
+            Slog.i(TAG, "No data for UI from: " + mComponentName.flattenToString());
             return null;
         }
 
@@ -216,7 +224,7 @@
         switch (entryType) {
             case SAVE_ENTRY_KEY:
                 if (mProviderResponseDataHandler.getCreateEntry(entryKey) == null) {
-                    Slog.w(TAG, "Unexpected save entry key");
+                    Slog.i(TAG, "Unexpected save entry key");
                     invokeCallbackOnInternalInvalidState();
                     return;
                 }
@@ -224,14 +232,14 @@
                 break;
             case REMOTE_ENTRY_KEY:
                 if (mProviderResponseDataHandler.getRemoteEntry(entryKey) == null) {
-                    Slog.w(TAG, "Unexpected remote entry key");
+                    Slog.i(TAG, "Unexpected remote entry key");
                     invokeCallbackOnInternalInvalidState();
                     return;
                 }
                 onRemoteEntrySelected(providerPendingIntentResponse);
                 break;
             default:
-                Slog.w(TAG, "Unsupported entry type selected");
+                Slog.i(TAG, "Unsupported entry type selected");
                 invokeCallbackOnInternalInvalidState();
         }
     }
@@ -266,7 +274,7 @@
         if (credentialResponse != null) {
             mCallbacks.onFinalResponseReceived(mComponentName, credentialResponse);
         } else {
-            Slog.w(TAG, "onSaveEntrySelected - no response or error found in pending "
+            Slog.i(TAG, "onSaveEntrySelected - no response or error found in pending "
                     + "intent response");
             invokeCallbackOnInternalInvalidState();
         }
@@ -282,14 +290,14 @@
     private CreateCredentialException maybeGetPendingIntentException(
             ProviderPendingIntentResponse pendingIntentResponse) {
         if (pendingIntentResponse == null) {
-            Slog.w(TAG, "pendingIntentResponse is null");
+            Slog.i(TAG, "pendingIntentResponse is null");
             return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREATE_OPTIONS);
         }
         if (PendingIntentResultHandler.isValidResponse(pendingIntentResponse)) {
             CreateCredentialException exception = PendingIntentResultHandler
                     .extractCreateCredentialException(pendingIntentResponse.getResultData());
             if (exception != null) {
-                Slog.d(TAG, "Pending intent contains provider exception");
+                Slog.i(TAG, "Pending intent contains provider exception");
                 return exception;
             }
         } else if (PendingIntentResultHandler.isCancelledResponse(pendingIntentResponse)) {
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index a62d9e8..8070fa7 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -40,7 +40,6 @@
 import android.service.credentials.CredentialProviderService;
 import android.service.credentials.GetCredentialRequest;
 import android.service.credentials.RemoteEntry;
-import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
 
@@ -115,7 +114,7 @@
                     getRequestSession.mHybridService
             );
         }
-        Slog.d(TAG, "Unable to create provider session for: "
+        Slog.i(TAG, "Unable to create provider session for: "
                 + providerInfo.getComponentName());
         return null;
     }
@@ -147,13 +146,13 @@
             android.credentials.GetCredentialRequest clientRequest,
             CredentialProviderInfo info
     ) {
-        Slog.d(TAG, "Filtering request options for: " + info.getComponentName());
+        Slog.i(TAG, "Filtering request options for: " + info.getComponentName());
         List<CredentialOption> filteredOptions = new ArrayList<>();
         for (CredentialOption option : clientRequest.getCredentialOptions()) {
             if (providerCapabilities.contains(option.getType())
                     && isProviderAllowed(option, info.getComponentName())
                     && checkSystemProviderRequirement(option, info.isSystemProvider())) {
-                Slog.d(TAG, "Option of type: " + option.getType() + " meets all filtering"
+                Slog.i(TAG, "Option of type: " + option.getType() + " meets all filtering"
                         + "conditions");
                 filteredOptions.add(option);
             }
@@ -164,14 +163,14 @@
                     .setCredentialOptions(
                             filteredOptions).build();
         }
-        Slog.d(TAG, "No options filtered");
+        Slog.i(TAG, "No options filtered");
         return null;
     }
 
     private static boolean isProviderAllowed(CredentialOption option, ComponentName componentName) {
         if (!option.getAllowedProviders().isEmpty() && !option.getAllowedProviders().contains(
                 componentName)) {
-            Slog.d(TAG, "Provider allow list specified but does not contain this provider");
+            Slog.i(TAG, "Provider allow list specified but does not contain this provider");
             return false;
         }
         return true;
@@ -180,7 +179,7 @@
     private static boolean checkSystemProviderRequirement(CredentialOption option,
             boolean isSystemProvider) {
         if (option.isSystemProviderRequired() && !isSystemProvider) {
-            Slog.d(TAG, "System provider required, but this service is not a system provider");
+            Slog.i(TAG, "System provider required, but this service is not a system provider");
             return false;
         }
         return true;
@@ -208,7 +207,7 @@
     /** Called when the provider response has been updated by an external source. */
     @Override // Callback from the remote provider
     public void onProviderResponseSuccess(@Nullable BeginGetCredentialResponse response) {
-        Slog.d(TAG, "Remote provider responded with a valid response: " + mComponentName);
+        Slog.i(TAG, "Remote provider responded with a valid response: " + mComponentName);
         onSetInitialRemoteResponse(response);
     }
 
@@ -245,14 +244,14 @@
     @Override // Selection call from the request provider
     protected void onUiEntrySelected(String entryType, String entryKey,
             ProviderPendingIntentResponse providerPendingIntentResponse) {
-        Slog.d(TAG, "onUiEntrySelected with entryType: " + entryType + ", and entryKey: "
+        Slog.i(TAG, "onUiEntrySelected with entryType: " + entryType + ", and entryKey: "
                 + entryKey);
         switch (entryType) {
             case CREDENTIAL_ENTRY_KEY:
                 CredentialEntry credentialEntry = mProviderResponseDataHandler
                         .getCredentialEntry(entryKey);
                 if (credentialEntry == null) {
-                    Slog.w(TAG, "Unexpected credential entry key");
+                    Slog.i(TAG, "Unexpected credential entry key");
                     invokeCallbackOnInternalInvalidState();
                     return;
                 }
@@ -261,7 +260,7 @@
             case ACTION_ENTRY_KEY:
                 Action actionEntry = mProviderResponseDataHandler.getActionEntry(entryKey);
                 if (actionEntry == null) {
-                    Slog.w(TAG, "Unexpected action entry key");
+                    Slog.i(TAG, "Unexpected action entry key");
                     invokeCallbackOnInternalInvalidState();
                     return;
                 }
@@ -271,21 +270,21 @@
                 Action authenticationEntry = mProviderResponseDataHandler
                         .getAuthenticationAction(entryKey);
                 if (authenticationEntry == null) {
-                    Slog.w(TAG, "Unexpected authenticationEntry key");
+                    Slog.i(TAG, "Unexpected authenticationEntry key");
                     invokeCallbackOnInternalInvalidState();
                     return;
                 }
                 boolean additionalContentReceived =
                         onAuthenticationEntrySelected(providerPendingIntentResponse);
                 if (additionalContentReceived) {
-                    Slog.d(TAG, "Additional content received - removing authentication entry");
+                    Slog.i(TAG, "Additional content received - removing authentication entry");
                     mProviderResponseDataHandler.removeAuthenticationAction(entryKey);
                     if (!mProviderResponseDataHandler.isEmptyResponse()) {
                         updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED,
                                 /*source=*/ CredentialsSource.AUTH_ENTRY);
                     }
                 } else {
-                    Slog.d(TAG, "Additional content not received from authentication entry");
+                    Slog.i(TAG, "Additional content not received from authentication entry");
                     mProviderResponseDataHandler
                             .updateAuthEntryWithNoCredentialsReceived(entryKey);
                     updateStatusAndInvokeCallback(Status.NO_CREDENTIALS_FROM_AUTH_ENTRY,
@@ -296,12 +295,12 @@
                 if (mProviderResponseDataHandler.getRemoteEntry(entryKey) != null) {
                     onRemoteEntrySelected(providerPendingIntentResponse);
                 } else {
-                    Slog.d(TAG, "Unexpected remote entry key");
+                    Slog.i(TAG, "Unexpected remote entry key");
                     invokeCallbackOnInternalInvalidState();
                 }
                 break;
             default:
-                Slog.w(TAG, "Unsupported entry type selected");
+                Slog.i(TAG, "Unsupported entry type selected");
                 invokeCallbackOnInternalInvalidState();
         }
     }
@@ -323,13 +322,12 @@
     @Nullable
     protected GetCredentialProviderData prepareUiData() throws IllegalArgumentException {
         if (!ProviderSession.isUiInvokingStatus(getStatus())) {
-            Slog.d(TAG, "No data for UI from: " + mComponentName.flattenToString());
+            Slog.i(TAG, "No data for UI from: " + mComponentName.flattenToString());
             return null;
         }
         if (mProviderResponse != null && !mProviderResponseDataHandler.isEmptyResponse()) {
             return mProviderResponseDataHandler.toGetCredentialProviderData();
         }
-        Slog.d(TAG, "In prepareUiData response null");
         return null;
     }
 
@@ -382,7 +380,7 @@
                     getCredentialResponse);
             return;
         }
-        Slog.d(TAG, "Pending intent response contains no credential, or error "
+        Slog.i(TAG, "Pending intent response contains no credential, or error "
                 + "for a credential entry");
         invokeCallbackOnInternalInvalidState();
     }
@@ -413,11 +411,9 @@
      */
     private boolean onAuthenticationEntrySelected(
             @Nullable ProviderPendingIntentResponse providerPendingIntentResponse) {
-        Log.i(TAG, "onAuthenticationEntrySelected");
         // Authentication entry is expected to have a BeginGetCredentialResponse instance. If it
         // does not have it, we remove the authentication entry and do not add any more content.
         if (providerPendingIntentResponse == null) {
-            Log.i(TAG, "providerPendingIntentResponse is null");
             // Nothing received. This is equivalent to no content received.
             return false;
         }
@@ -462,7 +458,7 @@
     /** Returns true if either an exception or a response is found. */
     private void onActionEntrySelected(ProviderPendingIntentResponse
             providerPendingIntentResponse) {
-        Slog.d(TAG, "onActionEntrySelected");
+        Slog.i(TAG, "onActionEntrySelected");
         onCredentialEntrySelected(providerPendingIntentResponse);
     }
 
diff --git a/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
index c10f564..21f4a05 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
@@ -171,11 +171,11 @@
     @Override
     protected ProviderData prepareUiData() {
         if (!ProviderSession.isUiInvokingStatus(getStatus())) {
-            Slog.d(TAG, "No date for UI coming from: " + mComponentName.flattenToString());
+            Slog.i(TAG, "No date for UI coming from: " + mComponentName.flattenToString());
             return null;
         }
         if (mProviderResponse == null) {
-            Slog.w(TAG, "In prepareUiData but response is null. This is strange.");
+            Slog.w(TAG, "response is null when preparing ui data. This is strange.");
             return null;
         }
         return new GetCredentialProviderData.Builder(
@@ -196,13 +196,13 @@
             case CREDENTIAL_ENTRY_KEY:
                 CredentialEntry credentialEntry = mUiCredentialEntries.get(entryKey);
                 if (credentialEntry == null) {
-                    Slog.w(TAG, "Unexpected credential entry key");
+                    Slog.i(TAG, "Unexpected credential entry key");
                     return;
                 }
                 onCredentialEntrySelected(credentialEntry, providerPendingIntentResponse);
                 break;
             default:
-                Slog.w(TAG, "Unsupported entry type selected");
+                Slog.i(TAG, "Unsupported entry type selected");
         }
     }
 
@@ -266,7 +266,7 @@
                 .collect(Collectors.toList());
         updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED,
                 /*source=*/ CredentialsSource.REGISTRY);
-        // TODO(use metric later)
+        // TODO(b/273353677) : metric should be emitted similarly to sibling classes
     }
 
     @Nullable
@@ -279,7 +279,7 @@
             GetCredentialException exception = PendingIntentResultHandler
                     .extractGetCredentialException(pendingIntentResponse.getResultData());
             if (exception != null) {
-                Slog.d(TAG, "Pending intent contains provider exception");
+                Slog.i(TAG, "Pending intent contains provider exception");
                 return exception;
             }
         } else if (PendingIntentResultHandler.isCancelledResponse(pendingIntentResponse)) {
diff --git a/services/credentials/java/com/android/server/credentials/ProviderSession.java b/services/credentials/java/com/android/server/credentials/ProviderSession.java
index d02a8c1..73fdc1c 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderSession.java
@@ -268,12 +268,9 @@
                     /*pId=*/-1, appInfo.uid) == PackageManager.PERMISSION_GRANTED) {
                 return true;
             }
-        } catch (SecurityException e) {
+        } catch (SecurityException | PackageManager.NameNotFoundException e) {
             Slog.e(TAG, "Error getting info for " + mComponentName.flattenToString(), e);
             return false;
-        } catch (PackageManager.NameNotFoundException e) {
-            Slog.i(TAG, "Error getting info for " + mComponentName.flattenToString(), e);
-            return false;
         }
         return false;
     }
diff --git a/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java b/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
index 0ad73c9..f5e3b86 100644
--- a/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
+++ b/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
@@ -292,13 +292,13 @@
             callback.onProviderResponseSuccess(result);
         } else {
             if (error instanceof TimeoutException) {
-                Slog.d(TAG, "Remote provider response timed tuo for: " + mComponentName);
+                Slog.i(TAG, "Remote provider response timed tuo for: " + mComponentName);
                 dispatchCancellationSignal(cancellationSink.get());
                 callback.onProviderResponseFailure(
                         CredentialProviderErrors.ERROR_TIMEOUT,
                         null);
             } else if (error instanceof CancellationException) {
-                Slog.d(TAG, "Cancellation exception for remote provider: " + mComponentName);
+                Slog.i(TAG, "Cancellation exception for remote provider: " + mComponentName);
                 dispatchCancellationSignal(cancellationSink.get());
                 callback.onProviderResponseFailure(
                         CredentialProviderErrors.ERROR_TASK_CANCELED,
diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java
index 15a30e4..7caa921 100644
--- a/services/credentials/java/com/android/server/credentials/RequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/RequestSession.java
@@ -201,7 +201,7 @@
     }
 
     protected void finishSession(boolean propagateCancellation) {
-        Slog.d(TAG, "finishing session with propagateCancellation " + propagateCancellation);
+        Slog.i(TAG, "finishing session with propagateCancellation " + propagateCancellation);
         if (propagateCancellation) {
             mProviders.values().forEach(ProviderSession::cancelProviderRemoteSession);
         }
@@ -265,7 +265,7 @@
 
     @NonNull
     protected ArrayList<ProviderData> getProviderDataForUi() {
-        Slog.d(TAG, "In getProviderDataAndInitiateUi providers size: " + mProviders.size());
+        Slog.i(TAG, "For ui, provider data size: " + mProviders.size());
         ArrayList<ProviderData> providerDataList = new ArrayList<>();
         mRequestSessionMetric.logCandidatePhaseMetrics(mProviders);
 
diff --git a/services/credentials/java/com/android/server/credentials/metrics/ApiName.java b/services/credentials/java/com/android/server/credentials/metrics/ApiName.java
index b99f28d..1930a48 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/ApiName.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/ApiName.java
@@ -27,7 +27,7 @@
 import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE_REPORTED__API_NAME__API_NAME_UNKNOWN;
 
 import android.credentials.ui.RequestInfo;
-import android.util.Log;
+import android.util.Slog;
 
 import java.util.AbstractMap;
 import java.util.Map;
@@ -79,7 +79,7 @@
      */
     public static int getMetricCodeFromRequestInfo(String stringKey) {
         if (!sRequestInfoToMetric.containsKey(stringKey)) {
-            Log.w(TAG, "Attempted to use an unsupported string key request info");
+            Slog.i(TAG, "Attempted to use an unsupported string key request info");
             return UNKNOWN.mInnerMetricCode;
         }
         return sRequestInfoToMetric.get(stringKey);
diff --git a/services/credentials/java/com/android/server/credentials/metrics/CandidateBrowsingPhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/CandidateBrowsingPhaseMetric.java
index 0e1e0389..07af654 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/CandidateBrowsingPhaseMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/CandidateBrowsingPhaseMetric.java
@@ -27,8 +27,6 @@
  * though collection will begin in the candidate phase when the user begins browsing options.
  */
 public class CandidateBrowsingPhaseMetric {
-
-    private static final String TAG = "CandidateBrowsingPhaseMetric";
     // The session id associated with the API Call this candidate provider is a part of, default -1
     private int mSessionId = -1;
     // The EntryEnum that was pressed, defaults to -1
diff --git a/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java
index 721d3d7..3ea9b1ce 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java
@@ -16,21 +16,18 @@
 
 package com.android.server.credentials.metrics;
 
-import android.util.IntArray;
-import android.util.Log;
+import android.util.Slog;
 
 import com.android.server.credentials.MetricUtilities;
+import com.android.server.credentials.metrics.shared.ResponseCollective;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
+import java.util.Map;
 
 /**
  * The central candidate provider metric object that mimics our defined metric setup.
  * Some types are redundant across these metric collectors, but that has debug use-cases as
  * these data-types are available at different moments of the flow (and typically, one can feed
  * into the next).
- * TODO(b/270403549) - iterate on this in V3+
  */
 public class CandidatePhaseMetric {
 
@@ -56,26 +53,12 @@
     private int mProviderQueryStatus = -1;
     // Indicates if an exception was thrown by this provider, false by default
     private boolean mHasException = false;
-    // Indicates the number of total entries available. We can also locally store the entries, but
-    // cannot emit them in the current split form. TODO(b/271135048) - possibly readjust candidate
-    // entries. Also, it may be okay to remove this and instead aggregate from inner counts.
-    // Defaults to -1
-    private int mNumEntriesTotal = -1;
-    // The count of action entries from this provider, defaults to -1
-    private int mActionEntryCount = -1;
-    // The count of credential entries from this provider, defaults to -1
-    private int mCredentialEntryCount = -1;
-    // The *type-count* of the credential entries, defaults to -1
-    private int mCredentialEntryTypeCount = -1;
-    // The count of remote entries from this provider, defaults to -1
-    private int mRemoteEntryCount = -1;
-    // The count of authentication entries from this provider, defaults to -1
-    private int mAuthenticationEntryCount = -1;
-    // Gathered to pass on to chosen provider when required
-    private final IntArray mAvailableEntries = new IntArray();
-    // The *framework only* exception held by this provider, empty string by default
     private String mFrameworkException = "";
 
+    // Stores the response credential information, as well as the response entry information which
+    // by default, contains empty info
+    private ResponseCollective mResponseCollective = new ResponseCollective(Map.of(), Map.of());
+
     public CandidatePhaseMetric() {
     }
 
@@ -129,7 +112,7 @@
      */
     public int getTimestampFromReferenceStartMicroseconds(long specificTimestamp) {
         if (specificTimestamp < mServiceBeganTimeNanoseconds) {
-            Log.i(TAG, "The timestamp is before service started, falling back to default int");
+            Slog.i(TAG, "The timestamp is before service started, falling back to default int");
             return MetricUtilities.DEFAULT_INT_32;
         }
         return (int) ((specificTimestamp
@@ -186,88 +169,13 @@
         return mHasException;
     }
 
-    /* -------------- Number of Entries ---------------- */
-
-    public void setNumEntriesTotal(int numEntriesTotal) {
-        mNumEntriesTotal = numEntriesTotal;
+    /* -------------- The Entries and Responses Gathered ---------------- */
+    public void setResponseCollective(ResponseCollective responseCollective) {
+        mResponseCollective = responseCollective;
     }
 
-    public int getNumEntriesTotal() {
-        return mNumEntriesTotal;
-    }
-
-    /* -------------- Count of Action Entries ---------------- */
-
-    public void setActionEntryCount(int actionEntryCount) {
-        mActionEntryCount = actionEntryCount;
-    }
-
-    public int getActionEntryCount() {
-        return mActionEntryCount;
-    }
-
-    /* -------------- Count of Credential Entries ---------------- */
-
-    public void setCredentialEntryCount(int credentialEntryCount) {
-        mCredentialEntryCount = credentialEntryCount;
-    }
-
-    public int getCredentialEntryCount() {
-        return mCredentialEntryCount;
-    }
-
-    /* -------------- Count of Credential Entry Types ---------------- */
-
-    public void setCredentialEntryTypeCount(int credentialEntryTypeCount) {
-        mCredentialEntryTypeCount = credentialEntryTypeCount;
-    }
-
-    public int getCredentialEntryTypeCount() {
-        return mCredentialEntryTypeCount;
-    }
-
-    /* -------------- Count of Remote Entries ---------------- */
-
-    public void setRemoteEntryCount(int remoteEntryCount) {
-        mRemoteEntryCount = remoteEntryCount;
-    }
-
-    public int getRemoteEntryCount() {
-        return mRemoteEntryCount;
-    }
-
-    /* -------------- Count of Authentication Entries ---------------- */
-
-    public void setAuthenticationEntryCount(int authenticationEntryCount) {
-        mAuthenticationEntryCount = authenticationEntryCount;
-    }
-
-    public int getAuthenticationEntryCount() {
-        return mAuthenticationEntryCount;
-    }
-
-    /* -------------- The Entries Gathered ---------------- */
-
-    /**
-     * Allows adding an entry record to this metric collector, which can then be propagated to
-     * the final phase to retain information on the data available to the candidate.
-     *
-     * @param e the entry enum collected by the candidate provider associated with this metric
-     *          collector
-     */
-    public void addEntry(EntryEnum e) {
-        mAvailableEntries.add(e.getMetricCode());
-    }
-
-    /**
-     * Returns a safely copied list of the entries captured by this metric collector associated
-     * with a particular candidate provider.
-     *
-     * @return the full collection of entries encountered by the candidate provider associated with
-     * this metric
-     */
-    public List<Integer> getAvailableEntries() {
-        return Arrays.stream(mAvailableEntries.toArray()).boxed().collect(Collectors.toList());
+    public ResponseCollective getResponseCollective() {
+        return mResponseCollective;
     }
 
     /* ------ Framework Exception for this Candidate ------ */
diff --git a/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java
index c80cc24..93a8290 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java
@@ -16,12 +16,12 @@
 
 package com.android.server.credentials.metrics;
 
-import android.util.Log;
+import android.util.Slog;
 
 import com.android.server.credentials.MetricUtilities;
+import com.android.server.credentials.metrics.shared.ResponseCollective;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Map;
 
 /**
  * The central chosen provider metric object that mimics our defined metric setup. This is used
@@ -29,11 +29,8 @@
  * Some types are redundant across these metric collectors, but that has debug use-cases as
  * these data-types are available at different moments of the flow (and typically, one can feed
  * into the next).
- * TODO(b/270403549) - iterate on this in V3+
  */
 public class ChosenProviderFinalPhaseMetric {
-
-    // TODO(b/270403549) - applies elsewhere, likely removed or replaced w/ some hashed/count index
     private static final String TAG = "ChosenFinalPhaseMetric";
     // The session id associated with this API call, used to unite split emits
     private int mSessionId = -1;
@@ -69,21 +66,10 @@
     private int mChosenProviderStatus = -1;
     // Indicates if an exception was thrown by this provider, false by default
     private boolean mHasException = false;
-    // Indicates the number of total entries available, defaults to -1. Not presently emitted, but
-    // left as a utility
-    private int mNumEntriesTotal = -1;
-    // The count of action entries from this provider, defaults to -1
-    private int mActionEntryCount = -1;
-    // The count of credential entries from this provider, defaults to -1
-    private int mCredentialEntryCount = -1;
-    // The *type-count* of the credential entries, defaults to -1
-    private int mCredentialEntryTypeCount = -1;
-    // The count of remote entries from this provider, defaults to -1
-    private int mRemoteEntryCount = -1;
-    // The count of authentication entries from this provider, defaults to -1
-    private int mAuthenticationEntryCount = -1;
-    // Gathered to pass on to chosen provider when required
-    private List<Integer> mAvailableEntries = new ArrayList<>();
+
+    // Stores the response credential information, as well as the response entry information which
+    // by default, contains empty info
+    private ResponseCollective mResponseCollective = new ResponseCollective(Map.of(), Map.of());
 
 
     public ChosenProviderFinalPhaseMetric() {
@@ -230,7 +216,7 @@
      */
     public int getTimestampFromReferenceStartMicroseconds(long specificTimestamp) {
         if (specificTimestamp < mServiceBeganTimeNanoseconds) {
-            Log.i(TAG, "The timestamp is before service started, falling back to default int");
+            Slog.i(TAG, "The timestamp is before service started, falling back to default int");
             return MetricUtilities.DEFAULT_INT_32;
         }
         return (int) ((specificTimestamp
@@ -267,87 +253,6 @@
         return mUiReturned;
     }
 
-    /* -------------- Number of Entries ---------------- */
-
-    public void setNumEntriesTotal(int numEntriesTotal) {
-        mNumEntriesTotal = numEntriesTotal;
-    }
-
-    public int getNumEntriesTotal() {
-        return mNumEntriesTotal;
-    }
-
-    /* -------------- Count of Action Entries ---------------- */
-
-    public void setActionEntryCount(int actionEntryCount) {
-        mActionEntryCount = actionEntryCount;
-    }
-
-    public int getActionEntryCount() {
-        return mActionEntryCount;
-    }
-
-    /* -------------- Count of Credential Entries ---------------- */
-
-    public void setCredentialEntryCount(int credentialEntryCount) {
-        mCredentialEntryCount = credentialEntryCount;
-    }
-
-    public int getCredentialEntryCount() {
-        return mCredentialEntryCount;
-    }
-
-    /* -------------- Count of Credential Entry Types ---------------- */
-
-    public void setCredentialEntryTypeCount(int credentialEntryTypeCount) {
-        mCredentialEntryTypeCount = credentialEntryTypeCount;
-    }
-
-    public int getCredentialEntryTypeCount() {
-        return mCredentialEntryTypeCount;
-    }
-
-    /* -------------- Count of Remote Entries ---------------- */
-
-    public void setRemoteEntryCount(int remoteEntryCount) {
-        mRemoteEntryCount = remoteEntryCount;
-    }
-
-    public int getRemoteEntryCount() {
-        return mRemoteEntryCount;
-    }
-
-    /* -------------- Count of Authentication Entries ---------------- */
-
-    public void setAuthenticationEntryCount(int authenticationEntryCount) {
-        mAuthenticationEntryCount = authenticationEntryCount;
-    }
-
-    public int getAuthenticationEntryCount() {
-        return mAuthenticationEntryCount;
-    }
-
-    /* -------------- The Entries Gathered ---------------- */
-
-    /**
-     * Sets the collected list of entries from the candidate phase to be retrievable in the
-     * chosen phase in a semantically correct way.
-     */
-    public void setAvailableEntries(List<Integer> entries) {
-        mAvailableEntries = new ArrayList<>(entries); // no alias copy
-    }
-
-    /**
-     * Returns a list of the entries captured by this metric collector associated
-     * with a particular chosen provider.
-     *
-     * @return the full collection of entries encountered by the chosen provider during the
-     * candidate phase.
-     */
-    public List<Integer> getAvailableEntries() {
-        return new ArrayList<>(mAvailableEntries); // no alias copy
-    }
-
     /* -------------- Has Exception ---------------- */
 
     public void setHasException(boolean hasException) {
@@ -357,4 +262,14 @@
     public boolean isHasException() {
         return mHasException;
     }
+
+    /* -------------- The Entries and Responses Gathered ---------------- */
+
+    public void setResponseCollective(ResponseCollective responseCollective) {
+        mResponseCollective = responseCollective;
+    }
+
+    public ResponseCollective getResponseCollective() {
+        return mResponseCollective;
+    }
 }
diff --git a/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java b/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java
index b9125dd..530f01c 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java
@@ -26,7 +26,7 @@
 import static com.android.server.credentials.ProviderGetSession.CREDENTIAL_ENTRY_KEY;
 import static com.android.server.credentials.ProviderGetSession.REMOTE_ENTRY_KEY;
 
-import android.util.Log;
+import android.util.Slog;
 
 import java.util.AbstractMap;
 import java.util.Map;
@@ -77,7 +77,7 @@
      */
     public static int getMetricCodeFromString(String stringKey) {
         if (!sKeyToEntryCode.containsKey(stringKey)) {
-            Log.w(TAG, "Attempted to use an unsupported string key entry type");
+            Slog.i(TAG, "Attempted to use an unsupported string key entry type");
             return UNKNOWN.mInnerMetricCode;
         }
         return sKeyToEntryCode.get(stringKey);
diff --git a/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java
index 0ecd9cc..060e56c 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/InitialPhaseMetric.java
@@ -16,8 +16,6 @@
 
 package com.android.server.credentials.metrics;
 
-import android.util.Log;
-
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -26,7 +24,6 @@
  * Some types are redundant across these metric collectors, but that has debug use-cases as
  * these data-types are available at different moments of the flow (and typically, one can feed
  * into the next).
- * TODO(b/270403549) - iterate on this in V3+
  */
 public class InitialPhaseMetric {
     private static final String TAG = "InitialPhaseMetric";
@@ -47,10 +44,9 @@
     private long mCredentialServiceBeginQueryTimeNanoseconds = -1;
 
     // Indicates if the origin was specified when making this API request
-    // TODO(b/271135048) - Emit once metrics approved
     private boolean mOriginSpecified = false;
 
-    // Stores the deduped request information, particularly {"req":5}.
+    // Stores the deduped request information, particularly {"req":5}
     private Map<String, Integer> mRequestCounts = new LinkedHashMap<>();
 
 
@@ -140,26 +136,20 @@
     }
 
     /**
-     * Reruns the unique, deduped, request classtypes for logging.
+     * Returns the unique, deduped, request classtypes for logging.
      * @return a string array for deduped classtypes
      */
     public String[] getUniqueRequestStrings() {
-        if (mRequestCounts.isEmpty()) {
-            Log.w(TAG, "There are no unique string request types collected");
-        }
         String[] result = new String[mRequestCounts.keySet().size()];
         mRequestCounts.keySet().toArray(result);
         return result;
     }
 
     /**
-     * Reruns the unique, deduped, request classtype counts for logging.
+     * Returns the unique, deduped, request classtype counts for logging.
      * @return a string array for deduped classtype counts
      */
     public int[] getUniqueRequestCounts() {
-        if (mRequestCounts.isEmpty()) {
-            Log.w(TAG, "There are no unique string request type counts collected");
-        }
         return mRequestCounts.values().stream().mapToInt(Integer::intValue).toArray();
     }
 }
diff --git a/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java b/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java
index 9a88255..e618f3b 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java
@@ -16,15 +16,19 @@
 
 package com.android.server.credentials.metrics;
 
+import static com.android.server.credentials.MetricUtilities.DELTA_CUT;
+import static com.android.server.credentials.MetricUtilities.generateMetricKey;
+
 import android.annotation.NonNull;
 import android.service.credentials.BeginCreateCredentialResponse;
 import android.service.credentials.BeginGetCredentialResponse;
-import android.service.credentials.CredentialEntry;
-import android.util.Log;
+import android.util.Slog;
 
 import com.android.server.credentials.MetricUtilities;
+import com.android.server.credentials.metrics.shared.ResponseCollective;
 
-import java.util.stream.Collectors;
+import java.util.LinkedHashMap;
+import java.util.Map;
 
 /**
  * Provides contextual metric collection for objects generated from
@@ -68,7 +72,7 @@
         try {
             mCandidatePhasePerProviderMetric.setFrameworkException(exceptionType);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during candidate exception metric logging: " + e);
         }
     }
 
@@ -97,7 +101,7 @@
                                 .getMetricCode());
             }
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during candidate update metric logging: " + e);
         }
     }
 
@@ -118,7 +122,7 @@
                     initMetric.getCredentialServiceStartedTimeNanoseconds());
             mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime());
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during candidate setup metric logging: " + e);
         }
     }
 
@@ -138,59 +142,52 @@
                 beginCreateCredentialResponseCollectionCandidateEntryMetrics(
                         (BeginCreateCredentialResponse) response);
             } else {
-                Log.i(TAG, "Your response type is unsupported for metric logging");
+                Slog.i(TAG, "Your response type is unsupported for metric logging");
             }
-
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during candidate entry metric logging: " + e);
         }
     }
 
     private void beginCreateCredentialResponseCollectionCandidateEntryMetrics(
             BeginCreateCredentialResponse response) {
+        Map<EntryEnum, Integer> entryCounts = new LinkedHashMap<>();
         var createEntries = response.getCreateEntries();
-        int numRemoteEntry = MetricUtilities.ZERO;
-        if (response.getRemoteCreateEntry() != null) {
-            numRemoteEntry = MetricUtilities.UNIT;
-            mCandidatePhasePerProviderMetric.addEntry(EntryEnum.REMOTE_ENTRY);
-        }
-        int numCreateEntries =
-                createEntries == null ? MetricUtilities.ZERO : createEntries.size();
-        if (numCreateEntries > MetricUtilities.ZERO) {
-            createEntries.forEach(c ->
-                    mCandidatePhasePerProviderMetric.addEntry(EntryEnum.CREDENTIAL_ENTRY));
-        }
-        mCandidatePhasePerProviderMetric.setNumEntriesTotal(numCreateEntries + numRemoteEntry);
-        mCandidatePhasePerProviderMetric.setRemoteEntryCount(numRemoteEntry);
-        mCandidatePhasePerProviderMetric.setCredentialEntryCount(numCreateEntries);
-        mCandidatePhasePerProviderMetric.setCredentialEntryTypeCount(MetricUtilities.UNIT);
+        int numRemoteEntry = response.getRemoteCreateEntry() != null ? MetricUtilities.ZERO :
+                MetricUtilities.UNIT;
+        int numCreateEntries = createEntries.size();
+        entryCounts.put(EntryEnum.REMOTE_ENTRY, numRemoteEntry);
+        entryCounts.put(EntryEnum.CREDENTIAL_ENTRY, numCreateEntries);
+
+        Map<String, Integer> responseCounts = new LinkedHashMap<>();
+        responseCounts.put(MetricUtilities.DEFAULT_STRING, numCreateEntries);
+        // We don't store create response because it's directly related to the request
+        // We do still store the count, however
+
+        ResponseCollective responseCollective = new ResponseCollective(responseCounts, entryCounts);
+        mCandidatePhasePerProviderMetric.setResponseCollective(responseCollective);
     }
 
     private void beginGetCredentialResponseCollectionCandidateEntryMetrics(
             BeginGetCredentialResponse response) {
+        Map<EntryEnum, Integer> entryCounts = new LinkedHashMap<>();
+        Map<String, Integer> responseCounts = new LinkedHashMap<>();
         int numCredEntries = response.getCredentialEntries().size();
         int numActionEntries = response.getActions().size();
         int numAuthEntries = response.getAuthenticationActions().size();
-        int numRemoteEntry = MetricUtilities.ZERO;
-        if (response.getRemoteCredentialEntry() != null) {
-            numRemoteEntry = MetricUtilities.UNIT;
-            mCandidatePhasePerProviderMetric.addEntry(EntryEnum.REMOTE_ENTRY);
-        }
-        response.getCredentialEntries().forEach(c ->
-                mCandidatePhasePerProviderMetric.addEntry(EntryEnum.CREDENTIAL_ENTRY));
-        response.getActions().forEach(c ->
-                mCandidatePhasePerProviderMetric.addEntry(EntryEnum.ACTION_ENTRY));
-        response.getAuthenticationActions().forEach(c ->
-                mCandidatePhasePerProviderMetric.addEntry(EntryEnum.AUTHENTICATION_ENTRY));
-        mCandidatePhasePerProviderMetric.setNumEntriesTotal(numCredEntries + numAuthEntries
-                + numActionEntries + numRemoteEntry);
-        mCandidatePhasePerProviderMetric.setCredentialEntryCount(numCredEntries);
-        int numTypes = (response.getCredentialEntries().stream()
-                .map(CredentialEntry::getType).collect(
-                        Collectors.toSet())).size(); // Dedupe type strings
-        mCandidatePhasePerProviderMetric.setCredentialEntryTypeCount(numTypes);
-        mCandidatePhasePerProviderMetric.setActionEntryCount(numActionEntries);
-        mCandidatePhasePerProviderMetric.setAuthenticationEntryCount(numAuthEntries);
-        mCandidatePhasePerProviderMetric.setRemoteEntryCount(numRemoteEntry);
+        int numRemoteEntry = response.getRemoteCredentialEntry() != null ? MetricUtilities.ZERO :
+                MetricUtilities.UNIT;
+        entryCounts.put(EntryEnum.REMOTE_ENTRY, numRemoteEntry);
+        entryCounts.put(EntryEnum.CREDENTIAL_ENTRY, numCredEntries);
+        entryCounts.put(EntryEnum.ACTION_ENTRY, numActionEntries);
+        entryCounts.put(EntryEnum.AUTHENTICATION_ENTRY, numAuthEntries);
+
+        response.getCredentialEntries().forEach(entry -> {
+            String entryKey = generateMetricKey(entry.getType(), DELTA_CUT);
+            responseCounts.put(entryKey, responseCounts.getOrDefault(entryKey, 0) + 1);
+        });
+
+        ResponseCollective responseCollective = new ResponseCollective(responseCounts, entryCounts);
+        mCandidatePhasePerProviderMetric.setResponseCollective(responseCollective);
     }
 }
diff --git a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
index 547c09a..4624e0b 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
@@ -24,7 +24,7 @@
 import android.credentials.GetCredentialRequest;
 import android.credentials.ui.UserSelectionDialogResult;
 import android.os.IBinder;
-import android.util.Log;
+import android.util.Slog;
 
 import com.android.server.credentials.ProviderSession;
 
@@ -90,7 +90,7 @@
             mInitialPhaseMetric.setCallerUid(mCallingUid);
             mInitialPhaseMetric.setApiName(metricCode);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error collecting initial metrics: " + e);
         }
     }
 
@@ -103,7 +103,7 @@
         try {
             mChosenProviderFinalPhaseMetric.setUiReturned(uiReturned);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error collecting ui end time metric: " + e);
         }
     }
 
@@ -116,7 +116,7 @@
         try {
             mChosenProviderFinalPhaseMetric.setUiCallStartTimeNanoseconds(uiCallStartTime);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error collecting ui start metric: " + e);
         }
     }
 
@@ -132,7 +132,7 @@
             mChosenProviderFinalPhaseMetric.setUiReturned(uiReturned);
             mChosenProviderFinalPhaseMetric.setUiCallEndTimeNanoseconds(uiEndTimestamp);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error collecting ui response metric: " + e);
         }
     }
 
@@ -146,7 +146,7 @@
         try {
             mChosenProviderFinalPhaseMetric.setChosenProviderStatus(status);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error setting chosen provider status metric: " + e);
         }
     }
 
@@ -159,7 +159,7 @@
         try {
             mInitialPhaseMetric.setOriginSpecified(origin);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error collecting create flow metric: " + e);
         }
     }
 
@@ -175,7 +175,7 @@
                 uniqueRequestCounts.put(optionKey, uniqueRequestCounts.get(optionKey) + 1);
             });
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during get request metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during get request metric logging: " + e);
         }
         return uniqueRequestCounts;
     }
@@ -190,7 +190,7 @@
             mInitialPhaseMetric.setOriginSpecified(request.getOrigin() != null);
             mInitialPhaseMetric.setRequestCounts(getRequestCountMap(request));
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error collecting get flow metric: " + e);
         }
     }
 
@@ -213,7 +213,7 @@
             browsingPhaseMetric.setProviderUid(selectedProviderPhaseMetric.getCandidateUid());
             mCandidateBrowsingPhaseMetric.add(browsingPhaseMetric);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error collecting browsing metric: " + e);
         }
     }
 
@@ -226,7 +226,7 @@
         try {
             mChosenProviderFinalPhaseMetric.setHasException(exceptionBitFinalPhase);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error setting final exception metric: " + e);
         }
     }
 
@@ -244,7 +244,7 @@
             mChosenProviderFinalPhaseMetric.setChosenProviderStatus(
                     finalStatus.getMetricCode());
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during metric logging: " + e);
         }
     }
 
@@ -272,24 +272,11 @@
                     candidatePhaseMetric.getStartQueryTimeNanoseconds());
             mChosenProviderFinalPhaseMetric.setQueryEndTimeNanoseconds(candidatePhaseMetric
                     .getQueryFinishTimeNanoseconds());
-
-            mChosenProviderFinalPhaseMetric.setNumEntriesTotal(candidatePhaseMetric
-                    .getNumEntriesTotal());
-            mChosenProviderFinalPhaseMetric.setCredentialEntryCount(candidatePhaseMetric
-                    .getCredentialEntryCount());
-            mChosenProviderFinalPhaseMetric.setCredentialEntryTypeCount(
-                    candidatePhaseMetric.getCredentialEntryTypeCount());
-            mChosenProviderFinalPhaseMetric.setActionEntryCount(candidatePhaseMetric
-                    .getActionEntryCount());
-            mChosenProviderFinalPhaseMetric.setRemoteEntryCount(candidatePhaseMetric
-                    .getRemoteEntryCount());
-            mChosenProviderFinalPhaseMetric.setAuthenticationEntryCount(
-                    candidatePhaseMetric.getAuthenticationEntryCount());
-            mChosenProviderFinalPhaseMetric.setAvailableEntries(candidatePhaseMetric
-                    .getAvailableEntries());
+            mChosenProviderFinalPhaseMetric.setResponseCollective(
+                    candidatePhaseMetric.getResponseCollective());
             mChosenProviderFinalPhaseMetric.setFinalFinishTimeNanoseconds(System.nanoTime());
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during metric candidate to final transfer: " + e);
         }
     }
 
@@ -312,7 +299,7 @@
                         /* apiStatus */ ApiStatus.FAILURE.getMetricCode());
             }
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during final metric failure emit: " + e);
         }
     }
 
@@ -326,7 +313,7 @@
         try {
             logApiCalledCandidatePhase(providers, ++mSequenceCounter, mInitialPhaseMetric);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during candidate metric emit: " + e);
         }
     }
 
@@ -337,15 +324,11 @@
      */
     public void logApiCalledAtFinish(int apiStatus) {
         try {
-            // TODO (b/270403549) - this browsing phase object is fine but also have a new emit
-            // For the returned types by authentication entries - i.e. a CandidatePhase During
-            // Browse
-            // Possibly think of adding in more atoms for other APIs as well.
             logApiCalledFinalPhase(mChosenProviderFinalPhaseMetric, mCandidateBrowsingPhaseMetric,
                     apiStatus,
                     ++mSequenceCounter);
         } catch (Exception e) {
-            Log.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during final metric emit: " + e);
         }
     }
 
diff --git a/services/credentials/java/com/android/server/credentials/metrics/shared/ResponseCollective.java b/services/credentials/java/com/android/server/credentials/metrics/shared/ResponseCollective.java
new file mode 100644
index 0000000..fd785c2
--- /dev/null
+++ b/services/credentials/java/com/android/server/credentials/metrics/shared/ResponseCollective.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.server.credentials.metrics.shared;
+
+import android.annotation.NonNull;
+
+import com.android.server.credentials.metrics.EntryEnum;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Some data is directly shared between the
+ * {@link com.android.server.credentials.metrics.CandidatePhaseMetric} and the
+ * {@link com.android.server.credentials.metrics.ChosenProviderFinalPhaseMetric}. This
+ * aims to create an abstraction that holds that information, to avoid duplication.
+ *
+ * This class should be immutable and threadsafe once generated.
+ */
+public class ResponseCollective {
+    /*
+    Abstract Function (responseCounts, entryCounts) -> A 'ResponseCollective' containing information
+    about a chosen or candidate providers available responses, be they entries or credentials.
+
+    RepInvariant: mResponseCounts and mEntryCounts are always initialized
+
+    Threadsafe and Immutability: Once generated, the maps remain unchangeable. The object is
+    threadsafe and immutable, and safe from external changes. This is threadsafe because it is
+    immutable after creation and only allows reads, not writes.
+    */
+
+    private static final String TAG = "ResponseCollective";
+
+    // Stores the deduped credential response information, eg {"response":5} for this provider
+    private final Map<String, Integer> mResponseCounts;
+    // Stores the deduped entry information, eg {ENTRY_ENUM:5} for this provider
+    private final Map<EntryEnum, Integer> mEntryCounts;
+
+    public ResponseCollective(@NonNull Map<String, Integer> responseCounts,
+            @NonNull Map<EntryEnum, Integer> entryCounts) {
+        mResponseCounts = responseCounts == null ? new LinkedHashMap<>() :
+                new LinkedHashMap<>(responseCounts);
+        mEntryCounts = entryCounts == null ? new LinkedHashMap<>() :
+                new LinkedHashMap<>(entryCounts);
+    }
+
+    /**
+     * Returns the unique, deduped, response classtypes for logging associated with this provider.
+     *
+     * @return a string array for deduped classtypes
+     */
+    public String[] getUniqueResponseStrings() {
+        String[] result = new String[mResponseCounts.keySet().size()];
+        mResponseCounts.keySet().toArray(result);
+        return result;
+    }
+
+    /**
+     * Returns the unique, deduped, response classtype counts for logging associated with this
+     * provider.
+     * @return a string array for deduped classtype counts
+     */
+    public int[] getUniqueResponseCounts() {
+        return mResponseCounts.values().stream().mapToInt(Integer::intValue).toArray();
+    }
+
+    /**
+     * Returns the unique, deduped, entry types for logging associated with this provider.
+     * @return an int array for deduped entries
+     */
+    public int[] getUniqueEntries() {
+        return mEntryCounts.keySet().stream().mapToInt(Enum::ordinal).toArray();
+    }
+
+    /**
+     * Returns the unique, deduped, entry classtype counts for logging associated with this
+     * provider.
+     * @return a string array for deduped classtype counts
+     */
+    public int[] getUniqueEntryCounts() {
+        return mEntryCounts.values().stream().mapToInt(Integer::intValue).toArray();
+    }
+
+    /**
+     * Given a specific {@link EntryEnum}, this provides us with the count of that entry within
+     * this particular provider.
+     * @param e the entry enum with which we want to know the count of
+     * @return a count of this particular entry enum stored by this provider
+     */
+    public int getCountForEntry(EntryEnum e) {
+        return mEntryCounts.get(e);
+    }
+
+    /**
+     * Indicates the total number of existing entries for this provider.
+     * @return a count of the total number of entries for this provider
+     */
+    public int getNumEntriesTotal() {
+        return mEntryCounts.values().stream().mapToInt(Integer::intValue).sum();
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
index 80100a9..c681b88 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
@@ -19,13 +19,13 @@
 import android.app.admin.DevicePolicyCache;
 import android.app.admin.DevicePolicyManager;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.IndentingPrintWriter;
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -55,8 +55,7 @@
     private final SparseIntArray mPermissionPolicy = new SparseIntArray();
 
     @GuardedBy("mLock")
-    private List<String> mLauncherShortcutOverrides =
-            new ArrayList<>();
+    private ArrayMap<String, String> mLauncherShortcutOverrides = new ArrayMap<>();
 
 
     /** Maps to {@code ActiveAdmin.mAdminCanGrantSensorsPermissions}. */
@@ -130,18 +129,20 @@
     }
 
     @Override
-    public List<String> getLauncherShortcutOverrides() {
+    public Map<String, String> getLauncherShortcutOverrides() {
         synchronized (mLock) {
-            return new ArrayList<>(mLauncherShortcutOverrides);
+            return new ArrayMap<>(mLauncherShortcutOverrides);
         }
     }
 
     /**
-     * Sets a list of packages for which shortcuts should be replaced by their badged version.
+     * Sets a map of packages names to package names, for which all launcher shortcuts which
+     * match a key package name should be modified to launch the corresponding value package
+     * name in the managed profile. The overridden shortcut should be badged accordingly.
      */
-    public void setLauncherShortcutOverrides(List<String> launcherShortcutOverrides) {
+    public void setLauncherShortcutOverrides(ArrayMap<String, String> launcherShortcutOverrides) {
         synchronized (mLock) {
-            mLauncherShortcutOverrides = new ArrayList<>(launcherShortcutOverrides);
+            mLauncherShortcutOverrides = new ArrayMap<>(launcherShortcutOverrides);
         }
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index 415440b..cf49dcf 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -130,12 +130,11 @@
     <V> void setLocalPolicy(
             @NonNull PolicyDefinition<V> policyDefinition,
             @NonNull EnforcingAdmin enforcingAdmin,
-            @NonNull PolicyValue<V> value,
+            @Nullable PolicyValue<V> value,
             int userId,
             boolean skipEnforcePolicy) {
         Objects.requireNonNull(policyDefinition);
         Objects.requireNonNull(enforcingAdmin);
-        Objects.requireNonNull(value);
 
         synchronized (mLock) {
             PolicyState<V> localPolicyState = getLocalPolicyStateLocked(policyDefinition, userId);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4d739d2..675ebd3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -80,6 +80,7 @@
 import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WINDOWS;
 import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIPE_DATA;
 import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
+import static android.Manifest.permission.MASTER_CLEAR;
 import static android.Manifest.permission.QUERY_ADMIN_POLICY;
 import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
 import static android.Manifest.permission.SET_TIME;
@@ -520,6 +521,7 @@
 import java.security.cert.X509Certificate;
 import java.text.DateFormat;
 import java.time.LocalDate;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -532,6 +534,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
@@ -567,7 +570,15 @@
 
     private static final int REQUEST_PROFILE_OFF_DEADLINE = 5572;
 
+    // Binary XML serializer doesn't support longer strings
+    private static final int MAX_POLICY_STRING_LENGTH = 65535;
+    // FrameworkParsingPackageUtils#MAX_FILE_NAME_SIZE, Android packages are used in dir names.
+    private static final int MAX_PACKAGE_NAME_LENGTH = 223;
+
     private static final int MAX_PROFILE_NAME_LENGTH = 200;
+    private static final int MAX_LONG_SUPPORT_MESSAGE_LENGTH = 20000;
+    private static final int MAX_SHORT_SUPPORT_MESSAGE_LENGTH = 200;
+    private static final int MAX_ORG_NAME_LENGTH = 200;
 
     private static final long MS_PER_DAY = TimeUnit.DAYS.toMillis(1);
 
@@ -863,7 +874,7 @@
 
     // TODO(b/265683382) remove the flag after rollout.
     private static final String KEEP_PROFILES_RUNNING_FLAG = "enable_keep_profiles_running";
-    private static final boolean DEFAULT_KEEP_PROFILES_RUNNING_FLAG = false;
+    private static final boolean DEFAULT_KEEP_PROFILES_RUNNING_FLAG = true;
 
     private static final String ENABLE_WORK_PROFILE_TELEPHONY_FLAG =
             "enable_work_profile_telephony";
@@ -3575,7 +3586,9 @@
     void handleStartUser(int userId) {
         synchronized (getLockObject()) {
             pushScreenCapturePolicy(userId);
-            pushUserControlDisabledPackagesLocked(userId);
+            if (!isPolicyEngineForFinanceFlagEnabled()) {
+                pushUserControlDisabledPackagesLocked(userId);
+            }
         }
         pushUserRestrictions(userId);
         // When system user is started (device boot), load cache for all users.
@@ -5865,8 +5878,7 @@
                 // would allow bypassing of the maximum time to lock.
                 mInjector.settingsGlobalPutInt(Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
             }
-            getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
-                    UserHandle.USER_SYSTEM, timeMs);
+            getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(parentId, timeMs);
         });
     }
 
@@ -7514,6 +7526,7 @@
         boolean success = false;
         try {
             if (getCurrentForegroundUserId() == userId) {
+                // TODO: We need to special case headless here as we can't switch to the system user
                 mInjector.getIActivityManager().switchUser(UserHandle.USER_SYSTEM);
             }
 
@@ -7521,7 +7534,8 @@
             if (!success) {
                 Slogf.w(LOG_TAG, "Couldn't remove user " + userId);
             } else if (isManagedProfile(userId) && !wipeSilently) {
-                sendWipeProfileNotification(wipeReasonForUser);
+                sendWipeProfileNotification(wipeReasonForUser,
+                        UserHandle.of(getProfileParentId(userId)));
             }
         } catch (RemoteException re) {
             // Shouldn't happen
@@ -7549,9 +7563,9 @@
         boolean calledByProfileOwnerOnOrgOwnedDevice =
                 isProfileOwnerOfOrganizationOwnedDevice(caller.getUserId());
         if (isPolicyEngineForFinanceFlagEnabled()) {
-            EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
+            EnforcingAdmin enforcingAdmin = enforcePermissionsAndGetEnforcingAdmin(
                     /*admin=*/ null,
-                    /*permission= */ MANAGE_DEVICE_POLICY_WIPE_DATA,
+                    /*permission=*/ new String[]{MANAGE_DEVICE_POLICY_WIPE_DATA, MASTER_CLEAR},
                     USES_POLICY_WIPE_DATA,
                     caller.getPackageName(),
                     factoryReset ? UserHandle.USER_ALL : getAffectedUser(calledOnParentInstance));
@@ -7573,12 +7587,13 @@
                 admin = getActiveAdminWithPolicyForUidLocked(/* who= */ null,
                         DeviceAdminInfo.USES_POLICY_WIPE_DATA, caller.getUid());
             }
+            Preconditions.checkCallAuthorization(
+                    (admin != null) || hasCallingOrSelfPermission(permission.MASTER_CLEAR),
+                    "No active admin for user %d and caller %d does not hold MASTER_CLEAR "
+                            + "permission",
+                    caller.getUserId(), caller.getUid());
         }
 
-        Preconditions.checkCallAuthorization(
-                (admin != null) || hasCallingOrSelfPermission(permission.MASTER_CLEAR),
-                "No active admin for user %d and caller %d does not hold MASTER_CLEAR permission",
-                caller.getUserId(), caller.getUid());
         checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_WIPE_DATA);
 
         if (TextUtils.isEmpty(wipeReasonForUser)) {
@@ -7718,7 +7733,7 @@
     }
 
     private void clearLauncherShortcutOverrides() {
-        mPolicyCache.setLauncherShortcutOverrides(new ArrayList<>());
+        mPolicyCache.setLauncherShortcutOverrides(new ArrayMap<>());
     }
 
     private void updateTelephonyCrossProfileIntentFilters(int parentUserId, int profileUserId,
@@ -7833,15 +7848,14 @@
             } else {
                 // Explicit behaviour
                 if (factoryReset) {
-                    // TODO(b/254031494) Replace with new factory reset permission checks
-                    if (!isPermissionCheckFlagEnabled()) {
-                        boolean hasPermission = isDeviceOwnerUserId(userId)
-                                || (isOrganizationOwnedDeviceWithManagedProfile()
-                                && calledOnParentInstance);
-                        Preconditions.checkCallAuthorization(hasPermission,
-                                "Admin %s does not have permission to factory reset the device.",
-                                userId);
-                    }
+                    EnforcingAdmin enforcingAdmin = enforcePermissionsAndGetEnforcingAdmin(
+                            /*admin=*/ null,
+                            /*permission=*/ new String[]{MANAGE_DEVICE_POLICY_WIPE_DATA,
+                                    MASTER_CLEAR},
+                            USES_POLICY_WIPE_DATA,
+                            adminPackage,
+                            factoryReset ? UserHandle.USER_ALL :
+                                    getAffectedUser(calledOnParentInstance));
                     wipeDevice = true;
                 } else {
                     Preconditions.checkCallAuthorization(!isSystemUser,
@@ -7869,7 +7883,7 @@
         });
     }
 
-    private void sendWipeProfileNotification(String wipeReasonForUser) {
+    private void sendWipeProfileNotification(String wipeReasonForUser, UserHandle user) {
         Notification notification =
                 new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN)
                         .setSmallIcon(android.R.drawable.stat_sys_warning)
@@ -7878,7 +7892,8 @@
                         .setColor(mContext.getColor(R.color.system_notification_accent_color))
                         .setStyle(new Notification.BigTextStyle().bigText(wipeReasonForUser))
                         .build();
-        mInjector.getNotificationManager().notify(SystemMessage.NOTE_PROFILE_WIPED, notification);
+        mInjector.getNotificationManager().notifyAsUser(
+                /* tag= */ null, SystemMessage.NOTE_PROFILE_WIPED, notification, user);
     }
 
     private String getWorkProfileDeletedTitle() {
@@ -9199,9 +9214,15 @@
                     MANAGE_DEVICE_POLICY_CAMERA,
                     caller.getPackageName(),
                     getProfileParentUserIfRequested(userId, parent));
-
-            setBackwardCompatibleUserRestriction(
-                    caller, enforcingAdmin, UserManager.DISALLOW_CAMERA, disabled, parent);
+            try {
+                setBackwardCompatibleUserRestriction(
+                        caller, enforcingAdmin, UserManager.DISALLOW_CAMERA, disabled, parent);
+            } catch (IllegalStateException e) {
+                throw new IllegalStateException(
+                        "Please use addUserRestriction or addUserRestrictionGlobally using the key"
+                                + " UserManager.DISALLOW_CAMERA to disable the camera locally or"
+                                + " globally, respectively");
+            }
         } else {
             Objects.requireNonNull(who, "ComponentName is null");
             if (parent) {
@@ -10057,7 +10078,9 @@
         setNetworkLoggingActiveInternal(false);
         deleteTransferOwnershipBundleLocked(userId);
         toggleBackupServiceActive(UserHandle.USER_SYSTEM, true);
-        pushUserControlDisabledPackagesLocked(userId);
+        if (!isPolicyEngineForFinanceFlagEnabled()) {
+            pushUserControlDisabledPackagesLocked(userId);
+        }
         setGlobalSettingDeviceOwnerType(DEVICE_OWNER_TYPE_DEFAULT);
 
         if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) {
@@ -11717,7 +11740,15 @@
         }
 
         Objects.requireNonNull(agent, "agent is null");
-        int userHandle = UserHandle.getCallingUserId();
+
+        enforceMaxPackageNameLength(agent.getPackageName());
+        final String agentAsString = agent.flattenToString();
+        enforceMaxStringLength(agentAsString, "agent name");
+        if (args != null) {
+            enforceMaxStringLength(args, "args");
+        }
+
+        int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (getLockObject()) {
             ActiveAdmin ap;
             if (isPermissionCheckFlagEnabled()) {
@@ -11734,7 +11765,7 @@
             checkCanExecuteOrThrowUnsafe(
                     DevicePolicyManager.OPERATION_SET_TRUST_AGENT_CONFIGURATION);
 
-            ap.trustAgentInfos.put(agent.flattenToString(), new TrustAgentInfo(args));
+            ap.trustAgentInfos.put(agentAsString, new TrustAgentInfo(args));
             saveSettingsLocked(userHandle);
         }
     }
@@ -12004,6 +12035,10 @@
                 isDeviceOwner(caller) || isProfileOwner(caller));
 
         if (packageList != null) {
+            for (String pkg : packageList) {
+                enforceMaxPackageNameLength(pkg);
+            }
+
             int userId = caller.getUserId();
             final List<AccessibilityServiceInfo> enabledServices;
             long id = mInjector.binderClearCallingIdentity();
@@ -12161,7 +12196,7 @@
         }
 
         CallerIdentity caller;
-        if (isPermissionCheckFlagEnabled()) {
+        if (isPolicyEngineForFinanceFlagEnabled()) {
             caller = getCallerIdentity(who, callerPackageName);
         } else {
             caller = getCallerIdentity(who);
@@ -12171,7 +12206,7 @@
         int userId = getProfileParentUserIfRequested(
                 caller.getUserId(), calledOnParentInstance);
         if (calledOnParentInstance) {
-            if (!isPermissionCheckFlagEnabled()) {
+            if (!isPolicyEngineForFinanceFlagEnabled()) {
                 Preconditions.checkCallAuthorization(
                         isProfileOwnerOfOrganizationOwnedDevice(caller));
             }
@@ -12179,12 +12214,16 @@
                     "Permitted input methods must allow all input methods or only "
                             + "system input methods when called on the parent instance of an "
                             + "organization-owned device");
-        } else if (!isPermissionCheckFlagEnabled()) {
+        } else if (!isPolicyEngineForFinanceFlagEnabled()) {
             Preconditions.checkCallAuthorization(
                     isDefaultDeviceOwner(caller) || isProfileOwner(caller));
         }
 
         if (packageList != null) {
+            for (String pkg : packageList) {
+                enforceMaxPackageNameLength(pkg);
+            }
+
             List<InputMethodInfo> enabledImes = mInjector.binderWithCleanCallingIdentity(() ->
                     InputMethodManagerInternal.get().getEnabledInputMethodListAsUser(userId));
             if (enabledImes != null) {
@@ -12202,17 +12241,24 @@
         }
 
         synchronized (getLockObject()) {
-            ActiveAdmin admin;
-            if (isPermissionCheckFlagEnabled()) {
-                admin = enforcePermissionAndGetEnforcingAdmin(
+            if (isPolicyEngineForFinanceFlagEnabled()) {
+                EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(
                         who, MANAGE_DEVICE_POLICY_INPUT_METHODS,
-                        caller.getPackageName(), userId).getActiveAdmin();
+                        caller.getPackageName(), userId);
+                mDevicePolicyEngine.setLocalPolicy(
+                        PolicyDefinition.PERMITTED_INPUT_METHODS,
+                        admin,
+                        packageList == null
+                                ? null
+                                : new StringSetPolicyValue(new HashSet<>(packageList)),
+                        userId);
             } else {
-                admin = getParentOfAdminIfRequired(
-                        getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), calledOnParentInstance);
+                ActiveAdmin admin = getParentOfAdminIfRequired(
+                        getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()),
+                        calledOnParentInstance);
+                admin.permittedInputMethods = packageList;
+                saveSettingsLocked(caller.getUserId());
             }
-            admin.permittedInputMethods = packageList;
-            saveSettingsLocked(caller.getUserId());
         }
 
         DevicePolicyEventLogger
@@ -12260,19 +12306,18 @@
         }
 
         synchronized (getLockObject()) {
-            ActiveAdmin admin;
-            if (isPermissionCheckFlagEnabled()) {
+            if (isPolicyEngineForFinanceFlagEnabled()) {
                 int affectedUser = calledOnParentInstance ? getProfileParentId(
                         caller.getUserId()) : caller.getUserId();
-                admin = enforcePermissionAndGetEnforcingAdmin(
-                        who, MANAGE_DEVICE_POLICY_INPUT_METHODS, caller.getPackageName(),
-                        affectedUser).getActiveAdmin();
+                Set<String> policy = mDevicePolicyEngine.getResolvedPolicy(
+                        PolicyDefinition.PERMITTED_INPUT_METHODS, affectedUser);
+                return policy == null ? null : new ArrayList<>(policy);
             } else {
-                admin = getParentOfAdminIfRequired(
+                ActiveAdmin admin = getParentOfAdminIfRequired(
                         getProfileOwnerOrDeviceOwnerLocked(
                                 caller.getUserId()), calledOnParentInstance);
+                return admin.permittedInputMethods;
             }
-            return admin.permittedInputMethods;
         }
     }
 
@@ -12290,37 +12335,45 @@
     }
 
     private @Nullable List<String> getPermittedInputMethodsUnchecked(@UserIdInt int userId) {
-        synchronized (getLockObject()) {
-            List<String> result = null;
-            // Only device or profile owners can have permitted lists set.
-            List<ActiveAdmin> admins = getActiveAdminsForAffectedUserInclPermissionBasedAdminLocked(userId);
-            for (ActiveAdmin admin: admins) {
-                List<String> fromAdmin = admin.permittedInputMethods;
-                if (fromAdmin != null) {
-                    if (result == null) {
-                        result = new ArrayList<String>(fromAdmin);
-                    } else {
-                        result.retainAll(fromAdmin);
-                    }
-                }
-            }
-
-            // If we have a permitted list add all system input methods.
-            if (result != null) {
-                List<InputMethodInfo> imes = InputMethodManagerInternal
-                        .get().getInputMethodListAsUser(userId);
-                if (imes != null) {
-                    for (InputMethodInfo ime : imes) {
-                        ServiceInfo serviceInfo = ime.getServiceInfo();
-                        ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
-                        if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-                            result.add(serviceInfo.packageName);
+        List<String> result = null;
+        if (isPolicyEngineForFinanceFlagEnabled()) {
+            Set<String> policy = mDevicePolicyEngine.getResolvedPolicy(
+                    PolicyDefinition.PERMITTED_INPUT_METHODS, userId);
+            result = policy == null ? null : new ArrayList<>(policy);
+        } else {
+            synchronized (getLockObject()) {
+                // Only device or profile owners can have permitted lists set.
+                List<ActiveAdmin> admins =
+                        getActiveAdminsForAffectedUserInclPermissionBasedAdminLocked(
+                                userId);
+                for (ActiveAdmin admin : admins) {
+                    List<String> fromAdmin = admin.permittedInputMethods;
+                    if (fromAdmin != null) {
+                        if (result == null) {
+                            result = new ArrayList<String>(fromAdmin);
+                        } else {
+                            result.retainAll(fromAdmin);
                         }
                     }
                 }
             }
-            return result;
         }
+
+        // If we have a permitted list add all system input methods.
+        if (result != null) {
+            List<InputMethodInfo> imes = InputMethodManagerInternal
+                    .get().getInputMethodListAsUser(userId);
+            if (imes != null) {
+                for (InputMethodInfo ime : imes) {
+                    ServiceInfo serviceInfo = ime.getServiceInfo();
+                    ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
+                    if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                        result.add(serviceInfo.packageName);
+                    }
+                }
+            }
+        }
+        return result;
     }
 
     @Override
@@ -12335,17 +12388,38 @@
                 String.format(NOT_SYSTEM_CALLER_MSG,
                         "query if an input method is disabled by admin"));
 
-        synchronized (getLockObject()) {
-            ActiveAdmin admin = getParentOfAdminIfRequired(
-                    getActiveAdminUncheckedLocked(who, userHandle), calledOnParentInstance);
-            if (admin == null) {
-                return false;
+        if (isPolicyEngineForFinanceFlagEnabled()) {
+            int affectedUser = calledOnParentInstance ? getProfileParentId(userHandle) : userHandle;
+            Map<EnforcingAdmin, PolicyValue<Set<String>>> policies =
+                    mDevicePolicyEngine.getLocalPoliciesSetByAdmins(
+                            PolicyDefinition.PERMITTED_INPUT_METHODS, affectedUser);
+            EnforcingAdmin admin = null;
+            for (EnforcingAdmin a : policies.keySet()) {
+                if (a.getPackageName().equals(who.getPackageName())) {
+                    if (policies.get(a).getValue() == null) {
+                        return true;
+                    } else {
+                        return checkPackagesInPermittedListOrSystem(
+                                Collections.singletonList(packageName),
+                                new ArrayList<>(policies.get(a).getValue()), affectedUser);
+                    }
+                }
             }
-            if (admin.permittedInputMethods == null) {
-                return true;
+            // Admin didn't set a policy
+            return false;
+        } else {
+            synchronized (getLockObject()) {
+                ActiveAdmin admin = getParentOfAdminIfRequired(
+                        getActiveAdminUncheckedLocked(who, userHandle), calledOnParentInstance);
+                if (admin == null) {
+                    return false;
+                }
+                if (admin.permittedInputMethods == null) {
+                    return true;
+                }
+                return checkPackagesInPermittedListOrSystem(Collections.singletonList(packageName),
+                        admin.permittedInputMethods, userHandle);
             }
-            return checkPackagesInPermittedListOrSystem(Collections.singletonList(packageName),
-                    admin.permittedInputMethods, userHandle);
         }
     }
 
@@ -13365,13 +13439,20 @@
     public void setUserRestrictionGlobally(String callerPackage, String key) {
         final CallerIdentity caller = getCallerIdentity(callerPackage);
 
+        EnforcingAdmin admin = enforcePermissionForUserRestriction(
+                /* who= */ null,
+                key,
+                caller.getPackageName(),
+                UserHandle.USER_ALL
+        );
+
         checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_USER_RESTRICTION);
 
         if (!isPolicyEngineForFinanceFlagEnabled()) {
             throw new IllegalStateException("Feature flag is not enabled.");
         }
         if (isDeviceOwner(caller) || isProfileOwner(caller)) {
-            throw new IllegalStateException("Admins are not allowed to call this API.");
+            throw new SecurityException("Admins are not allowed to call this API.");
         }
         if (!mInjector.isChangeEnabled(
                 ENABLE_COEXISTENCE_CHANGE, callerPackage, caller.getUserId())) {
@@ -13381,13 +13462,6 @@
             throw new IllegalArgumentException("Invalid restriction key: " + key);
         }
 
-        EnforcingAdmin admin = enforcePermissionForUserRestriction(
-                /* who= */ null,
-                key,
-                caller.getPackageName(),
-                UserHandle.USER_ALL
-        );
-
         setGlobalUserRestrictionInternal(admin, key, /* enabled= */ true);
 
         logUserRestrictionCall(key, /* enabled= */ true, /* parent= */ false, caller);
@@ -14036,6 +14110,9 @@
         if (!mHasFeature) {
             return;
         }
+
+        enforceMaxStringLength(accountType, "account type");
+
         CallerIdentity caller;
         if (isPermissionCheckFlagEnabled()) {
             caller = getCallerIdentity(who, callerPackageName);
@@ -14726,6 +14803,10 @@
     public void setLockTaskPackages(ComponentName who, String callerPackageName, String[] packages)
             throws SecurityException {
         Objects.requireNonNull(packages, "packages is null");
+        for (String pkg : packages) {
+            enforceMaxPackageNameLength(pkg);
+        }
+
         CallerIdentity caller;
         if (isPolicyEngineForFinanceFlagEnabled()) {
             caller = getCallerIdentity(who, callerPackageName);
@@ -14739,24 +14820,24 @@
             synchronized (getLockObject()) {
                 enforcingAdmin = enforceCanCallLockTaskLocked(who, caller.getPackageName());
             }
-            if (packages.length == 0) {
+            LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicySetByAdmin(
+                    PolicyDefinition.LOCK_TASK,
+                    enforcingAdmin,
+                    caller.getUserId());
+            LockTaskPolicy policy;
+            if (currentPolicy == null) {
+                policy = new LockTaskPolicy(Set.of(packages));
+            } else {
+                policy = new LockTaskPolicy(currentPolicy);
+                policy.setPackages(Set.of(packages));
+            }
+            if (policy.getPackages().isEmpty()
+                    && policy.getFlags() == DevicePolicyManager.LOCK_TASK_FEATURE_NONE) {
                 mDevicePolicyEngine.removeLocalPolicy(
                         PolicyDefinition.LOCK_TASK,
                         enforcingAdmin,
                         caller.getUserId());
             } else {
-                LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicySetByAdmin(
-                        PolicyDefinition.LOCK_TASK,
-                        enforcingAdmin,
-                        caller.getUserId());
-                LockTaskPolicy policy;
-                if (currentPolicy == null) {
-                    policy = new LockTaskPolicy(Set.of(packages));
-                } else {
-                    policy = new LockTaskPolicy(currentPolicy);
-                    policy.setPackages(Set.of(packages));
-                }
-
                 mDevicePolicyEngine.setLocalPolicy(
                         PolicyDefinition.LOCK_TASK,
                         enforcingAdmin,
@@ -14871,18 +14952,26 @@
                     PolicyDefinition.LOCK_TASK,
                     enforcingAdmin,
                     caller.getUserId());
+            LockTaskPolicy policy;
             if (currentPolicy == null) {
-                throw new IllegalArgumentException("Can't set a lock task flags without setting "
-                        + "lock task packages first.");
+                policy = new LockTaskPolicy(flags);
+            } else {
+                policy = new LockTaskPolicy(currentPolicy);
+                policy.setFlags(flags);
             }
-            LockTaskPolicy policy = new LockTaskPolicy(currentPolicy);
-            policy.setFlags(flags);
-
-            mDevicePolicyEngine.setLocalPolicy(
-                    PolicyDefinition.LOCK_TASK,
-                    enforcingAdmin,
-                    policy,
-                    caller.getUserId());
+            if (policy.getPackages().isEmpty()
+                    && policy.getFlags() == DevicePolicyManager.LOCK_TASK_FEATURE_NONE) {
+                mDevicePolicyEngine.removeLocalPolicy(
+                        PolicyDefinition.LOCK_TASK,
+                        enforcingAdmin,
+                        caller.getUserId());
+            } else {
+                mDevicePolicyEngine.setLocalPolicy(
+                        PolicyDefinition.LOCK_TASK,
+                        enforcingAdmin,
+                        policy,
+                        caller.getUserId());
+            }
         } else {
             Objects.requireNonNull(who, "ComponentName is null");
             synchronized (getLockObject()) {
@@ -14940,18 +15029,34 @@
                     continue;
                 }
 
-                final List<String> lockTaskPackages = getUserData(userId).mLockTaskPackages;
-                // TODO(b/278438525): handle in the policy engine
-                if (!lockTaskPackages.isEmpty()) {
-                    Slogf.d(LOG_TAG,
-                            "User id " + userId + " not affiliated. Clearing lock task packages");
-                    setLockTaskPackagesLocked(userId, Collections.<String>emptyList());
-                }
-                final int lockTaskFeatures = getUserData(userId).mLockTaskFeatures;
-                if (lockTaskFeatures != DevicePolicyManager.LOCK_TASK_FEATURE_NONE){
-                    Slogf.d(LOG_TAG,
-                            "User id " + userId + " not affiliated. Clearing lock task features");
-                    setLockTaskFeaturesLocked(userId, DevicePolicyManager.LOCK_TASK_FEATURE_NONE);
+                if (isPolicyEngineForFinanceFlagEnabled()) {
+                    Map<EnforcingAdmin, PolicyValue<LockTaskPolicy>> policies =
+                            mDevicePolicyEngine.getLocalPoliciesSetByAdmins(
+                                    PolicyDefinition.LOCK_TASK, userId);
+                    Set<EnforcingAdmin> admins = new HashSet<>(policies.keySet());
+                    for (EnforcingAdmin admin : admins) {
+                        if (admin.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)) {
+                            mDevicePolicyEngine.removeLocalPolicy(
+                                    PolicyDefinition.LOCK_TASK, admin, userId);
+                        }
+                    }
+                } else {
+                    final List<String> lockTaskPackages = getUserData(userId).mLockTaskPackages;
+                    // TODO(b/278438525): handle in the policy engine
+                    if (!lockTaskPackages.isEmpty()) {
+                        Slogf.d(LOG_TAG,
+                                "User id " + userId
+                                        + " not affiliated. Clearing lock task packages");
+                        setLockTaskPackagesLocked(userId, Collections.<String>emptyList());
+                    }
+                    final int lockTaskFeatures = getUserData(userId).mLockTaskFeatures;
+                    if (lockTaskFeatures != DevicePolicyManager.LOCK_TASK_FEATURE_NONE) {
+                        Slogf.d(LOG_TAG,
+                                "User id " + userId
+                                        + " not affiliated. Clearing lock task features");
+                        setLockTaskFeaturesLocked(userId,
+                                DevicePolicyManager.LOCK_TASK_FEATURE_NONE);
+                    }
                 }
             }
         });
@@ -15465,11 +15570,13 @@
 
         int userId = caller.getUserId();
         synchronized (getLockObject()) {
-            Preconditions.checkCallAuthorization(isUserAffiliatedWithDeviceLocked(userId),
-                    "Admin " + who
-                            + " is neither the device owner or affiliated user's profile owner.");
-            if (isManagedProfile(userId)) {
-                throw new SecurityException("Managed profile cannot disable status bar");
+            if (!isPermissionCheckFlagEnabled()) {
+                Preconditions.checkCallAuthorization(isUserAffiliatedWithDeviceLocked(userId),
+                        "Admin " + who + " is neither the device owner or affiliated "
+                                + "user's profile owner.");
+                if (isManagedProfile(userId)) {
+                    throw new SecurityException("Managed profile cannot disable status bar");
+                }
             }
             checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_STATUS_BAR_DISABLED);
 
@@ -15522,16 +15629,23 @@
     @Override
     public boolean isStatusBarDisabled(String callerPackage) {
         final CallerIdentity caller = getCallerIdentity(callerPackage);
-        Preconditions.checkCallAuthorization(
-                isProfileOwner(caller) || isDefaultDeviceOwner(caller));
+        if (isPermissionCheckFlagEnabled()) {
+            enforceCanQuery(
+                    MANAGE_DEVICE_POLICY_STATUS_BAR, caller.getPackageName(), caller.getUserId());
+        } else {
+            Preconditions.checkCallAuthorization(
+                    isProfileOwner(caller) || isDefaultDeviceOwner(caller));
+        }
 
         int userId = caller.getUserId();
         synchronized (getLockObject()) {
-            Preconditions.checkCallAuthorization(isUserAffiliatedWithDeviceLocked(userId),
-                    "Admin " + callerPackage
-                            + " is neither the device owner or affiliated user's profile owner.");
-            if (isManagedProfile(userId)) {
-                throw new SecurityException("Managed profile cannot disable status bar");
+            if (!isPermissionCheckFlagEnabled()) {
+                Preconditions.checkCallAuthorization(isUserAffiliatedWithDeviceLocked(userId),
+                        "Admin " + callerPackage
+                                + " is neither the device owner or affiliated user's profile owner.");
+                if (isManagedProfile(userId)) {
+                    throw new SecurityException("Managed profile cannot disable status bar");
+                }
             }
             DevicePolicyData policy = getUserData(userId);
             return policy.mStatusBarDisabled;
@@ -16177,17 +16291,13 @@
                         deviceOwner.second);
                 return result;
             }
-        } else if (DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction)
-                || DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE.equals(restriction)) {
+        } else if (DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE.equals(restriction)) {
             synchronized (getLockObject()) {
                 final DevicePolicyData policy = getUserData(userId);
                 final int N = policy.mAdminList.size();
                 for (int i = 0; i < N; i++) {
                     final ActiveAdmin admin = policy.mAdminList.get(i);
-                    if ((admin.disableCamera &&
-                            DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction))
-                            || (admin.disableScreenCapture && DevicePolicyManager
-                            .POLICY_DISABLE_SCREEN_CAPTURE.equals(restriction))) {
+                    if (admin.disableScreenCapture) {
                         result = new Bundle();
                         result.putInt(Intent.EXTRA_USER_ID, userId);
                         result.putParcelable(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
@@ -16195,17 +16305,44 @@
                         return result;
                     }
                 }
-                // For the camera, a device owner on a different user can disable it globally,
-                // so we need an additional check.
-                if (result == null
-                        && DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction)) {
-                    final ActiveAdmin admin = getDeviceOwnerAdminLocked();
-                    if (admin != null && admin.disableCamera) {
-                        result = new Bundle();
-                        result.putInt(Intent.EXTRA_USER_ID, mOwners.getDeviceOwnerUserId());
-                        result.putParcelable(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
-                                admin.info.getComponent());
-                        return result;
+            }
+        } else if (DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction)) {
+            if (isPolicyEngineForFinanceFlagEnabled()) {
+                PolicyDefinition<Boolean> policyDefinition =
+                        PolicyDefinition.getPolicyDefinitionForUserRestriction(
+                                UserManager.DISALLOW_CAMERA);
+                Boolean value = mDevicePolicyEngine.getResolvedPolicy(policyDefinition, userId);
+                if (value != null && value) {
+                    result = new Bundle();
+                    result.putInt(Intent.EXTRA_USER_ID, userId);
+                    return result;
+                }
+            } else {
+                synchronized (getLockObject()) {
+                    final DevicePolicyData policy = getUserData(userId);
+                    final int N = policy.mAdminList.size();
+                    for (int i = 0; i < N; i++) {
+                        final ActiveAdmin admin = policy.mAdminList.get(i);
+                        if (admin.disableCamera) {
+                            result = new Bundle();
+                            result.putInt(Intent.EXTRA_USER_ID, userId);
+                            result.putParcelable(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+                                    admin.info.getComponent());
+                            return result;
+                        }
+                    }
+                    // For the camera, a device owner on a different user can disable it globally,
+                    // so we need an additional check.
+                    if (result == null
+                            && DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction)) {
+                        final ActiveAdmin admin = getDeviceOwnerAdminLocked();
+                        if (admin != null && admin.disableCamera) {
+                            result = new Bundle();
+                            result.putInt(Intent.EXTRA_USER_ID, mOwners.getDeviceOwnerUserId());
+                            result.putParcelable(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+                                    admin.info.getComponent());
+                            return result;
+                        }
                     }
                 }
             }
@@ -16237,7 +16374,8 @@
                     // TODO(b/128928355): if this restriction is enforced by multiple DPCs, return
                     // the admin for the calling user.
                     Slogf.w(LOG_TAG, "getEnforcingAdminAndUserDetailsInternal(%d, %s): multiple "
-                            + "sources for restriction %s on user %d", restriction, userId);
+                            + "sources for restriction %s on user %d",
+                            userId, restriction, restriction, userId);
                     result = new Bundle();
                     result.putInt(Intent.EXTRA_USER_ID, userId);
                     return result;
@@ -16881,6 +17019,7 @@
                     } else {
                         granted = PackageManager.PERMISSION_GRANTED;
                     }
+
                 }
             }
         }
@@ -17271,6 +17410,8 @@
         CallerIdentity caller;
         ActiveAdmin admin;
 
+        message = truncateIfLonger(message, MAX_SHORT_SUPPORT_MESSAGE_LENGTH);
+
         if (isPermissionCheckFlagEnabled()) {
             caller = getCallerIdentity(who, callerPackageName);
             EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
@@ -17331,6 +17472,9 @@
         if (!mHasFeature) {
             return;
         }
+
+        message = truncateIfLonger(message, MAX_LONG_SUPPORT_MESSAGE_LENGTH);
+
         Objects.requireNonNull(who, "ComponentName is null");
         final CallerIdentity caller = getCallerIdentity(who);
         synchronized (getLockObject()) {
@@ -17495,6 +17639,8 @@
             Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
         }
 
+        text = truncateIfLonger(text, MAX_ORG_NAME_LENGTH);
+
         synchronized (getLockObject()) {
             if (!isPermissionCheckFlagEnabled()) {
                 admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
@@ -17775,9 +17921,8 @@
             throw new IllegalArgumentException("ids must not be null");
         }
         for (String id : ids) {
-            if (TextUtils.isEmpty(id)) {
-                throw new IllegalArgumentException("ids must not contain empty string");
-            }
+            Preconditions.checkArgument(!TextUtils.isEmpty(id), "ids must not have empty string");
+            enforceMaxStringLength(id, "affiliation id");
         }
 
         final Set<String> affiliationIds = new ArraySet<>(ids);
@@ -19290,6 +19435,9 @@
                 "Provided administrator and target are the same object.");
         Preconditions.checkArgument(!admin.getPackageName().equals(target.getPackageName()),
                 "Provided administrator and target have the same package name.");
+        if (bundle != null) {
+            enforceMaxStringLength(bundle, "bundle");
+        }
 
         final CallerIdentity caller = getCallerIdentity(admin);
         Preconditions.checkCallAuthorization(
@@ -19984,6 +20132,7 @@
         if (!mHasFeature) {
             return;
         }
+
         Objects.requireNonNull(who, "ComponentName is null");
         Objects.requireNonNull(packageNames, "Package names is null");
         final CallerIdentity caller = getCallerIdentity(who);
@@ -20000,9 +20149,12 @@
             saveSettingsLocked(caller.getUserId());
         }
         logSetCrossProfilePackages(who, packageNames);
-        final CrossProfileApps crossProfileApps = mContext.getSystemService(CrossProfileApps.class);
+        final CrossProfileApps crossProfileApps =
+                mContext.createContextAsUser(
+                        caller.getUserHandle(), /* flags= */ 0)
+                        .getSystemService(CrossProfileApps.class);
         mInjector.binderWithCleanCallingIdentity(
-                () -> crossProfileApps.resetInteractAcrossProfilesAppOps(
+        () -> crossProfileApps.resetInteractAcrossProfilesAppOps(
                         previousCrossProfilePackages, new HashSet<>(packageNames)));
     }
 
@@ -20142,9 +20294,20 @@
     }
 
     private boolean isLockTaskFeatureEnabled(int lockTaskFeature) throws RemoteException {
-        //TODO(b/175285301): Explicitly get the user's identity to check.
-        int lockTaskFeatures =
-                getUserData(getCurrentForegroundUserId()).mLockTaskFeatures;
+        int lockTaskFeatures = 0;
+        if (isPolicyEngineForFinanceFlagEnabled()) {
+            LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy(
+                    PolicyDefinition.LOCK_TASK, getCurrentForegroundUserId());
+            lockTaskFeatures = policy == null
+                    // We default on the power button menu, in order to be consistent with pre-P
+                    // behaviour.
+                    ? DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS
+                    : policy.getFlags();
+        } else {
+            //TODO(b/175285301): Explicitly get the user's identity to check.
+            lockTaskFeatures =
+                    getUserData(getCurrentForegroundUserId()).mLockTaskFeatures;
+        }
         return (lockTaskFeatures & lockTaskFeature) == lockTaskFeature;
     }
 
@@ -21529,7 +21692,7 @@
         }
         copyAccount(targetUser, sourceUser, accountToMigrate, callerPackage);
         if (!keepAccountMigrated) {
-            removeAccount(accountToMigrate);
+            removeAccount(accountToMigrate, sourceUserId);
         }
     }
 
@@ -21573,9 +21736,10 @@
                 .write();
     }
 
-    private void removeAccount(Account account) {
-        final AccountManager accountManager =
-                mContext.getSystemService(AccountManager.class);
+    private void removeAccount(Account account, @UserIdInt int sourceUserId) {
+        final AccountManager accountManager = mContext.createContextAsUser(
+                        UserHandle.of(sourceUserId), /* flags= */ 0)
+                .getSystemService(AccountManager.class);
         final AccountManagerFuture<Bundle> bundle = accountManager.removeAccount(account,
                 null, null /* callback */, null /* handler */);
         try {
@@ -22679,6 +22843,7 @@
             MANAGE_DEVICE_POLICY_DISPLAY,
             MANAGE_DEVICE_POLICY_FACTORY_RESET,
             MANAGE_DEVICE_POLICY_FUN,
+            MANAGE_DEVICE_POLICY_INPUT_METHODS,
             MANAGE_DEVICE_POLICY_INSTALL_UNKNOWN_SOURCES,
             MANAGE_DEVICE_POLICY_KEYGUARD,
             MANAGE_DEVICE_POLICY_LOCALE,
@@ -22753,9 +22918,12 @@
                     MANAGE_DEVICE_POLICY_AUTOFILL,
                     MANAGE_DEVICE_POLICY_BLUETOOTH,
                     MANAGE_DEVICE_POLICY_CALLS,
+                    MANAGE_DEVICE_POLICY_CAMERA,
+                    MANAGE_DEVICE_POLICY_CERTIFICATES,
                     MANAGE_DEVICE_POLICY_DEBUGGING_FEATURES,
                     MANAGE_DEVICE_POLICY_DISPLAY,
                     MANAGE_DEVICE_POLICY_FACTORY_RESET,
+                    MANAGE_DEVICE_POLICY_INPUT_METHODS,
                     MANAGE_DEVICE_POLICY_INSTALL_UNKNOWN_SOURCES,
                     MANAGE_DEVICE_POLICY_KEYGUARD,
                     MANAGE_DEVICE_POLICY_LOCALE,
@@ -22788,8 +22956,6 @@
                     MANAGE_DEVICE_POLICY_ACROSS_USERS,
                     MANAGE_DEVICE_POLICY_AIRPLANE_MODE,
                     MANAGE_DEVICE_POLICY_APPS_CONTROL,
-                    MANAGE_DEVICE_POLICY_CAMERA,
-                    MANAGE_DEVICE_POLICY_CERTIFICATES,
                     MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE,
                     MANAGE_DEVICE_POLICY_DEFAULT_SMS,
                     MANAGE_DEVICE_POLICY_LOCALE,
@@ -22816,7 +22982,6 @@
     private static final List<String> ADDITIONAL_PROFILE_OWNER_ON_USER_0_PERMISSIONS =
             List.of(
                     MANAGE_DEVICE_POLICY_AIRPLANE_MODE,
-                    MANAGE_DEVICE_POLICY_CAMERA,
                     MANAGE_DEVICE_POLICY_DISPLAY,
                     MANAGE_DEVICE_POLICY_FUN,
                     MANAGE_DEVICE_POLICY_LOCK_TASK,
@@ -22827,7 +22992,6 @@
                     MANAGE_DEVICE_POLICY_PROFILE_INTERACTION,
                     MANAGE_DEVICE_POLICY_SAFE_BOOT,
                     MANAGE_DEVICE_POLICY_SMS,
-                    MANAGE_DEVICE_POLICY_STATUS_BAR,
                     MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS,
                     MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER,
                     MANAGE_DEVICE_POLICY_USERS,
@@ -22848,7 +23012,9 @@
      * All the additional permissions granted to a Profile Owner on an affiliated user.
      */
     private static final List<String> ADDITIONAL_AFFILIATED_PROFILE_OWNER_ON_USER_PERMISSIONS =
-            List.of();
+            List.of(
+                    MANAGE_DEVICE_POLICY_STATUS_BAR
+            );
 
     /**
      * Combination of {@link PROFILE_OWNER_PERMISSIONS} and
@@ -22914,11 +23080,12 @@
     //Map of Permission to Delegate Scope.
     private static final HashMap<String, String> DELEGATE_SCOPES = new HashMap<>();
     {
-        DELEGATE_SCOPES.put(MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS, DELEGATION_PERMISSION_GRANT);
         DELEGATE_SCOPES.put(MANAGE_DEVICE_POLICY_APP_RESTRICTIONS, DELEGATION_APP_RESTRICTIONS);
         DELEGATE_SCOPES.put(MANAGE_DEVICE_POLICY_BLOCK_UNINSTALL, DELEGATION_BLOCK_UNINSTALL);
-        DELEGATE_SCOPES.put(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, DELEGATION_SECURITY_LOGGING);
+        DELEGATE_SCOPES.put(MANAGE_DEVICE_POLICY_CERTIFICATES, DELEGATION_CERT_INSTALL);
         DELEGATE_SCOPES.put(MANAGE_DEVICE_POLICY_PACKAGE_STATE, DELEGATION_PACKAGE_ACCESS);
+        DELEGATE_SCOPES.put(MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS, DELEGATION_PERMISSION_GRANT);
+        DELEGATE_SCOPES.put(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, DELEGATION_SECURITY_LOGGING);
     }
 
     private static final HashMap<String, String> CROSS_USER_PERMISSIONS =
@@ -23107,6 +23274,28 @@
     }
 
     /**
+     * Checks if the calling process has been granted permission to apply a device policy on a
+     * specific user.  Only one permission provided in the list needs to be granted to pass this
+     * check.
+     * The given permissions will be checked along with their associated cross-user permissions if
+     * they exist and the target user is different to the calling user.
+     * Returns an {@link EnforcingAdmin} for the caller.
+     *
+     * @param admin the component name of the admin.
+     * @param callerPackageName The package name of the calling application.
+     * @param permissions The names of the permissions being checked.
+     * @param deviceAdminPolicy 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 enforcePermissionsAndGetEnforcingAdmin(@Nullable ComponentName admin,
+            String[] permissions, int deviceAdminPolicy, String callerPackageName,
+            int targetUserId) {
+        enforcePermissions(permissions, deviceAdminPolicy, callerPackageName, targetUserId);
+        return getEnforcingAdminForCaller(admin, callerPackageName);
+    }
+
+    /**
      * 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
@@ -23152,12 +23341,13 @@
 
     /**
      * 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.
+     * specific user. Only one permission provided in the list needs to be granted to pass this
+     * check.
+     * The given permissions will be checked along with their associated cross-user permissions if
+     * they exists and the target user is different to the calling user.
      *
      * @param callerPackageName The package name  of the calling application.
-     * @param permission The name of the permission being checked.
+     * @param permissions The names of the permissions 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.
@@ -23222,6 +23412,27 @@
     }
 
     /**
+     * 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.
+     *
+     * @param callerPackageName The package name  of the calling application.
+     * @param adminPolicy The admin policy that should grant holders permission.
+     * @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 void enforcePermissions(String[] permissions, int adminPolicy,
+            String callerPackageName, int targetUserId) throws SecurityException {
+        if (hasAdminPolicy(adminPolicy, callerPackageName)) {
+            return;
+        }
+        enforcePermissions(permissions, callerPackageName, targetUserId);
+    }
+
+    /**
      * 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
@@ -23348,7 +23559,8 @@
         // Check for non-DPC active admins.
         admin = getActiveAdminForCaller(who, caller);
         if (admin != null) {
-            return EnforcingAdmin.createDeviceAdminEnforcingAdmin(who, userId, admin);
+            return EnforcingAdmin.createDeviceAdminEnforcingAdmin(admin.info.getComponent(), userId,
+                    admin);
         }
         admin = getUserData(userId).createOrGetPermissionBasedAdmin(userId);
         return  EnforcingAdmin.createEnforcingAdmin(caller.getPackageName(), userId, admin);
@@ -23636,15 +23848,14 @@
 
     private void updateDialerAndSmsManagedShortcutsOverrideCache(
             String defaultDialerPackageName, String defaultSmsPackageName) {
-
-        List<String> shortcutOverrides = new ArrayList<>();
+        ArrayMap<String, String> shortcutOverrides = new ArrayMap<>();
 
         if (defaultDialerPackageName != null) {
-            shortcutOverrides.add(defaultDialerPackageName);
+            shortcutOverrides.put(defaultDialerPackageName, defaultDialerPackageName);
         }
 
         if (defaultSmsPackageName != null) {
-            shortcutOverrides.add(defaultSmsPackageName);
+            shortcutOverrides.put(defaultSmsPackageName, defaultSmsPackageName);
         }
         mPolicyCache.setLauncherShortcutOverrides(shortcutOverrides);
     }
@@ -23709,6 +23920,7 @@
     public DevicePolicyState getDevicePolicyState() {
         Preconditions.checkCallAuthorization(
                 hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
+
         return mInjector.binderWithCleanCallingIdentity(mDevicePolicyEngine::getDevicePolicyState);
     }
 
@@ -23973,6 +24185,53 @@
         });
     }
 
+    /**
+     * Truncates char sequence to maximum length, nulls are ignored.
+     */
+    private static CharSequence truncateIfLonger(CharSequence input, int maxLength) {
+        return input == null || input.length() <= maxLength
+                ? input
+                : input.subSequence(0, maxLength);
+    }
+
+    /**
+     * Throw if string argument is too long to be serialized.
+     */
+    private static void enforceMaxStringLength(String str, String argName) {
+        Preconditions.checkArgument(
+                str.length() <= MAX_POLICY_STRING_LENGTH, argName + " loo long");
+    }
+
+    private static void enforceMaxPackageNameLength(String pkg) {
+        Preconditions.checkArgument(
+                pkg.length() <= MAX_PACKAGE_NAME_LENGTH, "Package name too long");
+    }
+
+    /**
+     * Throw if persistable bundle contains any string that we can't serialize.
+     */
+    private static void enforceMaxStringLength(PersistableBundle bundle, String argName) {
+        // Persistable bundles can have other persistable bundles as values, traverse with a queue.
+        Queue<PersistableBundle> queue = new ArrayDeque<>();
+        queue.add(bundle);
+        while (!queue.isEmpty()) {
+            PersistableBundle current = queue.remove();
+            for (String key : current.keySet()) {
+                enforceMaxStringLength(key, "key in " + argName);
+                Object value = current.get(key);
+                if (value instanceof String) {
+                    enforceMaxStringLength((String) value, "string value in " + argName);
+                } else if (value instanceof String[]) {
+                    for (String str : (String[]) value) {
+                        enforceMaxStringLength(str, "string value in " + argName);
+                    }
+                } else if (value instanceof PersistableBundle) {
+                    queue.add((PersistableBundle) value);
+                }
+            }
+        }
+    }
+
     private ActiveAdmin getActiveAdminForCaller(@Nullable ComponentName who,
             CallerIdentity caller) {
         synchronized (getLockObject()) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicySerializer.java
index 0f6f3c5..20bd2d7 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicySerializer.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicySerializer.java
@@ -42,10 +42,6 @@
     void saveToXml(PolicyKey policyKey, TypedXmlSerializer serializer,
             @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,
                 ATTR_PACKAGES,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
index 638596b..43a2c9b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -308,6 +308,13 @@
                         DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY, accountType));
     }
 
+    static PolicyDefinition<Set<String>> PERMITTED_INPUT_METHODS = new PolicyDefinition<>(
+            new NoArgsPolicyKey(DevicePolicyIdentifiers.PERMITTED_INPUT_METHODS_POLICY),
+            new MostRecent<>(),
+            POLICY_FLAG_LOCAL_ONLY_POLICY,
+            (Set<String> value, Context context, Integer userId, PolicyKey policyKey) -> true,
+            new StringSetPolicySerializer());
+
     private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>();
     private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>();
 
@@ -333,6 +340,8 @@
                 GENERIC_APPLICATION_HIDDEN);
         POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY,
                 GENERIC_ACCOUNT_MANAGEMENT_DISABLED);
+        POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.PERMITTED_INPUT_METHODS_POLICY,
+                PERMITTED_INPUT_METHODS);
 
         // User Restriction Policies
         USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
index 12a8a75..289098e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
@@ -26,6 +26,7 @@
 import android.app.admin.PackagePolicyKey;
 import android.app.admin.PolicyKey;
 import android.app.admin.UserRestrictionPolicyKey;
+import android.app.usage.UsageStatsManagerInternal;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IntentFilter;
@@ -38,6 +39,7 @@
 import android.permission.AdminPermissionControlParams;
 import android.permission.PermissionControllerManager;
 import android.provider.Settings;
+import android.util.ArraySet;
 import android.util.Slog;
 
 import com.android.server.LocalServices;
@@ -151,11 +153,15 @@
 
     static boolean setUserControlDisabledPackages(
             @Nullable Set<String> packages, int userId) {
-        Binder.withCleanCallingIdentity(() ->
-                LocalServices.getService(PackageManagerInternal.class)
-                        .setOwnerProtectedPackages(
-                                userId,
-                                packages == null ? null : packages.stream().toList()));
+        Binder.withCleanCallingIdentity(() -> {
+            LocalServices.getService(PackageManagerInternal.class)
+                    .setOwnerProtectedPackages(
+                            userId,
+                            packages == null ? null : packages.stream().toList());
+            LocalServices.getService(UsageStatsManagerInternal.class)
+                            .setAdminProtectedPackages(
+                            packages == null ? null : new ArraySet(packages), userId);
+        });
         return true;
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
index 741f209..dd4c6af 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
@@ -67,9 +67,8 @@
     /**
      * Returns {@code true} if the resolved policy has changed, {@code false} otherwise.
      */
-    boolean addPolicy(@NonNull EnforcingAdmin admin, @NonNull PolicyValue<V> policy) {
+    boolean addPolicy(@NonNull EnforcingAdmin admin, @Nullable 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.
@@ -89,9 +88,9 @@
      * Returns {@code true} if the resolved policy has changed, {@code false} otherwise.
      */
     boolean addPolicy(
-            @NonNull EnforcingAdmin admin, @NonNull PolicyValue<V> policy,
+            @NonNull EnforcingAdmin admin, @Nullable PolicyValue<V> policy,
             LinkedHashMap<EnforcingAdmin, PolicyValue<V>> globalPoliciesSetByAdmins) {
-        mPoliciesSetByAdmins.put(Objects.requireNonNull(admin), Objects.requireNonNull(policy));
+        mPoliciesSetByAdmins.put(Objects.requireNonNull(admin), policy);
 
         return resolvePolicy(globalPoliciesSetByAdmins);
     }
@@ -210,10 +209,12 @@
         for (EnforcingAdmin admin : mPoliciesSetByAdmins.keySet()) {
             serializer.startTag(/* namespace= */ null, TAG_ADMIN_POLICY_ENTRY);
 
-            serializer.startTag(/* namespace= */ null, TAG_POLICY_VALUE_ENTRY);
-            mPolicyDefinition.savePolicyValueToXml(
-                    serializer, mPoliciesSetByAdmins.get(admin).getValue());
-            serializer.endTag(/* namespace= */ null, TAG_POLICY_VALUE_ENTRY);
+            if (mPoliciesSetByAdmins.get(admin) != null) {
+                serializer.startTag(/* namespace= */ null, TAG_POLICY_VALUE_ENTRY);
+                mPolicyDefinition.savePolicyValueToXml(
+                        serializer, mPoliciesSetByAdmins.get(admin).getValue());
+                serializer.endTag(/* namespace= */ null, TAG_POLICY_VALUE_ENTRY);
+            }
 
             serializer.startTag(/* namespace= */ null, TAG_ENFORCING_ADMIN_ENTRY);
             admin.saveToXml(serializer);
@@ -250,7 +251,7 @@
                                 break;
                         }
                     }
-                    if (admin != null && value != null) {
+                    if (admin != null) {
                         policiesSetByAdmins.put(admin, value);
                     } else {
                         Log.e(TAG, "Error Parsing TAG_ADMIN_POLICY_ENTRY");
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 3a47b47..2b57c59 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -154,6 +154,7 @@
         // Freeze time for testing.
         long nowElapsed;
         boolean useMotionSensor = true;
+        boolean isLocationPrefetchEnabled = true;
 
         InjectorForTest(Context ctx) {
             super(ctx);
@@ -223,6 +224,11 @@
         }
 
         @Override
+        boolean isLocationPrefetchEnabled() {
+            return isLocationPrefetchEnabled;
+        }
+
+        @Override
         PowerManager getPowerManager() {
             return mPowerManager;
         }
@@ -991,6 +997,43 @@
     }
 
     @Test
+    public void testStepIdleStateLocked_ValidStates_LocationPrefetchDisabled() {
+        mInjector.locationManager = mLocationManager;
+        mInjector.isLocationPrefetchEnabled = false;
+        cleanupDeviceIdleController();
+        setupDeviceIdleController();
+        doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
+        // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
+        setAlarmSoon(false);
+        // Set state to INACTIVE.
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        setChargingOn(false);
+        setScreenOn(false);
+        verifyStateConditions(STATE_INACTIVE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_PENDING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_SENSING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        // Prefetch location is off, so SENSING should go straight through to IDLE.
+        verifyStateConditions(STATE_IDLE);
+
+        // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+    }
+
+    @Test
     public void testStepIdleStateLocked_ValidStates_WithLocationManager_NoProviders() {
         // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
         setAlarmSoon(false);
@@ -1024,6 +1067,46 @@
     }
 
     @Test
+    public void testStepIdleStateLocked_ValidStates_WithLocationManager_MissingProviders() {
+        mInjector.locationManager = mLocationManager;
+        doReturn(null).when(mLocationManager)
+                .getProvider(eq(LocationManager.FUSED_PROVIDER));
+        doReturn(null).when(mLocationManager)
+                .getProvider(eq(LocationManager.GPS_PROVIDER));
+        doReturn(mock(LocationProvider.class)).when(mLocationManager)
+                .getProvider(eq(LocationManager.NETWORK_PROVIDER));
+        // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
+        setAlarmSoon(false);
+        // Set state to INACTIVE.
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        setChargingOn(false);
+        setScreenOn(false);
+        verifyStateConditions(STATE_INACTIVE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_PENDING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_SENSING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        // Location manager exists, but the required providers don't exist,
+        // so SENSING should go straight through to IDLE.
+        verifyStateConditions(STATE_IDLE);
+
+        // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+    }
+
+    @Test
     public void testStepIdleStateLocked_ValidStates_WithLocationManager_WithProviders() {
         mInjector.locationManager = mLocationManager;
         doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
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 a5adf3f..f1d4de9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -54,6 +54,7 @@
 import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH;
 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_ALLOW_LIST;
 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_COMPAT;
+import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_LISTENER;
 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_NOT_APPLICABLE;
 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PERMISSION;
 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_POLICY_PERMISSION;
@@ -2728,6 +2729,66 @@
     }
 
     @Test
+    public void exactListenerBinderCallWithoutPermissionWithoutAllowlist() throws RemoteException {
+        mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+        mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
+
+        mockScheduleExactAlarmState(false);
+        mockUseExactAlarmState(false);
+        when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(false);
+
+        final IAlarmListener listener = getNewListener(() -> {});
+        mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
+                0, null, listener, "test-tag", null, null);
+
+        verify(mService, never()).hasUseExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID);
+        verify(mService, never()).hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE,
+                TEST_CALLING_UID);
+        verify(mDeviceIdleInternal, never()).isAppOnWhitelist(anyInt());
+
+        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L),
+                isNull(), eq(listener), eq("test-tag"), eq(FLAG_STANDALONE), isNull(), isNull(),
+                eq(TEST_CALLING_UID), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture(),
+                eq(EXACT_ALLOW_REASON_LISTENER));
+
+        final BroadcastOptions idleOptions = new BroadcastOptions(bundleCaptor.getValue());
+        final int type = idleOptions.getTemporaryAppAllowlistType();
+        assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type);
+    }
+
+    @Test
+    public void exactAllowWhileIdleListenerBinderCallWithoutPermissionWithoutAllowlist()
+            throws RemoteException {
+        mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+        mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
+
+        mockScheduleExactAlarmState(false);
+        mockUseExactAlarmState(false);
+        when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(false);
+
+        final IAlarmListener listener = getNewListener(() -> {});
+        mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
+                FLAG_ALLOW_WHILE_IDLE, null, listener, "test-tag", null, null);
+
+        verify(mService, never()).hasUseExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID);
+        verify(mService, never()).hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE,
+                TEST_CALLING_UID);
+        verify(mDeviceIdleInternal, never()).isAppOnWhitelist(anyInt());
+
+        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L),
+                isNull(), eq(listener), eq("test-tag"),
+                eq(FLAG_STANDALONE | FLAG_ALLOW_WHILE_IDLE_COMPAT), isNull(), isNull(),
+                eq(TEST_CALLING_UID), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture(),
+                eq(EXACT_ALLOW_REASON_LISTENER));
+
+        final BroadcastOptions idleOptions = new BroadcastOptions(bundleCaptor.getValue());
+        final int type = idleOptions.getTemporaryAppAllowlistType();
+        assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type);
+    }
+
+    @Test
     public void inexactAllowWhileIdleBinderCall() throws RemoteException {
         // Both permission and power exemption status don't matter for these alarms.
         // We only want to test that the flags and idleOptions are correct.
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 3fb7fb4..acfea85 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -40,6 +40,7 @@
 import static com.android.server.am.BroadcastQueueTest.getUidForPackage;
 import static com.android.server.am.BroadcastQueueTest.makeManifestReceiver;
 import static com.android.server.am.BroadcastQueueTest.withPriority;
+import static com.android.server.am.BroadcastRecord.isReceiverEquals;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -49,13 +50,16 @@
 import static org.junit.Assert.assertNull;
 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.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 
 import android.annotation.NonNull;
@@ -116,6 +120,7 @@
     TestLooperManager mLooper;
 
     BroadcastConstants mConstants;
+    private BroadcastSkipPolicy mSkipPolicy;
     BroadcastQueueModernImpl mImpl;
 
     BroadcastProcessQueue mHead;
@@ -139,29 +144,18 @@
         mConstants.DELAY_NORMAL_MILLIS = 10_000;
         mConstants.DELAY_CACHED_MILLIS = 120_000;
 
-        final BroadcastSkipPolicy emptySkipPolicy = new BroadcastSkipPolicy(mAms) {
-            public boolean shouldSkip(BroadcastRecord r, Object o) {
-                // Ignored
-                return false;
-            }
-            public String shouldSkipMessage(BroadcastRecord r, Object o) {
-                // Ignored
-                return null;
-            }
-            public boolean disallowBackgroundStart(BroadcastRecord r) {
-                // Ignored
-                return false;
-            }
-        };
+        mSkipPolicy = spy(new BroadcastSkipPolicy(mAms));
+        doReturn(null).when(mSkipPolicy).shouldSkipMessage(any(), any());
+        doReturn(false).when(mSkipPolicy).disallowBackgroundStart(any());
+
         final BroadcastHistory emptyHistory = new BroadcastHistory(mConstants) {
             public void addBroadcastToHistoryLocked(BroadcastRecord original) {
                 // Ignored
             }
         };
 
-
         mImpl = new BroadcastQueueModernImpl(mAms, mHandlerThread.getThreadHandler(),
-            mConstants, mConstants, emptySkipPolicy, emptyHistory);
+            mConstants, mConstants, mSkipPolicy, emptyHistory);
 
         doReturn(1L).when(mQueue1).getRunnableAt();
         doReturn(2L).when(mQueue2).getRunnableAt();
@@ -256,17 +250,12 @@
 
     private void enqueueOrReplaceBroadcast(BroadcastProcessQueue queue,
             BroadcastRecord record, int recordIndex) {
-        enqueueOrReplaceBroadcast(queue, record, recordIndex, false, 42_000_000L);
+        enqueueOrReplaceBroadcast(queue, record, recordIndex, 42_000_000L);
     }
 
     private void enqueueOrReplaceBroadcast(BroadcastProcessQueue queue,
             BroadcastRecord record, int recordIndex, long enqueueTime) {
-        enqueueOrReplaceBroadcast(queue, record, recordIndex, false, enqueueTime);
-    }
-
-    private void enqueueOrReplaceBroadcast(BroadcastProcessQueue queue,
-            BroadcastRecord record, int recordIndex, boolean wouldBeSkipped, long enqueueTime) {
-        queue.enqueueOrReplaceBroadcast(record, recordIndex, wouldBeSkipped, (r, i) -> {
+        queue.enqueueOrReplaceBroadcast(record, recordIndex, (r, i) -> {
             throw new UnsupportedOperationException();
         });
         record.enqueueTime = enqueueTime;
@@ -1199,6 +1188,42 @@
         assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
     }
 
+    @Test
+    public void testSkipPolicy_atEnqueueTime() throws Exception {
+        final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT);
+        final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
+        final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
+
+        final BroadcastRecord userPresentRecord = makeBroadcastRecord(userPresent,
+                List.of(greenReceiver, redReceiver));
+
+        final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+        final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
+                List.of(greenReceiver, redReceiver));
+
+        doAnswer(invocation -> {
+            final BroadcastRecord r = invocation.getArgument(0);
+            final Object o = invocation.getArgument(1);
+            if (userPresent.getAction().equals(r.intent.getAction())
+                    && isReceiverEquals(o, greenReceiver)) {
+                return "receiver skipped by test";
+            }
+            return null;
+        }).when(mSkipPolicy).shouldSkipMessage(any(BroadcastRecord.class), any());
+
+        mImpl.enqueueBroadcastLocked(userPresentRecord);
+        mImpl.enqueueBroadcastLocked(timeTickRecord);
+
+        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
+                getUidForPackage(PACKAGE_GREEN));
+        // There should be only one broadcast for green process as the other would have
+        // been skipped.
+        verifyPendingRecords(greenQueue, List.of(timeTick));
+        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
+                getUidForPackage(PACKAGE_RED));
+        verifyPendingRecords(redQueue, List.of(userPresent, timeTick));
+    }
+
     private Intent createPackageChangedIntent(int uid, List<String> componentNameList) {
         final Intent packageChangedIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
         packageChangedIntent.putExtra(Intent.EXTRA_UID, uid);
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 c4aa0bb..8dc0ac6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -64,6 +64,7 @@
 import com.android.server.LocalServices;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.display.RampAnimator.DualRampAnimator;
+import com.android.server.display.brightness.BrightnessEvent;
 import com.android.server.display.color.ColorDisplayService;
 import com.android.server.display.layout.Layout;
 import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
@@ -596,17 +597,17 @@
         // We should still set screen state for the default display
         DisplayPowerRequest dpr = new DisplayPowerRequest();
         mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
-        advanceTime(1);
+        advanceTime(1); // Run updatePowerState
         verify(mHolder.displayPowerState, times(2)).setScreenState(anyInt());
 
         mHolder = createDisplayPowerController(42, UNIQUE_ID);
 
         mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
-        advanceTime(1);
+        advanceTime(1); // Run updatePowerState
         verify(mHolder.displayPowerState, never()).setScreenState(anyInt());
 
         mHolder.dpc.onBootCompleted();
-        advanceTime(1);
+        advanceTime(1); // Run updatePowerState
         verify(mHolder.displayPowerState).setScreenState(anyInt());
     }
 
@@ -632,8 +633,8 @@
                 .thenReturn(brightness);
         dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
         when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
-        when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness())
-                .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+                any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
 
         mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
         advanceTime(1); // Run updatePowerState
@@ -667,8 +668,8 @@
                 .thenReturn(brightness);
         dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
         when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
-        when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness())
-                .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+                any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
 
         mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
         advanceTime(1); // Run updatePowerState
@@ -822,6 +823,21 @@
         );
     }
 
+    @Test
+    public void testUpdateBrightnessThrottlingDataId() {
+        mHolder.display.getDisplayInfoLocked().thermalBrightnessThrottlingDataId =
+                "throttling-data-id";
+        clearInvocations(mHolder.display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig());
+
+        mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        verify(mHolder.display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig())
+                .getThermalBrightnessThrottlingDataMapByThrottlingId();
+    }
+
     /**
      * Creates a mock and registers it to {@link LocalServices}.
      */
@@ -862,8 +878,6 @@
         when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
         when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
         when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
-        when(logicalDisplayMock.getThermalBrightnessThrottlingDataIdLocked()).thenReturn(
-                DisplayDeviceConfig.DEFAULT_ID);
         when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
         when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
         when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock);
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 415adbb..5c0810f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -829,6 +829,21 @@
         );
     }
 
+    @Test
+    public void testUpdateBrightnessThrottlingDataId() {
+        mHolder.display.getDisplayInfoLocked().thermalBrightnessThrottlingDataId =
+                "throttling-data-id";
+        clearInvocations(mHolder.display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig());
+
+        mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        verify(mHolder.display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig())
+                .getThermalBrightnessThrottlingDataMapByThrottlingId();
+    }
+
     /**
      * Creates a mock and registers it to {@link LocalServices}.
      */
@@ -869,8 +884,6 @@
         when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
         when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
         when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
-        when(logicalDisplayMock.getThermalBrightnessThrottlingDataIdLocked()).thenReturn(
-                DisplayDeviceConfig.DEFAULT_ID);
         when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
         when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
         when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock);
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java b/services/tests/mockingservicestests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
deleted file mode 100644
index 17fba9f..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
+++ /dev/null
@@ -1,121 +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.server.display;
-
-import static com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-import android.hardware.display.DisplayManager;
-import android.provider.Settings;
-import android.testing.TestableContext;
-import android.view.Display;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.display.RefreshRateSettingsUtils;
-
-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;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RefreshRateSettingsUtilsTest {
-
-    @Rule
-    public final TestableContext mContext = new TestableContext(
-            InstrumentationRegistry.getInstrumentation().getContext());
-
-    @Mock
-    private DisplayManager mDisplayManagerMock;
-    @Mock
-    private Display mDisplayMock;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mContext.addMockSystemService(DisplayManager.class, mDisplayManagerMock);
-
-        Display.Mode[] modes = new Display.Mode[] {
-                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
-                        /* refreshRate= */ 60),
-                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
-                        /* refreshRate= */ 120),
-                new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
-                        /* refreshRate= */ 90)
-        };
-
-        when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
-        when(mDisplayMock.getSupportedModes()).thenReturn(modes);
-    }
-
-    @Test
-    public void testFindHighestRefreshRateForDefaultDisplay() {
-        when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(null);
-        assertEquals(DEFAULT_REFRESH_RATE,
-                RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
-                /* delta= */ 0);
-
-        when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
-        assertEquals(120,
-                RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
-                /* delta= */ 0);
-    }
-
-    @Test
-    public void testGetMinRefreshRate() {
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.FORCE_PEAK_REFRESH_RATE, -1);
-        assertEquals(0, RefreshRateSettingsUtils.getMinRefreshRate(mContext), /* delta= */ 0);
-
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.FORCE_PEAK_REFRESH_RATE, 0);
-        assertEquals(0, RefreshRateSettingsUtils.getMinRefreshRate(mContext), /* delta= */ 0);
-
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.FORCE_PEAK_REFRESH_RATE, 1);
-        assertEquals(120, RefreshRateSettingsUtils.getMinRefreshRate(mContext), /* delta= */ 0);
-    }
-
-    @Test
-    public void testGetPeakRefreshRate() {
-        float defaultPeakRefreshRate = 100;
-
-        Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY, -1);
-        assertEquals(defaultPeakRefreshRate,
-                RefreshRateSettingsUtils.getPeakRefreshRate(mContext, defaultPeakRefreshRate),
-                /* delta= */ 0);
-
-        Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY, 0);
-        assertEquals(DEFAULT_REFRESH_RATE,
-                RefreshRateSettingsUtils.getPeakRefreshRate(mContext, defaultPeakRefreshRate),
-                /* delta= */ 0);
-
-        Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY, 1);
-        assertEquals(120,
-                RefreshRateSettingsUtils.getPeakRefreshRate(mContext, defaultPeakRefreshRate),
-                /* delta= */ 0);
-    }
-}
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 96eca71..8cfc150 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -281,8 +281,8 @@
     @Test
     public void testRegisterProxy() throws Exception {
         mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY);
-        verify(mProxyManager).registerProxy(eq(mMockServiceClient), eq(TEST_DISPLAY),
-                eq(mTestableContext), anyInt(), any(), eq(mMockSecurityPolicy),
+        verify(mProxyManager).registerProxy(eq(mMockServiceClient), eq(TEST_DISPLAY), anyInt(),
+                eq(mMockSecurityPolicy),
                 eq(mA11yms), eq(mA11yms.getTraceManager()),
                 eq(mMockWindowManagerService));
     }
@@ -295,7 +295,7 @@
 
         assertThrows(SecurityException.class,
                 () -> mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY));
-        verify(mProxyManager, never()).registerProxy(any(), anyInt(), any(), anyInt(), any(), any(),
+        verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
                 any(), any(), any());
     }
 
@@ -307,7 +307,7 @@
 
         assertThrows(SecurityException.class,
                 () -> mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY));
-        verify(mProxyManager, never()).registerProxy(any(), anyInt(), any(), anyInt(), any(), any(),
+        verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
                 any(), any(), any());
     }
 
@@ -316,7 +316,7 @@
     public void testRegisterProxyForDefaultDisplay() throws Exception {
         assertThrows(IllegalArgumentException.class,
                 () -> mA11yms.registerProxyForDisplay(mMockServiceClient, Display.DEFAULT_DISPLAY));
-        verify(mProxyManager, never()).registerProxy(any(), anyInt(), any(), anyInt(), any(), any(),
+        verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
                 any(), any(), any());
     }
 
@@ -325,7 +325,7 @@
     public void testRegisterProxyForInvalidDisplay() throws Exception {
         assertThrows(IllegalArgumentException.class,
                 () -> mA11yms.registerProxyForDisplay(mMockServiceClient, Display.INVALID_DISPLAY));
-        verify(mProxyManager, never()).registerProxy(any(), anyInt(), any(), anyInt(), any(), any(),
+        verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
                 any(), any(), any());
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/ProxyAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/ProxyAccessibilityServiceConnectionTest.java
index dd44a79..6ac3658 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/ProxyAccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/ProxyAccessibilityServiceConnectionTest.java
@@ -29,12 +29,14 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.os.Handler;
 import android.view.accessibility.AccessibilityEvent;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -79,12 +81,15 @@
     WindowManagerInternal mMockWindowManagerInternal;
     ProxyAccessibilityServiceConnection mProxyConnection;
     AccessibilityServiceInfo mAccessibilityServiceInfo;
+    private int mFocusStrokeWidthDefaultValue;
+    private int mFocusColorDefaultValue;
 
     @Before
     public void setup() {
         final Resources resources = getInstrumentation().getContext().getResources();
         MockitoAnnotations.initMocks(this);
         when(mMockContext.getResources()).thenReturn(resources);
+        when(mMockSecurityPolicy.checkAccessibilityAccess(any())).thenReturn(true);
 
         mAccessibilityServiceInfo = new AccessibilityServiceInfo();
         mProxyConnection = new ProxyAccessibilityServiceConnection(mMockContext, COMPONENT_NAME,
@@ -92,10 +97,13 @@
                         getInstrumentation().getContext().getMainLooper()),
                 mMockLock, mMockSecurityPolicy, mMockSystemSupport, mMockA11yTrace,
                 mMockWindowManagerInternal, mMockA11yWindowManager, DISPLAY_ID, DEVICE_ID);
+
+        mFocusStrokeWidthDefaultValue = mProxyConnection.getFocusStrokeWidthLocked();
+        mFocusColorDefaultValue = mProxyConnection.getFocusColorLocked();
     }
 
     @Test
-    public void testSetInstalledAndEnabledServices_clientChanged() {
+    public void testSetInstalledAndEnabledServices_updateInfos_notifiesSystemOfProxyChange() {
         final List<AccessibilityServiceInfo> infos = new ArrayList<>();
         final AccessibilityServiceInfo info1 = new AccessibilityServiceInfo();
         infos.add(info1);
@@ -106,6 +114,17 @@
     }
 
     @Test
+    public void testSetFocusAppearance_updateAppearance_notifiesSystemOfProxyChange() {
+        final int updatedWidth = mFocusStrokeWidthDefaultValue + 10;
+        final int updatedColor = mFocusColorDefaultValue
+                == Color.BLUE ? Color.RED : Color.BLUE;
+
+        mProxyConnection.setFocusAppearance(updatedWidth, updatedColor);
+
+        verify(mMockSystemSupport).onProxyChanged(DEVICE_ID);
+    }
+
+    @Test
     public void testSetInstalledAndEnabledServices_returnList() {
         final List<AccessibilityServiceInfo> infos = new ArrayList<>();
         final AccessibilityServiceInfo info1 = new AccessibilityServiceInfo();
@@ -196,7 +215,7 @@
     }
 
     @Test
-    public void testSetServiceInfo_setIllegalOperationExceptionThrown_() {
+    public void testSetServiceInfo_setIllegalOperationExceptionThrown() {
         UnsupportedOperationException thrown =
                 assertThrows(
                         UnsupportedOperationException.class,
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java
new file mode 100644
index 0000000..6c7b995
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 com.android.server.accessibility.ProxyAccessibilityServiceConnectionTest.INTERACTIVE_UI_TIMEOUT_100MS;
+import static com.android.server.accessibility.ProxyAccessibilityServiceConnectionTest.INTERACTIVE_UI_TIMEOUT_200MS;
+import static com.android.server.accessibility.ProxyAccessibilityServiceConnectionTest.NON_INTERACTIVE_UI_TIMEOUT_100MS;
+import static com.android.server.accessibility.ProxyAccessibilityServiceConnectionTest.NON_INTERACTIVE_UI_TIMEOUT_200MS;
+import static com.android.server.accessibility.ProxyManager.PROXY_COMPONENT_CLASS_NAME;
+import static com.android.server.accessibility.ProxyManager.PROXY_COMPONENT_PACKAGE_NAME;
+
+import static org.junit.Assert.fail;
+
+import android.accessibilityservice.AccessibilityGestureEvent;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.AccessibilityTrace;
+import android.accessibilityservice.IAccessibilityServiceClient;
+import android.accessibilityservice.IAccessibilityServiceConnection;
+import android.accessibilityservice.MagnificationConfig;
+import android.companion.virtual.IVirtualDeviceManager;
+import android.companion.virtual.VirtualDeviceManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.util.ArraySet;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IAccessibilityManagerClient;
+import android.view.inputmethod.EditorInfo;
+
+import com.android.internal.R;
+import com.android.internal.inputmethod.IAccessibilityInputMethodSession;
+import com.android.internal.inputmethod.IAccessibilityInputMethodSessionCallback;
+import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
+import com.android.internal.util.IntPair;
+import com.android.server.LocalServices;
+import com.android.server.accessibility.test.MessageCapturingHandler;
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
+import com.android.server.wm.WindowManagerInternal;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.InstrumentationRegistry;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Tests for ProxyManager.
+ */
+public class ProxyManagerTest {
+    private static final int DISPLAY_ID = 1000;
+    private static final int DISPLAY_2_ID = 1001;
+    private static final int DEVICE_ID = 10;
+    private static final int STREAMED_CALLING_UID = 9876;
+
+    @Mock private Context mMockContext;
+    @Mock private AccessibilitySecurityPolicy mMockSecurityPolicy;
+    @Mock private AccessibilityWindowManager mMockA11yWindowManager;
+    @Mock private ProxyManager.SystemSupport mMockProxySystemSupport;
+    @Mock private AbstractAccessibilityServiceConnection.SystemSupport mMockConnectionSystemSupport;
+    @Mock private AccessibilityTrace mMockA11yTrace;
+    @Mock private WindowManagerInternal mMockWindowManagerInternal;
+    @Mock private IAccessibilityServiceClient mMockAccessibilityServiceClient;
+    @Mock private IBinder mMockServiceAsBinder;
+    @Mock private VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal;
+    @Mock private IVirtualDeviceManager mMockIVirtualDeviceManager;
+
+    private int mFocusStrokeWidthDefaultValue;
+    private int mFocusColorDefaultValue;
+
+    private MessageCapturingHandler mMessageCapturingHandler  = new MessageCapturingHandler(null);
+    private ProxyManager mProxyManager;
+
+    @Before
+    public void setup() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+        final Resources resources = InstrumentationRegistry.getContext().getResources();
+
+        mFocusStrokeWidthDefaultValue =
+                resources.getDimensionPixelSize(R.dimen.accessibility_focus_highlight_stroke_width);
+        mFocusColorDefaultValue = resources.getColor(R.color.accessibility_focus_highlight_color);
+        when(mMockContext.getResources()).thenReturn(resources);
+
+        when(mMockVirtualDeviceManagerInternal.getDeviceIdsForUid(anyInt())).thenReturn(
+                new ArraySet(Set.of(DEVICE_ID)));
+        LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
+        LocalServices.addService(VirtualDeviceManagerInternal.class,
+                mMockVirtualDeviceManagerInternal);
+
+        when(mMockIVirtualDeviceManager.getDeviceIdForDisplayId(anyInt())).thenReturn(DEVICE_ID);
+        final VirtualDeviceManager virtualDeviceManager =
+                new VirtualDeviceManager(mMockIVirtualDeviceManager, mMockContext);
+        when(mMockContext.getSystemServiceName(VirtualDeviceManager.class)).thenReturn(
+                Context.VIRTUAL_DEVICE_SERVICE);
+        when(mMockContext.getSystemService(VirtualDeviceManager.class))
+                .thenReturn(virtualDeviceManager);
+
+        when(mMockA11yTrace.isA11yTracingEnabled()).thenReturn(false);
+
+        final RemoteCallbackList<IAccessibilityManagerClient> userClients =
+                new RemoteCallbackList<>();
+        final RemoteCallbackList<IAccessibilityManagerClient> globalClients =
+                new RemoteCallbackList<>();
+        when(mMockProxySystemSupport.getCurrentUserClientsLocked()).thenReturn(userClients);
+        when(mMockProxySystemSupport.getGlobalClientsLocked()).thenReturn(globalClients);
+
+        when(mMockAccessibilityServiceClient.asBinder()).thenReturn(mMockServiceAsBinder);
+
+        mProxyManager = new ProxyManager(new Object(), mMockA11yWindowManager, mMockContext,
+                mMessageCapturingHandler, new UiAutomationManager(new Object()),
+                mMockProxySystemSupport);
+    }
+
+    @After
+    public void tearDown() {
+        mMessageCapturingHandler.removeAllMessages();
+    }
+
+    /**
+     * Tests that the proxy’s backing AccessibilityServiceClient is initialized when registering a
+     * proxy.
+     */
+    @Test
+    public void registerProxy_always_connectsServiceClient() throws RemoteException {
+        registerProxy(DISPLAY_ID);
+        verify(mMockAccessibilityServiceClient).init(any(), anyInt(), any());
+    }
+
+    /** Tests that unregistering a proxy removes its display from tracking. */
+    @Test
+    public void unregisterProxy_always_stopsTrackingDisplay() {
+        registerProxy(DISPLAY_ID);
+
+        mProxyManager.unregisterProxy(DISPLAY_ID);
+
+        verify(mMockA11yWindowManager).stopTrackingDisplayProxy(DISPLAY_ID);
+        assertThat(mProxyManager.isProxyedDisplay(DISPLAY_ID)).isFalse();
+    }
+    /**
+     * Tests that unregistering a proxied display of a virtual device, where that virtual device
+     * owned only that one proxied display, removes the device from tracking.
+     */
+    @Test
+    public void unregisterProxy_deviceAssociatedWithSingleDisplay_stopsTrackingDevice() {
+        registerProxy(DISPLAY_ID);
+
+        mProxyManager.unregisterProxy(DISPLAY_ID);
+
+        assertThat(mProxyManager.isProxyedDeviceId(DEVICE_ID)).isFalse();
+        verify(mMockProxySystemSupport).removeDeviceIdLocked(DEVICE_ID);
+    }
+
+    /**
+     * Tests that unregistering a proxied display of a virtual device, where that virtual device
+     * owns more than one proxied display, does not remove the device from tracking.
+     */
+    @Test
+    public void unregisterProxy_deviceAssociatedWithMultipleDisplays_tracksRemainingProxy() {
+        registerProxy(DISPLAY_ID);
+        registerProxy(DISPLAY_2_ID);
+
+        mProxyManager.unregisterProxy(DISPLAY_ID);
+
+        assertThat(mProxyManager.isProxyedDeviceId(DEVICE_ID)).isTrue();
+        verify(mMockProxySystemSupport, never()).removeDeviceIdLocked(DEVICE_ID);
+    }
+
+    /**
+     * Tests that changing a proxy, e.g. registering/unregistering a proxy or updating its service
+     * info, notifies the apps being streamed and AccessibilityManagerService.
+     */
+    @Test
+    public void testOnProxyChanged_always_propagatesChange() {
+        registerProxy(DISPLAY_ID);
+        mMessageCapturingHandler.sendAllMessages();
+
+        mProxyManager.onProxyChanged(DEVICE_ID);
+
+        // Messages to notify IAccessibilityManagerClients should be posted.
+        assertThat(mMessageCapturingHandler.hasMessages()).isTrue();
+
+        verify(mMockProxySystemSupport).updateWindowsForAccessibilityCallbackLocked();
+        verify(mMockProxySystemSupport).notifyClearAccessibilityCacheLocked();
+    }
+
+    /**
+     * Tests that getting the first device id for an app uid, such as when an app queries for
+     * device-specific state, returns the right device id.
+     */
+    @Test
+    public void testGetFirstDeviceForUid_streamedAppQueriesState_getsHostDeviceId() {
+        registerProxy(DISPLAY_ID);
+        assertThat(mProxyManager.getFirstDeviceIdForUidLocked(STREAMED_CALLING_UID))
+                .isEqualTo(DEVICE_ID);
+    }
+
+    /**
+     * Tests that the app client state retrieved for a device reflects that touch exploration is
+     * enabled since a proxy info has requested touch exploration.
+     */
+    @Test
+    public void testGetClientState_proxyWantsTouchExploration_returnsTouchExplorationEnabled() {
+        registerProxy(DISPLAY_ID);
+
+        final AccessibilityServiceInfo secondDisplayInfo = new AccessibilityServiceInfo();
+        secondDisplayInfo.flags |= AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
+        AccessibilityServiceClientImpl client = new AccessibilityServiceClientImpl(
+                secondDisplayInfo);
+        registerProxy(DISPLAY_2_ID, client);
+
+        final int deviceClientState = mProxyManager.getStateLocked(DEVICE_ID);
+        assertThat((deviceClientState
+                & AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0).isTrue();
+    }
+
+    /**
+     * Tests that the highest interactive and non-interactive timeout is returned if there are
+     * multiple proxied displays belonging to a device.
+     */
+    @Test
+    public void testGetRecommendedTimeout_multipleProxies_returnsHighestTimeout() {
+        final AccessibilityServiceInfo firstDisplayInfo = new AccessibilityServiceInfo();
+        firstDisplayInfo.setInteractiveUiTimeoutMillis(INTERACTIVE_UI_TIMEOUT_100MS);
+        firstDisplayInfo.setNonInteractiveUiTimeoutMillis(NON_INTERACTIVE_UI_TIMEOUT_200MS);
+
+        final AccessibilityServiceInfo secondDisplayInfo = new AccessibilityServiceInfo();
+        secondDisplayInfo.setInteractiveUiTimeoutMillis(INTERACTIVE_UI_TIMEOUT_200MS);
+        secondDisplayInfo.setNonInteractiveUiTimeoutMillis(NON_INTERACTIVE_UI_TIMEOUT_100MS);
+
+        registerProxy(DISPLAY_ID, new AccessibilityServiceClientImpl(firstDisplayInfo));
+        registerProxy(DISPLAY_2_ID, new AccessibilityServiceClientImpl(secondDisplayInfo));
+
+        final long timeout = mProxyManager.getRecommendedTimeoutMillisLocked(DEVICE_ID);
+        final int interactiveTimeout = IntPair.first(timeout);
+        final int nonInteractiveTimeout = IntPair.second(timeout);
+
+        assertThat(interactiveTimeout).isEqualTo(INTERACTIVE_UI_TIMEOUT_200MS);
+        assertThat(nonInteractiveTimeout).isEqualTo(NON_INTERACTIVE_UI_TIMEOUT_200MS);
+    }
+    /**
+     * Tests that getting the installed and enabled services returns the info of the registered
+     * proxy. (The component name reflects the display id.)
+     */
+    @Test
+    public void testGetInstalledAndEnabledServices_defaultInfo_returnsInfoForDisplayId() {
+        final AccessibilityServiceInfo info = new AccessibilityServiceInfo();
+        registerProxy(DISPLAY_ID, new AccessibilityServiceClientImpl(info));
+        final List<AccessibilityServiceInfo> installedAndEnabledServices =
+                mProxyManager.getInstalledAndEnabledServiceInfosLocked(
+                        AccessibilityServiceInfo.FEEDBACK_ALL_MASK, DEVICE_ID);
+        assertThat(installedAndEnabledServices.size()).isEqualTo(1);
+        AccessibilityServiceInfo proxyInfo = installedAndEnabledServices.get(0);
+
+        assertThat(proxyInfo.getComponentName()).isEqualTo(new ComponentName(
+                PROXY_COMPONENT_PACKAGE_NAME, PROXY_COMPONENT_CLASS_NAME + DISPLAY_ID));
+    }
+
+    /**
+     * Tests that the app client state retrieved for a device reflects that accessibility is
+     * enabled.
+     */
+    @Test
+    public void testGetClientState_always_returnsAccessibilityEnabled() {
+        registerProxy(DISPLAY_ID);
+
+        final int deviceClientState = mProxyManager.getStateLocked(DEVICE_ID);
+        assertThat((deviceClientState
+                & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0).isTrue();
+    }
+
+    /**
+     * Tests that the manager can retrieve interactive windows if a proxy sets
+     * AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS.
+     */
+    @Test
+    public void testCanRetrieveInteractiveWindows_atLeastOneProxyWantsWindows_returnsTrue() {
+        registerProxy(DISPLAY_ID);
+
+        final AccessibilityServiceInfo secondDisplayInfo = new AccessibilityServiceInfo();
+        secondDisplayInfo.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
+        registerProxy(DISPLAY_2_ID, new AccessibilityServiceClientImpl(secondDisplayInfo));
+
+        assertThat(mProxyManager.canRetrieveInteractiveWindowsLocked()).isTrue();
+    }
+
+    /**
+     * Tests that getting service interfaces to interrupt when AccessibilityManager#interrupt
+     * returns the registered proxy interface.
+     */
+    @Test
+    public void testGetServiceInterfacesForInterrupt_defaultProxy_returnsProxyInterface() {
+        registerProxy(DISPLAY_ID);
+        final List<IAccessibilityServiceClient> interfacesToInterrupt = new ArrayList<>();
+        mProxyManager.addServiceInterfacesLocked(interfacesToInterrupt, DEVICE_ID);
+
+        assertThat(interfacesToInterrupt.size()).isEqualTo(1);
+        assertThat(interfacesToInterrupt.get(0).asBinder()).isEqualTo(mMockServiceAsBinder);
+    }
+
+    /** Tests that the default timeout (0) is returned when the proxy is registered. */
+    @Test
+    public void getRecommendedTimeout_defaultProxyInfo_getsDefaultTimeout() {
+        registerProxy(DISPLAY_ID);
+        final long timeout = mProxyManager.getRecommendedTimeoutMillisLocked(DEVICE_ID);
+        final int interactiveTimeout = IntPair.first(timeout);
+        final int nonInteractiveTimeout = IntPair.second(timeout);
+
+        assertThat(interactiveTimeout).isEqualTo(0);
+        assertThat(nonInteractiveTimeout).isEqualTo(0);
+    }
+
+    /** Tests that the manager returns the updated timeout when the proxy’s timeout is updated. */
+    @Test
+    public void getRecommendedTimeout_updateTimeout_getsUpdatedTimeout() {
+        registerProxy(DISPLAY_ID);
+
+        mProxyManager.updateTimeoutsIfNeeded(NON_INTERACTIVE_UI_TIMEOUT_100MS,
+                INTERACTIVE_UI_TIMEOUT_200MS);
+
+        final long updatedTimeout = mProxyManager.getRecommendedTimeoutMillisLocked(DEVICE_ID);
+        final int updatedInteractiveTimeout = IntPair.first(updatedTimeout);
+        final int updatedNonInteractiveTimeout = IntPair.second(updatedTimeout);
+
+        assertThat(updatedInteractiveTimeout).isEqualTo(INTERACTIVE_UI_TIMEOUT_200MS);
+        assertThat(updatedNonInteractiveTimeout).isEqualTo(NON_INTERACTIVE_UI_TIMEOUT_100MS);
+    }
+
+    /** Tests that the system’s default focus color is returned. */
+    @Test
+    public void testGetFocusColor_defaultProxy_getsDefaultSystemColor() {
+        registerProxy(DISPLAY_ID);
+        final int focusColor = mProxyManager.getFocusColorLocked(DEVICE_ID);
+        assertThat(focusColor).isEqualTo(mFocusColorDefaultValue);
+    }
+
+    /** Tests that the system’s default focus stroke width is returned. */
+    @Test
+    public void testGetFocusStrokeWidth_defaultProxy_getsDefaultSystemWidth() {
+        registerProxy(DISPLAY_ID);
+        final int focusStrokeWidth = mProxyManager.getFocusStrokeWidthLocked(DEVICE_ID);
+        assertThat(focusStrokeWidth).isEqualTo(mFocusStrokeWidthDefaultValue);
+    }
+
+    private void registerProxy(int displayId) {
+        try {
+            mProxyManager.registerProxy(mMockAccessibilityServiceClient, displayId, anyInt(),
+                    mMockSecurityPolicy, mMockConnectionSystemSupport,
+                    mMockA11yTrace, mMockWindowManagerInternal);
+        } catch (RemoteException e) {
+            fail("Failed to register proxy " + e);
+        }
+    }
+
+    private void registerProxy(int displayId, AccessibilityServiceClientImpl serviceClient) {
+        try {
+            mProxyManager.registerProxy(serviceClient, displayId, anyInt(),
+                    mMockSecurityPolicy, mMockConnectionSystemSupport,
+                    mMockA11yTrace, mMockWindowManagerInternal);
+        } catch (RemoteException e) {
+            fail("Failed to register proxy " + e);
+        }
+    }
+
+    /**
+     * IAccessibilityServiceClient implementation.
+     * A proxy connection does not populate non-default AccessibilityServiceInfo values until the
+     * proxy is connected in A11yDisplayProxy#onServiceConnected. For tests that check for
+     * non-default values, populate immediately in this testing class, since a real Service is not
+     * being used and connected.
+     */
+    static class AccessibilityServiceClientImpl extends IAccessibilityServiceClient.Stub {
+        List<AccessibilityServiceInfo> mInstalledAndEnabledServices;
+
+        AccessibilityServiceClientImpl(AccessibilityServiceInfo
+                installedAndEnabledService) {
+            mInstalledAndEnabledServices = List.of(installedAndEnabledService);
+        }
+
+        @Override
+        public void init(IAccessibilityServiceConnection connection, int connectionId,
+                IBinder windowToken) throws RemoteException {
+            connection.setInstalledAndEnabledServices(mInstalledAndEnabledServices);
+        }
+
+        @Override
+        public void onAccessibilityEvent(AccessibilityEvent event, boolean serviceWantsEvent)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public void onInterrupt() throws RemoteException {
+
+        }
+
+        @Override
+        public void onGesture(AccessibilityGestureEvent gestureEvent) throws RemoteException {
+
+        }
+
+        @Override
+        public void clearAccessibilityCache() throws RemoteException {
+
+        }
+
+        @Override
+        public void onKeyEvent(KeyEvent event, int sequence) throws RemoteException {
+
+        }
+
+        @Override
+        public void onMagnificationChanged(int displayId, Region region, MagnificationConfig config)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public void onMotionEvent(MotionEvent event) throws RemoteException {
+
+        }
+
+        @Override
+        public void onTouchStateChanged(int displayId, int state) throws RemoteException {
+
+        }
+
+        @Override
+        public void onSoftKeyboardShowModeChanged(int showMode) throws RemoteException {
+
+        }
+
+        @Override
+        public void onPerformGestureResult(int sequence, boolean completedSuccessfully)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public void onFingerprintCapturingGesturesChanged(boolean capturing)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public void onFingerprintGesture(int gesture) throws RemoteException {
+
+        }
+
+        @Override
+        public void onAccessibilityButtonClicked(int displayId) throws RemoteException {
+
+        }
+
+        @Override
+        public void onAccessibilityButtonAvailabilityChanged(boolean available)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public void onSystemActionsChanged() throws RemoteException {
+
+        }
+
+        @Override
+        public void createImeSession(IAccessibilityInputMethodSessionCallback callback)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public void setImeSessionEnabled(IAccessibilityInputMethodSession session, boolean enabled)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public void bindInput() throws RemoteException {
+
+        }
+
+        @Override
+        public void unbindInput() throws RemoteException {
+
+        }
+
+        @Override
+        public void startInput(IRemoteAccessibilityInputConnection connection,
+                EditorInfo editorInfo, boolean restarting) throws RemoteException {
+
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
index 16406bc..4167c7e 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
@@ -23,8 +23,9 @@
 
 import android.app.ActivityManagerInternal;
 import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.MediumTest;
+import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
@@ -39,13 +40,14 @@
  * Build/Install/Run:
  *  atest FrameworksServicesTests:ActivityManagerInternalTest
  */
+@Presubmit
+@SmallTest
 public class ActivityManagerInternalTest {
     private static final int TEST_UID1 = 111;
     private static final int TEST_UID2 = 112;
 
     private static final long TEST_PROC_STATE_SEQ1 = 1111;
     private static final long TEST_PROC_STATE_SEQ2 = 1112;
-    private static final long TEST_PROC_STATE_SEQ3 = 1113;
 
     @Rule public ServiceThreadRule mServiceThreadRule = new ServiceThreadRule();
 
@@ -68,7 +70,6 @@
         mAmi = mAms.new LocalService();
     }
 
-    @MediumTest
     @Test
     public void testNotifyNetworkPolicyRulesUpdated() throws Exception {
         // Check there is no crash when there are no active uid records.
@@ -89,14 +90,6 @@
                 TEST_PROC_STATE_SEQ1, // lastNetworkUpdateProcStateSeq
                 TEST_PROC_STATE_SEQ1, // procStateSeq to notify
                 false); // expectNotify
-
-        // Notify that network policy rules are updated for TEST_UID1 with procStateSeq older
-        // than it's UidRecord.curProcStateSeq and verify that there is no notify call.
-        verifyNetworkUpdatedProcStateSeq(
-                TEST_PROC_STATE_SEQ3, // curProcStateSeq
-                TEST_PROC_STATE_SEQ1, // lastNetworkUpdateProcStateSeq
-                TEST_PROC_STATE_SEQ2, // procStateSeq to notify
-                false); // expectNotify
     }
 
     private void verifyNetworkUpdatedProcStateSeq(long curProcStateSeq,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
index 07c6182..fb3a5f6 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
@@ -80,7 +80,7 @@
     @Mock
     private WindowManager mWindowManager;
 
-    private OperationContextExt mOpContext = new OperationContextExt();
+    private OperationContextExt mOpContext = new OperationContextExt(true);
     private IBiometricContextListener mListener;
     private BiometricContextProvider mProvider;
 
@@ -316,25 +316,6 @@
         assertThat(aidlContext.isAod).isEqualTo(false);
         assertThat(aidlContext.isCrypto).isEqualTo(false);
 
-        for (int type : List.of(StatusBarManager.SESSION_BIOMETRIC_PROMPT,
-                StatusBarManager.SESSION_KEYGUARD)) {
-            final int id = 40 + type;
-            final boolean aod = (type & 1) == 0;
-
-            mListener.onDisplayStateChanged(aod ? AuthenticateOptions.DISPLAY_STATE_AOD
-                    : AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN);
-            mSessionListener.onSessionStarted(type, InstanceId.fakeInstanceId(id));
-            context = mProvider.updateContext(mOpContext, false /* crypto */);
-            aidlContext = context.toAidlContext();
-            assertThat(context).isSameInstanceAs(mOpContext);
-            assertThat(aidlContext.id).isEqualTo(id);
-            assertThat(aidlContext.reason).isEqualTo(reason(type));
-            assertThat(aidlContext.isAod).isEqualTo(aod);
-            assertThat(aidlContext.isCrypto).isEqualTo(false);
-
-            mSessionListener.onSessionEnded(type, InstanceId.fakeInstanceId(id));
-        }
-
         context = mProvider.updateContext(mOpContext, false /* crypto */);
         aidlContext = context.toAidlContext();
         assertThat(context).isSameInstanceAs(mOpContext);
@@ -344,6 +325,33 @@
         assertThat(aidlContext.isCrypto).isEqualTo(false);
     }
 
+    @Test
+    public void testUpdateAllSessionTypes() throws RemoteException {
+        OperationContextExt context = mProvider.updateContext(mOpContext, false /* crypto */);
+        OperationContext aidlContext = context.toAidlContext();
+
+        for (int type : List.of(StatusBarManager.SESSION_BIOMETRIC_PROMPT,
+                StatusBarManager.SESSION_KEYGUARD)) {
+            final int id = 40 + type;
+            final boolean aod = (type & 1) == 0;
+
+            OperationContextExt opContext =
+                    new OperationContextExt(type == StatusBarManager.SESSION_BIOMETRIC_PROMPT);
+            mListener.onDisplayStateChanged(aod ? AuthenticateOptions.DISPLAY_STATE_AOD
+                    : AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN);
+            mSessionListener.onSessionStarted(type, InstanceId.fakeInstanceId(id));
+            context = mProvider.updateContext(opContext, false /* crypto */);
+            aidlContext = context.toAidlContext();
+            assertThat(context).isSameInstanceAs(opContext);
+            assertThat(aidlContext.id).isEqualTo(id);
+            assertThat(aidlContext.reason).isEqualTo(reason(type));
+            assertThat(aidlContext.isAod).isEqualTo(aod);
+            assertThat(aidlContext.isCrypto).isEqualTo(false);
+
+            mSessionListener.onSessionEnded(type, InstanceId.fakeInstanceId(id));
+        }
+    }
+
     private static byte reason(int type) {
         if (type == StatusBarManager.SESSION_BIOMETRIC_PROMPT) {
             return OperationReason.BIOMETRIC_PROMPT;
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java
index 5adf391..5cff48d 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java
@@ -34,7 +34,7 @@
 
     @Test
     public void testConvertsWakeReason_whenEmpty() {
-        final OperationContextExt ctx = new OperationContextExt();
+        final OperationContextExt ctx = new OperationContextExt(false);
 
         final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
         final int[] reasonDetails = BiometricFrameworkStatsLogger
@@ -48,11 +48,11 @@
     public void testConvertsWakeReason_whenPowerReason() {
         final OperationContext context = new OperationContext();
         context.wakeReason = WakeReason.WAKE_MOTION;
-        final OperationContextExt ctx = new OperationContextExt(context);
+        final OperationContextExt ctx = new OperationContextExt(context, false);
 
         final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
         final int[] reasonDetails = BiometricFrameworkStatsLogger
-                .toProtoWakeReasonDetails(new OperationContextExt(context));
+                .toProtoWakeReasonDetails(new OperationContextExt(context, false));
 
         assertThat(reason).isEqualTo(BiometricsProtoEnums.WAKE_REASON_WAKE_MOTION);
         assertThat(reasonDetails).isEmpty();
@@ -63,7 +63,7 @@
         final OperationContext context = new OperationContext();
         context.authenticateReason = AuthenticateReason.faceAuthenticateReason(
                 AuthenticateReason.Face.ASSISTANT_VISIBLE);
-        final OperationContextExt ctx = new OperationContextExt(context);
+        final OperationContextExt ctx = new OperationContextExt(context, false);
 
         final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
         final int[] reasonDetails = BiometricFrameworkStatsLogger
@@ -79,7 +79,7 @@
         final OperationContext context = new OperationContext();
         context.authenticateReason = AuthenticateReason.vendorAuthenticateReason(
                 new AuthenticateReason.Vendor());
-        final OperationContextExt ctx = new OperationContextExt(context);
+        final OperationContextExt ctx = new OperationContextExt(context, false);
 
         final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
         final int[] reasonDetails = BiometricFrameworkStatsLogger
@@ -96,7 +96,7 @@
         context.wakeReason = WakeReason.WAKE_KEY;
         context.authenticateReason = AuthenticateReason.faceAuthenticateReason(
                 AuthenticateReason.Face.PRIMARY_BOUNCER_SHOWN);
-        final OperationContextExt ctx = new OperationContextExt(context);
+        final OperationContextExt ctx = new OperationContextExt(context, false);
 
         final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
         final int[] reasonDetails = BiometricFrameworkStatsLogger
@@ -113,7 +113,7 @@
         context.wakeReason = WakeReason.LID;
         context.authenticateReason = AuthenticateReason.vendorAuthenticateReason(
                 new AuthenticateReason.Vendor());
-        final OperationContextExt ctx = new OperationContextExt(context);
+        final OperationContextExt ctx = new OperationContextExt(context, false);
 
         final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
         final int[] reasonDetails = BiometricFrameworkStatsLogger
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java
index 81dcf48..612f717 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java
@@ -74,7 +74,7 @@
 
     @Before
     public void setUp() {
-        mOpContext = new OperationContextExt();
+        mOpContext = new OperationContextExt(false);
         mContext.addMockSystemService(SensorManager.class, mSensorManager);
         when(mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)).thenReturn(
                 new Sensor(new InputSensorInfo("", "", 0, 0, Sensor.TYPE_LIGHT, 0, 0, 0, 0, 0, 0,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java
index c652b74..5cf5960 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java
@@ -53,12 +53,12 @@
 
     @Test
     public void hasAidlContext() {
-        OperationContextExt context = new OperationContextExt();
+        OperationContextExt context = new OperationContextExt(false);
         assertThat(context.toAidlContext()).isNotNull();
 
         final OperationContext aidlContext = newAidlContext();
 
-        context = new OperationContextExt(aidlContext);
+        context = new OperationContextExt(aidlContext, false);
         assertThat(context.toAidlContext()).isSameInstanceAs(aidlContext);
 
         final int id = 5;
@@ -79,7 +79,7 @@
 
     @Test
     public void hasNoOrderWithoutSession() {
-        OperationContextExt context = new OperationContextExt();
+        OperationContextExt context = new OperationContextExt(false);
         assertThat(context.getOrderAndIncrement()).isEqualTo(-1);
         assertThat(context.getOrderAndIncrement()).isEqualTo(-1);
     }
@@ -96,7 +96,7 @@
         );
 
         for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
-            final OperationContextExt context = new OperationContextExt(newAidlContext());
+            final OperationContextExt context = new OperationContextExt(newAidlContext(), true);
             when(mBiometricContext.getDisplayState()).thenReturn(entry.getKey());
             assertThat(context.update(mBiometricContext).getDisplayState())
                     .isEqualTo(entry.getValue());
@@ -136,7 +136,8 @@
         when(mBiometricContext.isDisplayOn()).thenReturn(true);
         when(mBiometricContext.getDisplayState()).thenReturn(displayState);
 
-        final OperationContextExt context = new OperationContextExt(newAidlContext());
+        final OperationContextExt context = new OperationContextExt(newAidlContext(),
+                sessionType == OperationReason.BIOMETRIC_PROMPT);
 
         assertThat(context.update(mBiometricContext)).isSameInstanceAs(context);
 
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
index c7fb97f..9d42a5b 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
@@ -18,9 +18,11 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import android.content.ComponentName;
 import android.platform.test.annotations.Presubmit;
 import android.telecom.Call;
 import android.telecom.ParcelableCall;
+import android.telecom.PhoneAccountHandle;
 import android.testing.AndroidTestingRunner;
 
 import androidx.test.InstrumentationRegistry;
@@ -37,12 +39,14 @@
 
     private static final String CALLER_DISPLAY_NAME = "name";
     private static final String CONTACT_DISPLAY_NAME = "contact";
+    private final Call.Details mUninitializedCallDetails = createCallDetails(
+            /* state= */ -1, /* capabilities= */ 0);
 
     @Test
     public void updateCallDetails_uninitialized() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         assertWithMessage("Wrong status").that(crossDeviceCall.getStatus())
                 .isEqualTo(android.companion.Telecom.Call.UNKNOWN_STATUS);
         assertWithMessage("Wrong controls").that(crossDeviceCall.getControls()).isEmpty();
@@ -51,8 +55,8 @@
     @Test
     public void updateCallDetails_ringing() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_RINGING,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
         assertWithMessage("Wrong status").that(crossDeviceCall.getStatus())
@@ -66,8 +70,8 @@
     @Test
     public void updateCallDetails_ongoing() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_ACTIVE,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
         assertWithMessage("Wrong status").that(crossDeviceCall.getStatus())
@@ -81,8 +85,8 @@
     @Test
     public void updateCallDetails_holding() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_HOLDING,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
         assertWithMessage("Wrong status").that(crossDeviceCall.getStatus())
@@ -95,8 +99,8 @@
     @Test
     public void updateCallDetails_cannotHold() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(
                 createCallDetails(Call.STATE_ACTIVE, Call.Details.CAPABILITY_MUTE));
         assertWithMessage("Wrong status").that(crossDeviceCall.getStatus())
@@ -109,8 +113,8 @@
     @Test
     public void updateCallDetails_cannotMute() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(
                 createCallDetails(Call.STATE_ACTIVE, Call.Details.CAPABILITY_HOLD));
         assertWithMessage("Wrong status").that(crossDeviceCall.getStatus())
@@ -123,8 +127,8 @@
     @Test
     public void updateCallDetails_transitionRingingToOngoing() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_RINGING,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
         assertWithMessage("Wrong status for ringing state").that(crossDeviceCall.getStatus())
@@ -146,8 +150,8 @@
     @Test
     public void updateSilencedIfRinging_ringing_silenced() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_RINGING,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
         crossDeviceCall.updateSilencedIfRinging();
@@ -161,8 +165,8 @@
     @Test
     public void updateSilencedIfRinging_notRinging_notSilenced() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_ACTIVE,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
         crossDeviceCall.updateSilencedIfRinging();
@@ -177,8 +181,8 @@
     @Test
     public void getReadableCallerId_enterpriseCall_adminBlocked_ott() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = true;
         crossDeviceCall.mIsOtt = true;
         crossDeviceCall.updateCallDetails(
@@ -193,8 +197,8 @@
     @Test
     public void getReadableCallerId_enterpriseCall_adminUnblocked_ott() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = true;
         crossDeviceCall.mIsOtt = true;
         crossDeviceCall.updateCallDetails(
@@ -209,8 +213,8 @@
     @Test
     public void getReadableCallerId_enterpriseCall_adminBlocked_pstn() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = true;
         crossDeviceCall.mIsOtt = false;
         crossDeviceCall.updateCallDetails(
@@ -225,8 +229,8 @@
     @Test
     public void getReadableCallerId_nonEnterpriseCall_adminBlocked_ott() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = false;
         crossDeviceCall.mIsOtt = true;
         crossDeviceCall.updateCallDetails(
@@ -241,8 +245,8 @@
     @Test
     public void getReadableCallerId_nonEnterpriseCall_adminUnblocked_ott() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = false;
         crossDeviceCall.mIsOtt = true;
         crossDeviceCall.updateCallDetails(
@@ -257,8 +261,8 @@
     @Test
     public void getReadableCallerId_nonEnterpriseCall_adminBlocked_pstn() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = false;
         crossDeviceCall.mIsOtt = false;
         crossDeviceCall.updateCallDetails(
@@ -273,8 +277,8 @@
     @Test
     public void getReadableCallerId_nonEnterpriseCall_adminUnblocked_pstn() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(), /* call= */
-                null, /* callAudioState= */ null);
+                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = false;
         crossDeviceCall.mIsOtt = false;
         crossDeviceCall.updateCallDetails(
@@ -294,6 +298,8 @@
         parcelableCallBuilder.setCapabilities(capabilities);
         parcelableCallBuilder.setState(state);
         parcelableCallBuilder.setConferenceableCallIds(Collections.emptyList());
+        parcelableCallBuilder.setAccountHandle(new PhoneAccountHandle(
+                new ComponentName("com.google.test", "com.google.test.Activity"), "label"));
         return Call.Details.createFromParcelableCall(parcelableCallBuilder.createParcelableCall());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
new file mode 100644
index 0000000..eec026cc
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion.datatransfer.contextsync;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.when;
+
+import android.platform.test.annotations.Presubmit;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.companion.transport.CompanionTransportManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Presubmit
+@RunWith(AndroidTestingRunner.class)
+public class CrossDeviceSyncControllerTest {
+
+    private CrossDeviceSyncController mCrossDeviceSyncController;
+    @Mock
+    private CompanionTransportManager mMockCompanionTransportManager;
+    @Mock
+    private CrossDeviceCall mMockCrossDeviceCall;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mCrossDeviceSyncController = new CrossDeviceSyncController(
+                InstrumentationRegistry.getInstrumentation().getContext(),
+                mMockCompanionTransportManager);
+    }
+
+    @Test
+    public void processTelecomDataFromSync_createCallUpdateMessage_emptyCallsAndRequests() {
+        final byte[] data = mCrossDeviceSyncController.createCallUpdateMessage(new HashSet<>(),
+                InstrumentationRegistry.getInstrumentation().getContext().getUserId());
+        final CallMetadataSyncData callMetadataSyncData =
+                mCrossDeviceSyncController.processTelecomDataFromSync(data);
+        assertWithMessage("Unexpectedly found a call").that(
+                callMetadataSyncData.getCalls()).isEmpty();
+        assertWithMessage("Unexpectedly found a request").that(
+                callMetadataSyncData.getRequests()).isEmpty();
+    }
+
+    @Test
+    public void processTelecomDataFromSync_createEmptyMessage_emptyCallsAndRequests() {
+        final byte[] data = CrossDeviceSyncController.createEmptyMessage();
+        final CallMetadataSyncData callMetadataSyncData =
+                mCrossDeviceSyncController.processTelecomDataFromSync(data);
+        assertWithMessage("Unexpectedly found a call").that(
+                callMetadataSyncData.getCalls()).isEmpty();
+        assertWithMessage("Unexpectedly found a request").that(
+                callMetadataSyncData.getRequests()).isEmpty();
+    }
+
+    @Test
+    public void processTelecomDataFromSync_createCallUpdateMessage_hasCalls() {
+        when(mMockCrossDeviceCall.getId()).thenReturn(5L);
+        final String callerId = "Firstname Lastname";
+        when(mMockCrossDeviceCall.getReadableCallerId(anyBoolean())).thenReturn(callerId);
+        final String appName = "AppName";
+        when(mMockCrossDeviceCall.getCallingAppName()).thenReturn(appName);
+        final String appIcon = "ABCD";
+        when(mMockCrossDeviceCall.getCallingAppIcon()).thenReturn(appIcon.getBytes());
+        when(mMockCrossDeviceCall.getStatus()).thenReturn(android.companion.Telecom.Call.RINGING);
+        final Set<Integer> controls = Set.of(
+                android.companion.Telecom.Call.ACCEPT,
+                android.companion.Telecom.Call.REJECT,
+                android.companion.Telecom.Call.SILENCE);
+        when(mMockCrossDeviceCall.getControls()).thenReturn(controls);
+        final byte[] data = mCrossDeviceSyncController.createCallUpdateMessage(
+                new HashSet<>(List.of(mMockCrossDeviceCall)),
+                InstrumentationRegistry.getInstrumentation().getContext().getUserId());
+        final CallMetadataSyncData callMetadataSyncData =
+                mCrossDeviceSyncController.processTelecomDataFromSync(data);
+        assertWithMessage("Wrong number of active calls").that(
+                callMetadataSyncData.getCalls()).hasSize(1);
+        final CallMetadataSyncData.Call call =
+                callMetadataSyncData.getCalls().stream().findAny().orElseThrow();
+        assertWithMessage("Wrong id").that(call.getId()).isEqualTo(5L);
+        assertWithMessage("Wrong app icon").that(new String(call.getAppIcon())).isEqualTo(appIcon);
+        assertWithMessage("Wrong app name").that(call.getAppName()).isEqualTo(appName);
+        assertWithMessage("Wrong caller id").that(call.getCallerId()).isEqualTo(callerId);
+        assertWithMessage("Wrong status").that(call.getStatus())
+                .isEqualTo(android.companion.Telecom.Call.RINGING);
+        assertWithMessage("Wrong controls").that(call.getControls()).isEqualTo(controls);
+        assertWithMessage("Unexpectedly has requests").that(
+                callMetadataSyncData.getRequests()).isEmpty();
+    }
+
+    @Test
+    public void processTelecomDataFromMessage_createCallControlMessage_hasCallControlRequest() {
+        final byte[] data = CrossDeviceSyncController.createCallControlMessage(
+                /* callId= */ 5L, /* status= */ android.companion.Telecom.Call.ACCEPT);
+        final CallMetadataSyncData callMetadataSyncData =
+                mCrossDeviceSyncController.processTelecomDataFromSync(data);
+        assertWithMessage("Wrong number of requests").that(
+                callMetadataSyncData.getRequests()).hasSize(1);
+        final CallMetadataSyncData.Call call =
+                callMetadataSyncData.getRequests().stream().findAny().orElseThrow();
+        assertWithMessage("Wrong id").that(call.getId()).isEqualTo(5L);
+        assertWithMessage("Wrong app icon").that(call.getAppIcon()).isNull();
+        assertWithMessage("Wrong app name").that(call.getAppName()).isNull();
+        assertWithMessage("Wrong caller id").that(call.getCallerId()).isNull();
+        assertWithMessage("Wrong status").that(call.getStatus())
+                .isEqualTo(android.companion.Telecom.Call.UNKNOWN_STATUS);
+        assertWithMessage("Wrong controls").that(call.getControls())
+                .isEqualTo(Set.of(android.companion.Telecom.Call.ACCEPT));
+        assertWithMessage("Unexpectedly has active calls").that(
+                callMetadataSyncData.getCalls()).isEmpty();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 16aadac..1e342f5 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -130,6 +130,7 @@
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
 import android.os.IpcDataCache;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -3267,31 +3268,31 @@
         reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 0);
-        verifyScreenTimeoutCall(null, UserHandle.USER_SYSTEM);
+        verifyScreenTimeoutCall(null, CALLER_USER_HANDLE);
         verifyStayOnWhilePluggedCleared(false);
         reset(getServices().powerManagerInternal);
         reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 1);
-        verifyScreenTimeoutCall(1L, UserHandle.USER_SYSTEM);
+        verifyScreenTimeoutCall(1L, CALLER_USER_HANDLE);
         verifyStayOnWhilePluggedCleared(true);
         reset(getServices().powerManagerInternal);
         reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, 10);
-        verifyScreenTimeoutCall(null, UserHandle.USER_SYSTEM);
+        verifyScreenTimeoutCall(null, CALLER_USER_HANDLE);
         verifyStayOnWhilePluggedCleared(false);
         reset(getServices().powerManagerInternal);
         reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin1, 5);
-        verifyScreenTimeoutCall(5L, UserHandle.USER_SYSTEM);
+        verifyScreenTimeoutCall(5L, CALLER_USER_HANDLE);
         verifyStayOnWhilePluggedCleared(true);
         reset(getServices().powerManagerInternal);
         reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, 4);
-        verifyScreenTimeoutCall(4L, UserHandle.USER_SYSTEM);
+        verifyScreenTimeoutCall(4L, CALLER_USER_HANDLE);
         verifyStayOnWhilePluggedCleared(true);
         reset(getServices().powerManagerInternal);
         reset(getServices().settings);
@@ -3301,20 +3302,20 @@
         reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, Long.MAX_VALUE);
-        verifyScreenTimeoutCall(Long.MAX_VALUE, UserHandle.USER_SYSTEM);
+        verifyScreenTimeoutCall(Long.MAX_VALUE, CALLER_USER_HANDLE);
         verifyStayOnWhilePluggedCleared(true);
         reset(getServices().powerManagerInternal);
         reset(getServices().settings);
 
         dpm.setMaximumTimeToLock(admin2, 10);
-        verifyScreenTimeoutCall(10L, UserHandle.USER_SYSTEM);
+        verifyScreenTimeoutCall(10L, CALLER_USER_HANDLE);
         verifyStayOnWhilePluggedCleared(true);
         reset(getServices().powerManagerInternal);
         reset(getServices().settings);
 
         // There's no restriction; should be set to MAX.
         dpm.setMaximumTimeToLock(admin2, 0);
-        verifyScreenTimeoutCall(Long.MAX_VALUE, UserHandle.USER_SYSTEM);
+        verifyScreenTimeoutCall(Long.MAX_VALUE, CALLER_USER_HANDLE);
         verifyStayOnWhilePluggedCleared(false);
     }
 
@@ -8526,6 +8527,46 @@
                 eq(FUSED_PROVIDER), any(), eq(getServices().executor), any());
     }
 
+    /**
+     * Verifies that bundles with tons of moderately long strings are persisted correctly.
+     *
+     * Policy is serialized into binary XML and there is a limit on the max string length: 65535.
+     * This test ensures that as long as each string in the trust agent configuration is below this
+     * limit, the policy can be serialized and deserialized correctly, even when the total length
+     * of the configuration is above that limit. This should be the case because PersistableBundle
+     * contents are stored as XML subtrees rather than as strings.
+     */
+    @Test
+    public void testSetTrustAgentConfiguration_largeBundlePersisted() {
+        setAsProfileOwner(admin1);
+
+        ComponentName agent = new ComponentName("some.trust.agent", "some.trust.agent.Agent");
+        PersistableBundle configIn = new PersistableBundle();
+        String kilobyteString = new String(new char[1024]).replace('\0', 'A');
+        for (int i = 0; i < 1024; i++) {
+            configIn.putString("key-" + i, kilobyteString);
+        }
+
+        runAsCaller(mAdmin1Context, dpms, dpm -> {
+            dpm.setTrustAgentConfiguration(admin1, agent, configIn);
+        });
+
+        // Re-read policies to see if they were serialized/deserialized correctly.
+        initializeDpms();
+
+        List<PersistableBundle> configsOut = new ArrayList<>();
+        runAsCaller(mAdmin1Context, dpms, dpm -> {
+            configsOut.addAll(dpm.getTrustAgentConfiguration(admin1, agent));
+        });
+
+        assertThat(configsOut.size()).isEqualTo(1);
+        PersistableBundle configOut = configsOut.get(0);
+        assertThat(configOut.size()).isEqualTo(1024);
+        for (int i = 0; i < 1024; i++) {
+            assertThat(configOut.getString("key-" + i, null)).isEqualTo(kilobyteString);
+        }
+    }
+
     private void setupVpnAuthorization(String userVpnPackage, int userVpnUid) {
         final AppOpsManager.PackageOps vpnOp = new AppOpsManager.PackageOps(userVpnPackage,
                 userVpnUid, List.of(new AppOpsManager.OpEntry(
diff --git a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
index 3b10db4..e2a66f0 100644
--- a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
@@ -16,8 +16,6 @@
 
 package com.android.server.display;
 
-import static android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
-import static android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL;
 import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR;
 import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
 import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT;
@@ -29,6 +27,8 @@
 import static com.android.server.display.HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.anyFloat;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.eq;
@@ -39,14 +39,10 @@
 
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.hardware.display.BrightnessInfo;
 import android.os.Binder;
 import android.os.Handler;
-import android.os.IThermalEventListener;
-import android.os.IThermalService;
 import android.os.Message;
-import android.os.PowerManager;
-import android.os.Temperature;
-import android.os.Temperature.ThrottlingStatus;
 import android.os.test.TestLooper;
 import android.test.mock.MockContentResolver;
 import android.util.MathUtils;
@@ -66,8 +62,6 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -80,7 +74,6 @@
     private static final long TIME_WINDOW_MILLIS = 55 * 1000;
     private static final long TIME_ALLOWED_IN_WINDOW_MILLIS = 12 * 1000;
     private static final long TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS = 5 * 1000;
-    private static final int THERMAL_STATUS_LIMIT = PowerManager.THERMAL_STATUS_SEVERE;
     private static final boolean ALLOW_IN_LOW_POWER_MODE = false;
 
     private static final float DEFAULT_MIN = 0.01f;
@@ -102,17 +95,13 @@
     @Rule
     public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
 
-    @Mock IThermalService mThermalServiceMock;
     @Mock Injector mInjectorMock;
     @Mock HighBrightnessModeController.HdrBrightnessDeviceConfig mHdrBrightnessDeviceConfigMock;
 
-    @Captor ArgumentCaptor<IThermalEventListener> mThermalEventListenerCaptor;
-
     private static final HighBrightnessModeData DEFAULT_HBM_DATA =
             new HighBrightnessModeData(MINIMUM_LUX, TRANSITION_POINT, TIME_WINDOW_MILLIS,
                     TIME_ALLOWED_IN_WINDOW_MILLIS, TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS,
-                    THERMAL_STATUS_LIMIT, ALLOW_IN_LOW_POWER_MODE,
-                    HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT);
+                    ALLOW_IN_LOW_POWER_MODE, HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT);
 
     @Before
     public void setUp() {
@@ -125,8 +114,6 @@
         mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
         final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
         when(mContextSpy.getContentResolver()).thenReturn(resolver);
-
-        when(mInjectorMock.getThermalService()).thenReturn(mThermalServiceMock);
     }
 
     /////////////////
@@ -321,34 +308,14 @@
     }
 
     @Test
-    public void testNoHbmInHighThermalState() throws Exception {
+    public void testHbmIsNotTurnedOffInHighThermalState() throws Exception {
         final HighBrightnessModeController hbmc = createDefaultHbm(new OffsettableClock());
 
-        verify(mThermalServiceMock).registerThermalEventListenerWithType(
-                mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
-        final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
+        // Disabled thermal throttling
+        hbmc.onBrightnessChanged(/*brightness=*/ 1f, /*unthrottledBrightness*/ 1f,
+                BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
 
-        // Set the thermal status too high.
-        listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL));
-
-        // Try to go into HBM mode but fail
-        hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED);
-        hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
-        advanceTime(10);
-
-        assertEquals(HIGH_BRIGHTNESS_MODE_OFF, hbmc.getHighBrightnessMode());
-    }
-
-    @Test
-    public void testHbmTurnsOffInHighThermalState() throws Exception {
-        final HighBrightnessModeController hbmc = createDefaultHbm(new OffsettableClock());
-
-        verify(mThermalServiceMock).registerThermalEventListenerWithType(
-                mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
-        final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
-
-        // Set the thermal status tolerable
-        listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_LIGHT));
+        assertFalse(hbmc.isThermalThrottlingActive());
 
         // Try to go into HBM mode
         hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED);
@@ -357,15 +324,19 @@
 
         assertEquals(HIGH_BRIGHTNESS_MODE_SUNLIGHT, hbmc.getHighBrightnessMode());
 
-        // Set the thermal status too high and verify we're off.
-        listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL));
+        // Enable thermal throttling
+        hbmc.onBrightnessChanged(/*brightness=*/ TRANSITION_POINT - 0.01f,
+                /*unthrottledBrightness*/ 1f, BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL);
         advanceTime(10);
-        assertEquals(HIGH_BRIGHTNESS_MODE_OFF, hbmc.getHighBrightnessMode());
+        assertEquals(HIGH_BRIGHTNESS_MODE_SUNLIGHT, hbmc.getHighBrightnessMode());
+        assertTrue(hbmc.isThermalThrottlingActive());
 
-        // Set the thermal status low again and verify we're back on.
-        listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_SEVERE));
+        // Disabled thermal throttling
+        hbmc.onBrightnessChanged(/*brightness=*/ 1f, /*unthrottledBrightness*/ 1f,
+                BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
         advanceTime(1);
         assertEquals(HIGH_BRIGHTNESS_MODE_SUNLIGHT, hbmc.getHighBrightnessMode());
+        assertFalse(hbmc.isThermalThrottlingActive());
     }
 
     @Test
@@ -578,33 +549,6 @@
             anyInt());
     }
 
-    // Test reporting of thermal throttling when triggered by HighBrightnessModeController's
-    // internal thermal throttling.
-    @Test
-    public void testHbmStats_InternalThermalOff() throws Exception {
-        final HighBrightnessModeController hbmc = createDefaultHbm(new OffsettableClock());
-        final int displayStatsId = mDisplayUniqueId.hashCode();
-
-        verify(mThermalServiceMock).registerThermalEventListenerWithType(
-                mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
-        final IThermalEventListener thermListener = mThermalEventListenerCaptor.getValue();
-
-        hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED);
-        hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
-        hbmcOnBrightnessChanged(hbmc, TRANSITION_POINT + 0.01f);
-        advanceTime(1);
-        verify(mInjectorMock).reportHbmStateChange(eq(displayStatsId),
-            eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT),
-            eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_TRANSITION_REASON_UNKNOWN));
-
-        thermListener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL));
-        advanceTime(10);
-        assertEquals(HIGH_BRIGHTNESS_MODE_OFF, hbmc.getHighBrightnessMode());
-        verify(mInjectorMock).reportHbmStateChange(eq(displayStatsId),
-            eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF),
-            eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_THERMAL_LIMIT));
-    }
-
     // Test reporting of thermal throttling when triggered externally through
     // HighBrightnessModeController.onBrightnessChanged()
     @Test
@@ -617,14 +561,16 @@
         hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED);
         hbmc.onAmbientLuxChange(MINIMUM_LUX + 1);
         // Brightness is unthrottled, HBM brightness granted
-        hbmc.onBrightnessChanged(hbmBrightness, hbmBrightness, BRIGHTNESS_MAX_REASON_NONE);
+        hbmc.onBrightnessChanged(hbmBrightness, hbmBrightness,
+                BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
         advanceTime(1);
         verify(mInjectorMock).reportHbmStateChange(eq(displayStatsId),
             eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT),
             eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_TRANSITION_REASON_UNKNOWN));
 
         // Brightness is thermally throttled, HBM brightness denied (NBM brightness granted)
-        hbmc.onBrightnessChanged(nbmBrightness, hbmBrightness, BRIGHTNESS_MAX_REASON_THERMAL);
+        hbmc.onBrightnessChanged(nbmBrightness, hbmBrightness,
+                BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL);
         advanceTime(1);
         // We expect HBM mode to remain set to sunlight, indicating that HBMC *allows* this mode.
         // However, we expect the HBM state reported by HBMC to be off, since external thermal
@@ -784,11 +730,7 @@
         mTestLooper.dispatchAll();
     }
 
-    private Temperature getSkinTemp(@ThrottlingStatus int status) {
-        return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status);
-    }
-
     private void hbmcOnBrightnessChanged(HighBrightnessModeController hbmc, float brightness) {
-        hbmc.onBrightnessChanged(brightness, brightness, BRIGHTNESS_MAX_REASON_NONE);
+        hbmc.onBrightnessChanged(brightness, brightness, BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
     }
 }
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 7536c79..1eec70d 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -649,9 +649,9 @@
         assertEquals(0, mLogicalDisplayMapper.getDisplayLocked(device2)
                 .getLeadDisplayIdLocked());
         assertEquals("concurrent", mLogicalDisplayMapper.getDisplayLocked(device1)
-                .getThermalBrightnessThrottlingDataIdLocked());
+                .getDisplayInfoLocked().thermalBrightnessThrottlingDataId);
         assertEquals("concurrent", mLogicalDisplayMapper.getDisplayLocked(device2)
-                .getThermalBrightnessThrottlingDataIdLocked());
+                .getDisplayInfoLocked().thermalBrightnessThrottlingDataId);
 
         mLogicalDisplayMapper.setDeviceStateLocked(1, false);
         advanceTime(1000);
@@ -661,10 +661,10 @@
         assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked());
         assertEquals(DisplayDeviceConfig.DEFAULT_ID,
                 mLogicalDisplayMapper.getDisplayLocked(device1)
-                        .getThermalBrightnessThrottlingDataIdLocked());
+                        .getDisplayInfoLocked().thermalBrightnessThrottlingDataId);
         assertEquals(DisplayDeviceConfig.DEFAULT_ID,
                 mLogicalDisplayMapper.getDisplayLocked(device2)
-                        .getThermalBrightnessThrottlingDataIdLocked());
+                        .getDisplayInfoLocked().thermalBrightnessThrottlingDataId);
 
         mLogicalDisplayMapper.setDeviceStateLocked(2, false);
         advanceTime(1000);
@@ -674,10 +674,10 @@
         assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked());
         assertEquals(DisplayDeviceConfig.DEFAULT_ID,
                 mLogicalDisplayMapper.getDisplayLocked(device1)
-                        .getThermalBrightnessThrottlingDataIdLocked());
+                        .getDisplayInfoLocked().thermalBrightnessThrottlingDataId);
         assertEquals(DisplayDeviceConfig.DEFAULT_ID,
                 mLogicalDisplayMapper.getDisplayLocked(device2)
-                        .getThermalBrightnessThrottlingDataIdLocked());
+                        .getDisplayInfoLocked().thermalBrightnessThrottlingDataId);
     }
 
     @Test
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 5ea3029..f6cf571 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
@@ -205,4 +205,19 @@
         assertNotEquals(info3, info2);
         assertTrue(refreshRanges.contentEquals(info3.thermalRefreshRateThrottling));
     }
+
+    @Test
+    public void testSetThermalBrightnessThrottlingDataId() {
+        String brightnessThrottlingDataId = "throttling_data_id";
+        DisplayInfo info1 = mLogicalDisplay.getDisplayInfoLocked();
+        mLogicalDisplay.setThermalBrightnessThrottlingDataIdLocked(brightnessThrottlingDataId);
+        DisplayInfo info2 = mLogicalDisplay.getDisplayInfoLocked();
+        // Display info should only be updated when updateLocked is called
+        assertEquals(info2, info1);
+
+        mLogicalDisplay.updateLocked(mDeviceRepo);
+        DisplayInfo info3 = mLogicalDisplay.getDisplayInfoLocked();
+        assertNotEquals(info3, info2);
+        assertEquals(brightnessThrottlingDataId, info3.thermalBrightnessThrottlingDataId);
+    }
 }
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 d7b12e0..e6d3bbc 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
@@ -19,10 +19,13 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -66,25 +69,27 @@
     @Mock
     private HandlerExecutor mBrightnessChangeExecutor;
 
+    private final DisplayBrightnessController.Injector mInjector = new
+            DisplayBrightnessController.Injector() {
+        @Override
+        DisplayBrightnessStrategySelector getDisplayBrightnessStrategySelector(
+                Context context, int displayId) {
+            return mDisplayBrightnessStrategySelector;
+        }
+    };
+
     private DisplayBrightnessController mDisplayBrightnessController;
 
     @Before
     public void before() {
         MockitoAnnotations.initMocks(this);
         when(mContext.getResources()).thenReturn(mResources);
-        DisplayBrightnessController.Injector injector = new DisplayBrightnessController.Injector() {
-            @Override
-            DisplayBrightnessStrategySelector getDisplayBrightnessStrategySelector(
-                    Context context, int displayId) {
-                return mDisplayBrightnessStrategySelector;
-            }
-        };
         when(mBrightnessSetting.getBrightness()).thenReturn(Float.NaN);
         when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(-1f);
         when(mResources.getBoolean(
                 com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay))
                 .thenReturn(true);
-        mDisplayBrightnessController = new DisplayBrightnessController(mContext, injector,
+        mDisplayBrightnessController = new DisplayBrightnessController(mContext, mInjector,
                 DISPLAY_ID, DEFAULT_BRIGHTNESS, mBrightnessSetting, mOnBrightnessChangeRunnable,
                 mBrightnessChangeExecutor);
     }
@@ -257,27 +262,6 @@
     }
 
     @Test
-    public void testBrightnessNitsForDefaultDisplay() {
-        float brightness = 0.3f;
-        float nits = 500;
-        AutomaticBrightnessController automaticBrightnessController =
-                mock(AutomaticBrightnessController.class);
-        when(automaticBrightnessController.convertToFloatScale(nits)).thenReturn(brightness);
-        when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits);
-
-        mDisplayBrightnessController.setAutomaticBrightnessController(
-                automaticBrightnessController);
-        assertEquals(brightness, mDisplayBrightnessController.getCurrentBrightness(),
-                /* delta= */ 0);
-
-        float newBrightness = 0.5f;
-        float newNits = 700;
-        when(automaticBrightnessController.convertToNits(newBrightness)).thenReturn(newNits);
-        mDisplayBrightnessController.setBrightness(newBrightness);
-        verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(newNits);
-    }
-
-    @Test
     public void testConvertToNits() {
         final float brightness = 0.5f;
         final float nits = 300;
@@ -330,4 +314,48 @@
         mDisplayBrightnessController.stop();
         verify(mBrightnessSetting).unregisterListener(brightnessSettingListener);
     }
+
+    @Test
+    public void testLoadNitBasedBrightnessSetting() {
+        // When the nits value is valid, the brightness is set from the old default display nits
+        // value
+        float nits = 200f;
+        float brightness = 0.3f;
+        AutomaticBrightnessController automaticBrightnessController =
+                mock(AutomaticBrightnessController.class);
+        when(automaticBrightnessController.convertToFloatScale(nits)).thenReturn(brightness);
+        when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits);
+        mDisplayBrightnessController.setAutomaticBrightnessController(
+                automaticBrightnessController);
+        verify(mBrightnessSetting).setBrightness(brightness);
+        assertEquals(brightness, mDisplayBrightnessController.getCurrentBrightness(), 0.01f);
+        clearInvocations(automaticBrightnessController, mBrightnessSetting);
+
+        // When the nits value is invalid, the brightness is resumed from where it was last set
+        nits = -1;
+        brightness = 0.4f;
+        when(automaticBrightnessController.convertToFloatScale(nits)).thenReturn(brightness);
+        when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits);
+        when(mBrightnessSetting.getBrightness()).thenReturn(brightness);
+        mDisplayBrightnessController.setAutomaticBrightnessController(
+                automaticBrightnessController);
+        verify(mBrightnessSetting, never()).setBrightness(brightness);
+        assertEquals(brightness, mDisplayBrightnessController.getCurrentBrightness(), 0.01f);
+        clearInvocations(automaticBrightnessController, mBrightnessSetting);
+
+        // When the display is a non-default display, the brightness is resumed from where it was
+        // last set
+        int nonDefaultDisplayId = 1;
+        mDisplayBrightnessController = new DisplayBrightnessController(mContext, mInjector,
+                nonDefaultDisplayId, DEFAULT_BRIGHTNESS, mBrightnessSetting,
+                mOnBrightnessChangeRunnable, mBrightnessChangeExecutor);
+        brightness = 0.5f;
+        when(mBrightnessSetting.getBrightness()).thenReturn(brightness);
+        mDisplayBrightnessController.setAutomaticBrightnessController(
+                automaticBrightnessController);
+        assertEquals(brightness, mDisplayBrightnessController.getCurrentBrightness(), 0.01f);
+        verifyZeroInteractions(automaticBrightnessController);
+        verify(mBrightnessSetting, never()).getBrightnessNitsForDefaultDisplay();
+        verify(mBrightnessSetting, never()).setBrightness(brightness);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
index eb208d2..d9cf15b 100644
--- a/services/tests/servicestests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
@@ -18,6 +18,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -40,6 +41,7 @@
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.util.test.FakeSettingsProviderRule;
 import com.android.server.display.AutomaticBrightnessController;
+import com.android.server.display.brightness.BrightnessEvent;
 import com.android.server.display.brightness.BrightnessReason;
 
 import org.junit.After;
@@ -262,12 +264,13 @@
         float automaticScreenBrightness = 0.3f;
         AutomaticBrightnessController automaticBrightnessController = mock(
                 AutomaticBrightnessController.class);
-        when(automaticBrightnessController.getAutomaticScreenBrightness()).thenReturn(
-                automaticScreenBrightness);
+        when(automaticBrightnessController.getAutomaticScreenBrightness(any(BrightnessEvent.class)))
+                .thenReturn(automaticScreenBrightness);
         mAutomaticBrightnessStrategy.setAutomaticBrightnessController(
                 automaticBrightnessController);
         assertEquals(automaticScreenBrightness,
-                mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(), 0.0f);
+                mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(
+                        new BrightnessEvent(DISPLAY_ID)), 0.0f);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
index 4cfcee5..b2a3a57 100644
--- a/services/tests/servicestests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
@@ -27,7 +27,7 @@
 import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE;
 import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_LOW_ZONE;
 
-import static com.android.server.display.mode.DisplayModeDirector.Vote.INVALID_SIZE;
+import static com.android.server.display.mode.Vote.INVALID_SIZE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -84,7 +84,6 @@
 
 import com.android.internal.R;
 import com.android.internal.display.BrightnessSynchronizer;
-import com.android.internal.display.RefreshRateSettingsUtils;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.test.FakeSettingsProvider;
@@ -94,7 +93,6 @@
 import com.android.server.display.TestUtils;
 import com.android.server.display.mode.DisplayModeDirector.BrightnessObserver;
 import com.android.server.display.mode.DisplayModeDirector.DesiredDisplayModeSpecs;
-import com.android.server.display.mode.DisplayModeDirector.Vote;
 import com.android.server.sensors.SensorManagerInternal;
 import com.android.server.sensors.SensorManagerInternal.ProximityActiveListener;
 import com.android.server.statusbar.StatusBarManagerInternal;
@@ -160,9 +158,6 @@
         LocalServices.addService(SensorManagerInternal.class, mSensorManagerInternalMock);
         LocalServices.removeServiceForTest(DisplayManagerInternal.class);
         LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock);
-
-        clearSmoothDisplaySetting();
-        clearForcePeakRefreshRateSetting();
     }
 
     private DisplayModeDirector createDirectorFromRefreshRateArray(
@@ -224,8 +219,7 @@
         assertThat(modeSpecs.appRequest.render.min).isEqualTo(0f);
         assertThat(modeSpecs.appRequest.render.max).isEqualTo(Float.POSITIVE_INFINITY);
 
-        int numPriorities =
-                DisplayModeDirector.Vote.MAX_PRIORITY - DisplayModeDirector.Vote.MIN_PRIORITY + 1;
+        int numPriorities =  Vote.MAX_PRIORITY - Vote.MIN_PRIORITY + 1;
 
         // Ensure vote priority works as expected. As we add new votes with higher priority, they
         // should take precedence over lower priority votes.
@@ -924,6 +918,7 @@
     public void testLockFpsForLowZone() throws Exception {
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
+        setPeakRefreshRate(90);
         director.getSettingsObserver().setDefaultRefreshRate(90);
         director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
 
@@ -931,7 +926,6 @@
         config.setRefreshRateInLowZone(90);
         config.setLowDisplayBrightnessThresholds(new int[] { 10 });
         config.setLowAmbientBrightnessThresholds(new int[] { 20 });
-        config.setDefaultPeakRefreshRate(90);
 
         Sensor lightSensor = createLightSensor();
         SensorManager sensorManager = createMockSensorManager(lightSensor);
@@ -982,6 +976,7 @@
     public void testLockFpsForHighZone() throws Exception {
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
+        setPeakRefreshRate(90 /*fps*/);
         director.getSettingsObserver().setDefaultRefreshRate(90);
         director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
 
@@ -989,7 +984,6 @@
         config.setRefreshRateInHighZone(60);
         config.setHighDisplayBrightnessThresholds(new int[] { 255 });
         config.setHighAmbientBrightnessThresholds(new int[] { 8000 });
-        config.setDefaultPeakRefreshRate(90);
 
         Sensor lightSensor = createLightSensor();
         SensorManager sensorManager = createMockSensorManager(lightSensor);
@@ -1037,123 +1031,16 @@
     }
 
     @Test
-    public void testSmoothDisplay() {
-        float defaultRefreshRate = 60;
-        int defaultPeakRefreshRate = 100;
-        DisplayModeDirector director =
-                createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
-        director.getSettingsObserver().setDefaultRefreshRate(defaultRefreshRate);
-        director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
-
-        final FakeDeviceConfig config = mInjector.getDeviceConfig();
-        config.setDefaultPeakRefreshRate(defaultPeakRefreshRate);
-
-        Sensor lightSensor = createLightSensor();
-        SensorManager sensorManager = createMockSensorManager(lightSensor);
-        director.start(sensorManager);
-
-        // Default value of the setting
-
-        Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                defaultPeakRefreshRate);
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                Float.POSITIVE_INFINITY);
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                defaultRefreshRate);
-
-        setSmoothDisplayEnabled(false);
-
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE);
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                Float.POSITIVE_INFINITY);
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                defaultRefreshRate);
-
-        setSmoothDisplayEnabled(true);
-
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                Float.POSITIVE_INFINITY);
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                defaultRefreshRate);
-    }
-
-    @Test
-    public void testForcePeakRefreshRate() {
-        float defaultRefreshRate = 60;
-        DisplayModeDirector director =
-                createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
-        director.getSettingsObserver().setDefaultRefreshRate(defaultRefreshRate);
-        director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
-
-        Sensor lightSensor = createLightSensor();
-        SensorManager sensorManager = createMockSensorManager(lightSensor);
-        director.start(sensorManager);
-
-        setForcePeakRefreshRateEnabled(false);
-        setSmoothDisplayEnabled(false);
-
-        Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE);
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0,
-                /* frameRateHigh= */ Float.POSITIVE_INFINITY);
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                defaultRefreshRate);
-
-        setForcePeakRefreshRateEnabled(true);
-
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */
-                RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
-                /* frameRateHigh= */ Float.POSITIVE_INFINITY);
-        vote = director.getVote(Display.DEFAULT_DISPLAY,
-                Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
-                defaultRefreshRate);
-    }
-
-    @Test
     public void testSensorRegistration() {
         // First, configure brightness zones or DMD won't register for sensor data.
         final FakeDeviceConfig config = mInjector.getDeviceConfig();
         config.setRefreshRateInHighZone(60);
         config.setHighDisplayBrightnessThresholds(new int[] { 255 });
         config.setHighAmbientBrightnessThresholds(new int[] { 8000 });
-        config.setDefaultPeakRefreshRate(90);
 
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
+        setPeakRefreshRate(90 /*fps*/);
         director.getSettingsObserver().setDefaultRefreshRate(90);
         director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
 
@@ -2529,10 +2416,10 @@
         config.setRefreshRateInHighZone(60);
         config.setHighDisplayBrightnessThresholds(new int[] { 255 });
         config.setHighAmbientBrightnessThresholds(new int[] { 8000 });
-        config.setDefaultPeakRefreshRate(90);
 
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
+        setPeakRefreshRate(90 /*fps*/);
         director.getSettingsObserver().setDefaultRefreshRate(90);
         director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
 
@@ -2646,7 +2533,7 @@
     }
 
     @Test
-    public void testUpdateLayoutLimitedRefreshRate() {
+    public void testUpdateLayoutLimitedRefreshRate_validDisplayInfo() {
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0);
         director.start(createMockSensorManager());
@@ -2672,6 +2559,26 @@
         assertNull(vote);
     }
 
+    @Test
+    public void testUpdateLayoutLimitedRefreshRate_invalidDisplayInfo() {
+        DisplayModeDirector director =
+                createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0);
+        director.start(createMockSensorManager());
+
+        ArgumentCaptor<DisplayListener> displayListenerCaptor =
+                ArgumentCaptor.forClass(DisplayListener.class);
+        verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
+                any(Handler.class));
+        DisplayListener displayListener = displayListenerCaptor.getValue();
+
+        mInjector.mDisplayInfo.layoutLimitedRefreshRate = new RefreshRateRange(10, 10);
+        mInjector.mDisplayInfoValid = false;
+        displayListener.onDisplayChanged(DISPLAY_ID);
+
+        Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_LAYOUT_LIMITED_FRAME_RATE);
+        assertNull(vote);
+    }
+
     private Temperature getSkinTemp(@Temperature.ThrottlingStatus int status) {
         return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status);
     }
@@ -2810,30 +2717,10 @@
         listener.onDisplayChanged(DISPLAY_ID);
     }
 
-    private void setSmoothDisplayEnabled(boolean enabled) {
-        Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY,
-                enabled ? 1 : 0);
-        mInjector.notifySmoothDisplaySettingChanged();
-        waitForIdleSync();
-    }
-
-    private void clearSmoothDisplaySetting() {
-        Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY, -1);
-        mInjector.notifySmoothDisplaySettingChanged();
-        waitForIdleSync();
-    }
-
-    private void setForcePeakRefreshRateEnabled(boolean enabled) {
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.FORCE_PEAK_REFRESH_RATE, enabled ? 1 : 0);
-        mInjector.notifyForcePeakRefreshRateSettingChanged();
-        waitForIdleSync();
-    }
-
-    private void clearForcePeakRefreshRateSetting() {
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.FORCE_PEAK_REFRESH_RATE, -1);
-        mInjector.notifySmoothDisplaySettingChanged();
+    private void setPeakRefreshRate(float fps) {
+        Settings.System.putFloat(mContext.getContentResolver(), Settings.System.PEAK_REFRESH_RATE,
+                 fps);
+        mInjector.notifyPeakRefreshRateChanged();
         waitForIdleSync();
     }
 
@@ -2880,9 +2767,9 @@
         private final FakeDeviceConfig mDeviceConfig;
         private final DisplayInfo mDisplayInfo;
         private final Display mDisplay;
+        private boolean mDisplayInfoValid = true;
         private ContentObserver mBrightnessObserver;
-        private ContentObserver mSmoothDisplaySettingObserver;
-        private ContentObserver mForcePeakRefreshRateSettingObserver;
+        private ContentObserver mPeakRefreshRateObserver;
 
         FakesInjector() {
             mDeviceConfig = new FakeDeviceConfig();
@@ -2899,15 +2786,9 @@
         }
 
         @Override
-        public void registerSmoothDisplayObserver(@NonNull ContentResolver cr,
+        public void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
                 @NonNull ContentObserver observer) {
-            mSmoothDisplaySettingObserver = observer;
-        }
-
-        @Override
-        public void registerForcePeakRefreshRateObserver(@NonNull ContentResolver cr,
-                @NonNull ContentObserver observer) {
-            mForcePeakRefreshRateSettingObserver = observer;
+            mPeakRefreshRateObserver = observer;
         }
 
         @Override
@@ -2929,7 +2810,7 @@
         @Override
         public boolean getDisplayInfo(int displayId, DisplayInfo displayInfo) {
             displayInfo.copyFrom(mDisplayInfo);
-            return true;
+            return mDisplayInfoValid;
         }
 
         @Override
@@ -2957,17 +2838,10 @@
                     ApplicationProvider.getApplicationContext().getResources());
         }
 
-        void notifySmoothDisplaySettingChanged() {
-            if (mSmoothDisplaySettingObserver != null) {
-                mSmoothDisplaySettingObserver.dispatchChange(false /*selfChange*/,
-                        SMOOTH_DISPLAY_URI);
-            }
-        }
-
-        void notifyForcePeakRefreshRateSettingChanged() {
-            if (mForcePeakRefreshRateSettingObserver != null) {
-                mForcePeakRefreshRateSettingObserver.dispatchChange(false /*selfChange*/,
-                        FORCE_PEAK_REFRESH_RATE_URI);
+        void notifyPeakRefreshRateChanged() {
+            if (mPeakRefreshRateObserver != null) {
+                mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/,
+                        PEAK_REFRESH_RATE_URI);
             }
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/display/mode/SkinThermalStatusObserverTest.java b/services/tests/servicestests/src/com/android/server/display/mode/SkinThermalStatusObserverTest.java
index 13540d6..9ab6ee5 100644
--- a/services/tests/servicestests/src/com/android/server/display/mode/SkinThermalStatusObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/mode/SkinThermalStatusObserverTest.java
@@ -18,7 +18,6 @@
 
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
 import android.hardware.display.DisplayManager;
@@ -57,7 +56,7 @@
     private RegisteringFakesInjector mInjector = new RegisteringFakesInjector();
 
     private final TestHandler mHandler = new TestHandler(null);
-    private final FakeVoteStorage mStorage = new FakeVoteStorage();
+    private final VotesStorage mStorage = new VotesStorage(() -> {});
 
     @Before
     public void setUp() {
@@ -92,28 +91,26 @@
     public void testNotifyWithDefaultVotesForCritical() {
         // GIVEN 2 displays with no thermalThrottling config
         mObserver.observe();
-        assertEquals(0, mStorage.mVoteRegistry.size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID).size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID_OTHER).size());
 
         // WHEN thermal sensor notifies CRITICAL
         mObserver.notifyThrottling(createTemperature(Temperature.THROTTLING_CRITICAL));
         mHandler.flush();
 
         // THEN 2 votes are added to storage with (0,60) render refresh rate(default behaviour)
-        assertEquals(2, mStorage.mVoteRegistry.size());
-
-        SparseArray<DisplayModeDirector.Vote> displayVotes = mStorage.mVoteRegistry.get(DISPLAY_ID);
+        SparseArray<Vote> displayVotes = mStorage.getVotes(DISPLAY_ID);
         assertEquals(1, displayVotes.size());
 
-        DisplayModeDirector.Vote vote = displayVotes.get(
-                DisplayModeDirector.Vote.PRIORITY_SKIN_TEMPERATURE);
+        Vote vote = displayVotes.get(
+                Vote.PRIORITY_SKIN_TEMPERATURE);
         assertEquals(0, vote.refreshRateRanges.render.min, FLOAT_TOLERANCE);
         assertEquals(60, vote.refreshRateRanges.render.max, FLOAT_TOLERANCE);
 
-        SparseArray<DisplayModeDirector.Vote> otherDisplayVotes = mStorage.mVoteRegistry.get(
-                DISPLAY_ID_OTHER);
+        SparseArray<Vote> otherDisplayVotes = mStorage.getVotes(DISPLAY_ID_OTHER);
         assertEquals(1, otherDisplayVotes.size());
 
-        vote = otherDisplayVotes.get(DisplayModeDirector.Vote.PRIORITY_SKIN_TEMPERATURE);
+        vote = otherDisplayVotes.get(Vote.PRIORITY_SKIN_TEMPERATURE);
         assertEquals(0, vote.refreshRateRanges.render.min, FLOAT_TOLERANCE);
         assertEquals(60, vote.refreshRateRanges.render.max, FLOAT_TOLERANCE);
     }
@@ -122,25 +119,29 @@
     public void testNotifyWithDefaultVotesChangeFromCriticalToSevere() {
         // GIVEN 2 displays with no thermalThrottling config AND temperature level CRITICAL
         mObserver.observe();
-        assertEquals(0, mStorage.mVoteRegistry.size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID).size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID_OTHER).size());
         mObserver.notifyThrottling(createTemperature(Temperature.THROTTLING_CRITICAL));
         // WHEN thermal sensor notifies SEVERE
         mObserver.notifyThrottling(createTemperature(Temperature.THROTTLING_SEVERE));
         mHandler.flush();
         // THEN all votes with PRIORITY_SKIN_TEMPERATURE are removed from the storage
-        assertEquals(0, mStorage.mVoteRegistry.size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID).size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID_OTHER).size());
     }
 
     @Test
     public void testNotifyWithDefaultVotesForSevere() {
         // GIVEN 2 displays with no thermalThrottling config
         mObserver.observe();
-        assertEquals(0, mStorage.mVoteRegistry.size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID).size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID_OTHER).size());
         // WHEN thermal sensor notifies CRITICAL
         mObserver.notifyThrottling(createTemperature(Temperature.THROTTLING_SEVERE));
         mHandler.flush();
         // THEN nothing is added to the storage
-        assertEquals(0, mStorage.mVoteRegistry.size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID).size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID_OTHER).size());
     }
 
     @Test
@@ -155,18 +156,20 @@
         mObserver = new SkinThermalStatusObserver(mInjector, mStorage, mHandler);
         mObserver.observe();
         mObserver.onDisplayChanged(DISPLAY_ID);
-        assertEquals(0, mStorage.mVoteRegistry.size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID).size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID_OTHER).size());
         // WHEN thermal sensor notifies temperature above configured
         mObserver.notifyThrottling(createTemperature(Temperature.THROTTLING_SEVERE));
         mHandler.flush();
         // THEN vote with refreshRate from config is added to the storage
-        assertEquals(1, mStorage.mVoteRegistry.size());
-        SparseArray<DisplayModeDirector.Vote> displayVotes = mStorage.mVoteRegistry.get(DISPLAY_ID);
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID_OTHER).size());
+
+        SparseArray<Vote> displayVotes = mStorage.getVotes(DISPLAY_ID);
         assertEquals(1, displayVotes.size());
-        DisplayModeDirector.Vote vote = displayVotes.get(
-                DisplayModeDirector.Vote.PRIORITY_SKIN_TEMPERATURE);
+        Vote vote = displayVotes.get(Vote.PRIORITY_SKIN_TEMPERATURE);
         assertEquals(90, vote.refreshRateRanges.render.min, FLOAT_TOLERANCE);
         assertEquals(120, vote.refreshRateRanges.render.max, FLOAT_TOLERANCE);
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID_OTHER).size());
     }
 
     @Test
@@ -178,14 +181,13 @@
         mObserver.onDisplayAdded(DISPLAY_ID_ADDED);
         mHandler.flush();
         // THEN 3rd vote is added to storage with (0,60) render refresh rate(default behaviour)
-        assertEquals(3, mStorage.mVoteRegistry.size());
+        assertEquals(1, mStorage.getVotes(DISPLAY_ID).size());
+        assertEquals(1, mStorage.getVotes(DISPLAY_ID_OTHER).size());
+        assertEquals(1, mStorage.getVotes(DISPLAY_ID_ADDED).size());
 
-        SparseArray<DisplayModeDirector.Vote> displayVotes = mStorage.mVoteRegistry.get(
-                DISPLAY_ID_ADDED);
-        assertEquals(1, displayVotes.size());
+        SparseArray<Vote> displayVotes = mStorage.getVotes(DISPLAY_ID_ADDED);
 
-        DisplayModeDirector.Vote vote = displayVotes.get(
-                DisplayModeDirector.Vote.PRIORITY_SKIN_TEMPERATURE);
+        Vote vote = displayVotes.get(Vote.PRIORITY_SKIN_TEMPERATURE);
         assertEquals(0, vote.refreshRateRanges.render.min, FLOAT_TOLERANCE);
         assertEquals(60, vote.refreshRateRanges.render.max, FLOAT_TOLERANCE);
     }
@@ -200,9 +202,9 @@
         mObserver.onDisplayRemoved(DISPLAY_ID_ADDED);
         mHandler.flush();
         // THEN there are 2 votes in registry
-        assertEquals(2, mStorage.mVoteRegistry.size());
-        assertNotNull(mStorage.mVoteRegistry.get(DISPLAY_ID));
-        assertNotNull(mStorage.mVoteRegistry.get(DISPLAY_ID_OTHER));
+        assertEquals(1, mStorage.getVotes(DISPLAY_ID).size());
+        assertEquals(1, mStorage.getVotes(DISPLAY_ID_OTHER).size());
+        assertEquals(0, mStorage.getVotes(DISPLAY_ID_ADDED).size());
     }
 
     private static Temperature createTemperature(@Temperature.ThrottlingStatus int status) {
@@ -259,27 +261,4 @@
             return false;
         }
     }
-
-
-    private static class FakeVoteStorage implements DisplayModeDirector.BallotBox {
-        private final SparseArray<SparseArray<DisplayModeDirector.Vote>> mVoteRegistry =
-                new SparseArray<>();
-
-        @Override
-        public void vote(int displayId, int priority, DisplayModeDirector.Vote vote) {
-            SparseArray<DisplayModeDirector.Vote> votesPerDisplay = mVoteRegistry.get(displayId);
-            if (votesPerDisplay == null) {
-                votesPerDisplay = new SparseArray<>();
-                mVoteRegistry.put(displayId, votesPerDisplay);
-            }
-            if (vote == null) {
-                votesPerDisplay.remove(priority);
-            } else {
-                votesPerDisplay.put(priority, vote);
-            }
-            if (votesPerDisplay.size() == 0) {
-                mVoteRegistry.remove(displayId);
-            }
-        }
-    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/mode/VotesStorageTest.java b/services/tests/servicestests/src/com/android/server/display/mode/VotesStorageTest.java
new file mode 100644
index 0000000..287fdd5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/mode/VotesStorageTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.mode;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.util.SparseArray;
+
+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;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class VotesStorageTest {
+    private static final int DISPLAY_ID = 100;
+    private static final int PRIORITY = Vote.PRIORITY_APP_REQUEST_SIZE;
+    private static final Vote VOTE = Vote.forDisableRefreshRateSwitching();
+    private static final int DISPLAY_ID_OTHER = 101;
+    private static final int PRIORITY_OTHER = Vote.PRIORITY_FLICKER_REFRESH_RATE;
+    private static final Vote VOTE_OTHER = Vote.forBaseModeRefreshRate(10f);
+
+    @Mock
+    public VotesStorage.Listener mVotesListener;
+
+    private VotesStorage mVotesStorage;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mVotesStorage = new VotesStorage(mVotesListener);
+    }
+
+    @Test
+    public void addsVoteToStorage() {
+        // WHEN updateVote is called
+        mVotesStorage.updateVote(DISPLAY_ID, PRIORITY, VOTE);
+        // THEN vote is added to the storage
+        SparseArray<Vote> votes = mVotesStorage.getVotes(DISPLAY_ID);
+        assertThat(votes.size()).isEqualTo(1);
+        assertThat(votes.get(PRIORITY)).isEqualTo(VOTE);
+        assertThat(mVotesStorage.getVotes(DISPLAY_ID_OTHER).size()).isEqualTo(0);
+    }
+
+    @Test
+    public void notifiesVoteListenerIfVoteAdded() {
+        // WHEN updateVote is called
+        mVotesStorage.updateVote(DISPLAY_ID, PRIORITY, VOTE);
+        // THEN listener is notified
+        verify(mVotesListener).onChanged();
+    }
+
+    @Test
+    public void addsAnotherVoteToStorageWithDifferentPriority() {
+        // GIVEN vote storage with one vote
+        mVotesStorage.updateVote(DISPLAY_ID, PRIORITY, VOTE);
+        // WHEN updateVote is called with other priority
+        mVotesStorage.updateVote(DISPLAY_ID, PRIORITY_OTHER, VOTE_OTHER);
+        // THEN another vote is added to storage
+        SparseArray<Vote> votes = mVotesStorage.getVotes(DISPLAY_ID);
+        assertThat(votes.size()).isEqualTo(2);
+        assertThat(votes.get(PRIORITY)).isEqualTo(VOTE);
+        assertThat(votes.get(PRIORITY_OTHER)).isEqualTo(VOTE_OTHER);
+        assertThat(mVotesStorage.getVotes(DISPLAY_ID_OTHER).size()).isEqualTo(0);
+    }
+
+    @Test
+    public void replacesVoteInStorageForSamePriority() {
+        // GIVEN vote storage with one vote
+        mVotesStorage.updateVote(DISPLAY_ID, PRIORITY, VOTE);
+        // WHEN updateVote is called with same priority
+        mVotesStorage.updateVote(DISPLAY_ID, PRIORITY, VOTE_OTHER);
+        // THEN vote is replaced by other vote
+        SparseArray<Vote> votes = mVotesStorage.getVotes(DISPLAY_ID);
+        assertThat(votes.size()).isEqualTo(1);
+        assertThat(votes.get(PRIORITY)).isEqualTo(VOTE_OTHER);
+        assertThat(mVotesStorage.getVotes(DISPLAY_ID_OTHER).size()).isEqualTo(0);
+    }
+
+    @Test
+    public void removesVoteInStorageForSamePriority() {
+        // GIVEN vote storage with one vote
+        mVotesStorage.updateVote(DISPLAY_ID, PRIORITY, VOTE);
+        // WHEN update is called with same priority and null vote
+        mVotesStorage.updateVote(DISPLAY_ID, PRIORITY, null);
+        // THEN vote removed from the storage
+        assertThat(mVotesStorage.getVotes(DISPLAY_ID).size()).isEqualTo(0);
+        assertThat(mVotesStorage.getVotes(DISPLAY_ID_OTHER).size()).isEqualTo(0);
+    }
+
+    @Test
+    public void addsGlobalDisplayVoteToStorage() {
+        // WHEN updateGlobalVote is called
+        mVotesStorage.updateGlobalVote(PRIORITY, VOTE);
+        // THEN it is added to the storage for every display
+        SparseArray<Vote> votes = mVotesStorage.getVotes(DISPLAY_ID);
+        assertThat(votes.size()).isEqualTo(1);
+        assertThat(votes.get(PRIORITY)).isEqualTo(VOTE);
+        votes = mVotesStorage.getVotes(DISPLAY_ID_OTHER);
+        assertThat(votes.size()).isEqualTo(1);
+        assertThat(votes.get(PRIORITY)).isEqualTo(VOTE);
+    }
+
+    @Test
+    public void ignoresVotesWithLowerThanMinPriority() {
+        // WHEN updateVote is called with invalid (lower than min) priority
+        mVotesStorage.updateVote(DISPLAY_ID, Vote.MIN_PRIORITY - 1, VOTE);
+        // THEN vote is not added to the storage AND listener not notified
+        assertThat(mVotesStorage.getVotes(DISPLAY_ID).size()).isEqualTo(0);
+        verify(mVotesListener, never()).onChanged();
+    }
+
+    @Test
+    public void ignoresVotesWithGreaterThanMaxPriority() {
+        // WHEN updateVote is called with invalid (greater than max) priority
+        mVotesStorage.updateVote(DISPLAY_ID, Vote.MAX_PRIORITY + 1, VOTE);
+        // THEN vote is not added to the storage AND listener not notified
+        assertThat(mVotesStorage.getVotes(DISPLAY_ID).size()).isEqualTo(0);
+        verify(mVotesListener, never()).onChanged();
+    }
+}
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 1ef1197..d5ad815 100644
--- a/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityTaskManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.ServiceConnection;
@@ -54,6 +55,10 @@
     private DreamController.Listener mListener;
     @Mock
     private Context mContext;
+
+    @Mock
+    private ActivityTaskManager mActivityTaskManager;
+
     @Mock
     private IBinder mIBinder;
     @Mock
@@ -80,6 +85,10 @@
         when(mIDreamService.asBinder()).thenReturn(mIBinder);
         when(mIBinder.queryLocalInterface(anyString())).thenReturn(mIDreamService);
         when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true);
+        when(mContext.getSystemService(Context.ACTIVITY_TASK_SERVICE))
+                .thenReturn(mActivityTaskManager);
+        when(mContext.getSystemServiceName(ActivityTaskManager.class))
+                .thenReturn(Context.ACTIVITY_TASK_SERVICE);
 
         mToken = new Binder();
         mDreamName = ComponentName.unflattenFromString("dream");
@@ -104,6 +113,37 @@
     }
 
     @Test
+    public void startDream_dreamListenerNotified() {
+        // Call dream controller to start dreaming.
+        mDreamController.startDream(mToken, mDreamName, false /*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(mListener).onDreamStarted(any());
+    }
+
+    @Test
+    public void stopDream_dreamListenerNotified() {
+        // Start dream.
+        mDreamController.startDream(mToken, mDreamName, false /*isPreview*/, false /*doze*/,
+                0 /*userId*/, null /*wakeLock*/, mOverlayName, "test" /*reason*/);
+        captureServiceConnection().onServiceConnected(mDreamName, mIBinder);
+        mLooper.dispatchAll();
+
+        // Stop dream.
+        mDreamController.stopDream(true /*immediate*/, "test stop dream" /*reason*/);
+        mLooper.dispatchAll();
+
+        // Verify that dream service is called to detach.
+        verify(mListener).onDreamStopped(any());
+    }
+
+    @Test
     public void startDream_attachOnServiceConnectedInPreviewMode() throws RemoteException {
         // Call dream controller to start dreaming.
         mDreamController.startDream(mToken, mDreamName, true /*isPreview*/, false /*doze*/,
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
index a446e10..c53a7a7 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
@@ -18,6 +18,7 @@
 
 import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_DESTINATION;
 import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_PARAMETER;
+import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_PARAMETER_LONG;
 import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_PARAMETER_SHORT;
 import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_SOURCE;
 import static com.android.server.hdmi.HdmiCecMessageValidator.OK;
@@ -145,11 +146,12 @@
     @Test
     public void isValid_systemAudioModeStatus() {
         assertMessageValidity("40:7E:00").isEqualTo(OK);
-        assertMessageValidity("40:7E:01:01").isEqualTo(OK);
+        assertMessageValidity("40:7E:01").isEqualTo(OK);
 
         assertMessageValidity("0F:7E:00").isEqualTo(ERROR_DESTINATION);
         assertMessageValidity("F0:7E").isEqualTo(ERROR_SOURCE);
         assertMessageValidity("40:7E").isEqualTo(ERROR_PARAMETER_SHORT);
+        assertMessageValidity("40:7E:01:1F:28").isEqualTo(ERROR_PARAMETER_LONG);
         assertMessageValidity("40:7E:02").isEqualTo(ERROR_PARAMETER);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 4dd5e94..fd6eb92 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -761,6 +761,13 @@
 
         assertThat(mHdmiControlServiceSpy.handleCecCommand(message))
                 .isEqualTo(Constants.ABORT_INVALID_OPERAND);
+
+        // Validating ERROR_PARAMETER_LONG will generate ABORT_INVALID_OPERAND.
+        // Taken from HdmiCecMessageValidatorTest#isValid_systemAudioModeStatus
+        HdmiCecMessage systemAudioModeStatus = HdmiUtils.buildMessage("40:7E:01:1F:28");
+
+        assertThat(mHdmiControlServiceSpy.handleCecCommand(systemAudioModeStatus))
+                .isEqualTo(Constants.ABORT_INVALID_OPERAND);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt b/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
index 0f4d4e8..64c05dc 100644
--- a/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/input/KeyboardBacklightControllerTests.kt
@@ -250,20 +250,24 @@
         `when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardWithBacklight)
         `when`(iInputManager.getLights(DEVICE_ID)).thenReturn(listOf(keyboardBacklight))
 
-        dataStore.setKeyboardBacklightBrightness(
-            keyboardWithBacklight.descriptor,
-            LIGHT_ID,
-            MAX_BRIGHTNESS
-        )
+        for (level in 1 until BRIGHTNESS_VALUE_FOR_LEVEL.size) {
+            dataStore.setKeyboardBacklightBrightness(
+                    keyboardWithBacklight.descriptor,
+                    LIGHT_ID,
+                    BRIGHTNESS_VALUE_FOR_LEVEL[level] - 1
+            )
 
-        keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
-        keyboardBacklightController.notifyUserActivity()
-        testLooper.dispatchNext()
-        assertEquals(
-            "Keyboard backlight level should be restored to the level saved in the data store",
-            Color.argb(MAX_BRIGHTNESS, 0, 0, 0),
-            lightColorMap[LIGHT_ID]
-        )
+            keyboardBacklightController.onInputDeviceAdded(DEVICE_ID)
+            keyboardBacklightController.notifyUserActivity()
+            testLooper.dispatchNext()
+            assertEquals(
+                    "Keyboard backlight level should be restored to the level saved in the data " +
+                            "store",
+                    Color.argb(BRIGHTNESS_VALUE_FOR_LEVEL[level], 0, 0, 0),
+                    lightColorMap[LIGHT_ID]
+            )
+            keyboardBacklightController.onInputDeviceRemoved(DEVICE_ID)
+        }
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/services/tests/servicestests/src/com/android/server/input/KeyboardLayoutManagerTests.kt
index ea3f3bc..d0d28c3 100644
--- a/services/tests/servicestests/src/com/android/server/input/KeyboardLayoutManagerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/input/KeyboardLayoutManagerTests.kt
@@ -633,6 +633,30 @@
                 0,
                 keyboardLayouts.size
             )
+
+            // If IME doesn't have a corresponding language tag, then should show all available
+            // layouts no matter the script code.
+            keyboardLayouts =
+                keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
+                    keyboardDevice.identifier, USER_ID, imeInfo, null
+                )
+            assertNotEquals(
+                "New UI: getKeyboardLayoutListForInputDevice API should return all layouts if" +
+                    "language tag or subtype not provided",
+                0,
+                keyboardLayouts.size
+            )
+            assertTrue("New UI: getKeyboardLayoutListForInputDevice API should contain Latin " +
+                "layouts if language tag or subtype not provided",
+                containsLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
+            )
+            assertTrue("New UI: getKeyboardLayoutListForInputDevice API should contain Cyrillic " +
+                "layouts if language tag or subtype not provided",
+                containsLayout(
+                    keyboardLayouts,
+                    createLayoutDescriptor("keyboard_layout_russian")
+                )
+            )
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
index d07831d..fd65807 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
@@ -20,16 +20,25 @@
 import static android.view.Display.INVALID_DISPLAY;
 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.SOFT_INPUT_STATE_UNSPECIFIED;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
+import android.platform.test.annotations.Presubmit;
+
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.inputmethod.SoftInputShowHideReason;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+@Presubmit
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class InputMethodManagerServiceTests {
@@ -87,4 +96,25 @@
                 InputMethodManagerService.computeImeDisplayIdForTarget(
                         SYSTEM_DECORATION_SUPPORT_DISPLAY_ID, sChecker));
     }
+
+    @Test
+    public void testSoftInputShowHideHistoryDump_withNulls_doesntThrow() {
+        var writer = new StringWriter();
+        var history = new InputMethodManagerService.SoftInputShowHideHistory();
+        history.addEntry(new InputMethodManagerService.SoftInputShowHideHistory.Entry(
+                null,
+                null,
+                null,
+                SOFT_INPUT_STATE_UNSPECIFIED,
+                SoftInputShowHideReason.SHOW_SOFT_INPUT,
+                false,
+                null,
+                null,
+                null,
+                null));
+
+        history.dump(new PrintWriter(writer), "" /* prefix */);
+
+        // Asserts that dump doesn't throw an NPE.
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index 36c2001..275533f 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -19,15 +19,25 @@
 
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
 import static android.media.projection.MediaProjectionManager.TYPE_MIRRORING;
+import static android.media.projection.ReviewGrantedConsentResult.RECORD_CANCEL;
+import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_DISPLAY;
+import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_TASK;
+import static android.media.projection.ReviewGrantedConsentResult.UNKNOWN;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.testng.Assert.assertThrows;
 
 import android.app.ActivityManagerInternal;
@@ -37,7 +47,9 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.media.projection.IMediaProjection;
 import android.media.projection.IMediaProjectionCallback;
+import android.media.projection.ReviewGrantedConsentResult;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -56,6 +68,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -108,6 +122,8 @@
     private WindowManagerInternal mWindowManagerInternal;
     @Mock
     private PackageManager mPackageManager;
+    @Captor
+    private ArgumentCaptor<ContentRecordingSession> mSessionCaptor;
 
     @Before
     public void setup() throws Exception {
@@ -154,12 +170,15 @@
 
     @Test
     public void testCreateProjection() throws NameNotFoundException {
-        MediaProjectionManagerService.MediaProjection projection =
-                startProjectionPreconditions(/* packageAttemptedReusingGrantedConsent= */ false);
+        // Create a first projection.
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
         projection.start(mIMediaProjectionCallback);
 
+        // We are allowed to create a new projection.
         MediaProjectionManagerService.MediaProjection secondProjection =
-                startProjectionPreconditions(/* packageAttemptedReusingGrantedConsent= */ false);
+                startProjectionPreconditions();
+
+        // This is a new projection.
         assertThat(secondProjection).isNotNull();
         assertThat(secondProjection).isNotEqualTo(projection);
     }
@@ -167,44 +186,58 @@
     @Test
     public void testCreateProjection_attemptReuse_noPriorProjectionGrant()
             throws NameNotFoundException {
-        MediaProjectionManagerService.MediaProjection projection =
-                startProjectionPreconditions(/* packageAttemptedReusingGrantedConsent= */ false);
+        // Create a first projection.
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
         projection.start(mIMediaProjectionCallback);
 
-        MediaProjectionManagerService.MediaProjection secondProjection =
-                startProjectionPreconditions(/* packageAttemptedReusingGrantedConsent= */ true);
-
-        assertThat(secondProjection).isNotNull();
-        assertThat(secondProjection).isNotEqualTo(projection);
+        // We are not allowed to retrieve the prior projection, since we are not waiting for the
+        // user's consent.
+        assertThat(startReusedProjectionPreconditions()).isNull();
     }
 
     @Test
     public void testCreateProjection_attemptReuse_priorProjectionGrant_notWaiting()
             throws NameNotFoundException {
-        MediaProjectionManagerService.MediaProjection projection =
-                startProjectionPreconditions(/* packageAttemptedReusingGrantedConsent= */ false);
+        // Create a first projection.
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
         projection.start(mIMediaProjectionCallback);
 
-        // Mark this projection as not waiting.
+        // Mark this projection as not waiting for the user to review consent.
         doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
                 any(ContentRecordingSession.class));
         mService.setContentRecordingSession(DISPLAY_SESSION);
 
-        // We are allowed to create another projection.
+        // We are not allowed to retrieve the prior projection, since we are not waiting for the
+        // user's consent.
+        assertThat(startReusedProjectionPreconditions()).isNull();
+    }
+
+    @Test
+    public void testCreateProjection_attemptReuse_priorProjectionGrant_waiting()
+            throws NameNotFoundException {
+        // Create a first projection.
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.start(mIMediaProjectionCallback);
+
+        // Mark this projection as waiting for the user to review consent.
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+        mService.setContentRecordingSession(mWaitingDisplaySession);
+
+        // We are allowed to create another projection, reusing a prior grant if necessary.
         MediaProjectionManagerService.MediaProjection secondProjection =
-                startProjectionPreconditions(/* packageAttemptedReusingGrantedConsent= */ true);
+                startReusedProjectionPreconditions();
 
+        // This is a new projection, since we are waiting for the user's consent; simply provide
+        // the projection grant from before.
         assertThat(secondProjection).isNotNull();
-
-        // But this is a new projection.
-        assertThat(secondProjection).isNotEqualTo(projection);
+        assertThat(secondProjection).isEqualTo(projection);
     }
 
     @Test
     public void testCreateProjection_attemptReuse_priorProjectionGrant_waiting_differentPackage()
             throws NameNotFoundException {
-        MediaProjectionManagerService.MediaProjection projection =
-                startProjectionPreconditions(/* packageAttemptedReusingGrantedConsent= */ false);
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
         projection.start(mIMediaProjectionCallback);
 
         // Mark this projection as not waiting.
@@ -213,8 +246,7 @@
         // We are allowed to create another projection.
         MediaProjectionManagerService.MediaProjection secondProjection =
                 mService.createProjectionInternal(UID + 10, PACKAGE_NAME + "foo",
-                        TYPE_MIRRORING, /* isPermanentGrant= */ true,
-                        UserHandle.CURRENT, /* packageAttemptedReusingGrantedConsent= */ true);
+                        TYPE_MIRRORING, /* isPermanentGrant= */ true, UserHandle.CURRENT);
 
         assertThat(secondProjection).isNotNull();
 
@@ -366,6 +398,286 @@
         assertThat(mService.isCurrentProjection(projection.asBinder())).isTrue();
     }
 
+    @Test
+    public void testSetUserReviewGrantedConsentResult_noCurrentProjection() {
+        // Gracefully handle invocation without a current projection.
+        mService.setUserReviewGrantedConsentResult(RECORD_CONTENT_DISPLAY,
+                mock(IMediaProjection.class));
+        assertThat(mService.getActiveProjectionInfo()).isNull();
+        verify(mWindowManagerInternal, never()).setContentRecordingSession(any(
+                ContentRecordingSession.class));
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_projectionNotCurrent() throws Exception {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.start(mIMediaProjectionCallback);
+        assertThat(mService.isCurrentProjection(projection)).isTrue();
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+        // Some other token.
+        final IMediaProjection otherProjection = mock(IMediaProjection.class);
+        doReturn(mock(IBinder.class)).when(otherProjection).asBinder();
+        // Waiting for user to review consent.
+        mService.setContentRecordingSession(mWaitingDisplaySession);
+        mService.setUserReviewGrantedConsentResult(RECORD_CONTENT_DISPLAY, otherProjection);
+
+        // Display result is ignored; only the first session is set.
+        verify(mWindowManagerInternal, times(1)).setContentRecordingSession(
+                eq(mWaitingDisplaySession));
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_projectionNull() throws Exception {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.start(mIMediaProjectionCallback);
+        assertThat(mService.isCurrentProjection(projection)).isTrue();
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+        // Some other token.
+        final IMediaProjection otherProjection = null;
+        // Waiting for user to review consent.
+        mService.setContentRecordingSession(mWaitingDisplaySession);
+        mService.setUserReviewGrantedConsentResult(RECORD_CONTENT_DISPLAY, otherProjection);
+
+        // Display result is ignored; only the first session is set.
+        verify(mWindowManagerInternal, times(1)).setContentRecordingSession(
+                eq(mWaitingDisplaySession));
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_projectionNull_consentNotGranted()
+            throws Exception {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.start(mIMediaProjectionCallback);
+        assertThat(mService.isCurrentProjection(projection)).isTrue();
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+        // Some other token.
+        final IMediaProjection otherProjection = null;
+        // Waiting for user to review consent.
+        mService.setContentRecordingSession(mWaitingDisplaySession);
+        mService.setUserReviewGrantedConsentResult(RECORD_CANCEL, otherProjection);
+
+        // Display result is ignored; only the first session is set.
+        verify(mWindowManagerInternal, times(1)).setContentRecordingSession(
+                eq(mWaitingDisplaySession));
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_noVirtualDisplay() throws Exception {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.start(mIMediaProjectionCallback);
+        // Do not indicate that the virtual display was created.
+        ContentRecordingSession session = mWaitingDisplaySession;
+        session.setVirtualDisplayId(INVALID_DISPLAY);
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+        // Waiting for user to review consent.
+        assertThat(mService.isCurrentProjection(projection)).isTrue();
+        mService.setContentRecordingSession(session);
+
+        mService.setUserReviewGrantedConsentResult(RECORD_CONTENT_DISPLAY, projection);
+        // A session is sent, indicating consent is granted to record but the virtual display isn't
+        // ready yet.
+        verify(mWindowManagerInternal, times(2)).setContentRecordingSession(
+                mSessionCaptor.capture());
+        // Examine latest value.
+        final ContentRecordingSession capturedSession = mSessionCaptor.getValue();
+        assertThat(capturedSession.isWaitingToRecord()).isFalse();
+        assertThat(capturedSession.getVirtualDisplayId()).isEqualTo(INVALID_DISPLAY);
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_thenVirtualDisplayCreated() throws Exception {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.start(mIMediaProjectionCallback);
+        assertThat(mService.isCurrentProjection(projection)).isTrue();
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+        // Waiting for user to review consent.
+        mService.setContentRecordingSession(mWaitingDisplaySession);
+        mService.setUserReviewGrantedConsentResult(RECORD_CONTENT_DISPLAY, projection);
+
+        // Virtual Display is finally created.
+        projection.notifyVirtualDisplayCreated(10);
+        verifySetSessionWithContent(ContentRecordingSession.RECORD_CONTENT_DISPLAY);
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_unknown_updatedSession() throws Exception {
+        testSetUserReviewGrantedConsentResult_userCancelsSession(
+                /* isSetSessionSuccessful= */ true, UNKNOWN);
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_unknown_failedToUpdateSession()
+            throws Exception {
+        testSetUserReviewGrantedConsentResult_userCancelsSession(
+                /* isSetSessionSuccessful= */ false, UNKNOWN);
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_cancel_updatedSession() throws Exception {
+        testSetUserReviewGrantedConsentResult_userCancelsSession(
+                /* isSetSessionSuccessful= */ true, RECORD_CANCEL);
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_cancel_failedToUpdateSession()
+            throws Exception {
+        testSetUserReviewGrantedConsentResult_userCancelsSession(
+                /* isSetSessionSuccessful= */ false, RECORD_CANCEL);
+    }
+
+    /**
+     * Executes and validates scenario where the consent result indicates the projection ends.
+     */
+    private void testSetUserReviewGrantedConsentResult_userCancelsSession(
+            boolean isSetSessionSuccessful, @ReviewGrantedConsentResult int consentResult)
+            throws Exception {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.start(mIMediaProjectionCallback);
+        projection.notifyVirtualDisplayCreated(10);
+        // Waiting for user to review consent.
+        assertThat(mService.isCurrentProjection(projection)).isTrue();
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+        mService.setContentRecordingSession(mWaitingDisplaySession);
+
+        doReturn(isSetSessionSuccessful).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+
+        mService.setUserReviewGrantedConsentResult(consentResult, projection);
+        verify(mWindowManagerInternal, atLeastOnce()).setContentRecordingSession(
+                mSessionCaptor.capture());
+        // Null value to stop session.
+        assertThat(mSessionCaptor.getValue()).isNull();
+        assertThat(mService.isCurrentProjection(projection.asBinder())).isFalse();
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_displayMirroring_startedSession()
+            throws NameNotFoundException {
+        testSetUserReviewGrantedConsentResult_startedSession(RECORD_CONTENT_DISPLAY,
+                ContentRecordingSession.RECORD_CONTENT_DISPLAY);
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_displayMirroring_failedToStartSession()
+            throws NameNotFoundException {
+        testSetUserReviewGrantedConsentResult_failedToStartSession(RECORD_CONTENT_DISPLAY,
+                ContentRecordingSession.RECORD_CONTENT_DISPLAY);
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_taskMirroring_startedSession()
+            throws NameNotFoundException {
+        testSetUserReviewGrantedConsentResult_startedSession(RECORD_CONTENT_TASK,
+                ContentRecordingSession.RECORD_CONTENT_TASK);
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_taskMirroring_failedToStartSession()
+            throws NameNotFoundException {
+        testSetUserReviewGrantedConsentResult_failedToStartSession(RECORD_CONTENT_TASK,
+                ContentRecordingSession.RECORD_CONTENT_TASK);
+    }
+
+    /**
+     * Executes and validates scenario where the consent result indicates the projection continues,
+     * and successfully started projection.
+     */
+    private void testSetUserReviewGrantedConsentResult_startedSession(
+            @ReviewGrantedConsentResult int consentResult,
+            @ContentRecordingSession.RecordContent int recordedContent)
+            throws NameNotFoundException {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.setLaunchCookie(mock(IBinder.class));
+        projection.start(mIMediaProjectionCallback);
+        projection.notifyVirtualDisplayCreated(10);
+        // Waiting for user to review consent.
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+        mService.setContentRecordingSession(mWaitingDisplaySession);
+
+        mService.setUserReviewGrantedConsentResult(consentResult, projection);
+        verifySetSessionWithContent(recordedContent);
+        assertThat(mService.isCurrentProjection(projection)).isTrue();
+    }
+
+    /**
+     * Executes and validates scenario where the consent result indicates the projection continues,
+     * but unable to continue projection.
+     */
+    private void testSetUserReviewGrantedConsentResult_failedToStartSession(
+            @ReviewGrantedConsentResult int consentResult,
+            @ContentRecordingSession.RecordContent int recordedContent)
+            throws NameNotFoundException {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.start(mIMediaProjectionCallback);
+        projection.notifyVirtualDisplayCreated(10);
+        // Waiting for user to review consent.
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                eq(mWaitingDisplaySession));
+        mService.setContentRecordingSession(mWaitingDisplaySession);
+
+        doReturn(false).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+
+        mService.setUserReviewGrantedConsentResult(consentResult, projection);
+        verifySetSessionWithContent(recordedContent);
+        assertThat(mService.isCurrentProjection(projection.asBinder())).isFalse();
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_displayMirroring_noPriorSession()
+            throws NameNotFoundException {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.setLaunchCookie(mock(IBinder.class));
+        projection.start(mIMediaProjectionCallback);
+        // Skip setting the prior session details.
+
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+
+        mService.setUserReviewGrantedConsentResult(RECORD_CONTENT_DISPLAY, projection);
+        // Result is ignored & session not updated.
+        verify(mWindowManagerInternal, never()).setContentRecordingSession(any(
+                ContentRecordingSession.class));
+        // Current session continues.
+        assertThat(mService.isCurrentProjection(projection)).isTrue();
+    }
+
+    @Test
+    public void testSetUserReviewGrantedConsentResult_displayMirroring_sessionNotWaiting()
+            throws NameNotFoundException {
+        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+        projection.setLaunchCookie(mock(IBinder.class));
+        projection.start(mIMediaProjectionCallback);
+        // Session is not waiting for user's consent.
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+        mService.setContentRecordingSession(DISPLAY_SESSION);
+
+        doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+                any(ContentRecordingSession.class));
+
+        mService.setUserReviewGrantedConsentResult(RECORD_CONTENT_DISPLAY, projection);
+        // Result is ignored; only the original session was ever sent.
+        verify(mWindowManagerInternal).setContentRecordingSession(eq(
+                DISPLAY_SESSION));
+        // Current session continues.
+        assertThat(mService.isCurrentProjection(projection)).isTrue();
+    }
+
+    private void verifySetSessionWithContent(@ContentRecordingSession.RecordContent int content) {
+        verify(mWindowManagerInternal, atLeastOnce()).setContentRecordingSession(
+                mSessionCaptor.capture());
+        assertThat(mSessionCaptor.getValue()).isNotNull();
+        assertThat(mSessionCaptor.getValue().getContentToRecord()).isEqualTo(content);
+    }
+
     // Set up preconditions for creating a projection.
     private MediaProjectionManagerService.MediaProjection createProjectionPreconditions(
             MediaProjectionManagerService service)
@@ -373,14 +685,7 @@
         doReturn(mAppInfo).when(mPackageManager).getApplicationInfoAsUser(anyString(),
                 any(ApplicationInfoFlags.class), any(UserHandle.class));
         return service.createProjectionInternal(UID, PACKAGE_NAME,
-                TYPE_MIRRORING, /* isPermanentGrant= */ true, UserHandle.CURRENT,
-                /* packageAttemptedReusingGrantedConsent= */ false);
-    }
-
-    // Set up preconditions for creating a projection.
-    private MediaProjectionManagerService.MediaProjection createProjectionPreconditions()
-            throws NameNotFoundException {
-        return createProjectionPreconditions(mService);
+                TYPE_MIRRORING, /* isPermanentGrant= */ true, UserHandle.CURRENT);
     }
 
     // Set up preconditions for starting a projection, with no foreground service requirements.
@@ -391,19 +696,6 @@
         return createProjectionPreconditions(service);
     }
 
-    // Set up preconditions for starting a projection, specifying if it is possible to reuse the
-    // the current projection.
-    private MediaProjectionManagerService.MediaProjection startProjectionPreconditions(
-            boolean packageAttemptedReusingGrantedConsent)
-            throws NameNotFoundException {
-        mAppInfo.privateFlags |= PRIVATE_FLAG_PRIVILEGED;
-        doReturn(mAppInfo).when(mPackageManager).getApplicationInfoAsUser(anyString(),
-                any(ApplicationInfoFlags.class), any(UserHandle.class));
-        return mService.createProjectionInternal(UID, PACKAGE_NAME,
-                TYPE_MIRRORING, /* isPermanentGrant= */ true, UserHandle.CURRENT,
-                packageAttemptedReusingGrantedConsent);
-    }
-
     // Set up preconditions for starting a projection, with no foreground service requirements.
     private MediaProjectionManagerService.MediaProjection startProjectionPreconditions()
             throws NameNotFoundException {
@@ -411,6 +703,15 @@
         return createProjectionPreconditions(mService);
     }
 
+    // Set up preconditions for starting a projection, retrieving a pre-existing projection.
+    private MediaProjectionManagerService.MediaProjection startReusedProjectionPreconditions()
+            throws NameNotFoundException {
+        mAppInfo.privateFlags |= PRIVATE_FLAG_PRIVILEGED;
+        doReturn(mAppInfo).when(mPackageManager).getApplicationInfoAsUser(anyString(),
+                any(ApplicationInfoFlags.class), any(UserHandle.class));
+        return mService.getProjectionInternal(UID, PACKAGE_NAME);
+    }
+
     private static class FakeIMediaProjectionCallback extends IMediaProjectionCallback.Stub {
         @Override
         public void onStop() throws RemoteException {
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java
index d9cd77d..af144cf 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java
@@ -37,7 +37,6 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.annotation.NonNull;
-import android.content.AttributionSource;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.INetd;
@@ -50,7 +49,7 @@
 import android.os.PermissionEnforcer;
 import android.os.Process;
 import android.os.RemoteException;
-import android.permission.PermissionCheckerManager;
+import android.os.test.FakePermissionEnforcer;
 import android.platform.test.annotations.Presubmit;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArrayMap;
@@ -90,7 +89,6 @@
     private ArgumentCaptor<INetdUnsolicitedEventListener> mUnsolListenerCaptor;
 
     private final MockDependencies mDeps = new MockDependencies();
-    private final MockPermissionEnforcer mPermissionEnforcer = new MockPermissionEnforcer();
 
     private final class MockDependencies extends NetworkManagementService.Dependencies {
         @Override
@@ -118,24 +116,6 @@
         }
     }
 
-    private static final class MockPermissionEnforcer extends PermissionEnforcer {
-        @Override
-        protected int checkPermission(@NonNull String permission,
-                @NonNull AttributionSource source) {
-            String[] granted = new String [] {
-                android.Manifest.permission.NETWORK_SETTINGS,
-                android.Manifest.permission.OBSERVE_NETWORK_POLICY,
-                android.Manifest.permission.SHUTDOWN
-            };
-            for (String p : granted) {
-                if (p.equals(permission)) {
-                    return PermissionCheckerManager.PERMISSION_GRANTED;
-                }
-            }
-            return PermissionCheckerManager.PERMISSION_HARD_DENIED;
-        }
-    }
-
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -145,12 +125,15 @@
                 eq(ConnectivityManager.class));
         doReturn(mCm).when(mContext).getSystemService(eq(Context.CONNECTIVITY_SERVICE));
         // The AIDL stub will use PermissionEnforcer to check permission from the caller.
-        // Mock the service. See MockPermissionEnforcer above.
+        // Mock the service and grant the expected permissions.
+        FakePermissionEnforcer permissionEnforcer = new FakePermissionEnforcer();
+        permissionEnforcer.grant(android.Manifest.permission.NETWORK_SETTINGS);
+        permissionEnforcer.grant(android.Manifest.permission.OBSERVE_NETWORK_POLICY);
+        permissionEnforcer.grant(android.Manifest.permission.SHUTDOWN);
         doReturn(Context.PERMISSION_ENFORCER_SERVICE).when(mContext).getSystemServiceName(
                 eq(PermissionEnforcer.class));
-        doReturn(mPermissionEnforcer).when(mContext).getSystemService(
+        doReturn(permissionEnforcer).when(mContext).getSystemService(
                 eq(Context.PERMISSION_ENFORCER_SERVICE));
-
         // Start the service and wait until it connects to our socket.
         mNMService = NetworkManagementService.create(mContext, mDeps);
     }
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index b7f90d4..c04df30 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -18,6 +18,12 @@
 
 import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
 import static android.Manifest.permission.NETWORK_STACK;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK;
+import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_TOP;
 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
 import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
@@ -396,6 +402,26 @@
         }
     }
 
+    // TODO: Use TestLooperManager instead.
+    /**
+     * Helper that leverages try-with-resources to pause dispatch of
+     * {@link #mHandlerThread} until released.
+     */
+    static class SyncBarrier implements AutoCloseable {
+        private final int mToken;
+        private Handler mHandler;
+
+        SyncBarrier(Handler handler) {
+            mHandler = handler;
+            mToken = mHandler.getLooper().getQueue().postSyncBarrier();
+        }
+
+        @Override
+        public void close() throws Exception {
+            mHandler.getLooper().getQueue().removeSyncBarrier(mToken);
+        }
+    }
+
     @Before
     public void callSystemReady() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -1018,25 +1044,113 @@
     // don't check for side-effects (like calls to NetworkManagementService) neither cover all
     // different modes (Data Saver, Battery Saver, Doze, App idle, etc...).
     // These scenarios are extensively tested on CTS' HostsideRestrictBackgroundNetworkTests.
+    @SuppressWarnings("GuardedBy")
     @Test
     public void testUidForeground() throws Exception {
         // push all uids into background
         long procStateSeq = 0;
-        callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq++);
-        callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq++);
-        assertFalse(mService.isUidForeground(UID_A));
-        assertFalse(mService.isUidForeground(UID_B));
+        callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++);
+        callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_SERVICE, procStateSeq++);
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
 
         // push one of the uids into foreground
-        callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, procStateSeq++);
-        assertTrue(mService.isUidForeground(UID_A));
-        assertFalse(mService.isUidForeground(UID_B));
+        callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, procStateSeq++);
+        assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+        assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
 
         // and swap another uid into foreground
-        callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq++);
-        callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, procStateSeq++);
-        assertFalse(mService.isUidForeground(UID_A));
-        assertTrue(mService.isUidForeground(UID_B));
+        callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++);
+        callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_TOP, procStateSeq++);
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+        assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+        assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+
+        // change capability of an uid to allow access to power restricted network
+        callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++,
+                PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK);
+        callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_SERVICE, procStateSeq++,
+                PROCESS_CAPABILITY_NONE);
+        assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+
+        // change capability of an uid to allow access to user restricted network
+        callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_IMPORTANT_FOREGROUND, procStateSeq++,
+                PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK);
+        callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_SERVICE, procStateSeq++,
+                PROCESS_CAPABILITY_NONE);
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+        assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+    }
+
+    @SuppressWarnings("GuardedBy")
+    @Test
+    public void testUidForeground_withPendingState() throws Exception {
+        long procStateSeq = 0;
+        callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE,
+                procStateSeq++, PROCESS_CAPABILITY_NONE);
+        callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_SERVICE,
+                procStateSeq++, PROCESS_CAPABILITY_NONE);
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+
+        try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
+            // Verify that a callback with an old procStateSeq is ignored.
+            callOnUidStatechanged(UID_A, PROCESS_STATE_TOP, 0,
+                    PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK);
+            assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+            assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+            assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+            assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+
+            callOnUidStatechanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++,
+                    PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK);
+            assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+            assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+            assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+            assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+
+            callOnUidStatechanged(UID_A, PROCESS_STATE_IMPORTANT_FOREGROUND, procStateSeq++,
+                    PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK);
+            assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+            assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+            assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+            assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+
+            callOnUidStatechanged(UID_A, PROCESS_STATE_TOP, procStateSeq++,
+                    PROCESS_CAPABILITY_NONE);
+            assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+            assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+            assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+            assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+        }
+        waitForUidEventHandlerIdle();
+
+        assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+        assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+        assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+        assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+
+        try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
+            callOnUidStatechanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++,
+                    PROCESS_CAPABILITY_NONE);
+            assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
+            assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
+            assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
+            assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
+        }
+        waitForUidEventHandlerIdle();
     }
 
     @Test
@@ -1417,14 +1531,28 @@
     @Test
     public void testOnUidStateChanged_notifyAMS() throws Exception {
         final long procStateSeq = 222;
-        callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq);
+        callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq);
         verify(mActivityManagerInternal).notifyNetworkPolicyRulesUpdated(UID_A, procStateSeq);
     }
 
-    private void callOnUidStateChanged(int uid, int procState, long procStateSeq)
+    private void callAndWaitOnUidStateChanged(int uid, int procState, long procStateSeq)
             throws Exception {
-        mUidObserver.onUidStateChanged(uid, procState, procStateSeq,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
+        callAndWaitOnUidStateChanged(uid, procState, procStateSeq,
+                PROCESS_CAPABILITY_NONE);
+    }
+
+    private void callAndWaitOnUidStateChanged(int uid, int procState, long procStateSeq,
+            int capability) throws Exception {
+        callOnUidStatechanged(uid, procState, procStateSeq, capability);
+        waitForUidEventHandlerIdle();
+    }
+
+    private void callOnUidStatechanged(int uid, int procState, long procStateSeq, int capability)
+            throws Exception {
+        mUidObserver.onUidStateChanged(uid, procState, procStateSeq, capability);
+    }
+
+    private void waitForUidEventHandlerIdle() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         mService.mUidEventHandler.post(() -> {
             latch.countDown();
@@ -1927,9 +2055,9 @@
 
     @Test
     public void testLowPowerStandbyAllowlist() throws Exception {
-        callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0);
-        callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
-        callOnUidStateChanged(UID_C, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
+        callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 0);
+        callAndWaitOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
+        callAndWaitOnUidStateChanged(UID_C, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
         expectHasInternetPermission(UID_A, true);
         expectHasInternetPermission(UID_B, true);
         expectHasInternetPermission(UID_C, true);
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index e65f8cf..7c1845f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -201,7 +201,7 @@
         mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
         assertResetTimes(START_TIME + 4 * INTERVAL, START_TIME + 5 * INTERVAL);
 
-        mService.saveBaseStateLocked();
+        mService.saveBaseState();
 
         dumpBaseStateFile();
 
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 21a11bc..52bf244 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -40,6 +40,7 @@
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.atMost;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -1611,7 +1612,8 @@
         startSystem();
 
         assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
-        verify(mNotifierMock, never()).onWakefulnessChangeStarted(anyInt(), anyInt(), anyLong());
+        verify(mNotifierMock, never()).onGlobalWakefulnessChangeStarted(anyInt(), anyInt(),
+                anyLong());
     }
 
     @Test
@@ -1630,7 +1632,7 @@
         startSystem();
 
         assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
-        verify(mNotifierMock).onWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP), anyInt(),
+        verify(mNotifierMock).onGlobalWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP), anyInt(),
                 anyLong());
     }
 
@@ -2112,7 +2114,7 @@
     }
 
     @Test
-    public void testMultiDisplay_defaultDozing_addNewDisplayDefaultGoesBackToDoze() {
+    public void testMultiDisplay_addNewDisplay_becomeGloballyAwakeButDefaultRemainsDozing() {
         final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
         final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
         final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
@@ -2142,6 +2144,7 @@
         assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
                 WAKEFULNESS_DOZING);
         assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+        verify(mDreamManagerInternalMock).stopDream(anyBoolean(), anyString());
         verify(mDreamManagerInternalMock).startDream(eq(true), anyString());
 
         listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
@@ -2152,7 +2155,10 @@
                 WAKEFULNESS_AWAKE);
         assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
                 WAKEFULNESS_DOZING);
-        verify(mDreamManagerInternalMock, times(2)).startDream(eq(true), anyString());
+
+        // Make sure there were no additional calls to stopDream or startDream
+        verify(mDreamManagerInternalMock, atMost(1)).stopDream(anyBoolean(), anyString());
+        verify(mDreamManagerInternalMock, atMost(1)).startDream(eq(true), anyString());
     }
 
     @Test
@@ -2169,7 +2175,7 @@
     }
 
     @Test
-    public void testMultiDisplay_onlyOneDisplaySleeps_onWakefulnessChangedEventFires() {
+    public void testMultiDisplay_onlyOneDisplaySleeps_onWakefulnessChangedEventsFire() {
         createService();
         startSystem();
         assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
@@ -2177,12 +2183,14 @@
         assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
                 WAKEFULNESS_ASLEEP);
 
-        verify(mNotifierMock).onPowerGroupWakefulnessChanged(eq(Display.DEFAULT_DISPLAY_GROUP),
-                eq(WAKEFULNESS_ASLEEP), anyInt(), eq(WAKEFULNESS_ASLEEP));
+        verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(Display.DEFAULT_DISPLAY_GROUP),
+                eq(WAKEFULNESS_ASLEEP), eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
+        verify(mNotifierMock).onGlobalWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP),
+                eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
     }
 
     @Test
-    public void testMultiDisplay_bothDisplaysSleep_onWakefulnessChangedEventFiresCorrectly() {
+    public void testMultiDisplay_bothDisplaysSleep_onWakefulnessChangedEventsFireCorrectly() {
         final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
         final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
         final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
@@ -2201,10 +2209,10 @@
         assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
         listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
 
-        mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
-                null, null);
-        mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
-                null, null);
+        mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, 0, 0,
+                PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
+        mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0,
+                PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
 
         assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
         assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
@@ -2212,14 +2220,16 @@
         assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
                 WAKEFULNESS_ASLEEP);
 
-        verify(mNotifierMock).onPowerGroupWakefulnessChanged(eq(nonDefaultDisplayGroupId),
-                eq(WAKEFULNESS_ASLEEP), anyInt(), eq(WAKEFULNESS_AWAKE));
-        verify(mNotifierMock).onPowerGroupWakefulnessChanged(eq(Display.DEFAULT_DISPLAY_GROUP),
-                eq(WAKEFULNESS_ASLEEP), anyInt(), eq(WAKEFULNESS_ASLEEP));
+        verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(nonDefaultDisplayGroupId),
+                eq(WAKEFULNESS_ASLEEP), eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
+        verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(Display.DEFAULT_DISPLAY_GROUP),
+                eq(WAKEFULNESS_ASLEEP), eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
+        verify(mNotifierMock).onGlobalWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP),
+                eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
     }
 
     @Test
-    public void testMultiDisplay_separateWakeStates_onWakefulnessChangedEventFiresCorrectly() {
+    public void testMultiDisplay_separateWakeStates_onWakefulnessChangedEventsFireCorrectly() {
         final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
         final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
         final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
@@ -2255,10 +2265,53 @@
                 WAKEFULNESS_ASLEEP);
         assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
                 WAKEFULNESS_AWAKE);
-        verify(mNotifierMock).onPowerGroupWakefulnessChanged(eq(Display.DEFAULT_DISPLAY_GROUP),
-                eq(WAKEFULNESS_ASLEEP), anyInt(), eq(WAKEFULNESS_AWAKE));
-        verify(mNotifierMock, never()).onPowerGroupWakefulnessChanged(
-                eq(nonDefaultDisplayGroupId), anyInt(), anyInt(), anyInt());
+        verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(nonDefaultDisplayGroupId),
+                eq(WAKEFULNESS_AWAKE), eq(PowerManager.WAKE_REASON_DISPLAY_GROUP_ADDED), anyLong());
+        verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(Display.DEFAULT_DISPLAY_GROUP),
+                eq(WAKEFULNESS_ASLEEP), eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
+        verify(mNotifierMock, never()).onGlobalWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP),
+                anyInt(), anyLong());
+    }
+
+    @Test
+    public void testMultiDisplay_oneDisplayGroupChanges_globalDoesNotChange() {
+        final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
+        final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
+        final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
+                new AtomicReference<>();
+        doAnswer((Answer<Void>) invocation -> {
+            listener.set(invocation.getArgument(0));
+            return null;
+        }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
+        final DisplayInfo info = new DisplayInfo();
+        info.displayGroupId = nonDefaultDisplayGroupId;
+        when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info);
+
+        createService();
+        startSystem();
+
+        listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
+
+        assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        long eventTime = mClock.now();
+        mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, eventTime, 0,
+                PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
+
+        assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
+                WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
+                WAKEFULNESS_ASLEEP);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        verify(mNotifierMock, never()).onGlobalWakefulnessChangeStarted(anyInt(), anyInt(),
+                anyLong());
+        verify(mNotifierMock, atMost(1)).onGroupWakefulnessChangeStarted(
+                eq(nonDefaultDisplayGroupId), eq(WAKEFULNESS_ASLEEP),
+                eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), eq(eventTime));
     }
 
     @Test
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 94f52bb..e31eed2 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -40,7 +40,6 @@
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MAX;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
@@ -95,6 +94,7 @@
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 
+import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyLong;
@@ -213,7 +213,6 @@
 
 import androidx.test.InstrumentationRegistry;
 
-import com.android.internal.app.IAppOpsService;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.Flag;
 import com.android.internal.config.sysui.TestableFlagResolver;
@@ -233,6 +232,8 @@
 import com.android.server.lights.LogicalLight;
 import com.android.server.notification.NotificationManagerService.NotificationAssistants;
 import com.android.server.notification.NotificationManagerService.NotificationListeners;
+import com.android.server.notification.NotificationManagerService.PostNotificationTracker;
+import com.android.server.notification.NotificationManagerService.PostNotificationTrackerFactory;
 import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.policy.PermissionPolicyInternal;
@@ -346,6 +347,8 @@
     private PermissionManager mPermissionManager;
     @Mock
     private DevicePolicyManagerInternal mDevicePolicyManager;
+    private final TestPostNotificationTrackerFactory mPostNotificationTrackerFactory =
+            new TestPostNotificationTrackerFactory();
 
     @Mock
     IIntentSender pi1;
@@ -382,8 +385,6 @@
     @Mock
     AppOpsManager mAppOpsManager;
     @Mock
-    IAppOpsService mAppOpsService;
-    @Mock
     private TestableNotificationManagerService.NotificationAssistantAccessGrantedCallback
             mNotificationAssistantAccessGrantedCallback;
     @Mock
@@ -421,6 +422,18 @@
         }
     }
 
+    private class TestPostNotificationTrackerFactory implements PostNotificationTrackerFactory {
+
+        private final List<PostNotificationTracker> mCreatedTrackers = new ArrayList<>();
+
+        @Override
+        public PostNotificationTracker newTracker() {
+            PostNotificationTracker tracker = PostNotificationTrackerFactory.super.newTracker();
+            mCreatedTrackers.add(tracker);
+            return tracker;
+        }
+    }
+
     @Before
     public void setUp() throws Exception {
         // Shell permisssions will override permissions of our app, so add all necessary permissions
@@ -558,10 +571,11 @@
                 mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr,
                 mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm,
                 mAppUsageStats, mDevicePolicyManager, mUgm, mUgmInternal,
-                mAppOpsManager, mAppOpsService, mUm, mHistoryManager, mStatsManager,
+                mAppOpsManager, mUm, mHistoryManager, mStatsManager,
                 mock(TelephonyManager.class),
                 mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class),
-                mTelecomManager, mLogger, mTestFlagResolver, mPermissionManager);
+                mTelecomManager, mLogger, mTestFlagResolver, mPermissionManager,
+                mPostNotificationTrackerFactory);
         // Return first true for RoleObserver main-thread check
         when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false);
         mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper);
@@ -644,11 +658,22 @@
 
     @After
     public void assertNotificationRecordLoggerCallsValid() {
+        waitForIdle(); // Finish async work, including all logging calls done by Runnables.
         for (NotificationRecordLoggerFake.CallRecord call : mNotificationRecordLogger.getCalls()) {
             if (call.wasLogged) {
                 assertNotNull(call.event);
             }
         }
+        assertThat(mNotificationRecordLogger.getPendingLogs()).isEmpty();
+    }
+
+    @After
+    public void assertAllTrackersFinishedOrCancelled() {
+        // Verify that no trackers were left dangling.
+        for (PostNotificationTracker tracker : mPostNotificationTrackerFactory.mCreatedTrackers) {
+            assertThat(tracker.isOngoing()).isFalse();
+        }
+        mPostNotificationTrackerFactory.mCreatedTrackers.clear();
     }
 
     @After
@@ -1452,7 +1477,7 @@
 
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                        r.getUid(), SystemClock.elapsedRealtime());
+                        r.getUid(), mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -1473,7 +1498,7 @@
 
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                        r.getUid(), SystemClock.elapsedRealtime());
+                        r.getUid(), mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -1713,6 +1738,68 @@
     }
 
     @Test
+    public void enqueueNotificationWithTag_usesAndFinishesTracker() throws Exception {
+        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+                "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
+                generateNotificationRecord(null).getNotification(), 0);
+
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isTrue();
+
+        waitForIdle();
+
+        assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(1);
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
+    }
+
+    @Test
+    public void enqueueNotificationWithTag_throws_usesAndCancelsTracker() throws Exception {
+        // Simulate not enqueued due to rejected inputs.
+        assertThrows(Exception.class,
+                () -> mBinderService.enqueueNotificationWithTag(PKG, PKG,
+                        "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
+                        /* notification= */ null, 0));
+
+        waitForIdle();
+
+        assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(0);
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
+    }
+
+    @Test
+    public void enqueueNotificationWithTag_notEnqueued_usesAndCancelsTracker() throws Exception {
+        // Simulate not enqueued due to snoozing inputs.
+        when(mSnoozeHelper.getSnoozeContextForUnpostedNotification(anyInt(), any(), any()))
+                .thenReturn("zzzzzzz");
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+                "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
+                generateNotificationRecord(null).getNotification(), 0);
+        waitForIdle();
+
+        assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(0);
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
+    }
+
+    @Test
+    public void enqueueNotificationWithTag_notPosted_usesAndCancelsTracker() throws Exception {
+        // Simulate not posted due to blocked app.
+        when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+                "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
+                generateNotificationRecord(null).getNotification(), 0);
+        waitForIdle();
+
+        assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(0);
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+        assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
+    }
+
+    @Test
     public void testCancelNonexistentNotification() throws Exception {
         mBinderService.cancelNotificationWithTag(PKG, PKG,
                 "testCancelNonexistentNotification", 0, 0);
@@ -1909,8 +1996,10 @@
         mService.mSummaryByGroupKey.put("pkg", summary);
         mService.mAutobundledSummaries.put(0, new ArrayMap<>());
         mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
+
         mService.updateAutobundledSummaryFlags(
                 0, "pkg", GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, false);
+        waitForIdle();
 
         assertTrue(summary.getSbn().isOngoing());
     }
@@ -1927,6 +2016,7 @@
         mService.mSummaryByGroupKey.put("pkg", summary);
 
         mService.updateAutobundledSummaryFlags(0, "pkg", GroupHelper.BASE_FLAGS, false);
+        waitForIdle();
 
         assertFalse(summary.getSbn().isOngoing());
     }
@@ -3776,6 +3866,37 @@
     }
 
     @Test
+    public void testSnoozeRunnable_snoozeAutoGroupChild_summaryNotSnoozed() throws Exception {
+        final NotificationRecord parent = generateNotificationRecord(
+                mTestNotificationChannel, 1, GroupHelper.AUTOGROUP_KEY, true);
+        final NotificationRecord child = generateNotificationRecord(
+                mTestNotificationChannel, 2, GroupHelper.AUTOGROUP_KEY, false);
+        mService.addNotification(parent);
+        mService.addNotification(child);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
+
+        // snooze child only
+        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
+                mService.new SnoozeNotificationRunnable(
+                        child.getKey(), 100, null);
+        snoozeNotificationRunnable.run();
+
+        // only child should be snoozed
+        verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
+
+        // both group summary and child should be cancelled
+        assertNull(mService.getNotificationRecord(parent.getKey()));
+        assertNull(mService.getNotificationRecord(child.getKey()));
+
+        assertEquals(4, mNotificationRecordLogger.numCalls());
+        assertEquals(NotificationRecordLogger.NotificationEvent.NOTIFICATION_SNOOZED,
+                mNotificationRecordLogger.event(0));
+        assertEquals(
+                NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_SNOOZED,
+                mNotificationRecordLogger.event(1));
+    }
+
+    @Test
     public void testPostGroupChild_unsnoozeParent() throws Exception {
         final NotificationRecord child = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group", false);
@@ -4229,7 +4350,7 @@
         mService.addEnqueuedNotification(r);
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                        r.getUid(), SystemClock.elapsedRealtime());
+                        r.getUid(), mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -4248,7 +4369,7 @@
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(update.getKey(),
                         update.getSbn().getPackageName(), update.getUid(),
-                        SystemClock.elapsedRealtime());
+                        mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -4268,7 +4389,7 @@
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(update.getKey(),
                         update.getSbn().getPackageName(), update.getUid(),
-                        SystemClock.elapsedRealtime());
+                        mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -4288,7 +4409,7 @@
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(update.getKey(),
                         update.getSbn().getPackageName(),
-                        update.getUid(), SystemClock.elapsedRealtime());
+                        update.getUid(), mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -4302,13 +4423,13 @@
         mService.addEnqueuedNotification(r);
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                        r.getUid(), SystemClock.elapsedRealtime());
+                        r.getUid(), mPostNotificationTrackerFactory.newTracker());
         runnable.run();
 
         r = generateNotificationRecord(mTestNotificationChannel, 1, null, false);
         r.setCriticality(CriticalNotificationExtractor.CRITICAL);
         runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                r.getUid(), SystemClock.elapsedRealtime());
+                r.getUid(), mPostNotificationTrackerFactory.newTracker());
         mService.addEnqueuedNotification(r);
 
         runnable.run();
@@ -4957,7 +5078,7 @@
                 mService.new PostNotificationRunnable(original.getKey(),
                         original.getSbn().getPackageName(),
                         original.getUid(),
-                        SystemClock.elapsedRealtime());
+                        mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -4981,7 +5102,7 @@
                 mService.new PostNotificationRunnable(update.getKey(),
                         update.getSbn().getPackageName(),
                         update.getUid(),
-                        SystemClock.elapsedRealtime());
+                        mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -5312,7 +5433,7 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(baos.toByteArray())), null);
         NotificationChannel restored = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
-        restored.populateFromXmlForRestore(parser, getContext());
+        restored.populateFromXmlForRestore(parser, true, getContext());
 
         assertNull(restored.getSound());
     }
@@ -7287,8 +7408,7 @@
 
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(update.getKey(), r.getSbn().getPackageName(),
-                        r.getUid(),
-                        SystemClock.elapsedRealtime());
+                        r.getUid(), mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -7596,13 +7716,12 @@
 
     @Test
     public void clearDefaultDnDPackageShouldEnableIt() throws RemoteException {
-        ComponentName deviceConfig = new ComponentName("device", "config");
         ArrayMap<Boolean, ArrayList<ComponentName>> changed = generateResetComponentValues();
         when(mAssistants.resetComponents(anyString(), anyInt())).thenReturn(changed);
         when(mListeners.resetComponents(anyString(), anyInt())).thenReturn(changed);
-        mService.getBinderService().clearData("device", 0, false);
+        mService.getBinderService().clearData("pkgName", 0, false);
         verify(mConditionProviders, times(1)).resetPackage(
-                        eq("device"), eq(0));
+                        eq("pkgName"), eq(0));
     }
 
     @Test
@@ -8446,7 +8565,6 @@
         assertEquals(0, notifsBefore.length);
 
         Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1);
-        int uid = 0; // sysui on primary user
 
         mService.mNotificationDelegate.grantInlineReplyUriPermission(
                 nr.getKey(), uri, nr.getSbn().getUser(), nr.getSbn().getPackageName(),
@@ -8579,7 +8697,6 @@
         reset(mPackageManager);
 
         Uri uri1 = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1);
-        Uri uri2 = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 2);
 
         // create an inline record a uri in it
         mService.mNotificationDelegate.grantInlineReplyUriPermission(
@@ -9983,7 +10100,7 @@
         mService.addEnqueuedNotification(r);
         NotificationManagerService.PostNotificationRunnable runnable =
                 mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                        r.getUid(), SystemClock.elapsedRealtime());
+                        r.getUid(), mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -10000,7 +10117,7 @@
 
         mService.addEnqueuedNotification(r);
         runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                r.getUid(), SystemClock.elapsedRealtime());
+                r.getUid(), mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -10017,7 +10134,7 @@
 
         mService.addEnqueuedNotification(r);
         runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                r.getUid(), SystemClock.elapsedRealtime());
+                r.getUid(), mPostNotificationTrackerFactory.newTracker());
         runnable.run();
         waitForIdle();
 
@@ -10109,10 +10226,8 @@
 
         // normal blocked notifications - blocked
         mService.addEnqueuedNotification(r);
-        NotificationManagerService.PostNotificationRunnable runnable =
-                mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
-                        r.getUid(), SystemClock.elapsedRealtime());
-        runnable.run();
+        mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+                mPostNotificationTrackerFactory.newTracker()).run();
         waitForIdle();
 
         verify(mUsageStats).registerBlocked(any());
@@ -10129,9 +10244,8 @@
         r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         mService.addEnqueuedNotification(r);
-        runnable = mService.new PostNotificationRunnable(
-                r.getKey(), r.getSbn().getPackageName(), r.getUid(), SystemClock.elapsedRealtime());
-        runnable.run();
+        mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+                mPostNotificationTrackerFactory.newTracker()).run();
         waitForIdle();
 
         verify(mUsageStats).registerBlocked(any());
@@ -10143,7 +10257,8 @@
         when(mTelecomManager.isInManagedCall()).thenReturn(true);
 
         mService.addEnqueuedNotification(r);
-        runnable.run();
+        mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+                mPostNotificationTrackerFactory.newTracker()).run();
         waitForIdle();
 
         verify(mUsageStats, never()).registerBlocked(any());
@@ -10156,7 +10271,8 @@
                 .thenReturn(true);
 
         mService.addEnqueuedNotification(r);
-        runnable.run();
+        mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+                mPostNotificationTrackerFactory.newTracker()).run();
         waitForIdle();
 
         verify(mUsageStats, never()).registerBlocked(any());
@@ -10169,7 +10285,8 @@
         mService.setTelecomManager(null);
 
         mService.addEnqueuedNotification(r);
-        runnable.run();
+        mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+                mPostNotificationTrackerFactory.newTracker()).run();
         waitForIdle();
 
         verify(mUsageStats).registerBlocked(any());
@@ -10183,7 +10300,8 @@
         mService.setTelecomManager(null);
 
         mService.addEnqueuedNotification(r);
-        runnable.run();
+        mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+                mPostNotificationTrackerFactory.newTracker()).run();
         waitForIdle();
 
         verify(mUsageStats).registerBlocked(any());
@@ -10195,7 +10313,8 @@
         reset(mUsageStats);
 
         mService.addEnqueuedNotification(r);
-        runnable.run();
+        mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+                mPostNotificationTrackerFactory.newTracker()).run();
         waitForIdle();
 
         verify(mUsageStats).registerBlocked(any());
@@ -10593,6 +10712,90 @@
     }
 
     @Test
+    public void checkCallStyleNotification_withoutAnyValidUseCase_throws() throws Exception {
+        Person person = new Person.Builder().setName("caller").build();
+        Notification n = new Notification.Builder(mContext, "test")
+                .setStyle(Notification.CallStyle.forOngoingCall(
+                        person, mock(PendingIntent.class)))
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+                n, UserHandle.getUserHandleForUid(mUid), null, 0);
+        NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        try {
+            mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+                    r.getSbn().getId(), r.getSbn().getTag(), r, false);
+            assertFalse("CallStyle should not be allowed without a valid use case", true);
+        } catch (IllegalArgumentException error) {
+            assertThat(error.getMessage()).contains("CallStyle");
+        }
+    }
+
+    @Test
+    public void checkCallStyleNotification_allowedForFgs() throws Exception {
+        Person person = new Person.Builder().setName("caller").build();
+        Notification n = new Notification.Builder(mContext, "test")
+                .setFlag(FLAG_FOREGROUND_SERVICE, true)
+                .setStyle(Notification.CallStyle.forOngoingCall(
+                        person, mock(PendingIntent.class)))
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+                n, UserHandle.getUserHandleForUid(mUid), null, 0);
+        NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+    }
+
+    @Test
+    public void checkCallStyleNotification_allowedForUij() throws Exception {
+        Person person = new Person.Builder().setName("caller").build();
+        Notification n = new Notification.Builder(mContext, "test")
+                .setFlag(FLAG_USER_INITIATED_JOB, true)
+                .setStyle(Notification.CallStyle.forOngoingCall(
+                        person, mock(PendingIntent.class)))
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+                n, UserHandle.getUserHandleForUid(mUid), null, 0);
+        NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+    }
+
+    @Test
+    public void checkCallStyleNotification_allowedForFsiAllowed() throws Exception {
+        Person person = new Person.Builder().setName("caller").build();
+        Notification n = new Notification.Builder(mContext, "test")
+                .setFullScreenIntent(mock(PendingIntent.class), true)
+                .setStyle(Notification.CallStyle.forOngoingCall(
+                        person, mock(PendingIntent.class)))
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+                n, UserHandle.getUserHandleForUid(mUid), null, 0);
+        NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+    }
+
+    @Test
+    public void checkCallStyleNotification_allowedForFsiDenied() throws Exception {
+        Person person = new Person.Builder().setName("caller").build();
+        Notification n = new Notification.Builder(mContext, "test")
+                .setFlag(Notification.FLAG_FSI_REQUESTED_BUT_DENIED, true)
+                .setStyle(Notification.CallStyle.forOngoingCall(
+                        person, mock(PendingIntent.class)))
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+                n, UserHandle.getUserHandleForUid(mUid), null, 0);
+        NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+                r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+    }
+
+    @Test
     public void fixSystemNotification_withOnGoingFlag_shouldBeDismissible()
             throws Exception {
         final ApplicationInfo ai = new ApplicationInfo();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
index 8a11798..1bb3502 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
@@ -16,11 +16,15 @@
 
 package com.android.server.notification;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.logging.InstanceId;
 import com.android.internal.logging.UiEventLogger;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Fake implementation of NotificationRecordLogger, for testing.
@@ -60,7 +64,8 @@
             this.event = event;
         }
     }
-    private List<CallRecord> mCalls = new ArrayList<>();
+    private final List<CallRecord> mCalls = new ArrayList<>();
+    private final Map<NotificationReported, CallRecord> mPendingLogs = new HashMap<>();
 
     public int numCalls() {
         return mCalls.size();
@@ -70,6 +75,10 @@
         return mCalls;
     }
 
+    List<NotificationReported> getPendingLogs() {
+        return new ArrayList<>(mPendingLogs.keySet());
+    }
+
     CallRecord get(int index) {
         return mCalls.get(index);
     }
@@ -77,10 +86,31 @@
         return mCalls.get(index).event;
     }
 
+    @Nullable
     @Override
-    public void maybeLogNotificationPosted(NotificationRecord r, NotificationRecord old,
-            int position, int buzzBeepBlink, InstanceId groupId) {
-        mCalls.add(new CallRecord(r, old, position, buzzBeepBlink, groupId));
+    public NotificationReported prepareToLogNotificationPosted(@Nullable NotificationRecord r,
+            @Nullable NotificationRecord old, int position, int buzzBeepBlink, InstanceId groupId) {
+        NotificationReported nr = NotificationRecordLogger.super.prepareToLogNotificationPosted(r,
+                old, position, buzzBeepBlink, groupId);
+        CallRecord callRecord = new CallRecord(r, old, position, buzzBeepBlink, groupId);
+        callRecord.wasLogged = false;
+        mCalls.add(callRecord);
+        if (nr != null) {
+            mPendingLogs.put(nr, callRecord);
+        }
+        return nr;
+    }
+
+    @Override
+    public void logNotificationPosted(NotificationReported nr) {
+        CallRecord callRecord = mPendingLogs.get(nr);
+        if (callRecord == null) {
+            throw new IllegalStateException(
+                    "Didn't find corresponding CallRecord in mPreparedCalls. Did you call "
+                            + "logNotificationPosted() twice!?");
+        }
+        mPendingLogs.remove(nr);
+        callRecord.wasLogged = true;
     }
 
     @Override
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index 397e3c1..539f329 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -36,6 +36,7 @@
 import static org.mockito.Mockito.when;
 
 import android.Manifest;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
@@ -47,7 +48,6 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.UiServiceTestCase;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -67,7 +67,7 @@
 public class PermissionHelperTest extends UiServiceTestCase {
 
     @Mock
-    private PermissionManagerServiceInternal mPmi;
+    private Context mContext;
     @Mock
     private IPackageManager mPackageManager;
     @Mock
@@ -80,7 +80,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager);
+        mPermissionHelper = new PermissionHelper(mContext, mPackageManager, mPermManager);
         PackageInfo testPkgInfo = new PackageInfo();
         testPkgInfo.requestedPermissions = new String[]{ Manifest.permission.POST_NOTIFICATIONS };
         when(mPackageManager.getPackageInfo(anyString(), anyLong(), anyInt()))
@@ -89,12 +89,12 @@
 
     @Test
     public void testHasPermission() throws Exception {
-        when(mPmi.checkUidPermission(anyInt(), anyString()))
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_GRANTED);
 
         assertThat(mPermissionHelper.hasPermission(1)).isTrue();
 
-        when(mPmi.checkUidPermission(anyInt(), anyString()))
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_DENIED);
 
         assertThat(mPermissionHelper.hasPermission(1)).isFalse();
@@ -241,7 +241,7 @@
 
     @Test
     public void testSetNotificationPermission_grantUserSet() throws Exception {
-        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_DENIED);
         mPermissionHelper.setNotificationPermission("pkg", 10, true, true);
 
@@ -255,7 +255,7 @@
     @Test
     public void testSetNotificationPermission_pkgPerm_grantedByDefaultPermSet_allUserSet()
             throws Exception {
-        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_DENIED);
         when(mPermManager.getPermissionFlags(anyString(),
                 eq(Manifest.permission.POST_NOTIFICATIONS),
@@ -273,7 +273,7 @@
 
     @Test
     public void testSetNotificationPermission_revokeUserSet() throws Exception {
-        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_GRANTED);
 
         mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
@@ -287,7 +287,7 @@
 
     @Test
     public void testSetNotificationPermission_grantNotUserSet() throws Exception {
-        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_DENIED);
 
         mPermissionHelper.setNotificationPermission("pkg", 10, true, false);
@@ -300,7 +300,7 @@
 
     @Test
     public void testSetNotificationPermission_revokeNotUserSet() throws Exception {
-        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_GRANTED);
 
         mPermissionHelper.setNotificationPermission("pkg", 10, false, false);
@@ -340,7 +340,7 @@
 
     @Test
     public void testSetNotificationPermission_alreadyGrantedNotRegranted() throws Exception {
-        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_GRANTED);
         mPermissionHelper.setNotificationPermission("pkg", 10, true, false);
 
@@ -350,7 +350,7 @@
 
     @Test
     public void testSetNotificationPermission_alreadyRevokedNotRerevoked() throws Exception {
-        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_DENIED);
         mPermissionHelper.setNotificationPermission("pkg", 10, false, false);
 
@@ -360,16 +360,19 @@
 
     @Test
     public void testSetNotificationPermission_doesntRequestNotChanged() throws Exception {
-        when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+        int testUid = -1;
+        when(mContext.checkPermission(anyString(), anyInt(), anyInt()))
                 .thenReturn(PERMISSION_GRANTED);
+        when(mPackageManager.getPackageUid(anyString(), anyInt(), anyInt()))
+                .thenReturn(testUid);
         PackageInfo testPkgInfo = new PackageInfo();
         testPkgInfo.requestedPermissions = new String[]{ Manifest.permission.RECORD_AUDIO };
         when(mPackageManager.getPackageInfo(anyString(), anyLong(), anyInt()))
                 .thenReturn(testPkgInfo);
         mPermissionHelper.setNotificationPermission("pkg", 10, false, false);
 
-        verify(mPmi, never()).checkPermission(
-                eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10));
+        verify(mContext, never()).checkPermission(
+                eq(Manifest.permission.POST_NOTIFICATIONS), eq(-1), eq(testUid));
         verify(mPermManager, never()).revokeRuntimePermission(
                 eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10), anyString());
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index f6d10b9..c78b03e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -140,6 +140,7 @@
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.ArrayList;
@@ -170,6 +171,12 @@
             Uri.parse("content://" + TEST_AUTHORITY
                     + "/internal/audio/media/10?title=Test&canonical=1");
 
+    private static final Uri ANDROID_RES_SOUND_URI =
+            Uri.parse("android.resource://" + TEST_AUTHORITY + "/raw/test");
+
+    private static final Uri FILE_SOUND_URI =
+            Uri.parse("file://" + TEST_AUTHORITY + "/product/media/test.ogg");
+
     @Mock PermissionHelper mPermissionHelper;
     @Mock RankingHandler mHandler;
     @Mock PackageManager mPm;
@@ -1338,6 +1345,57 @@
         assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
     }
 
+    /**
+     * Test sound Uri restore retry behavior when channel is restored before package
+     *  and then package is installed.
+     */
+    @Test
+    public void testRestoreXml_withNonExistentCanonicalizedSoundUriAndMissingPackage()
+            throws Exception {
+        // canonicalization returns CANONICAL_SOUND_URI for getSoundForBackup (backup part)
+        doReturn(CANONICAL_SOUND_URI)
+                .when(mTestIContentProvider).canonicalize(any(), eq(SOUND_URI));
+
+        NotificationChannel channel =
+                new NotificationChannel("id", "name", IMPORTANCE_LOW);
+        channel.setSound(SOUND_URI, mAudioAttributes);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
+                USER_SYSTEM, channel.getId());
+
+        // canonicalization / uncanonicalization returns null for the restore part
+        doReturn(null)
+                .when(mTestIContentProvider).canonicalize(any(), eq(CANONICAL_SOUND_URI));
+        doReturn(null)
+                .when(mTestIContentProvider).uncanonicalize(any(), any());
+
+        // simulate package not installed
+        when(mPm.getPackageUidAsUser(PKG_N_MR1, USER_SYSTEM)).thenReturn(UNKNOWN_UID);
+        when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenThrow(
+                new PackageManager.NameNotFoundException());
+
+        loadStreamXml(baos, true, USER_SYSTEM);
+
+        // 1st restore pass fails
+        NotificationChannel actualChannel = mHelper.getNotificationChannel(
+                PKG_N_MR1, UNKNOWN_UID, channel.getId(), false);
+        // sound is CANONICAL_SOUND_URI, unchanged from backup
+        assertEquals(CANONICAL_SOUND_URI, actualChannel.getSound());
+        // sound is flagged as not restored
+        assertFalse(actualChannel.isSoundRestored());
+
+        // package is "installed"
+        when(mPm.getPackageUidAsUser(PKG_N_MR1, USER_SYSTEM)).thenReturn(UID_N_MR1);
+
+        // Trigger 2nd restore pass
+        mHelper.onPackagesChanged(false, USER_SYSTEM, new String[]{PKG_N_MR1},
+                new int[]{UID_N_MR1});
+
+        // sound is flagged as restored and set to default URI
+        assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
+        assertTrue(actualChannel.isSoundRestored());
+    }
+
 
     /**
      * Although we don't make backups with uncanonicalized uris anymore, we used to, so we have to
@@ -1363,7 +1421,9 @@
                 backupWithUncanonicalizedSoundUri.getBytes(), true, USER_SYSTEM);
 
         NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, id, false);
+
         assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
+        assertTrue(actualChannel.isSoundRestored());
     }
 
     @Test
@@ -1389,6 +1449,73 @@
     }
 
     @Test
+    public void testBackupRestoreXml_withAndroidResourceSoundUri() throws Exception {
+        // Mock ContentResolver.getResourceId:
+        // throw exception on restore 1st pass => simulate app not installed yet
+        // then return a valid resource on package update => sim. app installed
+        ContentResolver contentResolver = mock(ContentResolver.class);
+        when(mContext.getContentResolver()).thenReturn(contentResolver);
+        ContentResolver.OpenResourceIdResult resId = mock(
+                ContentResolver.OpenResourceIdResult.class);
+        when(contentResolver.getResourceId(ANDROID_RES_SOUND_URI)).thenReturn(resId).thenThrow(
+                new FileNotFoundException("")).thenReturn(resId);
+
+        mHelper = new PreferencesHelper(mContext, mPm, mHandler, mMockZenModeHelper,
+                mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory, false);
+
+        NotificationChannel channel =
+                new NotificationChannel("id", "name", IMPORTANCE_LOW);
+        channel.setSound(ANDROID_RES_SOUND_URI, mAudioAttributes);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
+                USER_SYSTEM, channel.getId());
+
+        // simulate package not installed
+        when(mPm.getPackageUidAsUser(PKG_N_MR1, USER_SYSTEM)).thenReturn(UNKNOWN_UID);
+        when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenThrow(
+                new PackageManager.NameNotFoundException());
+
+        loadStreamXml(baos, true, USER_SYSTEM);
+
+        NotificationChannel actualChannel = mHelper.getNotificationChannel(
+                PKG_N_MR1, UNKNOWN_UID, channel.getId(), false);
+        // sound is ANDROID_RES_SOUND_URI, unchanged from backup
+        assertEquals(ANDROID_RES_SOUND_URI, actualChannel.getSound());
+        // sound is flagged as not restored
+        assertFalse(actualChannel.isSoundRestored());
+
+        // package is "installed"
+        when(mPm.getPackageUidAsUser(PKG_N_MR1, USER_SYSTEM)).thenReturn(UID_N_MR1);
+
+        // Trigger 2nd restore pass
+        mHelper.onPackagesChanged(false, USER_SYSTEM, new String[]{PKG_N_MR1},
+                new int[]{UID_N_MR1});
+
+        // sound is flagged as restored
+        assertEquals(ANDROID_RES_SOUND_URI, actualChannel.getSound());
+        assertTrue(actualChannel.isSoundRestored());
+    }
+
+    @Test
+    public void testBackupRestoreXml_withFileResourceSoundUri() throws Exception {
+        NotificationChannel channel =
+                new NotificationChannel("id", "name", IMPORTANCE_LOW);
+        channel.setSound(FILE_SOUND_URI, mAudioAttributes);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
+                USER_SYSTEM, channel.getId());
+
+        loadStreamXml(baos, true, USER_SYSTEM);
+
+        NotificationChannel actualChannel = mHelper.getNotificationChannel(
+                PKG_N_MR1, UID_N_MR1, channel.getId(), false);
+        // sound is FILE_SOUND_URI, unchanged from backup
+        assertEquals(FILE_SOUND_URI, actualChannel.getSound());
+        // sound is flagged as restored
+        assertTrue(actualChannel.isSoundRestored());
+    }
+
+    @Test
     public void testChannelXml_backup() throws Exception {
         NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
         NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello");
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 34bb664..d4a2e9a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -28,7 +28,6 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -56,7 +55,6 @@
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
-import android.testing.TestableContext;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -64,7 +62,6 @@
 
 import androidx.test.InstrumentationRegistry;
 
-import com.android.internal.app.IAppOpsService;
 import com.android.internal.config.sysui.TestableFlagResolver;
 import com.android.internal.logging.InstanceIdSequence;
 import com.android.internal.logging.InstanceIdSequenceFake;
@@ -162,14 +159,14 @@
                     mock(UsageStatsManagerInternal.class),
                     mock(DevicePolicyManagerInternal.class), mock(IUriGrantsManager.class),
                     mock(UriGrantsManagerInternal.class),
-                    mock(AppOpsManager.class), mock(IAppOpsService.class),
-                    mUm, mock(NotificationHistoryManager.class),
+                    mock(AppOpsManager.class), mUm, mock(NotificationHistoryManager.class),
                     mock(StatsManager.class), mock(TelephonyManager.class),
                     mock(ActivityManagerInternal.class),
                     mock(MultiRateLimiter.class), mock(PermissionHelper.class),
-                    mock(UsageStatsManagerInternal.class), mock (TelecomManager.class),
+                    mock(UsageStatsManagerInternal.class), mock(TelecomManager.class),
                     mock(NotificationChannelLogger.class), new TestableFlagResolver(),
-                    mock(PermissionManager.class));
+                    mock(PermissionManager.class),
+                    new NotificationManagerService.PostNotificationTrackerFactory() {});
         } 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/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index b2a5401..cb41769 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -55,14 +55,13 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.notNull;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -149,7 +148,7 @@
     @Mock PackageManager mPackageManager;
     private Resources mResources;
     private TestableLooper mTestableLooper;
-    private ZenModeHelper mZenModeHelperSpy;
+    private ZenModeHelper mZenModeHelper;
     private ContentResolver mContentResolver;
     @Mock AppOpsManager mAppOps;
     private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory;
@@ -176,8 +175,8 @@
         mConditionProviders = new ConditionProviders(mContext, new UserProfiles(),
                 AppGlobals.getPackageManager());
         mConditionProviders.addSystemProvider(new CountdownConditionProvider());
-        mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(),
-                mConditionProviders, mStatsEventBuilderFactory));
+        mZenModeHelper = new ZenModeHelper(mContext, mTestableLooper.getLooper(),
+                mConditionProviders, mStatsEventBuilderFactory);
 
         ResolveInfo ri = new ResolveInfo();
         ri.activityInfo = new ActivityInfo();
@@ -187,7 +186,7 @@
                 .thenReturn(CUSTOM_PKG_UID);
         when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
                 new String[] {pkg});
-        mZenModeHelperSpy.mPm = mPackageManager;
+        mZenModeHelper.mPm = mPackageManager;
     }
 
     private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException {
@@ -221,10 +220,10 @@
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
         serializer.startDocument(null, true);
-        mZenModeHelperSpy.writeXml(serializer, false, version, UserHandle.USER_ALL);
+        mZenModeHelper.writeXml(serializer, false, version, UserHandle.USER_ALL);
         serializer.endDocument();
         serializer.flush();
-        mZenModeHelperSpy.setConfig(new ZenModeConfig(), null, "writing xml");
+        mZenModeHelper.setConfig(new ZenModeConfig(), null, "writing xml");
         return baos;
     }
 
@@ -234,12 +233,12 @@
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
         serializer.startDocument(null, true);
-        mZenModeHelperSpy.writeXml(serializer, true, version, userId);
+        mZenModeHelper.writeXml(serializer, true, version, userId);
         serializer.endDocument();
         serializer.flush();
         ZenModeConfig newConfig = new ZenModeConfig();
         newConfig.user = userId;
-        mZenModeHelperSpy.setConfig(newConfig, null, "writing xml");
+        mZenModeHelper.setConfig(newConfig, null, "writing xml");
         return baos;
     }
 
@@ -277,209 +276,209 @@
         return customRule;
     }
 
+    // Verify that the appropriate appOpps operations are called for the restrictions requested.
+    // Note that this method assumes that priority only DND exempt packages is set to something
+    // in order to be able to distinguish it from the null case, so callers should make sure
+    // setPriorityOnlyDndExemptPackages has been called bofre this verify statement.
+    private void verifyApplyRestrictions(boolean zenPriorityOnly, boolean mute, int usage) {
+        int expectedMode = mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
+        verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_VIBRATE), eq(usage),
+                eq(expectedMode), zenPriorityOnly ? notNull() : eq(null));
+        verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage),
+                eq(expectedMode), zenPriorityOnly ? notNull() : eq(null));
+    }
+
     @Test
     public void testZenOff_NoMuteApplied() {
-        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_OFF;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
-                PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_OFF;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+                | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
 
-        doNothing().when(mZenModeHelperSpy).applyRestrictions(eq(false), anyBoolean(), anyInt());
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
-                AudioAttributes.USAGE_ALARM);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
-                AudioAttributes.USAGE_MEDIA);
+        // Check that we call through to applyRestrictions with usages USAGE_ALARM and USAGE_MEDIA
+        verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
+        verifyApplyRestrictions(false, false, AudioAttributes.USAGE_MEDIA);
     }
 
     @Test
     public void testZenOn_NotificationApplied() {
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
         // The most permissive policy
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
-                PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
+        mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+                | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
                 | PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
                 | PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
                 | PRIORITY_CATEGORY_REPEAT_CALLERS | PRIORITY_CATEGORY_SYSTEM, PRIORITY_SENDERS_ANY,
                 PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.applyRestrictions();
 
-        doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyBoolean(), anyInt());
-        verify(mZenModeHelperSpy).applyRestrictions(true, true,
-                AudioAttributes.USAGE_NOTIFICATION);
-        verify(mZenModeHelperSpy).applyRestrictions(true, true,
-                AudioAttributes.USAGE_NOTIFICATION_EVENT);
-        verify(mZenModeHelperSpy).applyRestrictions(true, true,
+        verifyApplyRestrictions(true, true, AudioAttributes.USAGE_NOTIFICATION);
+        verifyApplyRestrictions(true, true, AudioAttributes.USAGE_NOTIFICATION_EVENT);
+        verifyApplyRestrictions(true, true,
                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED);
-        verify(mZenModeHelperSpy).applyRestrictions(true, true,
+        verifyApplyRestrictions(true, true,
                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT);
     }
 
     @Test
     public void testZenOn_StarredCallers_CallTypesBlocked() {
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
         // The most permissive policy
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
-                PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
+        mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+                | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
                 | PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
                 | PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
                 | PRIORITY_CATEGORY_SYSTEM,
                 PRIORITY_SENDERS_STARRED,
                 PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.applyRestrictions();
 
-        doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyBoolean(), anyInt());
-        verify(mZenModeHelperSpy).applyRestrictions(true, true,
+        verifyApplyRestrictions(true, true,
                 AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
-        verify(mZenModeHelperSpy).applyRestrictions(true, true,
+        verifyApplyRestrictions(true, true,
                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
     }
 
     @Test
     public void testZenOn_AllCallers_CallTypesAllowed() {
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
         // The most permissive policy
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
-                PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
+        mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+                | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
                 | PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
                 | PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
                 | PRIORITY_CATEGORY_REPEAT_CALLERS | PRIORITY_CATEGORY_SYSTEM,
                 PRIORITY_SENDERS_ANY,
                 PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.applyRestrictions();
 
-        doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyBoolean(), anyInt());
-        verify(mZenModeHelperSpy).applyRestrictions(true, false,
-                AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
-        verify(mZenModeHelperSpy).applyRestrictions(true, false,
+        verifyApplyRestrictions(true, false, AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
+        verifyApplyRestrictions(true, false,
                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
     }
 
     @Test
     public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() {
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
-                PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+                | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
 
-        mZenModeHelperSpy.applyRestrictions();
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false,
-                AudioAttributes.USAGE_ALARM);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false,
-                AudioAttributes.USAGE_MEDIA);
+        mZenModeHelper.applyRestrictions();
+        verifyApplyRestrictions(true, false, AudioAttributes.USAGE_ALARM);
+        verifyApplyRestrictions(true, false, AudioAttributes.USAGE_MEDIA);
     }
 
     @Test
     public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() {
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
-                AudioAttributes.USAGE_ALARM);
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
+        verifyApplyRestrictions(true, true, AudioAttributes.USAGE_ALARM);
 
         // Media is a catch-all that includes games
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
-                AudioAttributes.USAGE_MEDIA);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
-                AudioAttributes.USAGE_GAME);
+        verifyApplyRestrictions(true, true, AudioAttributes.USAGE_MEDIA);
+        verifyApplyRestrictions(true, true, AudioAttributes.USAGE_GAME);
     }
 
     @Test
     public void testTotalSilence() {
-        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
-                PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+                | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
 
         // Total silence will silence alarms, media and system noises (but not vibrations)
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
-                AudioAttributes.USAGE_ALARM);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
-                AudioAttributes.USAGE_MEDIA);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
-                AudioAttributes.USAGE_GAME);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
-                AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
-                AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_VIBRATE);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
-                AudioAttributes.USAGE_UNKNOWN);
+        verifyApplyRestrictions(false, true, AudioAttributes.USAGE_ALARM);
+        verifyApplyRestrictions(false, true, AudioAttributes.USAGE_MEDIA);
+        verifyApplyRestrictions(false, true, AudioAttributes.USAGE_GAME);
+        verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_PLAY_AUDIO,
+                AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_IGNORED, null);
+        verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_VIBRATE,
+                AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_ALLOWED, null);
+        verifyApplyRestrictions(false, true, AudioAttributes.USAGE_UNKNOWN);
     }
 
     @Test
     public void testAlarmsOnly_alarmMediaMuteNotApplied() {
-        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
 
         // Alarms only mode will not silence alarms
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
-                AudioAttributes.USAGE_ALARM);
+        verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
 
         // Alarms only mode will not silence media
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
-                AudioAttributes.USAGE_MEDIA);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
-                AudioAttributes.USAGE_GAME);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
-                AudioAttributes.USAGE_UNKNOWN);
+        verifyApplyRestrictions(false, false, AudioAttributes.USAGE_MEDIA);
+        verifyApplyRestrictions(false, false, AudioAttributes.USAGE_GAME);
+        verifyApplyRestrictions(false, false, AudioAttributes.USAGE_UNKNOWN);
 
         // Alarms only will silence system noises (but not vibrations)
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
-                AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO);
+        verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_PLAY_AUDIO,
+                AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_IGNORED, null);
     }
 
     @Test
     public void testAlarmsOnly_callsMuteApplied() {
-        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
 
         // Alarms only mode will silence calls despite priority-mode config
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
-                AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
+        verifyApplyRestrictions(false, true, AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
+        verifyApplyRestrictions(false, true,
                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
     }
 
     @Test
     public void testAlarmsOnly_allZenConfigToggledCannotBypass_alarmMuteNotApplied() {
         // Only audio attributes with SUPPRESIBLE_NEVER can bypass
-        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
 
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
-                AudioAttributes.USAGE_ALARM);
+        verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
     }
 
     @Test
     public void testZenAllCannotBypass() {
         // Only audio attributes with SUPPRESIBLE_NEVER can bypass
         // with special case USAGE_ASSISTANCE_SONIFICATION
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
 
         for (int usage : AudioAttributes.SDK_USAGES) {
             if (usage == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) {
                 // only mute audio, not vibrations
-                verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true, usage,
-                        AppOpsManager.OP_PLAY_AUDIO);
-                verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false, usage,
-                        AppOpsManager.OP_VIBRATE);
+                verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_PLAY_AUDIO),
+                        eq(usage), eq(AppOpsManager.MODE_IGNORED), notNull());
+                verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_VIBRATE),
+                        eq(usage), eq(AppOpsManager.MODE_ALLOWED), notNull());
             } else {
                 boolean shouldMute = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage)
                         != AudioAttributes.SUPPRESSIBLE_NEVER;
-                verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, shouldMute, usage);
+                verifyApplyRestrictions(true, shouldMute, usage);
             }
         }
     }
 
     @Test
     public void testApplyRestrictions_whitelist_priorityOnlyMode() {
-        mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
 
         for (int usage : AudioAttributes.SDK_USAGES) {
             verify(mAppOps).setRestriction(
@@ -491,10 +490,10 @@
 
     @Test
     public void testApplyRestrictions_whitelist_alarmsOnlyMode() {
-        mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
-        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_ALARMS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_ALARMS;
+        mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
 
         for (int usage : AudioAttributes.SDK_USAGES) {
             verify(mAppOps).setRestriction(
@@ -506,10 +505,10 @@
 
     @Test
     public void testApplyRestrictions_whitelist_totalSilenceMode() {
-        mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
-        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_NO_INTERRUPTIONS;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.applyRestrictions();
+        mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_NO_INTERRUPTIONS;
+        mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+        mZenModeHelper.applyRestrictions();
 
         for (int usage : AudioAttributes.SDK_USAGES) {
             verify(mAppOps).setRestriction(
@@ -533,11 +532,10 @@
         // and we're setting zen mode on
         Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);
         Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 0);
-        mZenModeHelperSpy.mIsBootComplete = true;
-        mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
-        mZenModeHelperSpy.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+        mZenModeHelper.mIsBootComplete = true;
+        mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+        mZenModeHelper.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
 
-        verify(mZenModeHelperSpy, times(1)).createZenUpgradeNotification();
         verify(mNotificationManager, times(1)).notify(eq(ZenModeHelper.TAG),
                 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
         assertEquals(0, Settings.Secure.getInt(mContentResolver,
@@ -549,10 +547,9 @@
         // doesn't show upgrade notification if stored settings says don't show
         Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
         Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 0);
-        mZenModeHelperSpy.mIsBootComplete = true;
-        mZenModeHelperSpy.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+        mZenModeHelper.mIsBootComplete = true;
+        mZenModeHelper.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
 
-        verify(mZenModeHelperSpy, never()).createZenUpgradeNotification();
         verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG),
                 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
     }
@@ -562,10 +559,9 @@
         // doesn't show upgrade notification since zen was already updated
         Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
         Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 1);
-        mZenModeHelperSpy.mIsBootComplete = true;
-        mZenModeHelperSpy.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+        mZenModeHelper.mIsBootComplete = true;
+        mZenModeHelper.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
 
-        verify(mZenModeHelperSpy, never()).createZenUpgradeNotification();
         verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG),
                 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
     }
@@ -573,41 +569,41 @@
     @Test
     public void testZenSetInternalRinger_AllPriorityNotificationSoundsMuted() {
         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
-        mZenModeHelperSpy.mAudioManager = mAudioManager;
+        mZenModeHelper.mAudioManager = mAudioManager;
         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
                 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
 
         // 1. Current ringer is normal
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
         // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConfig.allowReminders = false;
-        mZenModeHelperSpy.mConfig.allowCalls = false;
-        mZenModeHelperSpy.mConfig.allowMessages = false;
-        mZenModeHelperSpy.mConfig.allowEvents = false;
-        mZenModeHelperSpy.mConfig.allowRepeatCallers = false;
-        mZenModeHelperSpy.mConfig.allowConversations = false;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mConfig.allowReminders = false;
+        mZenModeHelper.mConfig.allowCalls = false;
+        mZenModeHelper.mConfig.allowMessages = false;
+        mZenModeHelper.mConfig.allowEvents = false;
+        mZenModeHelper.mConfig.allowRepeatCallers = false;
+        mZenModeHelper.mConfig.allowConversations = false;
 
         // 2. apply priority only zen - verify ringer is unchanged
-        mZenModeHelperSpy.applyZenToRingerMode();
+        mZenModeHelper.applyZenToRingerMode();
         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
 
         // 3. apply zen off - verify zen is set to previous ringer (normal)
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
-        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
-        mZenModeHelperSpy.applyZenToRingerMode();
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelper.applyZenToRingerMode();
         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
     }
 
     @Test
     public void testRingerAffectedStreamsTotalSilence() {
         // in total silence:
         // ringtone, notification, system, alarm, streams, music are affected by ringer mode
-        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+        mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
-                mZenModeHelperSpy.new RingerModeDelegate();
+                mZenModeHelper.new RingerModeDelegate();
         int ringerModeAffectedStreams = ringerModeDelegate.getRingerModeAffectedStreams(0);
         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
@@ -622,11 +618,11 @@
     public void testRingerAffectedStreamsPriorityOnly() {
         // in priority only mode:
         // ringtone, notification and system streams are affected by ringer mode
-        mZenModeHelperSpy.mConfig.allowAlarms = true;
-        mZenModeHelperSpy.mConfig.allowReminders = true;
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mConfig.allowAlarms = true;
+        mZenModeHelper.mConfig.allowReminders = true;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerMuted =
-                mZenModeHelperSpy.new RingerModeDelegate();
+                mZenModeHelper.new RingerModeDelegate();
 
         int ringerModeAffectedStreams =
                 ringerModeDelegateRingerMuted.getRingerModeAffectedStreams(0);
@@ -640,15 +636,15 @@
 
         // even when ringer is muted (since all ringer sounds cannot bypass DND),
         // system stream is still affected by ringer mode
-        mZenModeHelperSpy.mConfig.allowSystem = false;
-        mZenModeHelperSpy.mConfig.allowReminders = false;
-        mZenModeHelperSpy.mConfig.allowCalls = false;
-        mZenModeHelperSpy.mConfig.allowMessages = false;
-        mZenModeHelperSpy.mConfig.allowEvents = false;
-        mZenModeHelperSpy.mConfig.allowRepeatCallers = false;
-        mZenModeHelperSpy.mConfig.allowConversations = false;
+        mZenModeHelper.mConfig.allowSystem = false;
+        mZenModeHelper.mConfig.allowReminders = false;
+        mZenModeHelper.mConfig.allowCalls = false;
+        mZenModeHelper.mConfig.allowMessages = false;
+        mZenModeHelper.mConfig.allowEvents = false;
+        mZenModeHelper.mConfig.allowRepeatCallers = false;
+        mZenModeHelper.mConfig.allowConversations = false;
         ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerNotMuted =
-                mZenModeHelperSpy.new RingerModeDelegate();
+                mZenModeHelper.new RingerModeDelegate();
 
         int ringerMutedRingerModeAffectedStreams =
                 ringerModeDelegateRingerNotMuted.getRingerModeAffectedStreams(0);
@@ -665,74 +661,74 @@
     @Test
     public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartNormal() {
         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
-        mZenModeHelperSpy.mAudioManager = mAudioManager;
+        mZenModeHelper.mAudioManager = mAudioManager;
         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
                 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
 
         // 1. Current ringer is normal
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConfig.allowReminders = true;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mConfig.allowReminders = true;
 
         // 2. apply priority only zen - verify ringer is normal
-        mZenModeHelperSpy.applyZenToRingerMode();
+        mZenModeHelper.applyZenToRingerMode();
         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
 
         // 3.  apply zen off - verify ringer remains normal
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
-        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
-        mZenModeHelperSpy.applyZenToRingerMode();
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelper.applyZenToRingerMode();
         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
     }
 
     @Test
     public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartSilent() {
         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
-        mZenModeHelperSpy.mAudioManager = mAudioManager;
+        mZenModeHelper.mAudioManager = mAudioManager;
         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
                 Integer.toString(AudioManager.RINGER_MODE_SILENT));
 
         // 1. Current ringer is silent
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConfig.allowReminders = true;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mConfig.allowReminders = true;
 
         // 2. apply priority only zen - verify ringer is silent
-        mZenModeHelperSpy.applyZenToRingerMode();
+        mZenModeHelper.applyZenToRingerMode();
         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
 
         // 3. apply zen-off - verify ringer is still silent
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
-        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
-        mZenModeHelperSpy.applyZenToRingerMode();
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelper.applyZenToRingerMode();
         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
     }
 
     @Test
     public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_RingerChanges() {
         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
-        mZenModeHelperSpy.mAudioManager = mAudioManager;
+        mZenModeHelper.mAudioManager = mAudioManager;
         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
                 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
 
         // 1. Current ringer is normal
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
         // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConfig.allowReminders = true;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mConfig.allowReminders = true;
 
         // 2. apply priority only zen - verify zen will still be normal
-        mZenModeHelperSpy.applyZenToRingerMode();
+        mZenModeHelper.applyZenToRingerMode();
         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
 
         // 3. change ringer from normal to silent, verify previous ringer set to new ringer (silent)
         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
-                mZenModeHelperSpy.new RingerModeDelegate();
+                mZenModeHelper.new RingerModeDelegate();
         ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
                 AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
                 VolumePolicy.DEFAULT);
@@ -741,41 +737,40 @@
 
         // 4.  apply zen off - verify ringer still silenced
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
-        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
-        mZenModeHelperSpy.applyZenToRingerMode();
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelper.applyZenToRingerMode();
         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
     }
 
     @Test
     public void testSilentRingerSavedInZenOff_startsZenOff() {
         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
-        mZenModeHelperSpy.mConfig = new ZenModeConfig();
-        mZenModeHelperSpy.mAudioManager = mAudioManager;
+        mZenModeHelper.mConfig = new ZenModeConfig();
+        mZenModeHelper.mAudioManager = mAudioManager;
 
         // apply zen off multiple times - verify ringer is not set to normal
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
-        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
-        mZenModeHelperSpy.mConfig = null; // will evaluate config to zen mode off
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelper.mConfig = null; // will evaluate config to zen mode off
         for (int i = 0; i < 3; i++) {
             // if zen doesn't change, zen should not reapply itself to the ringer
-            mZenModeHelperSpy.evaluateZenMode("test", true);
+            mZenModeHelper.evaluateZenMode("test", true);
         }
-        verify(mZenModeHelperSpy, never()).applyZenToRingerMode();
         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
     }
 
     @Test
     public void testSilentRingerSavedOnZenOff_startsZenOn() {
         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
-        mZenModeHelperSpy.mAudioManager = mAudioManager;
-        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
-        mZenModeHelperSpy.mConfig = new ZenModeConfig();
+        mZenModeHelper.mAudioManager = mAudioManager;
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelper.mConfig = new ZenModeConfig();
 
         // previously set silent ringer
         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
-                mZenModeHelperSpy.new RingerModeDelegate();
+                mZenModeHelper.new RingerModeDelegate();
         ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
                 AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
                 VolumePolicy.DEFAULT);
@@ -784,26 +779,25 @@
 
         // apply zen off multiple times - verify ringer is not set to normal
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         for (int i = 0; i < 3; i++) {
             // if zen doesn't change, zen should not reapply itself to the ringer
-            mZenModeHelperSpy.evaluateZenMode("test", true);
+            mZenModeHelper.evaluateZenMode("test", true);
         }
-        verify(mZenModeHelperSpy, times(1)).applyZenToRingerMode();
         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
     }
 
     @Test
     public void testVibrateRingerSavedOnZenOff_startsZenOn() {
         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
-        mZenModeHelperSpy.mAudioManager = mAudioManager;
-        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
-        mZenModeHelperSpy.mConfig = new ZenModeConfig();
+        mZenModeHelper.mAudioManager = mAudioManager;
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelper.mConfig = new ZenModeConfig();
 
         // previously set silent ringer
         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
-                mZenModeHelperSpy.new RingerModeDelegate();
+                mZenModeHelper.new RingerModeDelegate();
         ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
                 AudioManager.RINGER_MODE_VIBRATE, "test", AudioManager.RINGER_MODE_NORMAL,
                 VolumePolicy.DEFAULT);
@@ -812,89 +806,88 @@
 
         // apply zen off multiple times - verify ringer is not set to normal
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         for (int i = 0; i < 3; i++) {
             // if zen doesn't change, zen should not reapply itself to the ringer
-            mZenModeHelperSpy.evaluateZenMode("test", true);
+            mZenModeHelper.evaluateZenMode("test", true);
         }
-        verify(mZenModeHelperSpy, times(1)).applyZenToRingerMode();
         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
-                mZenModeHelperSpy.TAG);
+                mZenModeHelper.TAG);
     }
 
     @Test
     public void testParcelConfig() {
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConfig.allowAlarms = false;
-        mZenModeHelperSpy.mConfig.allowMedia = false;
-        mZenModeHelperSpy.mConfig.allowSystem = false;
-        mZenModeHelperSpy.mConfig.allowReminders = true;
-        mZenModeHelperSpy.mConfig.allowCalls = true;
-        mZenModeHelperSpy.mConfig.allowMessages = true;
-        mZenModeHelperSpy.mConfig.allowEvents = true;
-        mZenModeHelperSpy.mConfig.allowRepeatCallers = true;
-        mZenModeHelperSpy.mConfig.allowConversations = true;
-        mZenModeHelperSpy.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
-        mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
-        mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
-        mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
-        mZenModeHelperSpy.mConfig.manualRule.enabled = true;
-        mZenModeHelperSpy.mConfig.manualRule.snoozing = true;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mConfig.allowAlarms = false;
+        mZenModeHelper.mConfig.allowMedia = false;
+        mZenModeHelper.mConfig.allowSystem = false;
+        mZenModeHelper.mConfig.allowReminders = true;
+        mZenModeHelper.mConfig.allowCalls = true;
+        mZenModeHelper.mConfig.allowMessages = true;
+        mZenModeHelper.mConfig.allowEvents = true;
+        mZenModeHelper.mConfig.allowRepeatCallers = true;
+        mZenModeHelper.mConfig.allowConversations = true;
+        mZenModeHelper.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
+        mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
+        mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
+        mZenModeHelper.mConfig.manualRule.component = new ComponentName("a", "a");
+        mZenModeHelper.mConfig.manualRule.enabled = true;
+        mZenModeHelper.mConfig.manualRule.snoozing = true;
 
-        ZenModeConfig actual = mZenModeHelperSpy.mConfig.copy();
+        ZenModeConfig actual = mZenModeHelper.mConfig.copy();
 
-        assertEquals(mZenModeHelperSpy.mConfig, actual);
+        assertEquals(mZenModeHelper.mConfig, actual);
     }
 
     @Test
     public void testWriteXml() throws Exception {
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConfig.allowAlarms = false;
-        mZenModeHelperSpy.mConfig.allowMedia = false;
-        mZenModeHelperSpy.mConfig.allowSystem = false;
-        mZenModeHelperSpy.mConfig.allowReminders = true;
-        mZenModeHelperSpy.mConfig.allowCalls = true;
-        mZenModeHelperSpy.mConfig.allowMessages = true;
-        mZenModeHelperSpy.mConfig.allowEvents = true;
-        mZenModeHelperSpy.mConfig.allowRepeatCallers = true;
-        mZenModeHelperSpy.mConfig.allowConversations = true;
-        mZenModeHelperSpy.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
-        mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
-        mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
-        mZenModeHelperSpy.mConfig.manualRule.zenMode =
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mConfig.allowAlarms = false;
+        mZenModeHelper.mConfig.allowMedia = false;
+        mZenModeHelper.mConfig.allowSystem = false;
+        mZenModeHelper.mConfig.allowReminders = true;
+        mZenModeHelper.mConfig.allowCalls = true;
+        mZenModeHelper.mConfig.allowMessages = true;
+        mZenModeHelper.mConfig.allowEvents = true;
+        mZenModeHelper.mConfig.allowRepeatCallers = true;
+        mZenModeHelper.mConfig.allowConversations = true;
+        mZenModeHelper.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
+        mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
+        mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
+        mZenModeHelper.mConfig.manualRule.zenMode =
                 ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
-        mZenModeHelperSpy.mConfig.manualRule.pkg = "a";
-        mZenModeHelperSpy.mConfig.manualRule.enabled = true;
+        mZenModeHelper.mConfig.manualRule.component = new ComponentName("a", "a");
+        mZenModeHelper.mConfig.manualRule.pkg = "a";
+        mZenModeHelper.mConfig.manualRule.enabled = true;
 
-        ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
+        ZenModeConfig expected = mZenModeHelper.mConfig.copy();
 
         ByteArrayOutputStream baos = writeXmlAndPurge(null);
         TypedXmlPullParser parser = getParserForByteStream(baos);
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
         assertEquals("Config mismatch: current vs expected: "
-                + new ZenModeDiff.ConfigDiff(mZenModeHelperSpy.mConfig, expected), expected,
-                mZenModeHelperSpy.mConfig);
+                + new ZenModeDiff.ConfigDiff(mZenModeHelper.mConfig, expected), expected,
+                mZenModeHelper.mConfig);
     }
 
     @Test
     public void testProto() {
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         // existence of manual rule means it should be in output
-        mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
-        mZenModeHelperSpy.mConfig.manualRule.pkg = "android";  // system
+        mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
+        mZenModeHelper.mConfig.manualRule.pkg = "android";  // system
 
-        int n = mZenModeHelperSpy.mConfig.automaticRules.size();
+        int n = mZenModeHelper.mConfig.automaticRules.size();
         List<String> ids = new ArrayList<>(n);
-        for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) {
+        for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
             ids.add(rule.id);
         }
         ids.add(ZenModeConfig.MANUAL_RULE_ID);
         ids.add(""); // for ROOT_CONFIG, logged with empty string as id
 
         List<StatsEvent> events = new LinkedList<>();
-        mZenModeHelperSpy.pullRules(events);
+        mZenModeHelper.pullRules(events);
         assertEquals(n + 2, events.size());  // automatic rules + manual rule + root config
         for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
             if (builder.getAtomId() == DND_MODE_RULE) {
@@ -918,10 +911,10 @@
     public void testProtoWithAutoRule() throws Exception {
         setupZenConfig();
         // one enabled automatic rule
-        mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules(ZEN_MODE_FOR_TESTING);
+        mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules(ZEN_MODE_FOR_TESTING);
 
         List<StatsEvent> events = new LinkedList<>();
-        mZenModeHelperSpy.pullRules(events);
+        mZenModeHelper.pullRules(events);
 
         boolean foundCustomEvent = false;
         for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
@@ -942,23 +935,23 @@
     public void ruleUidsCached() throws Exception {
         setupZenConfig();
         // one enabled automatic rule
-        mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
+        mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
         List<StatsEvent> events = new LinkedList<>();
         // first time retrieving uid:
-        mZenModeHelperSpy.pullRules(events);
+        mZenModeHelper.pullRules(events);
         verify(mPackageManager, atLeastOnce()).getPackageUidAsUser(anyString(), anyInt());
 
         // second time retrieving uid:
         reset(mPackageManager);
-        mZenModeHelperSpy.pullRules(events);
+        mZenModeHelper.pullRules(events);
         verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());
 
         // new rule from same package + user added
         reset(mPackageManager);
         ZenModeConfig.ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                 CUSTOM_RULE_ID + "2");
-        mZenModeHelperSpy.mConfig.automaticRules.put(rule.id, rule);
-        mZenModeHelperSpy.pullRules(events);
+        mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
+        mZenModeHelper.pullRules(events);
         verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());
     }
 
@@ -969,23 +962,23 @@
 
         setupZenConfig();
         // one enabled automatic rule
-        mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
+        mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
         List<StatsEvent> events = new LinkedList<>();
 
-        mZenModeHelperSpy.pullRules(events);
-        mZenModeHelperSpy.removeAutomaticZenRule(CUSTOM_RULE_ID, "test");
+        mZenModeHelper.pullRules(events);
+        mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, "test");
         assertTrue(-1
-                == mZenModeHelperSpy.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
+                == mZenModeHelper.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
     }
 
     @Test
     public void testProtoRedactsIds() throws Exception {
         setupZenConfig();
         // one enabled automatic rule
-        mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
+        mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
 
         List<StatsEvent> events = new LinkedList<>();
-        mZenModeHelperSpy.pullRules(events);
+        mZenModeHelper.pullRules(events);
 
         boolean foundCustomEvent = false;
         for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
@@ -999,12 +992,12 @@
     @Test
     public void testProtoWithManualRule() throws Exception {
         setupZenConfig();
-        mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
-        mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
-        mZenModeHelperSpy.mConfig.manualRule.enabled = true;
+        mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
+        mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
+        mZenModeHelper.mConfig.manualRule.enabled = true;
 
         List<StatsEvent> events = new LinkedList<>();
-        mZenModeHelperSpy.pullRules(events);
+        mZenModeHelper.pullRules(events);
 
         boolean foundManualRule = false;
         for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
@@ -1020,50 +1013,50 @@
     public void testWriteXml_onlyBackupsTargetUser() throws Exception {
         // Setup configs for user 10 and 11.
         setupZenConfig();
-        ZenModeConfig config10 = mZenModeHelperSpy.mConfig.copy();
+        ZenModeConfig config10 = mZenModeHelper.mConfig.copy();
         config10.user = 10;
         config10.allowAlarms = true;
         config10.allowMedia = true;
-        mZenModeHelperSpy.setConfig(config10, null, "writeXml");
-        ZenModeConfig config11 = mZenModeHelperSpy.mConfig.copy();
+        mZenModeHelper.setConfig(config10, null, "writeXml");
+        ZenModeConfig config11 = mZenModeHelper.mConfig.copy();
         config11.user = 11;
         config11.allowAlarms = false;
         config11.allowMedia = false;
-        mZenModeHelperSpy.setConfig(config11, null, "writeXml");
+        mZenModeHelper.setConfig(config11, null, "writeXml");
 
         // Backup user 10 and reset values.
         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, 10);
         ZenModeConfig newConfig11 = new ZenModeConfig();
         newConfig11.user = 11;
-        mZenModeHelperSpy.mConfigs.put(11, newConfig11);
+        mZenModeHelper.mConfigs.put(11, newConfig11);
 
         // Parse backup data.
         TypedXmlPullParser parser = getParserForByteStream(baos);
-        mZenModeHelperSpy.readXml(parser, true, 10);
-        mZenModeHelperSpy.readXml(parser, true, 11);
+        mZenModeHelper.readXml(parser, true, 10);
+        mZenModeHelper.readXml(parser, true, 11);
 
-        ZenModeConfig actual = mZenModeHelperSpy.mConfigs.get(10);
+        ZenModeConfig actual = mZenModeHelper.mConfigs.get(10);
         assertEquals(
                 "Config mismatch: current vs expected: "
                         + new ZenModeDiff.ConfigDiff(actual, config10), config10, actual);
-        assertNotEquals("Expected config mismatch", config11, mZenModeHelperSpy.mConfigs.get(11));
+        assertNotEquals("Expected config mismatch", config11, mZenModeHelper.mConfigs.get(11));
     }
 
     @Test
     public void testReadXmlRestore_forSystemUser() throws Exception {
         setupZenConfig();
         // one enabled automatic rule
-        mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
-        ZenModeConfig original = mZenModeHelperSpy.mConfig.copy();
+        mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
+        ZenModeConfig original = mZenModeHelper.mConfig.copy();
 
         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
         TypedXmlPullParser parser = getParserForByteStream(baos);
-        mZenModeHelperSpy.readXml(parser, true, UserHandle.USER_SYSTEM);
+        mZenModeHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
 
         assertEquals("Config mismatch: current vs original: "
-                + new ZenModeDiff.ConfigDiff(mZenModeHelperSpy.mConfig, original),
-                original, mZenModeHelperSpy.mConfig);
-        assertEquals(original.hashCode(), mZenModeHelperSpy.mConfig.hashCode());
+                + new ZenModeDiff.ConfigDiff(mZenModeHelper.mConfig, original),
+                original, mZenModeHelper.mConfig);
+        assertEquals(original.hashCode(), mZenModeHelper.mConfig.hashCode());
     }
 
     /** Restore should ignore the data's user id and restore for the target user. */
@@ -1071,24 +1064,24 @@
     public void testReadXmlRestore_forNonSystemUser() throws Exception {
         // Setup config.
         setupZenConfig();
-        mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
-        ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
+        mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
+        ZenModeConfig expected = mZenModeHelper.mConfig.copy();
 
         // Backup data for user 0.
         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
 
         // Restore data for user 10.
         TypedXmlPullParser parser = getParserForByteStream(baos);
-        mZenModeHelperSpy.readXml(parser, true, 10);
+        mZenModeHelper.readXml(parser, true, 10);
 
-        ZenModeConfig actual = mZenModeHelperSpy.mConfigs.get(10);
+        ZenModeConfig actual = mZenModeHelper.mConfigs.get(10);
         expected.user = 10;
         assertEquals("Config mismatch: current vs original: "
                         + new ZenModeDiff.ConfigDiff(actual, expected),
                 expected, actual);
         assertEquals(expected.hashCode(), actual.hashCode());
         expected.user = 0;
-        assertNotEquals(expected, mZenModeHelperSpy.mConfig);
+        assertNotEquals(expected, mZenModeHelper.mConfig);
     }
 
     @Test
@@ -1119,19 +1112,19 @@
                 .allowReminders(false)
                 .build();
         automaticRules.put("customRule", customRule);
-        mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+        mZenModeHelper.mConfig.automaticRules = automaticRules;
 
-        ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
+        ZenModeConfig expected = mZenModeHelper.mConfig.copy();
 
         ByteArrayOutputStream baos = writeXmlAndPurge(null);
         TypedXmlPullParser parser = Xml.newFastPullParser();
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(baos.toByteArray())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
         ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
-        ZenModeConfig.ZenRule current = mZenModeHelperSpy.mConfig.automaticRules.get(ruleId);
+        ZenModeConfig.ZenRule current = mZenModeHelper.mConfig.automaticRules.get(ruleId);
 
         assertEquals("Automatic rules mismatch", original, current);
     }
@@ -1160,16 +1153,16 @@
                 .allowReminders(true)
                 .build();
         automaticRules.put(ruleId, customRule);
-        mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+        mZenModeHelper.mConfig.automaticRules = automaticRules;
 
-        ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
+        ZenModeConfig expected = mZenModeHelper.mConfig.copy();
 
         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
         TypedXmlPullParser parser = getParserForByteStream(baos);
-        mZenModeHelperSpy.readXml(parser, true, UserHandle.USER_SYSTEM);
+        mZenModeHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
 
         ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
-        ZenModeConfig.ZenRule current = mZenModeHelperSpy.mConfig.automaticRules.get(ruleId);
+        ZenModeConfig.ZenRule current = mZenModeHelper.mConfig.automaticRules.get(ruleId);
 
         assertEquals("Automatic rules mismatch", original, current);
     }
@@ -1188,7 +1181,7 @@
         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
         enabledAutoRule.put("customRule", customRule);
-        mZenModeHelperSpy.mConfig.automaticRules = enabledAutoRule;
+        mZenModeHelper.mConfig.automaticRules = enabledAutoRule;
 
         // set previous version
         ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1196,9 +1189,9 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(baos.toByteArray())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
-        assertTrue(mZenModeHelperSpy.mConfig.automaticRules.containsKey("customRule"));
+        assertTrue(mZenModeHelper.mConfig.automaticRules.containsKey("customRule"));
         setupZenConfigMaintained();
     }
 
@@ -1216,9 +1209,9 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(xml.getBytes())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
-        assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+        assertEquals(0, mZenModeHelper.mConfig.suppressedVisualEffects);
 
         xml = "<zen version=\"6\" user=\"0\">\n"
                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
@@ -1232,9 +1225,9 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(xml.getBytes())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
-        assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+        assertEquals(0, mZenModeHelper.mConfig.suppressedVisualEffects);
     }
 
     @Test
@@ -1251,9 +1244,9 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(xml.getBytes())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
-        assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+        assertEquals(0, mZenModeHelper.mConfig.suppressedVisualEffects);
     }
 
     @Test
@@ -1270,13 +1263,13 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(xml.getBytes())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
         assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
                         | SUPPRESSED_EFFECT_LIGHTS
                         | SUPPRESSED_EFFECT_AMBIENT
                         | SUPPRESSED_EFFECT_PEEK,
-                mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+                mZenModeHelper.mConfig.suppressedVisualEffects);
 
         xml = "<zen version=\"6\" user=\"0\">\n"
                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
@@ -1290,9 +1283,9 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(xml.getBytes())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
-        assertEquals(SUPPRESSED_EFFECT_PEEK, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+        assertEquals(SUPPRESSED_EFFECT_PEEK, mZenModeHelper.mConfig.suppressedVisualEffects);
 
         xml = "<zen version=\"6\" user=\"0\">\n"
                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
@@ -1306,12 +1299,12 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(xml.getBytes())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
         assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
                         | SUPPRESSED_EFFECT_LIGHTS
                         | SUPPRESSED_EFFECT_AMBIENT,
-                mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+                mZenModeHelper.mConfig.suppressedVisualEffects);
     }
 
     @Test
@@ -1320,7 +1313,7 @@
 
         // no enabled automatic zen rules and no default rules
         // so rules should be overriden by default rules
-        mZenModeHelperSpy.mConfig.automaticRules = new ArrayMap<>();
+        mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();
 
         // set previous version
         ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1328,10 +1321,10 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(baos.toByteArray())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
         // check default rules
-        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
         assertTrue(rules.size() != 0);
         for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
             assertTrue(rules.containsKey(defaultId));
@@ -1356,7 +1349,7 @@
         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
         disabledAutoRule.put("customRule", customRule);
-        mZenModeHelperSpy.mConfig.automaticRules = disabledAutoRule;
+        mZenModeHelper.mConfig.automaticRules = disabledAutoRule;
 
         // set previous version
         ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1364,10 +1357,10 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(baos.toByteArray())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
         // check default rules
-        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
         assertTrue(rules.size() != 0);
         for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
             assertTrue(rules.containsKey(defaultId));
@@ -1408,7 +1401,7 @@
         defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
         automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
 
-        mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+        mZenModeHelper.mConfig.automaticRules = automaticRules;
 
         // set previous version
         ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1416,10 +1409,10 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(baos.toByteArray())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
         // check default rules
-        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
         assertTrue(rules.size() != 0);
         for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
             assertTrue(rules.containsKey(defaultId));
@@ -1477,7 +1470,7 @@
                 .build();
         automaticRules.put(ZenModeConfig.EVENTS_DEFAULT_RULE_ID, defaultEventRule);
 
-        mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+        mZenModeHelper.mConfig.automaticRules = automaticRules;
 
         // set previous version
         ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1485,10 +1478,10 @@
         parser.setInput(new BufferedInputStream(
                 new ByteArrayInputStream(baos.toByteArray())), null);
         parser.nextTag();
-        mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+        mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
 
         // check default rules
-        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+        ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
         assertTrue(rules.size() != 0);
         for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
             assertTrue(rules.containsKey(defaultId));
@@ -1498,32 +1491,32 @@
         setupZenConfigMaintained();
 
         List<StatsEvent> events = new LinkedList<>();
-        mZenModeHelperSpy.pullRules(events);
+        mZenModeHelper.pullRules(events);
         assertEquals(4, events.size());
     }
 
     @Test
     public void testCountdownConditionSubscription() throws Exception {
         ZenModeConfig config = new ZenModeConfig();
-        mZenModeHelperSpy.mConfig = config;
-        mZenModeHelperSpy.mConditions.evaluateConfig(mZenModeHelperSpy.mConfig, null, true);
-        assertEquals(0, mZenModeHelperSpy.mConditions.mSubscriptions.size());
+        mZenModeHelper.mConfig = config;
+        mZenModeHelper.mConditions.evaluateConfig(mZenModeHelper.mConfig, null, true);
+        assertEquals(0, mZenModeHelper.mConditions.mSubscriptions.size());
 
-        mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
+        mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
         Uri conditionId = ZenModeConfig.toCountdownConditionId(9000000, false);
-        mZenModeHelperSpy.mConfig.manualRule.conditionId = conditionId;
-        mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("android",
+        mZenModeHelper.mConfig.manualRule.conditionId = conditionId;
+        mZenModeHelper.mConfig.manualRule.component = new ComponentName("android",
                 CountdownConditionProvider.class.getName());
-        mZenModeHelperSpy.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0,
+        mZenModeHelper.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0,
                 STATE_TRUE, Condition.FLAG_RELEVANT_NOW);
-        mZenModeHelperSpy.mConfig.manualRule.enabled = true;
-        ZenModeConfig originalConfig = mZenModeHelperSpy.mConfig.copy();
+        mZenModeHelper.mConfig.manualRule.enabled = true;
+        ZenModeConfig originalConfig = mZenModeHelper.mConfig.copy();
 
-        mZenModeHelperSpy.mConditions.evaluateConfig(mZenModeHelperSpy.mConfig, null, true);
+        mZenModeHelper.mConditions.evaluateConfig(mZenModeHelper.mConfig, null, true);
 
         assertEquals(true, ZenModeConfig.isValidCountdownConditionId(conditionId));
-        assertEquals(originalConfig, mZenModeHelperSpy.mConfig);
-        assertEquals(1, mZenModeHelperSpy.mConditions.mSubscriptions.size());
+        assertEquals(originalConfig, mZenModeHelper.mConfig);
+        assertEquals(1, mZenModeHelper.mConditions.mSubscriptions.size());
     }
 
     @Test
@@ -1531,9 +1524,9 @@
         List<StatsEvent> events = new LinkedList<>();
         ZenModeConfig config = new ZenModeConfig();
         config.automaticRules = new ArrayMap<>();
-        mZenModeHelperSpy.mConfig = config;
-        mZenModeHelperSpy.updateDefaultZenRules(); // shouldn't throw null pointer
-        mZenModeHelperSpy.pullRules(events); // shouldn't throw null pointer
+        mZenModeHelper.mConfig = config;
+        mZenModeHelper.updateDefaultZenRules(); // shouldn't throw null pointer
+        mZenModeHelper.pullRules(events); // shouldn't throw null pointer
     }
 
     @Test
@@ -1555,11 +1548,11 @@
 
         ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
-        mZenModeHelperSpy.mConfig.automaticRules = autoRules;
+        mZenModeHelper.mConfig.automaticRules = autoRules;
 
-        mZenModeHelperSpy.updateDefaultZenRules();
+        mZenModeHelper.updateDefaultZenRules();
         assertEquals(updatedDefaultRule,
-                mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
+                mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
     }
 
     @Test
@@ -1581,11 +1574,11 @@
 
         ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
-        mZenModeHelperSpy.mConfig.automaticRules = autoRules;
+        mZenModeHelper.mConfig.automaticRules = autoRules;
 
-        mZenModeHelperSpy.updateDefaultZenRules();
+        mZenModeHelper.updateDefaultZenRules();
         assertEquals(updatedDefaultRule,
-                mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
+                mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
     }
 
     @Test
@@ -1608,11 +1601,11 @@
 
         ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, customDefaultRule);
-        mZenModeHelperSpy.mConfig.automaticRules = autoRules;
+        mZenModeHelper.mConfig.automaticRules = autoRules;
 
-        mZenModeHelperSpy.updateDefaultZenRules();
+        mZenModeHelper.updateDefaultZenRules();
         ZenModeConfig.ZenRule ruleAfterUpdating =
-                mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID);
+                mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID);
         assertEquals(customDefaultRule.enabled, ruleAfterUpdating.enabled);
         assertEquals(customDefaultRule.modified, ruleAfterUpdating.modified);
         assertEquals(customDefaultRule.id, ruleAfterUpdating.id);
@@ -1633,7 +1626,7 @@
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
             // We need the package name to be something that's not "android" so there aren't any
             // existing rules under that package.
-            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
             assertNotNull(id);
         }
         try {
@@ -1643,7 +1636,7 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1663,7 +1656,7 @@
                     ZenModeConfig.toScheduleConditionId(si),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
             assertNotNull(id);
         }
         try {
@@ -1673,7 +1666,7 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1693,7 +1686,7 @@
                     ZenModeConfig.toScheduleConditionId(si),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
             assertNotNull(id);
         }
         try {
@@ -1703,7 +1696,7 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1718,10 +1711,10 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
 
         assertTrue(id != null);
-        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertTrue(ruleInConfig != null);
         assertEquals(zenRule.isEnabled(), ruleInConfig.enabled);
         assertEquals(zenRule.isModified(), ruleInConfig.modified);
@@ -1738,10 +1731,10 @@
                 new ComponentName("android", "ScheduleConditionProvider"),
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
 
         assertTrue(id != null);
-        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertTrue(ruleInConfig != null);
         assertEquals(zenRule.isEnabled(), ruleInConfig.enabled);
         assertEquals(zenRule.isModified(), ruleInConfig.modified);
@@ -1761,11 +1754,11 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
-        mZenModeHelperSpy.setAutomaticZenRuleState(zenRule.getConditionId(),
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+        mZenModeHelper.setAutomaticZenRuleState(zenRule.getConditionId(),
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE));
 
-        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertEquals(STATE_TRUE, ruleInConfig.condition.state);
     }
 
@@ -1778,7 +1771,7 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
 
         AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW",
                 null,
@@ -1787,9 +1780,9 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        mZenModeHelperSpy.updateAutomaticZenRule(id, zenRule2, "");
+        mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "");
 
-        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertEquals("NEW", ruleInConfig.name);
     }
 
@@ -1802,15 +1795,15 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
 
         assertTrue(id != null);
-        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertTrue(ruleInConfig != null);
         assertEquals(zenRule.getName(), ruleInConfig.name);
 
-        mZenModeHelperSpy.removeAutomaticZenRule(id, "test");
-        assertNull(mZenModeHelperSpy.mConfig.automaticRules.get(id));
+        mZenModeHelper.removeAutomaticZenRule(id, "test");
+        assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
     }
 
     @Test
@@ -1821,15 +1814,15 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
 
         assertTrue(id != null);
-        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+        ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertTrue(ruleInConfig != null);
         assertEquals(zenRule.getName(), ruleInConfig.name);
 
-        mZenModeHelperSpy.removeAutomaticZenRules(mContext.getPackageName(), "test");
-        assertNull(mZenModeHelperSpy.mConfig.automaticRules.get(id));
+        mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), "test");
+        assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
     }
 
     @Test
@@ -1839,17 +1832,17 @@
                 new ComponentName("android", "ScheduleConditionProvider"),
                 sharedUri,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
                 new ComponentName("android", "ScheduleConditionProvider"),
                 sharedUri,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id2 = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule2, "test");
+        String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, "test");
 
         Condition condition = new Condition(sharedUri, "", STATE_TRUE);
-        mZenModeHelperSpy.setAutomaticZenRuleState(sharedUri, condition);
+        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition);
 
-        for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) {
+        for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
             if (rule.id.equals(id)) {
                 assertNotNull(rule.condition);
                 assertTrue(rule.condition.state == STATE_TRUE);
@@ -1861,9 +1854,9 @@
         }
 
         condition = new Condition(sharedUri, "", Condition.STATE_FALSE);
-        mZenModeHelperSpy.setAutomaticZenRuleState(sharedUri, condition);
+        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition);
 
-        for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) {
+        for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
             if (rule.id.equals(id)) {
                 assertNotNull(rule.condition);
                 assertTrue(rule.condition.state == Condition.STATE_FALSE);
@@ -1875,31 +1868,48 @@
         }
     }
 
+    @Test
+    public void testSetManualZenMode() {
+        setupZenConfig();
+
+        // note that caller=null because that's how it comes in from NMS.setZenMode
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "");
+        mTestableLooper.processAllMessages();
+
+        // confirm that setting zen mode via setManualZenMode changed the zen mode correctly
+        assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode);
+
+        // and also that it works to turn it back off again
+        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "");
+        mTestableLooper.processAllMessages();
+        assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
+    }
+
     private void setupZenConfig() {
-        mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelperSpy.mConfig.allowAlarms = false;
-        mZenModeHelperSpy.mConfig.allowMedia = false;
-        mZenModeHelperSpy.mConfig.allowSystem = false;
-        mZenModeHelperSpy.mConfig.allowReminders = true;
-        mZenModeHelperSpy.mConfig.allowCalls = true;
-        mZenModeHelperSpy.mConfig.allowMessages = true;
-        mZenModeHelperSpy.mConfig.allowEvents = true;
-        mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
-        mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
-        mZenModeHelperSpy.mConfig.manualRule = null;
+        mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelper.mConfig.allowAlarms = false;
+        mZenModeHelper.mConfig.allowMedia = false;
+        mZenModeHelper.mConfig.allowSystem = false;
+        mZenModeHelper.mConfig.allowReminders = true;
+        mZenModeHelper.mConfig.allowCalls = true;
+        mZenModeHelper.mConfig.allowMessages = true;
+        mZenModeHelper.mConfig.allowEvents = true;
+        mZenModeHelper.mConfig.allowRepeatCallers = true;
+        mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
+        mZenModeHelper.mConfig.manualRule = null;
     }
 
     private void setupZenConfigMaintained() {
         // config is still the same as when it was setup (setupZenConfig)
-        assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
-        assertFalse(mZenModeHelperSpy.mConfig.allowMedia);
-        assertFalse(mZenModeHelperSpy.mConfig.allowSystem);
-        assertTrue(mZenModeHelperSpy.mConfig.allowReminders);
-        assertTrue(mZenModeHelperSpy.mConfig.allowCalls);
-        assertTrue(mZenModeHelperSpy.mConfig.allowMessages);
-        assertTrue(mZenModeHelperSpy.mConfig.allowEvents);
-        assertTrue(mZenModeHelperSpy.mConfig.allowRepeatCallers);
-        assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+        assertFalse(mZenModeHelper.mConfig.allowAlarms);
+        assertFalse(mZenModeHelper.mConfig.allowMedia);
+        assertFalse(mZenModeHelper.mConfig.allowSystem);
+        assertTrue(mZenModeHelper.mConfig.allowReminders);
+        assertTrue(mZenModeHelper.mConfig.allowCalls);
+        assertTrue(mZenModeHelper.mConfig.allowMessages);
+        assertTrue(mZenModeHelper.mConfig.allowEvents);
+        assertTrue(mZenModeHelper.mConfig.allowRepeatCallers);
+        assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelper.mConfig.suppressedVisualEffects);
     }
 
     /**
diff --git a/services/tests/voiceinteractiontests/TEST_MAPPING b/services/tests/voiceinteractiontests/TEST_MAPPING
new file mode 100644
index 0000000..6cbc49a
--- /dev/null
+++ b/services/tests/voiceinteractiontests/TEST_MAPPING
@@ -0,0 +1,17 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksVoiceInteractionTests",
+      "options": [
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    }
+  ],
+  "postsubmit": [
+    {
+      "name": "FrameworksVoiceInteractionTests"
+    }
+  ]
+}
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerEventTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerEventTest.java
new file mode 100644
index 0000000..1c89506
--- /dev/null
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerEventTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.soundtrigger;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.soundtrigger.SoundTriggerEvent.ServiceEvent;
+import com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.UUID;
+
+@RunWith(AndroidJUnit4.class)
+public final class SoundTriggerEventTest {
+    private static final ServiceEvent.Type serviceEventType = ServiceEvent.Type.ATTACH;
+    private static final SessionEvent.Type sessionEventType = SessionEvent.Type.DETACH;
+
+    @Test
+    public void serviceEventNoPackageNoError_getStringContainsType() {
+        final var event = new ServiceEvent(serviceEventType);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(serviceEventType.name());
+        assertThat(stringRep).ignoringCase().doesNotContain("error");
+    }
+
+    @Test
+    public void serviceEventPackageNoError_getStringContainsTypeAndPackage() {
+        final var packageName = "com.android.package.name";
+        final var event = new ServiceEvent(serviceEventType, packageName);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(serviceEventType.name());
+        assertThat(stringRep).contains(packageName);
+        assertThat(stringRep).ignoringCase().doesNotContain("error");
+    }
+
+    @Test
+    public void serviceEventPackageError_getStringContainsTypeAndPackageAndErrorAndMessage() {
+        final var packageName = "com.android.package.name";
+        final var errorString = "oh no an ERROR occurred";
+        final var event = new ServiceEvent(serviceEventType, packageName, errorString);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(serviceEventType.name());
+        assertThat(stringRep).contains(packageName);
+        assertThat(stringRep).contains(errorString);
+        assertThat(stringRep).ignoringCase().contains("error");
+    }
+
+    @Test
+    public void sessionEventUUIDNoError_getStringContainsUUID() {
+        final var uuid = new UUID(5, -7);
+        final var event = new SessionEvent(sessionEventType, uuid);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(sessionEventType.name());
+        assertThat(stringRep).contains(uuid.toString());
+        assertThat(stringRep).ignoringCase().doesNotContain("error");
+    }
+
+    @Test
+    public void sessionEventUUIDError_getStringContainsUUIDAndError() {
+        final var uuid = new UUID(5, -7);
+        final var errorString = "oh no an ERROR occurred";
+        final var event = new SessionEvent(sessionEventType, uuid, errorString);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(sessionEventType.name());
+        assertThat(stringRep).contains(uuid.toString());
+        assertThat(stringRep).ignoringCase().contains("error");
+        assertThat(stringRep).contains(errorString);
+    }
+}
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
new file mode 100644
index 0000000..f8a068c
--- /dev/null
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.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.server.soundtrigger_middleware;
+
+import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.verify;
+
+import android.Manifest;
+import android.app.ActivityThread;
+import android.media.permission.Identity;
+import android.media.permission.IdentityContext;
+import android.media.soundtrigger.PhraseRecognitionEvent;
+import android.media.soundtrigger.PhraseRecognitionExtra;
+import android.media.soundtrigger.RecognitionEvent;
+import android.media.soundtrigger.RecognitionStatus;
+import android.media.soundtrigger_middleware.ISoundTriggerCallback;
+import android.media.soundtrigger_middleware.ISoundTriggerModule;
+import android.os.BatteryStatsInternal;
+import android.os.Process;
+import android.os.RemoteException;
+
+import androidx.test.filters.FlakyTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.internal.util.FakeLatencyTracker;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+@RunWith(JUnit4.class)
+public class SoundTriggerMiddlewareLoggingLatencyTest {
+
+    private FakeLatencyTracker mLatencyTracker;
+    @Mock
+    private BatteryStatsInternal mBatteryStatsInternal;
+    @Mock
+    private ISoundTriggerMiddlewareInternal mDelegateMiddleware;
+    @Mock
+    private ISoundTriggerCallback mISoundTriggerCallback;
+    @Mock
+    private ISoundTriggerModule mSoundTriggerModule;
+    private SoundTriggerMiddlewareLogging mSoundTriggerMiddlewareLogging;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity(Manifest.permission.WRITE_DEVICE_CONFIG,
+                        Manifest.permission.READ_DEVICE_CONFIG);
+
+        Identity identity = new Identity();
+        identity.uid = Process.myUid();
+        identity.pid = Process.myPid();
+        identity.packageName = ActivityThread.currentOpPackageName();
+        IdentityContext.create(identity);
+
+        mLatencyTracker = FakeLatencyTracker.create();
+        mLatencyTracker.forceEnabled(ACTION_SHOW_VOICE_INTERACTION, -1);
+        mSoundTriggerMiddlewareLogging = new SoundTriggerMiddlewareLogging(mLatencyTracker,
+                () -> mBatteryStatsInternal,
+                mDelegateMiddleware);
+    }
+
+    @After
+    public void tearDown() {
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .dropShellPermissionIdentity();
+    }
+
+    @Test
+    @FlakyTest(bugId = 275113847)
+    public void testSetUpAndTearDown() {
+    }
+
+    @Test
+    @FlakyTest(bugId = 275113847)
+    public void testOnPhraseRecognitionStartsLatencyTrackerWithSuccessfulPhraseIdTrigger()
+            throws RemoteException {
+        ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
+                ISoundTriggerCallback.class);
+        mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
+        verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
+
+        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+                RecognitionStatus.SUCCESS, Optional.of(100) /* keyphraseId */);
+
+        assertThat(mLatencyTracker.getActiveActionStartTime(
+                ACTION_SHOW_VOICE_INTERACTION)).isGreaterThan(-1);
+    }
+
+    @Test
+    @FlakyTest(bugId = 275113847)
+    public void testOnPhraseRecognitionRestartsActiveSession() throws RemoteException {
+        ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
+                ISoundTriggerCallback.class);
+        mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
+        verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
+
+        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+                RecognitionStatus.SUCCESS, Optional.of(100) /* keyphraseId */);
+        long firstTriggerSessionStartTime = mLatencyTracker.getActiveActionStartTime(
+                ACTION_SHOW_VOICE_INTERACTION);
+        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+                RecognitionStatus.SUCCESS, Optional.of(100) /* keyphraseId */);
+        assertThat(mLatencyTracker.getActiveActionStartTime(
+                ACTION_SHOW_VOICE_INTERACTION)).isGreaterThan(-1);
+        assertThat(mLatencyTracker.getActiveActionStartTime(
+                ACTION_SHOW_VOICE_INTERACTION)).isNotEqualTo(firstTriggerSessionStartTime);
+    }
+
+    @Test
+    @FlakyTest(bugId = 275113847)
+    public void testOnPhraseRecognitionNeverStartsLatencyTrackerWithNonSuccessEvent()
+            throws RemoteException {
+        ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
+                ISoundTriggerCallback.class);
+        mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
+        verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
+
+        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+                RecognitionStatus.ABORTED, Optional.of(100) /* keyphraseId */);
+
+        assertThat(
+                mLatencyTracker.getActiveActionStartTime(ACTION_SHOW_VOICE_INTERACTION)).isEqualTo(
+                -1);
+    }
+
+    @Test
+    @FlakyTest(bugId = 275113847)
+    public void testOnPhraseRecognitionNeverStartsLatencyTrackerWithNoKeyphraseId()
+            throws RemoteException {
+        ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
+                ISoundTriggerCallback.class);
+        mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
+        verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
+
+        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+                RecognitionStatus.SUCCESS, Optional.empty() /* keyphraseId */);
+
+        assertThat(
+                mLatencyTracker.getActiveActionStartTime(ACTION_SHOW_VOICE_INTERACTION)).isEqualTo(
+                -1);
+    }
+
+    private void triggerPhraseRecognitionEvent(ISoundTriggerCallback callback,
+            @RecognitionStatus int triggerEventStatus, Optional<Integer> optionalKeyphraseId)
+            throws RemoteException {
+        // trigger a phrase recognition to start a latency tracker session
+        PhraseRecognitionEvent successEventWithKeyphraseId = new PhraseRecognitionEvent();
+        successEventWithKeyphraseId.common = new RecognitionEvent();
+        successEventWithKeyphraseId.common.status = triggerEventStatus;
+        if (optionalKeyphraseId.isPresent()) {
+            PhraseRecognitionExtra recognitionExtra = new PhraseRecognitionExtra();
+            recognitionExtra.id = optionalKeyphraseId.get();
+            successEventWithKeyphraseId.phraseExtras =
+                    new PhraseRecognitionExtra[]{recognitionExtra};
+        }
+        callback.onPhraseRecognition(0 /* modelHandle */, successEventWithKeyphraseId,
+                0 /* captureSession */);
+    }
+}
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingTest.java
index 4d3c26f..f92e0db 100644
--- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingTest.java
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingTest.java
@@ -16,172 +16,144 @@
 
 package com.android.server.soundtrigger_middleware;
 
-import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+import static com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareLogging.ServiceEvent;
+import static com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareLogging.SessionEvent;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.verify;
-
-import android.Manifest;
-import android.app.ActivityThread;
-import android.media.permission.Identity;
-import android.media.permission.IdentityContext;
-import android.media.soundtrigger.PhraseRecognitionEvent;
-import android.media.soundtrigger.PhraseRecognitionExtra;
-import android.media.soundtrigger.RecognitionEvent;
-import android.media.soundtrigger.RecognitionStatus;
-import android.media.soundtrigger_middleware.ISoundTriggerCallback;
-import android.media.soundtrigger_middleware.ISoundTriggerModule;
-import android.os.BatteryStatsInternal;
-import android.os.Process;
-import android.os.RemoteException;
-
-import androidx.test.filters.FlakyTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.internal.util.FakeLatencyTracker;
-
-import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Optional;
 
 @RunWith(JUnit4.class)
 public class SoundTriggerMiddlewareLoggingTest {
-    private FakeLatencyTracker mLatencyTracker;
-    @Mock
-    private BatteryStatsInternal mBatteryStatsInternal;
-    @Mock
-    private ISoundTriggerMiddlewareInternal mDelegateMiddleware;
-    @Mock
-    private ISoundTriggerCallback mISoundTriggerCallback;
-    @Mock
-    private ISoundTriggerModule mSoundTriggerModule;
-    private SoundTriggerMiddlewareLogging mSoundTriggerMiddlewareLogging;
+    private static final ServiceEvent.Type SERVICE_TYPE = ServiceEvent.Type.ATTACH;
+    private static final SessionEvent.Type SESSION_TYPE = SessionEvent.Type.LOAD_MODEL;
 
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                .adoptShellPermissionIdentity(Manifest.permission.WRITE_DEVICE_CONFIG,
-                        Manifest.permission.READ_DEVICE_CONFIG);
-
-        Identity identity = new Identity();
-        identity.uid = Process.myUid();
-        identity.pid = Process.myPid();
-        identity.packageName = ActivityThread.currentOpPackageName();
-        IdentityContext.create(identity);
-
-        mLatencyTracker = FakeLatencyTracker.create();
-        mLatencyTracker.forceEnabled(ACTION_SHOW_VOICE_INTERACTION, -1);
-        mSoundTriggerMiddlewareLogging = new SoundTriggerMiddlewareLogging(mLatencyTracker,
-                () -> mBatteryStatsInternal,
-                mDelegateMiddleware);
-    }
-
-    @After
-    public void tearDown() {
-        InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                .dropShellPermissionIdentity();
+    @Test
+    public void serviceEventException_getStringContainsInfo() {
+        String packageName = "com.android.test";
+        Exception exception = new Exception("test");
+        Object param1 = new Object();
+        Object param2 = new Object();
+        final var event =
+                ServiceEvent.createForException(
+                        SERVICE_TYPE, packageName, exception, param1, param2);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SERVICE_TYPE.name());
+        assertThat(stringRep).contains(packageName);
+        assertThat(stringRep).contains(exception.toString());
+        assertThat(stringRep).contains(param1.toString());
+        assertThat(stringRep).contains(param2.toString());
+        assertThat(stringRep).ignoringCase().contains("error");
     }
 
     @Test
-    @FlakyTest(bugId = 275113847)
-    public void testSetUpAndTearDown() {
+    public void serviceEventExceptionNoArgs_getStringContainsInfo() {
+        String packageName = "com.android.test";
+        Exception exception = new Exception("test");
+        final var event = ServiceEvent.createForException(SERVICE_TYPE, packageName, exception);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SERVICE_TYPE.name());
+        assertThat(stringRep).contains(packageName);
+        assertThat(stringRep).contains(exception.toString());
+        assertThat(stringRep).ignoringCase().contains("error");
     }
 
     @Test
-    @FlakyTest(bugId = 275113847)
-    public void testOnPhraseRecognitionStartsLatencyTrackerWithSuccessfulPhraseIdTrigger()
-            throws RemoteException {
-        ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
-                ISoundTriggerCallback.class);
-        mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
-        verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
-
-        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
-                RecognitionStatus.SUCCESS, Optional.of(100) /* keyphraseId */);
-
-        assertThat(mLatencyTracker.getActiveActionStartTime(
-                ACTION_SHOW_VOICE_INTERACTION)).isGreaterThan(-1);
+    public void serviceEventReturn_getStringContainsInfo() {
+        String packageName = "com.android.test";
+        Object param1 = new Object();
+        Object param2 = new Object();
+        Object retValue = new Object();
+        final var event =
+                ServiceEvent.createForReturn(SERVICE_TYPE, packageName, retValue, param1, param2);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SERVICE_TYPE.name());
+        assertThat(stringRep).contains(packageName);
+        assertThat(stringRep).contains(retValue.toString());
+        assertThat(stringRep).contains(param1.toString());
+        assertThat(stringRep).contains(param2.toString());
+        assertThat(stringRep).ignoringCase().doesNotContain("error");
     }
 
     @Test
-    @FlakyTest(bugId = 275113847)
-    public void testOnPhraseRecognitionRestartsActiveSession() throws RemoteException {
-        ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
-                ISoundTriggerCallback.class);
-        mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
-        verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
-
-        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
-                RecognitionStatus.SUCCESS, Optional.of(100) /* keyphraseId */);
-        long firstTriggerSessionStartTime = mLatencyTracker.getActiveActionStartTime(
-                ACTION_SHOW_VOICE_INTERACTION);
-        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
-                RecognitionStatus.SUCCESS, Optional.of(100) /* keyphraseId */);
-        assertThat(mLatencyTracker.getActiveActionStartTime(
-                ACTION_SHOW_VOICE_INTERACTION)).isGreaterThan(-1);
-        assertThat(mLatencyTracker.getActiveActionStartTime(
-                ACTION_SHOW_VOICE_INTERACTION)).isNotEqualTo(firstTriggerSessionStartTime);
+    public void serviceEventReturnNoArgs_getStringContainsInfo() {
+        String packageName = "com.android.test";
+        Object retValue = new Object();
+        final var event = ServiceEvent.createForReturn(SERVICE_TYPE, packageName, retValue);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SERVICE_TYPE.name());
+        assertThat(stringRep).contains(packageName);
+        assertThat(stringRep).contains(retValue.toString());
+        assertThat(stringRep).ignoringCase().doesNotContain("error");
     }
 
     @Test
-    @FlakyTest(bugId = 275113847)
-    public void testOnPhraseRecognitionNeverStartsLatencyTrackerWithNonSuccessEvent()
-            throws RemoteException {
-        ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
-                ISoundTriggerCallback.class);
-        mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
-        verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
-
-        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
-                RecognitionStatus.ABORTED, Optional.of(100) /* keyphraseId */);
-
-        assertThat(
-                mLatencyTracker.getActiveActionStartTime(ACTION_SHOW_VOICE_INTERACTION)).isEqualTo(
-                -1);
+    public void sessionEventException_getStringContainsInfo() {
+        Object param1 = new Object();
+        Object param2 = new Object();
+        Exception exception = new Exception("test");
+        final var event = SessionEvent.createForException(SESSION_TYPE, exception, param1, param2);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SESSION_TYPE.name());
+        assertThat(stringRep).contains(exception.toString());
+        assertThat(stringRep).contains(param1.toString());
+        assertThat(stringRep).contains(param2.toString());
+        assertThat(stringRep).ignoringCase().contains("error");
     }
 
     @Test
-    @FlakyTest(bugId = 275113847)
-    public void testOnPhraseRecognitionNeverStartsLatencyTrackerWithNoKeyphraseId()
-            throws RemoteException {
-        ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
-                ISoundTriggerCallback.class);
-        mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
-        verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
-
-        triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
-                RecognitionStatus.SUCCESS, Optional.empty() /* keyphraseId */);
-
-        assertThat(
-                mLatencyTracker.getActiveActionStartTime(ACTION_SHOW_VOICE_INTERACTION)).isEqualTo(
-                -1);
+    public void sessionEventExceptionNoArgs_getStringContainsInfo() {
+        Exception exception = new Exception("test");
+        final var event = SessionEvent.createForException(SESSION_TYPE, exception);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SESSION_TYPE.name());
+        assertThat(stringRep).contains(exception.toString());
+        assertThat(stringRep).ignoringCase().contains("error");
     }
 
-    private void triggerPhraseRecognitionEvent(ISoundTriggerCallback callback,
-            @RecognitionStatus int triggerEventStatus, Optional<Integer> optionalKeyphraseId)
-            throws RemoteException {
-        // trigger a phrase recognition to start a latency tracker session
-        PhraseRecognitionEvent successEventWithKeyphraseId = new PhraseRecognitionEvent();
-        successEventWithKeyphraseId.common = new RecognitionEvent();
-        successEventWithKeyphraseId.common.status = triggerEventStatus;
-        if (optionalKeyphraseId.isPresent()) {
-            PhraseRecognitionExtra recognitionExtra = new PhraseRecognitionExtra();
-            recognitionExtra.id = optionalKeyphraseId.get();
-            successEventWithKeyphraseId.phraseExtras =
-                    new PhraseRecognitionExtra[]{recognitionExtra};
-        }
-        callback.onPhraseRecognition(0 /* modelHandle */, successEventWithKeyphraseId,
-                0 /* captureSession */);
+    @Test
+    public void sessionEventReturn_getStringContainsInfo() {
+        Object param1 = new Object();
+        Object param2 = new Object();
+        Object retValue = new Object();
+        final var event = SessionEvent.createForReturn(SESSION_TYPE, retValue, param1, param2);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SESSION_TYPE.name());
+        assertThat(stringRep).contains(retValue.toString());
+        assertThat(stringRep).contains(param1.toString());
+        assertThat(stringRep).contains(param2.toString());
+        assertThat(stringRep).ignoringCase().doesNotContain("error");
+    }
+
+    @Test
+    public void sessionEventReturnNoArgs_getStringContainsInfo() {
+        Object retValue = new Object();
+        final var event = SessionEvent.createForReturn(SESSION_TYPE, retValue);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SESSION_TYPE.name());
+        assertThat(stringRep).contains(retValue.toString());
+        assertThat(stringRep).ignoringCase().doesNotContain("error");
+    }
+
+    @Test
+    public void sessionEventVoid_getStringContainsInfo() {
+        Object param1 = new Object();
+        Object param2 = new Object();
+        final var event = SessionEvent.createForVoid(SESSION_TYPE, param1, param2);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SESSION_TYPE.name());
+        assertThat(stringRep).contains(param1.toString());
+        assertThat(stringRep).contains(param2.toString());
+        assertThat(stringRep).ignoringCase().doesNotContain("error");
+    }
+
+    @Test
+    public void sessionEventVoidNoArgs_getStringContainsInfo() {
+        final var event = SessionEvent.createForVoid(SESSION_TYPE);
+        final var stringRep = event.eventToString();
+        assertThat(stringRep).contains(SESSION_TYPE.name());
+        assertThat(stringRep).ignoringCase().doesNotContain("error");
     }
 }
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index fe7cd4a..37e5da5 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -79,6 +79,7 @@
                   android:turnScreenOn="true"
                   android:showWhenLocked="true" />
         <activity android:name="com.android.server.wm.ActivityOptionsTest$MainActivity"
+                  android:configChanges="screenLayout|screenSize|smallestScreenSize|orientation"
                   android:turnScreenOn="true"
                   android:showWhenLocked="true" />
         <activity android:name="com.android.server.wm.ScreenshotTests$ScreenshotActivity"
diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
index 8f0a5e6..bf6901e 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
@@ -21,6 +21,8 @@
 import static android.view.KeyEvent.KEYCODE_C;
 import static android.view.KeyEvent.KEYCODE_CTRL_LEFT;
 import static android.view.KeyEvent.KEYCODE_E;
+import static android.view.KeyEvent.KEYCODE_ENTER;
+import static android.view.KeyEvent.KEYCODE_H;
 import static android.view.KeyEvent.KEYCODE_K;
 import static android.view.KeyEvent.KEYCODE_M;
 import static android.view.KeyEvent.KEYCODE_META_LEFT;
@@ -164,4 +166,24 @@
         sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_ALT_LEFT}, 0);
         mPhoneWindowManager.assertToggleCapsLock();
     }
+
+    /**
+     * META + H to go to homescreen
+     */
+    @Test
+    public void testMetaH() {
+        mPhoneWindowManager.overrideLaunchHome();
+        sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_H}, 0);
+        mPhoneWindowManager.assertGoToHomescreen();
+    }
+
+    /**
+     * META + ENTER to go to homescreen
+     */
+    @Test
+    public void testMetaEnter() {
+        mPhoneWindowManager.overrideLaunchHome();
+        sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_ENTER}, 0);
+        mPhoneWindowManager.assertGoToHomescreen();
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
index 6368f47..676bfb0 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
@@ -117,9 +117,9 @@
             throw new RuntimeException(e);
         }
 
-        for (KeyEvent event: events) {
+        for (int i = count - 1; i >= 0; i--) {
             final long eventTime = SystemClock.uptimeMillis();
-            final int keyCode = event.getKeyCode();
+            final int keyCode = keyCodes[i];
             final KeyEvent upEvent = new KeyEvent(downTime, eventTime, KeyEvent.ACTION_UP, keyCode,
                     0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, 0 /*flags*/,
                     InputDevice.SOURCE_KEYBOARD);
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index a2ee8a4..3513557 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -202,9 +202,11 @@
                     .canonicalToCurrentPackageNames(any());
         } catch (PackageManager.NameNotFoundException ignored) { }
 
-        doReturn(mTelecomManager).when(mContext).getSystemService(eq(Context.TELECOM_SERVICE));
-        doReturn(mNotificationManager).when(mContext)
-                .getSystemService(eq(NotificationManager.class));
+        doReturn(false).when(mTelecomManager).isInCall();
+        doReturn(false).when(mTelecomManager).isRinging();
+        doReturn(mTelecomManager).when(mPhoneWindowManager).getTelecommService();
+        doNothing().when(mNotificationManager).silenceNotificationSound();
+        doReturn(mNotificationManager).when(mPhoneWindowManager).getNotificationService();
         doReturn(mVibrator).when(mContext).getSystemService(eq(Context.VIBRATOR_SERVICE));
 
         final PowerManager.WakeLock wakeLock = mock(PowerManager.WakeLock.class);
@@ -233,8 +235,9 @@
         doNothing().when(mPhoneWindowManager).updateSettings();
         doNothing().when(mPhoneWindowManager).screenTurningOn(anyInt(), any());
         doNothing().when(mPhoneWindowManager).screenTurnedOn(anyInt());
-        doNothing().when(mPhoneWindowManager).startedWakingUp(anyInt());
-        doNothing().when(mPhoneWindowManager).finishedWakingUp(anyInt());
+        doNothing().when(mPhoneWindowManager).startedWakingUp(anyInt(), anyInt());
+        doNothing().when(mPhoneWindowManager).finishedWakingUp(anyInt(), anyInt());
+        doNothing().when(mPhoneWindowManager).lockNow(any());
 
         mPhoneWindowManager.init(new TestInjector(mContext, mWindowManagerFuncsImpl));
         mPhoneWindowManager.systemReady();
@@ -249,6 +252,7 @@
     void tearDown() {
         mHandlerThread.quitSafely();
         LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
+        Mockito.reset(mPhoneWindowManager);
         mMockitoSession.finishMocking();
     }
 
@@ -322,6 +326,7 @@
 
     void overrideDisplayState(int state) {
         doReturn(state).when(mDisplay).getState();
+        doReturn(state == STATE_ON).when(mDisplayPolicy).isAwake();
         Mockito.reset(mPowerManager);
     }
 
@@ -353,6 +358,10 @@
                 () -> LocalServices.getService(eq(StatusBarManagerInternal.class)));
     }
 
+    void overrideLaunchHome() {
+        doNothing().when(mPhoneWindowManager).launchHomeFromHotKey(anyInt());
+    }
+
     /**
      * Below functions will check the policy behavior could be invoked.
      */
@@ -384,6 +393,7 @@
     }
 
     void assertDreamRequest() {
+        waitForIdle();
         verify(mDreamManagerInternal).requestDream();
     }
 
@@ -480,4 +490,9 @@
         transitionCaptor.getValue().onAppTransitionFinishedLocked(any());
         verify(mPhoneWindowManager).lockNow(null);
     }
+
+    void assertGoToHomescreen() {
+        waitForIdle();
+        verify(mPhoneWindowManager).launchHomeFromHotKey(anyInt());
+    }
 }
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 0033e3e..cb984f8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -851,7 +851,7 @@
                     }
 
                     @Override
-                    public void onAnimationCancelled(boolean isKeyguardOccluded) {
+                    public void onAnimationCancelled() {
                     }
                 }, 0, 0));
         activity.updateOptionsLocked(opts);
@@ -3124,7 +3124,7 @@
                 .setSystemDecorations(true).build();
         // Add a decor insets provider window.
         final WindowState navbar = createNavBarWithProvidedInsets(squareDisplay);
-        assertTrue(navbar.providesNonDecorInsets()
+        assertTrue(navbar.providesDisplayDecorInsets()
                 && squareDisplay.getDisplayPolicy().updateDecorInsetsInfo());
         squareDisplay.sendNewConfiguration();
         final Task task = new TaskBuilder(mSupervisor).setDisplay(squareDisplay).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index 6d13124..169968c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -87,7 +87,7 @@
         }
 
         @Override
-        public void onAnimationCancelled(boolean isKeyguardOccluded) {
+        public void onAnimationCancelled() {
         }
 
         @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 0ae579b..a11079b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -735,7 +735,7 @@
         }
 
         @Override
-        public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException {
+        public void onAnimationCancelled() throws RemoteException {
             mFinishedCallback = null;
         }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 59cc4f5..ba8c94d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -549,7 +549,7 @@
         }
 
         @Override
-        public void onAnimationCancelled(boolean isKeyguardOccluded) {
+        public void onAnimationCancelled() {
             mCancelled = true;
         }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
index 06b4ad9..7b4392b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
@@ -50,7 +50,6 @@
 import android.util.Log;
 import android.view.IWindowManager;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import com.android.server.am.AssistDataRequester;
@@ -155,7 +154,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 130388718)
     public void testRequestData() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
                 CALLER_ASSIST_SCREENSHOT_ALLOWED);
@@ -263,7 +261,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 130388718)
     public void testNoFetchScreenshots_expectNoScreenshotCallbacks() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
                 CALLER_ASSIST_SCREENSHOT_ALLOWED);
@@ -275,7 +272,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 130388718)
     public void testDisallowAssistScreenshot_expectNullScreenshotCallback() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
                 !CALLER_ASSIST_SCREENSHOT_ALLOWED);
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 c8fdee0..353a8ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -45,6 +45,8 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
@@ -298,20 +300,27 @@
 
     @Test
     public void testUpdateDisplayConfigurationByDecor() {
+        doReturn(NO_CUTOUT).when(mDisplayContent).calculateDisplayCutoutForRotation(anyInt());
         final WindowState navbar = createNavBarWithProvidedInsets(mDisplayContent);
         final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
         final DisplayInfo di = mDisplayContent.getDisplayInfo();
         final int prevScreenHeightDp = mDisplayContent.getConfiguration().screenHeightDp;
-        assertTrue(navbar.providesNonDecorInsets() && displayPolicy.updateDecorInsetsInfo());
+        assertTrue(navbar.providesDisplayDecorInsets() && displayPolicy.updateDecorInsetsInfo());
         assertEquals(NAV_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation,
                 di.logicalWidth, di.logicalHeight).mConfigInsets.bottom);
         mDisplayContent.sendNewConfiguration();
         assertNotEquals(prevScreenHeightDp, mDisplayContent.getConfiguration().screenHeightDp);
-        assertFalse(navbar.providesNonDecorInsets() && displayPolicy.updateDecorInsetsInfo());
+        assertFalse(navbar.providesDisplayDecorInsets() && displayPolicy.updateDecorInsetsInfo());
 
         navbar.removeIfPossible();
         assertEquals(0, displayPolicy.getDecorInsetsInfo(di.rotation, di.logicalWidth,
                 di.logicalHeight).mNonDecorInsets.bottom);
+
+        final WindowState statusBar = createStatusBarWithProvidedInsets(mDisplayContent);
+        assertTrue(statusBar.providesDisplayDecorInsets()
+                && displayPolicy.updateDecorInsetsInfo());
+        assertEquals(STATUS_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation,
+                di.logicalWidth, di.logicalHeight).mConfigInsets.top);
     }
 
     @SetupWindows(addWindows = { W_NAVIGATION_BAR, W_INPUT_METHOD })
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 4b2d107..8e80485 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -541,6 +541,24 @@
                 SCREEN_ORIENTATION_UNSPECIFIED, Surface.ROTATION_180));
     }
 
+    @Test
+    public void testFreezeRotation_reverseRotationDirectionAroundZAxis_yes() throws Exception {
+        mBuilder.build();
+        when(mDeviceStateController.shouldReverseRotationDirectionAroundZAxis()).thenReturn(true);
+
+        freezeRotation(Surface.ROTATION_90);
+        assertEquals(Surface.ROTATION_270, mTarget.getUserRotation());
+    }
+
+    @Test
+    public void testFreezeRotation_reverseRotationDirectionAroundZAxis_no() throws Exception {
+        mBuilder.build();
+        when(mDeviceStateController.shouldReverseRotationDirectionAroundZAxis()).thenReturn(false);
+
+        freezeRotation(Surface.ROTATION_90);
+        assertEquals(Surface.ROTATION_90, mTarget.getUserRotation());
+    }
+
     private boolean waitForUiHandler() {
         final CountDownLatch latch = new CountDownLatch(1);
         UiThread.getHandler().post(latch::countDown);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index fb4f2ee..1cec0ef 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -41,8 +41,9 @@
 
 import android.annotation.NonNull;
 import android.app.WindowConfiguration;
-import android.content.res.Configuration;
+import android.content.ContentResolver;
 import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Surface;
@@ -439,6 +440,7 @@
     public void testDisplayWindowSettingsAppliedOnDisplayReady() {
         // Set forced densities for two displays in DisplayWindowSettings
         final DisplayContent dc = createMockSimulatedDisplay();
+        final ContentResolver contentResolver = useFakeSettingsProvider();
         mDisplayWindowSettings.setForcedDensity(mPrimaryDisplay.getDisplayInfo(), 123,
                 0 /* userId */);
         mDisplayWindowSettings.setForcedDensity(dc.getDisplayInfo(), 456, 0 /* userId */);
@@ -450,15 +452,21 @@
         assertFalse(mPrimaryDisplay.mWaitingForConfig);
         assertFalse(dc.mWaitingForConfig);
 
+        final int invalidW = Integer.MAX_VALUE;
+        final int invalidH = Integer.MAX_VALUE;
+        // Verify that applyForcedPropertiesForDefaultDisplay() handles invalid size request.
+        Settings.Global.putString(contentResolver, Settings.Global.DISPLAY_SIZE_FORCED,
+                invalidW + "," + invalidH);
         // Notify WM that the displays are ready and check that they are reconfigured.
         mWm.displayReady();
         waitUntilHandlersIdle();
 
-        final Configuration config = new Configuration();
-        mPrimaryDisplay.computeScreenConfiguration(config);
-        assertEquals(123, config.densityDpi);
-        dc.computeScreenConfiguration(config);
-        assertEquals(456, config.densityDpi);
+        // Density is set successfully.
+        assertEquals(123, mPrimaryDisplay.getConfiguration().densityDpi);
+        assertEquals(456, dc.getConfiguration().densityDpi);
+        // Invalid size won't be applied.
+        assertNotEquals(invalidW, mPrimaryDisplay.mBaseDisplayWidth);
+        assertNotEquals(invalidH, mPrimaryDisplay.mBaseDisplayHeight);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index 027f903..8cf2776 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -27,7 +27,6 @@
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import org.junit.After;
@@ -110,7 +109,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 131005232)
     public void testProcessOneItem_Flush() throws Exception {
         mFactory.setExpectedProcessedItemNumber(1);
         mListener.setExpectedOnPreProcessItemCallbackTimes(1);
@@ -162,7 +160,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 128526085)
     public void testProcessTwoItems_OneAfterAnother() throws Exception {
         // First item
         mFactory.setExpectedProcessedItemNumber(1);
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 0db983c..c4d03be 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -37,7 +37,6 @@
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.RefreshRatePolicy.FrameRateVote;
@@ -53,7 +52,6 @@
 @SmallTest
 @Presubmit
 @RunWith(WindowTestRunner.class)
-@FlakyTest
 public class RefreshRatePolicyTest extends WindowTestsBase {
     private static final int HI_MODE_ID = 1;
     private static final float HI_REFRESH_RATE = 90;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index eb26415..11d9629 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -211,7 +211,7 @@
         mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
 
         adapter.onAnimationCancelled(mMockLeash);
-        verify(mMockRunner).onAnimationCancelled(anyBoolean());
+        verify(mMockRunner).onAnimationCancelled();
     }
 
     @Test
@@ -227,7 +227,7 @@
         mClock.fastForward(10500);
         mHandler.timeAdvance();
 
-        verify(mMockRunner).onAnimationCancelled(anyBoolean());
+        verify(mMockRunner).onAnimationCancelled();
         verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
                 eq(adapter));
     }
@@ -248,12 +248,12 @@
             mClock.fastForward(10500);
             mHandler.timeAdvance();
 
-            verify(mMockRunner, never()).onAnimationCancelled(anyBoolean());
+            verify(mMockRunner, never()).onAnimationCancelled();
 
             mClock.fastForward(52500);
             mHandler.timeAdvance();
 
-            verify(mMockRunner).onAnimationCancelled(anyBoolean());
+            verify(mMockRunner).onAnimationCancelled();
             verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
                     eq(adapter));
         } finally {
@@ -265,7 +265,7 @@
     public void testZeroAnimations() throws Exception {
         mController.goodToGo(TRANSIT_OLD_NONE);
         verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
-        verify(mMockRunner).onAnimationCancelled(anyBoolean());
+        verify(mMockRunner).onAnimationCancelled();
     }
 
     @Test
@@ -275,7 +275,7 @@
                 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false);
         mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
         verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
-        verify(mMockRunner).onAnimationCancelled(anyBoolean());
+        verify(mMockRunner).onAnimationCancelled();
     }
 
     @Test
@@ -317,7 +317,7 @@
         win.mActivityRecord.removeImmediately();
         mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
         verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
-        verify(mMockRunner).onAnimationCancelled(anyBoolean());
+        verify(mMockRunner).onAnimationCancelled();
         verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
                 eq(adapter));
     }
@@ -575,7 +575,7 @@
 
             // Cancel the wallpaper window animator and ensure the runner is not canceled
             wallpaperWindowToken.cancelAnimation();
-            verify(mMockRunner, never()).onAnimationCancelled(anyBoolean());
+            verify(mMockRunner, never()).onAnimationCancelled();
         } finally {
             mDisplayContent.mOpeningApps.clear();
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index dfc453f..d173ce9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -1134,7 +1134,7 @@
         TaskChangeNotificationController controller = mAtm.getTaskChangeNotificationController();
         spyOn(controller);
         mWm.mRoot.lockAllProfileTasks(profileUserId);
-        verify(controller).notifyTaskProfileLocked(any());
+        verify(controller).notifyTaskProfileLocked(any(), eq(profileUserId));
 
         // Create the work lock activity on top of the task
         final ActivityRecord workLockActivity = new ActivityBuilder(mAtm).setTask(task).build();
@@ -1144,7 +1144,7 @@
         // Make sure the listener won't be notified again.
         clearInvocations(controller);
         mWm.mRoot.lockAllProfileTasks(profileUserId);
-        verify(controller, never()).notifyTaskProfileLocked(any());
+        verify(controller, never()).notifyTaskProfileLocked(any(), anyInt());
     }
 
     /**
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
index ff753f2..339162a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
@@ -98,7 +98,6 @@
         mFinishCallbackLatch.countDown();
     }
 
-    @FlakyTest(bugId = 144611135)
     @Test
     public void testAnimation() throws Exception {
         mSurfaceAnimationRunner
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java
index a27a5fd..4f45d5c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java
@@ -16,19 +16,34 @@
 
 package com.android.server.wm;
 
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.os.Parcel;
 import android.platform.test.annotations.Presubmit;
+import android.util.Log;
 import android.view.SurfaceControl;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
 
+import androidx.annotation.NonNull;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  * Class for testing {@link SurfaceControl}.
  *
@@ -106,6 +121,66 @@
         }
     }
 
+    @Test
+    public void testSurfaceChangedOnRotation() {
+        final Instrumentation instrumentation = getInstrumentation();
+        final Context context = instrumentation.getContext();
+        final Intent intent = new Intent().setComponent(
+                new ComponentName(context, ActivityOptionsTest.MainActivity.class))
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+        final Activity activity = instrumentation.startActivitySync(intent);
+        final SurfaceView sv = new SurfaceView(activity);
+        final AtomicInteger surfaceChangedCount = new AtomicInteger();
+        instrumentation.runOnMainSync(() -> activity.setContentView(sv));
+        sv.getHolder().addCallback(new SurfaceHolder.Callback() {
+            @Override
+            public void surfaceCreated(@NonNull SurfaceHolder holder) {
+            }
+            @Override
+            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
+                    int height) {
+                surfaceChangedCount.getAndIncrement();
+                Log.i("surfaceChanged", "width=" + width + " height=" + height
+                        + " getTransformHint="
+                        + sv.getViewRootImpl().getSurfaceControl().getTransformHint());
+            }
+            @Override
+            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+            }
+        });
+        final int rotation = activity.getResources().getConfiguration()
+                .windowConfiguration.getRotation();
+        activity.setRequestedOrientation(activity.getResources().getConfiguration().orientation
+                == Configuration.ORIENTATION_PORTRAIT
+                ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+                : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        instrumentation.getUiAutomation().syncInputTransactions();
+        instrumentation.waitForIdleSync();
+        final int newRotation = activity.getResources().getConfiguration()
+                .windowConfiguration.getRotation();
+        if (rotation == newRotation) {
+            // The device might not support requested orientation.
+            activity.finishAndRemoveTask();
+            return;
+        }
+        final int count = surfaceChangedCount.get();
+        activity.moveTaskToBack(true /* nonRoot */);
+        instrumentation.getUiAutomation().syncInputTransactions();
+        context.startActivity(intent);
+        instrumentation.getUiAutomation().syncInputTransactions();
+        final int countAfterToFront = count - surfaceChangedCount.get();
+        activity.finishAndRemoveTask();
+
+        // The first count is triggered from creation, so the target number is 2.
+        if (count > 2) {
+            fail("More than once surfaceChanged for rotation change: " + count);
+        }
+        if (countAfterToFront > 1) {
+            fail("More than once surfaceChanged for app transition with rotation change: "
+                    + countAfterToFront);
+        }
+    }
+
     private SurfaceControl buildTestSurface() {
         return new SurfaceControl.Builder()
                 .setContainerLayer()
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java
index 9db647a..89d7252 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.os.Build.HW_TIMEOUT_MULTIPLIER;
 import static android.window.SurfaceSyncGroup.TRANSACTION_READY_TIMEOUT;
 
 import static org.junit.Assert.assertEquals;
@@ -52,6 +53,8 @@
 public class SurfaceSyncGroupTests {
     private static final String TAG = "SurfaceSyncGroupTests";
 
+    private static final long TIMEOUT_S = HW_TIMEOUT_MULTIPLIER * 5L;
+
     @Rule
     public ActivityTestRule<SurfaceSyncGroupActivity> mActivityRule = new ActivityTestRule<>(
             SurfaceSyncGroupActivity.class);
@@ -93,7 +96,7 @@
         addSecondSyncGroup(secondSsg, secondDrawCompleteLatch, bothSyncGroupsComplete);
 
         assertTrue("Failed to draw two frames",
-                secondDrawCompleteLatch.await(5, TimeUnit.SECONDS));
+                secondDrawCompleteLatch.await(TIMEOUT_S, TimeUnit.SECONDS));
 
         mHandler.postDelayed(() -> {
             // Don't add a markSyncReady for the first sync group until after it's added to another
@@ -105,7 +108,7 @@
         }, 200);
 
         assertTrue("Failed to wait for both SurfaceSyncGroups to apply",
-                bothSyncGroupsComplete.await(5, TimeUnit.SECONDS));
+                bothSyncGroupsComplete.await(TIMEOUT_S, TimeUnit.SECONDS));
 
         validateScreenshot();
     }
@@ -123,7 +126,7 @@
                 transaction -> mHandler.postDelayed(() -> {
                     try {
                         assertTrue("Failed to draw two frames",
-                                secondDrawCompleteLatch.await(5, TimeUnit.SECONDS));
+                                secondDrawCompleteLatch.await(TIMEOUT_S, TimeUnit.SECONDS));
                     } catch (InterruptedException e) {
                         throw new RuntimeException(e);
                     }
@@ -143,7 +146,7 @@
         addSecondSyncGroup(secondSsg, secondDrawCompleteLatch, bothSyncGroupsComplete);
 
         assertTrue("Failed to wait for both SurfaceSyncGroups to apply",
-                bothSyncGroupsComplete.await(5, TimeUnit.SECONDS));
+                bothSyncGroupsComplete.await(TIMEOUT_S, TimeUnit.SECONDS));
 
         validateScreenshot();
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
index dfb789c..a3a3684 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
@@ -49,6 +49,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
 
 /**
  * Test class for {@link BLASTSyncEngine}.
@@ -226,7 +228,7 @@
         parentWC.onSyncFinishedDrawing();
         topChildWC.onSyncFinishedDrawing();
         // Even though bottom isn't finished, we should see callback because it is occluded by top.
-        assertFalse(botChildWC.isSyncFinished());
+        assertFalse(botChildWC.isSyncFinished(botChildWC.getSyncGroup()));
         bse.onSurfacePlacement();
         verify(listener, times(1)).onTransactionReady(eq(id), notNull());
 
@@ -417,9 +419,217 @@
         assertTrue(bse.isReady(nextId[0]));
     }
 
+    @Test
+    public void testStratifiedParallel() {
+        TestWindowContainer parentWC = new TestWindowContainer(mWm, true /* waiter */);
+        TestWindowContainer childWC = new TestWindowContainer(mWm, true /* waiter */);
+        parentWC.addChild(childWC, POSITION_TOP);
+        childWC.mVisibleRequested = true;
+        childWC.mFillsParent = true;
+
+        final BLASTSyncEngine bse = createTestBLASTSyncEngine();
+
+        BLASTSyncEngine.TransactionReadyListener listenerChild = mock(
+                BLASTSyncEngine.TransactionReadyListener.class);
+        BLASTSyncEngine.TransactionReadyListener listenerParent = mock(
+                BLASTSyncEngine.TransactionReadyListener.class);
+
+        // Start a sync-set for the "inner" stuff
+        int childSync = startSyncSet(bse, listenerChild);
+        bse.addToSyncSet(childSync, childWC);
+        bse.setReady(childSync);
+
+        // Start sync-set for the "outer" stuff but explicitly parallel (it should ignore child)
+        int parentSync = startSyncSet(bse, listenerParent, true /* parallel */);
+        bse.addToSyncSet(parentSync, parentWC);
+        bse.setReady(parentSync);
+
+        bse.onSurfacePlacement();
+        // Nothing should have happened yet
+        verify(listenerChild, times(0)).onTransactionReady(anyInt(), any());
+        verify(listenerParent, times(0)).onTransactionReady(anyInt(), any());
+
+        // Now, make PARENT ready, since they are in parallel, this should work
+        parentWC.onSyncFinishedDrawing();
+        bse.onSurfacePlacement();
+
+        // Parent should become ready while child is still waiting.
+        verify(listenerParent, times(1)).onTransactionReady(eq(parentSync), notNull());
+        verify(listenerChild, times(0)).onTransactionReady(anyInt(), any());
+
+        // Child should still work
+        childWC.onSyncFinishedDrawing();
+        bse.onSurfacePlacement();
+        verify(listenerChild, times(1)).onTransactionReady(eq(childSync), notNull());
+    }
+
+    @Test
+    public void testDependencies() {
+        TestWindowContainer parentWC = new TestWindowContainer(mWm, true /* waiter */);
+        TestWindowContainer childWC = new TestWindowContainer(mWm, true /* waiter */);
+        TestWindowContainer childWC2 = new TestWindowContainer(mWm, true /* waiter */);
+        parentWC.addChild(childWC, POSITION_TOP);
+        childWC.mVisibleRequested = true;
+        childWC.mFillsParent = true;
+        childWC2.mVisibleRequested = true;
+        childWC2.mFillsParent = true;
+
+        final BLASTSyncEngine bse = createTestBLASTSyncEngine();
+
+        BLASTSyncEngine.TransactionReadyListener listener = mock(
+                BLASTSyncEngine.TransactionReadyListener.class);
+
+        // This is non-parallel, so it is waiting on the child as-well
+        int sync1 = startSyncSet(bse, listener);
+        bse.addToSyncSet(sync1, parentWC);
+        bse.setReady(sync1);
+
+        // Create one which will end-up depending on the *next* sync
+        int sync2 = startSyncSet(bse, listener, true /* parallel */);
+
+        // If another sync tries to sync on the same subtree, it must now serialize with the other.
+        int sync3 = startSyncSet(bse, listener, true /* parallel */);
+        bse.addToSyncSet(sync3, childWC);
+        bse.addToSyncSet(sync3, childWC2);
+        bse.setReady(sync3);
+
+        // This will depend on sync3.
+        int sync4 = startSyncSet(bse, listener, true /* parallel */);
+        bse.addToSyncSet(sync4, childWC2);
+        bse.setReady(sync4);
+
+        // This makes sync2 depend on sync3. Since both sync2 and sync4 depend on sync3, when sync3
+        // finishes, sync2 should run first since it was created first.
+        bse.addToSyncSet(sync2, childWC2);
+        bse.setReady(sync2);
+
+        childWC.onSyncFinishedDrawing();
+        childWC2.onSyncFinishedDrawing();
+        bse.onSurfacePlacement();
+
+        // Nothing should be ready yet since everything ultimately depends on sync1.
+        verify(listener, times(0)).onTransactionReady(anyInt(), any());
+
+        parentWC.onSyncFinishedDrawing();
+        bse.onSurfacePlacement();
+
+        // They should all be ready, now, so just verify that the order is expected
+        InOrder readyOrder = Mockito.inOrder(listener);
+        // sync1 is the first one, so it should call ready first.
+        readyOrder.verify(listener).onTransactionReady(eq(sync1), any());
+        // everything else depends on sync3, so it should call ready next.
+        readyOrder.verify(listener).onTransactionReady(eq(sync3), any());
+        // both sync2 and sync4 depend on sync3, but sync2 started first, so it should go next.
+        readyOrder.verify(listener).onTransactionReady(eq(sync2), any());
+        readyOrder.verify(listener).onTransactionReady(eq(sync4), any());
+    }
+
+    @Test
+    public void testStratifiedParallelParentFirst() {
+        TestWindowContainer parentWC = new TestWindowContainer(mWm, true /* waiter */);
+        TestWindowContainer childWC = new TestWindowContainer(mWm, true /* waiter */);
+        parentWC.addChild(childWC, POSITION_TOP);
+        childWC.mVisibleRequested = true;
+        childWC.mFillsParent = true;
+
+        final BLASTSyncEngine bse = createTestBLASTSyncEngine();
+
+        BLASTSyncEngine.TransactionReadyListener listener = mock(
+                BLASTSyncEngine.TransactionReadyListener.class);
+
+        // This is parallel, so it should ignore children
+        int sync1 = startSyncSet(bse, listener, true /* parallel */);
+        bse.addToSyncSet(sync1, parentWC);
+        bse.setReady(sync1);
+
+        int sync2 = startSyncSet(bse, listener, true /* parallel */);
+        bse.addToSyncSet(sync2, childWC);
+        bse.setReady(sync2);
+
+        childWC.onSyncFinishedDrawing();
+        bse.onSurfacePlacement();
+
+        // Sync2 should have run in parallel
+        verify(listener, times(1)).onTransactionReady(eq(sync2), any());
+        verify(listener, times(0)).onTransactionReady(eq(sync1), any());
+
+        parentWC.onSyncFinishedDrawing();
+        bse.onSurfacePlacement();
+
+        verify(listener, times(1)).onTransactionReady(eq(sync1), any());
+    }
+
+    @Test
+    public void testDependencyCycle() {
+        TestWindowContainer parentWC = new TestWindowContainer(mWm, true /* waiter */);
+        TestWindowContainer childWC = new TestWindowContainer(mWm, true /* waiter */);
+        TestWindowContainer childWC2 = new TestWindowContainer(mWm, true /* waiter */);
+        TestWindowContainer childWC3 = new TestWindowContainer(mWm, true /* waiter */);
+        parentWC.addChild(childWC, POSITION_TOP);
+        childWC.mVisibleRequested = true;
+        childWC.mFillsParent = true;
+        childWC2.mVisibleRequested = true;
+        childWC2.mFillsParent = true;
+        childWC3.mVisibleRequested = true;
+        childWC3.mFillsParent = true;
+
+        final BLASTSyncEngine bse = createTestBLASTSyncEngine();
+
+        BLASTSyncEngine.TransactionReadyListener listener = mock(
+                BLASTSyncEngine.TransactionReadyListener.class);
+
+        // This is non-parallel, so it is waiting on the child as-well
+        int sync1 = startSyncSet(bse, listener);
+        bse.addToSyncSet(sync1, parentWC);
+        bse.setReady(sync1);
+
+        // Sync 2 depends on sync1 AND childWC2
+        int sync2 = startSyncSet(bse, listener, true /* parallel */);
+        bse.addToSyncSet(sync2, childWC);
+        bse.addToSyncSet(sync2, childWC2);
+        bse.setReady(sync2);
+
+        // Sync 3 depends on sync2 AND childWC3
+        int sync3 = startSyncSet(bse, listener, true /* parallel */);
+        bse.addToSyncSet(sync3, childWC2);
+        bse.addToSyncSet(sync3, childWC3);
+        bse.setReady(sync3);
+
+        // Now make sync1 depend on WC3 (which would make it depend on sync3). This would form
+        // a cycle, so it should instead move childWC3 into sync1.
+        bse.addToSyncSet(sync1, childWC3);
+
+        // Sync3 should no-longer have childWC3 as a root-member since a window can currently only
+        // be directly watched by 1 syncgroup maximum (due to implementation of isSyncFinished).
+        assertFalse(bse.getSyncSet(sync3).mRootMembers.contains(childWC3));
+
+        childWC3.onSyncFinishedDrawing();
+        childWC2.onSyncFinishedDrawing();
+        parentWC.onSyncFinishedDrawing();
+        bse.onSurfacePlacement();
+
+        // make sure sync3 hasn't run even though all its (original) members are ready
+        verify(listener, times(0)).onTransactionReady(anyInt(), any());
+
+        // Now finish the last container and make sure everything finishes (didn't "deadlock" due
+        // to a dependency cycle.
+        childWC.onSyncFinishedDrawing();
+        bse.onSurfacePlacement();
+
+        InOrder readyOrder = Mockito.inOrder(listener);
+        readyOrder.verify(listener).onTransactionReady(eq(sync1), any());
+        readyOrder.verify(listener).onTransactionReady(eq(sync2), any());
+        readyOrder.verify(listener).onTransactionReady(eq(sync3), any());
+    }
+
     static int startSyncSet(BLASTSyncEngine engine,
             BLASTSyncEngine.TransactionReadyListener listener) {
-        return engine.startSyncSet(listener, BLAST_TIMEOUT_DURATION, "Test");
+        return engine.startSyncSet(listener, BLAST_TIMEOUT_DURATION, "Test", false /* parallel */);
+    }
+
+    static int startSyncSet(BLASTSyncEngine engine,
+            BLASTSyncEngine.TransactionReadyListener listener, boolean parallel) {
+        return engine.startSyncSet(listener, BLAST_TIMEOUT_DURATION, "Test", parallel);
     }
 
     static class TestWindowContainer extends WindowContainer {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index d43805a..c53addc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -63,6 +63,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.List;
+
 /**
  * Tests for the {@link TaskDisplayArea} container.
  *
@@ -349,23 +351,24 @@
     @Test
     public void testReuseTaskAsRootTask() {
         final Task candidateTask = createTask(mDisplayContent);
-        final int type = ACTIVITY_TYPE_STANDARD;
-        assertGetOrCreateRootTask(WINDOWING_MODE_FULLSCREEN, type, candidateTask,
-                true /* reuseCandidate */);
-        assertGetOrCreateRootTask(WINDOWING_MODE_UNDEFINED, type, candidateTask,
-                true /* reuseCandidate */);
-        assertGetOrCreateRootTask(WINDOWING_MODE_FREEFORM, type, candidateTask,
-                true /* reuseCandidate */);
-        assertGetOrCreateRootTask(WINDOWING_MODE_MULTI_WINDOW, type, candidateTask,
-                true /* reuseCandidate */);
-        assertGetOrCreateRootTask(WINDOWING_MODE_PINNED, type, candidateTask,
-                true /* reuseCandidate */);
+        List<Integer> activityTypesWithReusableRootTask = List.of(ACTIVITY_TYPE_STANDARD,
+                ACTIVITY_TYPE_RECENTS);
+        for (Integer type : activityTypesWithReusableRootTask) {
+            assertGetOrCreateRootTask(WINDOWING_MODE_FULLSCREEN, type, candidateTask,
+                    true /* reuseCandidate */);
+            assertGetOrCreateRootTask(WINDOWING_MODE_UNDEFINED, type, candidateTask,
+                    true /* reuseCandidate */);
+            assertGetOrCreateRootTask(WINDOWING_MODE_FREEFORM, type, candidateTask,
+                    true /* reuseCandidate */);
+            assertGetOrCreateRootTask(WINDOWING_MODE_MULTI_WINDOW, type, candidateTask,
+                    true /* reuseCandidate */);
+            assertGetOrCreateRootTask(WINDOWING_MODE_PINNED, type, candidateTask,
+                    true /* reuseCandidate */);
+        }
 
         final int windowingMode = WINDOWING_MODE_FULLSCREEN;
         assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_HOME, candidateTask,
                 false /* reuseCandidate */);
-        assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_RECENTS, candidateTask,
-                false /* reuseCandidate */);
         assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_ASSISTANT, candidateTask,
                 false /* reuseCandidate */);
         assertGetOrCreateRootTask(windowingMode, ACTIVITY_TYPE_DREAM, candidateTask,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 790b154..453e468 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -52,7 +52,6 @@
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import org.junit.After;
@@ -319,7 +318,6 @@
     };
 
     @Presubmit
-    @FlakyTest(bugId = 150409355)
     @Test
     public void testNotifyTaskRequestedOrientationChanged() throws Exception {
         final ArrayBlockingQueue<int[]> taskIdAndOrientationQueue = new ArrayBlockingQueue<>(10);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 2a2641e..adf3f39 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -114,24 +114,35 @@
     }
 
     @Override
-    public void startedWakingUp(@WakeReason int wakeReason) {
+    public void startedWakingUpGlobal(@WakeReason int reason) {
     }
 
     @Override
-    public void finishedWakingUp(@WakeReason int wakeReason) {
+    public void finishedWakingUpGlobal(@WakeReason int reason) {
     }
 
     @Override
-    public void startedGoingToSleep(@GoToSleepReason int sleepReason) {
+    public void startedGoingToSleepGlobal(@GoToSleepReason int reason) {
     }
 
     @Override
-    public void finishedGoingToSleep(@GoToSleepReason int sleepReason) {
+    public void finishedGoingToSleepGlobal(@GoToSleepReason int reason) {
     }
 
     @Override
-    public void onPowerGroupWakefulnessChanged(int groupId, int wakefulness,
-            @GoToSleepReason int pmSleepReason, int globalWakefulness) {
+    public void startedWakingUp(int displayGroupId, @WakeReason int wakeReason) {
+    }
+
+    @Override
+    public void finishedWakingUp(int displayGroupId, @WakeReason int wakeReason) {
+    }
+
+    @Override
+    public void startedGoingToSleep(int displayGroupId, @GoToSleepReason int sleepReason) {
+    }
+
+    @Override
+    public void finishedGoingToSleep(int displayGroupId, @GoToSleepReason int sleepReason) {
     }
 
     @Override
@@ -147,7 +158,7 @@
     }
 
     @Override
-    public void screenTurnedOff(int displayId) {
+    public void screenTurnedOff(int displayId, boolean isSwappingDisplay) {
     }
 
     @Override
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 653b52b..b59f027 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -23,6 +23,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
+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_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
@@ -36,6 +37,7 @@
 import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
 import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
+import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
 import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 import static android.window.TransitionInfo.isIndependent;
@@ -74,6 +76,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.view.SurfaceControl;
+import android.view.WindowManager;
 import android.window.IDisplayAreaOrganizer;
 import android.window.IRemoteTransition;
 import android.window.ITaskFragmentOrganizer;
@@ -96,6 +99,7 @@
 import java.util.Objects;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 import java.util.function.Function;
 
 /**
@@ -1196,7 +1200,8 @@
 
         player.start();
         player.finish();
-        app.getTask().finishSync(mWm.mTransactionFactory.get(), false /* cancel */);
+        app.getTask().finishSync(mWm.mTransactionFactory.get(), app.getTask().getSyncGroup(),
+                false /* cancel */);
 
         // The open transition is finished. Continue to play seamless display change transition,
         // so the previous async rotation controller should still exist.
@@ -1902,7 +1907,7 @@
         assertTrue(targets.isEmpty());
 
         // After collecting order changes, it should recognize that a task moved to top.
-        transition.collectOrderChanges();
+        transition.collectOrderChanges(true);
         targets = Transition.calculateTargets(participants, changes);
         assertEquals(1, targets.size());
 
@@ -1913,6 +1918,192 @@
         assertEquals(TRANSIT_CHANGE, info.getChanges().get(0).getMode());
     }
 
+    private class OrderChangeTestSetup {
+        final TransitionController mController;
+        final TestTransitionPlayer mPlayer;
+        final Transition mTransitA;
+        final Transition mTransitB;
+
+        OrderChangeTestSetup() {
+            mController = mAtm.getTransitionController();
+            mPlayer = registerTestTransitionPlayer();
+            mController.setSyncEngine(mWm.mSyncEngine);
+
+            mTransitA = createTestTransition(TRANSIT_OPEN, mController);
+            mTransitA.mParallelCollectType = Transition.PARALLEL_TYPE_MUTUAL;
+            mTransitB = createTestTransition(TRANSIT_OPEN, mController);
+            mTransitB.mParallelCollectType = Transition.PARALLEL_TYPE_MUTUAL;
+        }
+
+        void startParallelCollect(boolean activityLevelFirst) {
+            // Start with taskB on top and taskA on bottom but both visible.
+            final Task taskA = createTask(mDisplayContent);
+            taskA.setVisibleRequested(true);
+            final ActivityRecord actA = createActivityRecord(taskA);
+            final TestWindowState winA = createWindowState(
+                    new WindowManager.LayoutParams(TYPE_BASE_APPLICATION), actA);
+            actA.addWindow(winA);
+            final ActivityRecord actB = createActivityRecord(taskA);
+            final TestWindowState winB = createWindowState(
+                    new WindowManager.LayoutParams(TYPE_BASE_APPLICATION), actB);
+            actB.addWindow(winB);
+
+            final Task taskB = createTask(mDisplayContent);
+            actA.setVisibleRequested(true);
+            actB.setVisibleRequested(false);
+            taskB.setVisibleRequested(true);
+            assertTrue(actA.isAttached());
+
+            final Consumer<Boolean> startAndCollectA = (doReady) -> {
+                mController.startCollectOrQueue(mTransitA, (deferred) -> {
+                });
+
+                // Collect activity-level change into A
+                mTransitA.collect(actA);
+                actA.setVisibleRequested(false);
+                winA.onSyncFinishedDrawing();
+                mTransitA.collect(actB);
+                actB.setVisibleRequested(true);
+                winB.onSyncFinishedDrawing();
+                mTransitA.start();
+                if (doReady) {
+                    mTransitA.setReady(mDisplayContent, true);
+                }
+            };
+            final Consumer<Boolean> startAndCollectB = (doReady) -> {
+                mController.startCollectOrQueue(mTransitB, (deferred) -> {
+                });
+                mTransitB.collect(taskA);
+                taskA.moveToFront("test");
+                mTransitB.start();
+                if (doReady) {
+                    mTransitB.setReady(mDisplayContent, true);
+                }
+            };
+
+            if (activityLevelFirst) {
+                startAndCollectA.accept(true);
+                startAndCollectB.accept(false);
+            } else {
+                startAndCollectB.accept(true);
+                startAndCollectA.accept(false);
+            }
+        }
+    }
+
+    @Test
+    public void testMoveToTopStartAfterReadyAfterParallel() {
+        // Start collect activity-only transit A
+        // Start collect task transit B in parallel
+        // finish A first -> should not include order change from B.
+        final OrderChangeTestSetup setup = new OrderChangeTestSetup();
+        setup.startParallelCollect(true /* activity first */);
+
+        mWm.mSyncEngine.tryFinishForTest(setup.mTransitA.getSyncId());
+        waitUntilHandlersIdle();
+        for (int i = 0; i < setup.mPlayer.mLastReady.getChanges().size(); ++i) {
+            assertNull(setup.mPlayer.mLastReady.getChanges().get(i).getTaskInfo());
+        }
+
+        setup.mTransitB.setAllReady();
+        mWm.mSyncEngine.tryFinishForTest(setup.mTransitB.getSyncId());
+        waitUntilHandlersIdle();
+        boolean hasOrderChange = false;
+        for (int i = 0; i < setup.mPlayer.mLastReady.getChanges().size(); ++i) {
+            final TransitionInfo.Change chg = setup.mPlayer.mLastReady.getChanges().get(i);
+            if (chg.getTaskInfo() == null) continue;
+            hasOrderChange = hasOrderChange || (chg.getFlags() & FLAG_MOVED_TO_TOP) != 0;
+        }
+        assertTrue(hasOrderChange);
+    }
+
+    @Test
+    public void testMoveToTopStartAfterReadyBeforeParallel() {
+        // Start collect activity-only transit A
+        // Start collect task transit B in parallel
+        // finish B first -> should include order change
+        // then finish A -> should NOT include order change.
+        final OrderChangeTestSetup setup = new OrderChangeTestSetup();
+        setup.startParallelCollect(true /* activity first */);
+        // Make it unready now so that it doesn't get dequeued automatically.
+        setup.mTransitA.setReady(mDisplayContent, false);
+
+        // Make task change ready first
+        setup.mTransitB.setAllReady();
+        mWm.mSyncEngine.tryFinishForTest(setup.mTransitB.getSyncId());
+        waitUntilHandlersIdle();
+        boolean hasOrderChange = false;
+        for (int i = 0; i < setup.mPlayer.mLastReady.getChanges().size(); ++i) {
+            final TransitionInfo.Change chg = setup.mPlayer.mLastReady.getChanges().get(i);
+            if (chg.getTaskInfo() == null) continue;
+            hasOrderChange = hasOrderChange || (chg.getFlags() & FLAG_MOVED_TO_TOP) != 0;
+        }
+        assertTrue(hasOrderChange);
+
+        setup.mTransitA.setAllReady();
+        mWm.mSyncEngine.tryFinishForTest(setup.mTransitA.getSyncId());
+        waitUntilHandlersIdle();
+        for (int i = 0; i < setup.mPlayer.mLastReady.getChanges().size(); ++i) {
+            assertNull(setup.mPlayer.mLastReady.getChanges().get(i).getTaskInfo());
+        }
+    }
+
+    @Test
+    public void testMoveToTopStartBeforeReadyAfterParallel() {
+        // Start collect task transit B
+        // Start collect activity-only transit A in parallel
+        // finish A first -> should not include order change from B.
+        final OrderChangeTestSetup setup = new OrderChangeTestSetup();
+        setup.startParallelCollect(false /* activity first */);
+        // Make B unready now so that it doesn't get dequeued automatically.
+        setup.mTransitB.setReady(mDisplayContent, false);
+
+        setup.mTransitA.setAllReady();
+        mWm.mSyncEngine.tryFinishForTest(setup.mTransitA.getSyncId());
+        waitUntilHandlersIdle();
+        for (int i = 0; i < setup.mPlayer.mLastReady.getChanges().size(); ++i) {
+            assertNull(setup.mPlayer.mLastReady.getChanges().get(i).getTaskInfo());
+        }
+
+        setup.mTransitB.setAllReady();
+        mWm.mSyncEngine.tryFinishForTest(setup.mTransitB.getSyncId());
+        waitUntilHandlersIdle();
+        boolean hasOrderChange = false;
+        for (int i = 0; i < setup.mPlayer.mLastReady.getChanges().size(); ++i) {
+            final TransitionInfo.Change chg = setup.mPlayer.mLastReady.getChanges().get(i);
+            if (chg.getTaskInfo() == null) continue;
+            hasOrderChange = hasOrderChange || (chg.getFlags() & FLAG_MOVED_TO_TOP) != 0;
+        }
+        assertTrue(hasOrderChange);
+    }
+
+    @Test
+    public void testMoveToTopStartBeforeReadyBeforeParallel() {
+        // Start collect task transit B
+        // Start collect activity-only transit A in parallel
+        // finish B first -> should include order change
+        // then finish A -> should NOT include order change.
+        final OrderChangeTestSetup setup = new OrderChangeTestSetup();
+        setup.startParallelCollect(false /* activity first */);
+
+        mWm.mSyncEngine.tryFinishForTest(setup.mTransitB.getSyncId());
+        waitUntilHandlersIdle();
+        boolean hasOrderChange = false;
+        for (int i = 0; i < setup.mPlayer.mLastReady.getChanges().size(); ++i) {
+            final TransitionInfo.Change chg = setup.mPlayer.mLastReady.getChanges().get(i);
+            if (chg.getTaskInfo() == null) continue;
+            hasOrderChange = hasOrderChange || (chg.getFlags() & FLAG_MOVED_TO_TOP) != 0;
+        }
+        assertTrue(hasOrderChange);
+
+        setup.mTransitA.setAllReady();
+        mWm.mSyncEngine.tryFinishForTest(setup.mTransitA.getSyncId());
+        waitUntilHandlersIdle();
+        for (int i = 0; i < setup.mPlayer.mLastReady.getChanges().size(); ++i) {
+            assertNull(setup.mPlayer.mLastReady.getChanges().get(i).getTaskInfo());
+        }
+    }
+
     @Test
     public void testQueueStartCollect() {
         final TransitionController controller = mAtm.getTransitionController();
@@ -2017,6 +2208,94 @@
         assertTrue(transitB.isCollecting());
     }
 
+    @Test
+    public void testQueueParallel() {
+        final TransitionController controller = mAtm.getTransitionController();
+        final TestTransitionPlayer player = registerTestTransitionPlayer();
+
+        mSyncEngine = createTestBLASTSyncEngine();
+        controller.setSyncEngine(mSyncEngine);
+
+        final Transition transitA = createTestTransition(TRANSIT_OPEN, controller);
+        transitA.mParallelCollectType = Transition.PARALLEL_TYPE_MUTUAL;
+        final Transition transitB = createTestTransition(TRANSIT_OPEN, controller);
+        transitB.mParallelCollectType = Transition.PARALLEL_TYPE_MUTUAL;
+        final Transition transitC = createTestTransition(TRANSIT_OPEN, controller);
+        transitC.mParallelCollectType = Transition.PARALLEL_TYPE_MUTUAL;
+        final Transition transitSync = createTestTransition(TRANSIT_OPEN, controller);
+        final Transition transitD = createTestTransition(TRANSIT_OPEN, controller);
+
+        controller.startCollectOrQueue(transitA, (deferred) -> {});
+        controller.startCollectOrQueue(transitB, (deferred) -> {});
+        controller.startCollectOrQueue(transitC, (deferred) -> {});
+        controller.startCollectOrQueue(transitSync, (deferred) -> {});
+        controller.startCollectOrQueue(transitD, (deferred) -> {});
+
+        assertTrue(transitA.isCollecting() && !transitA.isStarted());
+        // We still serialize on readiness
+        assertTrue(transitB.isPending());
+        assertTrue(transitC.isPending());
+
+        transitA.start();
+        transitA.setAllReady();
+        transitB.start();
+        transitB.setAllReady();
+
+        // A, B, and C should be collecting in parallel now.
+        assertTrue(transitA.isStarted());
+        assertTrue(transitB.isStarted());
+        assertTrue(transitC.isCollecting() && !transitC.isStarted());
+
+        transitC.start();
+        transitC.setAllReady();
+
+        assertTrue(transitA.isStarted());
+        assertTrue(transitB.isStarted());
+        assertTrue(transitC.isStarted());
+        // Not parallel so should remain pending
+        assertTrue(transitSync.isPending());
+        // After Sync, so should also remain pending.
+        assertTrue(transitD.isPending());
+        // There should always be a collector, since Sync can't collect yet, C should remain.
+        assertEquals(transitC, controller.getCollectingTransition());
+
+        mSyncEngine.tryFinishForTest(transitB.getSyncId());
+
+        // The other transitions should remain waiting.
+        assertTrue(transitA.isStarted());
+        assertTrue(transitB.isPlaying());
+        assertTrue(transitC.isStarted());
+        assertEquals(transitC, controller.getCollectingTransition());
+
+        mSyncEngine.tryFinishForTest(transitC.getSyncId());
+        assertTrue(transitA.isStarted());
+        assertTrue(transitC.isPlaying());
+        // The "collecting" one became ready, so the first "waiting" should move back to collecting.
+        assertEquals(transitA, controller.getCollectingTransition());
+
+        assertTrue(transitSync.isPending());
+        assertTrue(transitD.isPending());
+        mSyncEngine.tryFinishForTest(transitA.getSyncId());
+
+        // Now all collectors are done, so sync can be pulled-off the queue.
+        assertTrue(transitSync.isCollecting() && !transitSync.isStarted());
+        transitSync.start();
+        transitSync.setAllReady();
+        // Since D can run in parallel, it should be pulled-off the queue.
+        assertTrue(transitSync.isStarted());
+        assertTrue(transitD.isPending());
+
+        mSyncEngine.tryFinishForTest(transitSync.getSyncId());
+        assertTrue(transitD.isCollecting());
+
+        transitD.start();
+        transitD.setAllReady();
+        mSyncEngine.tryFinishForTest(transitD.getSyncId());
+
+        // Now nothing should be collecting
+        assertFalse(controller.isCollecting());
+    }
+
     private static void makeTaskOrganized(Task... tasks) {
         final ITaskOrganizer organizer = mock(ITaskOrganizer.class);
         for (Task t : tasks) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 984b868..01ddcca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -382,7 +382,7 @@
         assertTrue(wallpaperWindow.isVisible());
         assertTrue(token.isVisibleRequested());
         assertTrue(token.isVisible());
-        mWm.mAtmService.getTransitionController().abort(transit);
+        transit.abort();
 
         // In a transition, setting invisible should ONLY set requestedVisible false; otherwise
         // wallpaper should remain "visible" until transition is over.
@@ -394,7 +394,7 @@
         assertTrue(token.isVisible());
 
         final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
-        token.finishSync(t, false /* cancel */);
+        token.finishSync(t, token.getSyncGroup(), false /* cancel */);
         transit.onTransactionReady(transit.getSyncId(), t);
         dc.mTransitionController.finishTransition(transit);
         assertFalse(wallpaperWindow.isVisible());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index a1ddd57..ad606cb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -1112,7 +1112,7 @@
                     }
 
                     @Override
-                    public void onAnimationCancelled(boolean isKeyguardOccluded) {
+                    public void onAnimationCancelled() {
                     }
                 }, 0, 0, false);
         adapter.setCallingPidUid(123, 456);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
index 83111ab..849072e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
@@ -26,7 +26,6 @@
 import android.hardware.HardwareBuffer;
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.testutils.StubTransaction;
@@ -57,7 +56,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 131005232)
     public void testDestroy_nullsSurface() {
         final WindowContainerThumbnail t = buildThumbnail();
         assertNotNull(t.getSurfaceControl());
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 ba6b3b6..58bf184 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -27,6 +27,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_OWN_FOCUS;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY;
 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
@@ -65,6 +66,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -89,6 +91,7 @@
 import android.view.View;
 import android.view.WindowInsets;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 import android.window.ClientWindowFrames;
 import android.window.ScreenCapture;
 import android.window.WindowContainerToken;
@@ -101,6 +104,7 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 
 /**
  * Build/Install/Run:
@@ -272,6 +276,124 @@
     }
 
     @Test
+    public void testRelayout_firstLayout_dwpcHelperCalledWithCorrectFlags() {
+        // When doing the first layout, the initial flags should be reported as changed to
+        // keepActivityOnWindowFlagsChanged.
+        testRelayoutFlagChanges(
+                /*firstRelayout=*/ true,
+                /*startFlags=*/ FLAG_SECURE,
+                /*startPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY,
+                /*newFlags=*/ FLAG_SECURE,
+                /*newPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY,
+                /*expectedChangedFlags=*/ FLAG_SECURE,
+                /*expectedChangedPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY,
+                /*expectedFlagsValue=*/ FLAG_SECURE,
+                /*expectedPrivateFlagsValue=*/ PRIVATE_FLAG_TRUSTED_OVERLAY);
+    }
+
+    @Test
+    public void testRelayout_secondLayoutFlagAdded_dwpcHelperCalledWithCorrectFlags() {
+        testRelayoutFlagChanges(
+                /*firstRelayout=*/ false,
+                /*startFlags=*/ 0,
+                /*startPrivateFlags=*/ 0,
+                /*newFlags=*/ FLAG_SECURE,
+                /*newPrivateFlags=*/ 0,
+                /*expectedChangedFlags=*/ FLAG_SECURE,
+                /*expectedChangedPrivateFlags=*/ 0,
+                /*expectedFlagsValue=*/ FLAG_SECURE,
+                /*expectedPrivateFlagsValue=*/ 0);
+    }
+
+    @Test
+    public void testRelayout_secondLayoutMultipleFlagsAddOne_dwpcHelperCalledWithCorrectFlags() {
+        testRelayoutFlagChanges(
+                /*firstRelayout=*/ false,
+                /*startFlags=*/ FLAG_NOT_FOCUSABLE,
+                /*startPrivateFlags=*/ 0,
+                /*newFlags=*/ FLAG_SECURE | FLAG_NOT_FOCUSABLE,
+                /*newPrivateFlags=*/ 0,
+                /*expectedChangedFlags=*/ FLAG_SECURE,
+                /*expectedChangedPrivateFlags=*/ 0,
+                /*expectedFlagsValue=*/ FLAG_SECURE | FLAG_NOT_FOCUSABLE,
+                /*expectedPrivateFlagsValue=*/ 0);
+    }
+
+    @Test
+    public void testRelayout_secondLayoutPrivateFlagAdded_dwpcHelperCalledWithCorrectFlags() {
+        testRelayoutFlagChanges(
+                /*firstRelayout=*/ false,
+                /*startFlags=*/ 0,
+                /*startPrivateFlags=*/ 0,
+                /*newFlags=*/ 0,
+                /*newPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY,
+                /*expectedChangedFlags=*/ 0,
+                /*expectedChangedPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY,
+                /*expectedFlagsValue=*/ 0,
+                /*expectedPrivateFlagsValue=*/ PRIVATE_FLAG_TRUSTED_OVERLAY);
+    }
+
+    @Test
+    public void testRelayout_secondLayoutFlagsRemoved_dwpcHelperCalledWithCorrectFlags() {
+        testRelayoutFlagChanges(
+                /*firstRelayout=*/ false,
+                /*startFlags=*/ FLAG_SECURE,
+                /*startPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY,
+                /*newFlags=*/ 0,
+                /*newPrivateFlags=*/ 0,
+                /*expectedChangedFlags=*/ FLAG_SECURE,
+                /*expectedChangedPrivateFlags=*/ PRIVATE_FLAG_TRUSTED_OVERLAY,
+                /*expectedFlagsValue=*/ 0,
+                /*expectedPrivateFlagsValue=*/ 0);
+    }
+
+    // Helper method to test relayout of a window, either for the initial layout, or a subsequent
+    // one, and makes sure that the flags and private flags changes and final values are properly
+    // reported to mDwpcHelper.keepActivityOnWindowFlagsChanged.
+    private void testRelayoutFlagChanges(boolean firstRelayout, int startFlags,
+            int startPrivateFlags, int newFlags, int newPrivateFlags, int expectedChangedFlags,
+            int expectedChangedPrivateFlags, int expectedFlagsValue,
+            int expectedPrivateFlagsValue) {
+        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, "appWin");
+        win.mRelayoutCalled = !firstRelayout;
+        mWm.mWindowMap.put(win.mClient.asBinder(), win);
+        spyOn(mDisplayContent.mDwpcHelper);
+        when(mDisplayContent.mDwpcHelper.hasController()).thenReturn(true);
+
+        win.mAttrs.flags = startFlags;
+        win.mAttrs.privateFlags = startPrivateFlags;
+
+        LayoutParams newParams = new LayoutParams();
+        newParams.copyFrom(win.mAttrs);
+        newParams.flags = newFlags;
+        newParams.privateFlags = newPrivateFlags;
+
+        int seq = 1;
+        if (!firstRelayout) {
+            win.mRelayoutSeq = 1;
+            seq = 2;
+        }
+        mWm.relayoutWindow(win.mSession, win.mClient, newParams, 100, 200, View.VISIBLE, 0, seq,
+                0, new ClientWindowFrames(), new MergedConfiguration(),
+                new SurfaceControl(), new InsetsState(), new InsetsSourceControl.Array(),
+                new Bundle());
+
+        ArgumentCaptor<Integer> changedFlags = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> changedPrivateFlags = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> flagsValue = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> privateFlagsValue = ArgumentCaptor.forClass(Integer.class);
+
+        verify(mDisplayContent.mDwpcHelper).keepActivityOnWindowFlagsChanged(
+                any(ActivityInfo.class), changedFlags.capture(), changedPrivateFlags.capture(),
+                flagsValue.capture(), privateFlagsValue.capture());
+
+        assertThat(changedFlags.getValue()).isEqualTo(expectedChangedFlags);
+        assertThat(changedPrivateFlags.getValue()).isEqualTo(expectedChangedPrivateFlags);
+        assertThat(flagsValue.getValue()).isEqualTo(expectedFlagsValue);
+        assertThat(privateFlagsValue.getValue()).isEqualTo(expectedPrivateFlagsValue);
+    }
+
+    @Test
     public void testMoveWindowTokenToDisplay_NullToken_DoNothing() {
         mWm.moveWindowTokenToDisplay(null, mDisplayContent.getDisplayId());
 
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 d19c996..600681f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -1006,7 +1006,8 @@
         BLASTSyncEngine.TransactionReadyListener transactionListener =
                 mock(BLASTSyncEngine.TransactionReadyListener.class);
 
-        final int id = bse.startSyncSet(transactionListener, BLAST_TIMEOUT_DURATION, "Test");
+        final int id = bse.startSyncSet(transactionListener, BLAST_TIMEOUT_DURATION, "Test",
+                false /* parallel */);
         bse.addToSyncSet(id, task);
         bse.setReady(id);
         bse.onSurfacePlacement();
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 f85cdf0..a63807d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -66,6 +66,7 @@
 import android.annotation.Nullable;
 import android.app.ActivityOptions;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -81,6 +82,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.SparseArray;
 import android.view.Display;
@@ -109,6 +111,7 @@
 
 import com.android.internal.policy.AttributeCache;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
 
 import org.junit.After;
@@ -146,6 +149,7 @@
     WindowManagerService mWm;
     private final IWindow mIWindow = new TestIWindow();
     private Session mMockSession;
+    private boolean mUseFakeSettingsProvider;
 
     DisplayInfo mDisplayInfo = new DisplayInfo();
     DisplayContent mDefaultDisplay;
@@ -272,16 +276,9 @@
 
     @After
     public void tearDown() throws Exception {
-        // Revert back to device overrides.
-        mAtm.mWindowManager.mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
-        mAtm.mWindowManager.mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
-        mAtm.mWindowManager.mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier();
-        mAtm.mWindowManager.mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
-        mAtm.mWindowManager.mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
-        mAtm.mWindowManager.mLetterboxConfiguration
-                .resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
-        mAtm.mWindowManager.mLetterboxConfiguration
-                .resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox();
+        if (mUseFakeSettingsProvider) {
+            FakeSettingsProvider.clearSettingsProvider();
+        }
     }
 
     /**
@@ -428,6 +425,17 @@
         // Called before display is created.
     }
 
+    /** Avoid writing values to real Settings. */
+    ContentResolver useFakeSettingsProvider() {
+        mUseFakeSettingsProvider = true;
+        FakeSettingsProvider.clearSettingsProvider();
+        final FakeSettingsProvider provider = new FakeSettingsProvider();
+        // SystemServicesTestRule#setUpSystemCore has called spyOn for the ContentResolver.
+        final ContentResolver resolver = mContext.getContentResolver();
+        doReturn(provider.getIContentProvider()).when(resolver).acquireProvider(Settings.AUTHORITY);
+        return resolver;
+    }
+
     private WindowState createCommonWindow(WindowState parent, int type, String name) {
         final WindowState win = createWindow(parent, type, name);
         // Prevent common windows from been IME targets.
@@ -463,6 +471,17 @@
         return navbar;
     }
 
+    WindowState createStatusBarWithProvidedInsets(DisplayContent dc) {
+        final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, dc, "statusBar");
+        final Binder owner = new Binder();
+        statusBar.mAttrs.providedInsets = new InsetsFrameProvider[] {
+                new InsetsFrameProvider(owner, 0, WindowInsets.Type.statusBars())
+                        .setInsetsSize(Insets.of(0, STATUS_BAR_HEIGHT, 0, 0))
+        };
+        dc.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
+        return statusBar;
+    }
+
     WindowState createAppWindow(Task task, int type, String name) {
         final ActivityRecord activity = createNonAttachedActivityRecord(task.getDisplayContent());
         task.addChild(activity, 0);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index a98429a..ef13594 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -2539,10 +2539,20 @@
         }
 
         @Override
-        public void reportChooserSelection(String packageName, int userId, String contentType,
-                                           String[] annotations, String action) {
+        public void reportChooserSelection(@NonNull String packageName, int userId,
+                @NonNull String contentType, String[] annotations, @NonNull String action) {
             if (packageName == null) {
-                Slog.w(TAG, "Event report user selecting a null package");
+                throw new IllegalArgumentException("Package selection must not be null.");
+            }
+            if (contentType == null) {
+                throw new IllegalArgumentException("Content type for selection must not be null.");
+            }
+            if (action == null) {
+                throw new IllegalArgumentException("Selection action must not be null.");
+            }
+            // Verify if this package exists before reporting an event for it.
+            if (mPackageManagerInternal.getPackageUid(packageName, 0, userId) < 0) {
+                Slog.w(TAG, "Event report user selecting an invalid package");
                 return;
             }
 
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index 10b7952..ba17884 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -584,15 +584,34 @@
     }
 
     /**
+     * Returns true only if there is a terminal whose subtype and terminal type are the same as
+     * the given values.
      * @hide
      */
-    public boolean hasAudioTerminal(int subType) {
+    public boolean hasAudioTerminal(int subType, int terminalType) {
         for (UsbDescriptor descriptor : mDescriptors) {
-            if (descriptor instanceof UsbACInterface) {
-                if (((UsbACInterface) descriptor).getSubclass()
-                        == UsbDescriptor.AUDIO_AUDIOCONTROL
-                        && ((UsbACInterface) descriptor).getSubtype()
-                        == subType) {
+            if (descriptor instanceof UsbACTerminal) {
+                if (((UsbACTerminal) descriptor).getSubclass() == UsbDescriptor.AUDIO_AUDIOCONTROL
+                        && ((UsbACTerminal) descriptor).getSubtype() == subType
+                        && ((UsbACTerminal) descriptor).getTerminalType() == terminalType) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns true only if there is an interface whose subtype is the same as the given one and
+     * terminal type is different from the given one.
+     * @hide
+     */
+    public boolean hasAudioTerminalExcludeType(int subType, int excludedTerminalType) {
+        for (UsbDescriptor descriptor : mDescriptors) {
+            if (descriptor instanceof UsbACTerminal) {
+                if (((UsbACTerminal) descriptor).getSubclass() == UsbDescriptor.AUDIO_AUDIOCONTROL
+                        && ((UsbACTerminal) descriptor).getSubtype() == subType
+                        && ((UsbACTerminal) descriptor).getTerminalType() != excludedTerminalType) {
                     return true;
                 }
             }
@@ -604,14 +623,21 @@
      * @hide
      */
     public boolean hasAudioPlayback() {
-        return hasAudioTerminal(UsbACInterface.ACI_OUTPUT_TERMINAL);
+        return hasAudioTerminalExcludeType(
+                UsbACInterface.ACI_OUTPUT_TERMINAL, UsbTerminalTypes.TERMINAL_USB_STREAMING)
+                && hasAudioTerminal(
+                        UsbACInterface.ACI_INPUT_TERMINAL, UsbTerminalTypes.TERMINAL_USB_STREAMING);
     }
 
     /**
      * @hide
      */
     public boolean hasAudioCapture() {
-        return hasAudioTerminal(UsbACInterface.ACI_INPUT_TERMINAL);
+        return hasAudioTerminalExcludeType(
+                UsbACInterface.ACI_INPUT_TERMINAL, UsbTerminalTypes.TERMINAL_USB_STREAMING)
+                && hasAudioTerminal(
+                        UsbACInterface.ACI_OUTPUT_TERMINAL,
+                        UsbTerminalTypes.TERMINAL_USB_STREAMING);
     }
 
     /**
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerEvent.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerEvent.java
new file mode 100644
index 0000000..2a55496
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerEvent.java
@@ -0,0 +1,135 @@
+/**
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.soundtrigger;
+
+import android.util.Slog;
+
+import com.android.server.utils.EventLogger.Event;
+
+import java.util.UUID;
+
+public abstract class SoundTriggerEvent extends Event {
+
+    @Override
+    public Event printLog(int type, String tag) {
+        switch (type) {
+            case ALOGI:
+                Slog.i(tag, eventToString());
+                break;
+            case ALOGE:
+                Slog.e(tag, eventToString());
+                break;
+            case ALOGW:
+                Slog.w(tag, eventToString());
+                break;
+            case ALOGV:
+            default:
+                Slog.v(tag, eventToString());
+        }
+        return this;
+    }
+
+    public static class ServiceEvent extends SoundTriggerEvent {
+        public enum Type {
+            ATTACH,
+            LIST_MODULE,
+            DETACH,
+        }
+
+        private final Type mType;
+        private final String mPackageName;
+        private final String mErrorString;
+
+        public ServiceEvent(Type type) {
+            this(type, null, null);
+        }
+
+        public ServiceEvent(Type type, String packageName) {
+            this(type, packageName, null);
+        }
+
+        public ServiceEvent(Type type, String packageName, String errorString) {
+            mType = type;
+            mPackageName = packageName;
+            mErrorString = errorString;
+        }
+
+        @Override
+        public String eventToString() {
+            var res = new StringBuilder(String.format("%-12s", mType.name()));
+            if (mErrorString != null) {
+                res.append(" ERROR: ").append(mErrorString);
+            }
+            if (mPackageName != null) {
+                res.append(" for: ").append(mPackageName);
+            }
+            return res.toString();
+        }
+    }
+
+    public static class SessionEvent extends SoundTriggerEvent {
+        public enum Type {
+            // Downward calls
+            START_RECOGNITION,
+            STOP_RECOGNITION,
+            LOAD_MODEL,
+            UNLOAD_MODEL,
+            UPDATE_MODEL,
+            DELETE_MODEL,
+            START_RECOGNITION_SERVICE,
+            STOP_RECOGNITION_SERVICE,
+            GET_MODEL_STATE,
+            SET_PARAMETER,
+            GET_MODULE_PROPERTIES,
+            DETACH,
+            // Callback events
+            RECOGNITION,
+            RESUME,
+            RESUME_FAILED,
+            PAUSE,
+            PAUSE_FAILED,
+            RESOURCES_AVAILABLE,
+            MODULE_DIED
+        }
+
+        private final UUID mModelUuid;
+        private final Type mType;
+        private final String mErrorString;
+
+        public SessionEvent(Type type, UUID modelUuid, String errorString) {
+            mType = type;
+            mModelUuid = modelUuid;
+            mErrorString = errorString;
+        }
+
+        public SessionEvent(Type type, UUID modelUuid) {
+            this(type, modelUuid, null);
+        }
+
+        @Override
+        public String eventToString() {
+            var res = new StringBuilder(String.format("%-25s", mType.name()));
+            if (mErrorString != null) {
+                res.append(" ERROR: ").append(mErrorString);
+            }
+            if (mModelUuid != null) {
+                res.append(" for: ").append(mModelUuid);
+            }
+            return res.toString();
+        }
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 07dc1c6..255db1e 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -16,6 +16,9 @@
 
 package com.android.server.soundtrigger;
 
+import static com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent.Type;
+import static com.android.server.utils.EventLogger.Event.ALOGW;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
@@ -49,7 +52,11 @@
 import android.telephony.TelephonyManager;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
+import com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent;
+import com.android.server.utils.EventLogger.Event;
+import com.android.server.utils.EventLogger;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -75,7 +82,6 @@
  */
 public class SoundTriggerHelper implements SoundTrigger.StatusListener {
     static final String TAG = "SoundTriggerHelper";
-    static final boolean DBG = false;
 
     // Module ID if there is no available module to connect to.
     public static final int INVALID_MODULE_ID = -1;
@@ -128,8 +134,12 @@
     private final int mModuleId;
     private final Function<SoundTrigger.StatusListener, SoundTriggerModule> mModuleProvider;
     private final Supplier<List<ModuleProperties>> mModulePropertiesProvider;
+    private final EventLogger mEventLogger;
 
-    SoundTriggerHelper(Context context,
+    @GuardedBy("mLock")
+    private boolean mIsDetached = false;
+
+    SoundTriggerHelper(Context context, EventLogger eventLogger,
             @NonNull Function<SoundTrigger.StatusListener, SoundTriggerModule> moduleProvider,
             int moduleId,
             @NonNull Supplier<List<ModuleProperties>> modulePropertiesProvider) {
@@ -140,6 +150,7 @@
         mModelDataMap = new HashMap<UUID, ModelData>();
         mKeyphraseUuidMap = new HashMap<Integer, UUID>();
         mModuleProvider = moduleProvider;
+        mEventLogger = eventLogger;
         mModulePropertiesProvider = modulePropertiesProvider;
         if (moduleId == INVALID_MODULE_ID) {
             mModule = null;
@@ -184,7 +195,7 @@
      * recognition.
      * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
      */
-    int startGenericRecognition(UUID modelId, GenericSoundModel soundModel,
+    public int startGenericRecognition(UUID modelId, GenericSoundModel soundModel,
             IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
             boolean runInBatterySaverMode) {
         MetricsLogger.count(mContext, "sth_start_recognition", 1);
@@ -195,6 +206,9 @@
         }
 
         synchronized (mLock) {
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             ModelData modelData = getOrCreateGenericModelDataLocked(modelId);
             if (modelData == null) {
                 Slog.w(TAG, "Irrecoverable error occurred, check UUID / sound model data.");
@@ -214,7 +228,7 @@
      * @param callback The callback for the recognition events related to the given keyphrase.
      * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
      */
-    int startKeyphraseRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
+    public int startKeyphraseRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
             IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
             boolean runInBatterySaverMode) {
         synchronized (mLock) {
@@ -223,12 +237,8 @@
                 return STATUS_ERROR;
             }
 
-            if (DBG) {
-                Slog.d(TAG, "startKeyphraseRecognition for keyphraseId=" + keyphraseId
-                        + " soundModel=" + soundModel + ", callback=" + callback.asBinder()
-                        + ", recognitionConfig=" + recognitionConfig
-                        + ", runInBatterySaverMode=" + runInBatterySaverMode);
-                dumpModelStateLocked();
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
             }
 
             ModelData model = getKeyphraseModelDataLocked(keyphraseId);
@@ -290,9 +300,6 @@
             }
             modelData.setHandle(handle[0]);
             modelData.setLoaded();
-            if (DBG) {
-                Slog.d(TAG, "prepareForRecognition: Sound model loaded with handle:" + handle[0]);
-            }
         }
         return STATUS_OK;
     }
@@ -311,7 +318,7 @@
      * for the recognition.
      * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
      */
-    int startRecognition(SoundModel soundModel, ModelData modelData,
+    private int startRecognition(SoundModel soundModel, ModelData modelData,
             IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
             int keyphraseId, boolean runInBatterySaverMode) {
         synchronized (mLock) {
@@ -385,7 +392,7 @@
      *
      * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
      */
-    int stopGenericRecognition(UUID modelId, IRecognitionStatusCallback callback) {
+    public int stopGenericRecognition(UUID modelId, IRecognitionStatusCallback callback) {
         synchronized (mLock) {
             MetricsLogger.count(mContext, "sth_stop_recognition", 1);
             if (callback == null || modelId == null) {
@@ -393,7 +400,9 @@
                         modelId);
                 return STATUS_ERROR;
             }
-
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             ModelData modelData = mModelDataMap.get(modelId);
             if (modelData == null || !modelData.isGenericModel()) {
                 Slog.w(TAG, "Attempting stopRecognition on invalid model with id:" + modelId);
@@ -418,7 +427,7 @@
      *
      * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
      */
-    int stopKeyphraseRecognition(int keyphraseId, IRecognitionStatusCallback callback) {
+    public int stopKeyphraseRecognition(int keyphraseId, IRecognitionStatusCallback callback) {
         synchronized (mLock) {
             MetricsLogger.count(mContext, "sth_stop_recognition", 1);
             if (callback == null) {
@@ -426,20 +435,15 @@
                         keyphraseId);
                 return STATUS_ERROR;
             }
-
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             ModelData modelData = getKeyphraseModelDataLocked(keyphraseId);
             if (modelData == null || !modelData.isKeyphraseModel()) {
                 Slog.w(TAG, "No model exists for given keyphrase Id " + keyphraseId);
                 return STATUS_ERROR;
             }
 
-            if (DBG) {
-                Slog.d(TAG, "stopRecognition for keyphraseId=" + keyphraseId + ", callback =" +
-                        callback.asBinder());
-                Slog.d(TAG, "current callback="
-                        + ((modelData == null || modelData.getCallback() == null) ? "null" :
-                            modelData.getCallback().asBinder()));
-            }
             int status = stopRecognition(modelData, callback);
             if (status != SoundTrigger.STATUS_OK) {
                 return status;
@@ -538,6 +542,11 @@
     }
 
     public ModuleProperties getModuleProperties() {
+        synchronized (mLock) {
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
+        }
         for (ModuleProperties moduleProperties : mModulePropertiesProvider.get()) {
             if (moduleProperties.getId() == mModuleId) {
                 return moduleProperties;
@@ -547,7 +556,7 @@
         return null;
     }
 
-    int unloadKeyphraseSoundModel(int keyphraseId) {
+    public int unloadKeyphraseSoundModel(int keyphraseId) {
         synchronized (mLock) {
             MetricsLogger.count(mContext, "sth_unload_keyphrase_sound_model", 1);
             ModelData modelData = getKeyphraseModelDataLocked(keyphraseId);
@@ -555,7 +564,9 @@
                     || !modelData.isKeyphraseModel()) {
                 return STATUS_ERROR;
             }
-
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             // Stop recognition if it's the current one.
             modelData.setRequested(false);
             int status = updateRecognitionLocked(modelData, false);
@@ -574,12 +585,15 @@
         }
     }
 
-    int unloadGenericSoundModel(UUID modelId) {
+    public int unloadGenericSoundModel(UUID modelId) {
         synchronized (mLock) {
             MetricsLogger.count(mContext, "sth_unload_generic_sound_model", 1);
             if (modelId == null || mModule == null) {
                 return STATUS_ERROR;
             }
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             ModelData modelData = mModelDataMap.get(modelId);
             if (modelData == null || !modelData.isGenericModel()) {
                 Slog.w(TAG, "Unload error: Attempting unload invalid generic model with id:" +
@@ -610,24 +624,29 @@
 
             // Remove it from existence.
             mModelDataMap.remove(modelId);
-            if (DBG) dumpModelStateLocked();
             return status;
         }
     }
 
-    boolean isRecognitionRequested(UUID modelId) {
+    public boolean isRecognitionRequested(UUID modelId) {
         synchronized (mLock) {
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             ModelData modelData = mModelDataMap.get(modelId);
             return modelData != null && modelData.isRequested();
         }
     }
 
-    int getGenericModelState(UUID modelId) {
+    public int getGenericModelState(UUID modelId) {
         synchronized (mLock) {
             MetricsLogger.count(mContext, "sth_get_generic_model_state", 1);
             if (modelId == null || mModule == null) {
                 return STATUS_ERROR;
             }
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             ModelData modelData = mModelDataMap.get(modelId);
             if (modelData == null || !modelData.isGenericModel()) {
                 Slog.w(TAG, "GetGenericModelState error: Invalid generic model id:" +
@@ -647,19 +666,20 @@
         }
     }
 
-    int getKeyphraseModelState(UUID modelId) {
-        Slog.w(TAG, "GetKeyphraseModelState error: Not implemented");
-        return STATUS_ERROR;
-    }
-
-    int setParameter(UUID modelId, @ModelParams int modelParam, int value) {
+    public int setParameter(UUID modelId, @ModelParams int modelParam, int value) {
         synchronized (mLock) {
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             return setParameterLocked(mModelDataMap.get(modelId), modelParam, value);
         }
     }
 
-    int setKeyphraseParameter(int keyphraseId, @ModelParams int modelParam, int value) {
+    public int setKeyphraseParameter(int keyphraseId, @ModelParams int modelParam, int value) {
         synchronized (mLock) {
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             return setParameterLocked(getKeyphraseModelDataLocked(keyphraseId), modelParam, value);
         }
     }
@@ -678,14 +698,20 @@
         return mModule.setParameter(modelData.getHandle(), modelParam, value);
     }
 
-    int getParameter(@NonNull UUID modelId, @ModelParams int modelParam) {
+    public int getParameter(@NonNull UUID modelId, @ModelParams int modelParam) {
         synchronized (mLock) {
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             return getParameterLocked(mModelDataMap.get(modelId), modelParam);
         }
     }
 
-    int getKeyphraseParameter(int keyphraseId, @ModelParams int modelParam) {
+    public int getKeyphraseParameter(int keyphraseId, @ModelParams int modelParam) {
         synchronized (mLock) {
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             return getParameterLocked(getKeyphraseModelDataLocked(keyphraseId), modelParam);
         }
     }
@@ -707,15 +733,21 @@
     }
 
     @Nullable
-    ModelParamRange queryParameter(@NonNull UUID modelId, @ModelParams int modelParam) {
+    public ModelParamRange queryParameter(@NonNull UUID modelId, @ModelParams int modelParam) {
         synchronized (mLock) {
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             return queryParameterLocked(mModelDataMap.get(modelId), modelParam);
         }
     }
 
     @Nullable
-    ModelParamRange queryKeyphraseParameter(int keyphraseId, @ModelParams int modelParam) {
+    public ModelParamRange queryKeyphraseParameter(int keyphraseId, @ModelParams int modelParam) {
         synchronized (mLock) {
+            if (mIsDetached) {
+                throw new IllegalStateException("SoundTriggerHelper has been detached");
+            }
             return queryParameterLocked(getKeyphraseModelDataLocked(keyphraseId), modelParam);
         }
     }
@@ -753,7 +785,6 @@
             return;
         }
 
-        if (DBG) Slog.d(TAG, "onRecognition: " + event);
         synchronized (mLock) {
             switch (event.status) {
                 case SoundTrigger.RECOGNITION_STATUS_ABORT:
@@ -801,12 +832,14 @@
         }
 
         try {
+            mEventLogger.enqueue(new SessionEvent(Type.RECOGNITION, model.getModelId()));
             callback.onGenericSoundTriggerDetected((GenericRecognitionEvent) event);
-        } catch (DeadObjectException e) {
+        } catch (RemoteException e) {
+            mEventLogger.enqueue(new SessionEvent(
+                        Type.RECOGNITION, model.getModelId(), "RemoteException")
+                    .printLog(ALOGW, TAG));
             forceStopAndUnloadModelLocked(model, e);
             return;
-        } catch (RemoteException e) {
-            Slog.w(TAG, "RemoteException in onGenericSoundTriggerDetected", e);
         }
 
         RecognitionConfig config = model.getRecognitionConfig();
@@ -825,7 +858,6 @@
 
     @Override
     public void onModelUnloaded(int modelHandle) {
-        if (DBG) Slog.d(TAG, "onModelUnloaded: " + modelHandle);
         synchronized (mLock) {
             MetricsLogger.count(mContext, "sth_sound_model_updated", 1);
             onModelUnloadedLocked(modelHandle);
@@ -834,7 +866,6 @@
 
     @Override
     public void onResourcesAvailable() {
-        if (DBG) Slog.d(TAG, "onResourcesAvailable");
         synchronized (mLock) {
             onResourcesAvailableLocked();
         }
@@ -876,6 +907,7 @@
     }
 
     private void onResourcesAvailableLocked() {
+        mEventLogger.enqueue(new SessionEvent(Type.RESOURCES_AVAILABLE, null));
         updateAllRecognitionsLocked();
     }
 
@@ -888,12 +920,14 @@
             try {
                 IRecognitionStatusCallback callback = modelData.getCallback();
                 if (callback != null) {
+                    mEventLogger.enqueue(new SessionEvent(Type.PAUSE, modelData.getModelId()));
                     callback.onRecognitionPaused();
                 }
-            } catch (DeadObjectException e) {
-                forceStopAndUnloadModelLocked(modelData, e);
             } catch (RemoteException e) {
-                Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
+                mEventLogger.enqueue(new SessionEvent(
+                            Type.PAUSE, modelData.getModelId(), "RemoteException")
+                        .printLog(ALOGW, TAG));
+                forceStopAndUnloadModelLocked(modelData, e);
             }
             updateRecognitionLocked(modelData, true);
         }
@@ -935,12 +969,14 @@
         }
 
         try {
+            mEventLogger.enqueue(new SessionEvent(Type.RECOGNITION, modelData.getModelId()));
             modelData.getCallback().onKeyphraseDetected((KeyphraseRecognitionEvent) event);
-        } catch (DeadObjectException e) {
+        } catch (RemoteException e) {
+            mEventLogger.enqueue(new SessionEvent(
+                        Type.RECOGNITION, modelData.getModelId(), "RemoteException")
+                    .printLog(ALOGW, TAG));
             forceStopAndUnloadModelLocked(modelData, e);
             return;
-        } catch (RemoteException e) {
-            Slog.w(TAG, "RemoteException in onKeyphraseDetected", e);
         }
 
         RecognitionConfig config = modelData.getRecognitionConfig();
@@ -992,10 +1028,13 @@
                 IRecognitionStatusCallback callback = modelData.getCallback();
                 if (callback != null) {
                     try {
+                        mEventLogger.enqueue(new SessionEvent(Type.MODULE_DIED,
+                                    modelData.getModelId()).printLog(ALOGW, TAG));
                         callback.onModuleDied();
                     } catch (RemoteException e) {
-                        Slog.w(TAG, "RemoteException send moduleDied for model handle " +
-                                modelData.getHandle(), e);
+                        mEventLogger.enqueue(new SessionEvent(Type.MODULE_DIED,
+                                    modelData.getModelId(), "RemoteException")
+                                .printLog(ALOGW, TAG));
                     }
                 }
             }
@@ -1004,7 +1043,13 @@
             internalClearGlobalStateLocked();
             if (mModule != null) {
                 mModule.detach();
-                mModule = mModuleProvider.apply(this);
+                try {
+                    // This is best effort
+                    // TODO (b/279507851)
+                    mModule = mModuleProvider.apply(this);
+                } catch (Exception e) {
+                    mModule = null;
+                }
             }
         }
     }
@@ -1041,7 +1086,6 @@
 
         @Override
         public void onCallStateChanged(int state, String arg1) {
-            if (DBG) Slog.d(TAG, "onCallStateChanged: " + state);
 
             if (mHandler != null) {
                 synchronized (mLock) {
@@ -1063,24 +1107,12 @@
             }
             @SoundTriggerPowerSaveMode int soundTriggerPowerSaveMode =
                     mPowerManager.getSoundTriggerPowerSaveMode();
-            if (DBG) {
-                Slog.d(TAG, "onPowerSaveModeChanged: " + soundTriggerPowerSaveMode);
-            }
             synchronized (mLock) {
                 onPowerSaveModeChangedLocked(soundTriggerPowerSaveMode);
             }
         }
     }
 
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        synchronized (mLock) {
-            pw.print("  module properties=");
-            pw.print("  call active=");
-            pw.println(mCallActive);
-            pw.println("  SoundTrigger Power State=" + mSoundTriggerPowerSaveMode);
-        }
-    }
-
     private void initializeDeviceStateListeners() {
         if (mRecognitionRequested) {
             return;
@@ -1115,6 +1147,8 @@
      */
     public void detach() {
         synchronized (mLock) {
+            if (mIsDetached) return;
+            mIsDetached = true;
             for (ModelData model : mModelDataMap.values()) {
                 forceStopAndUnloadModelLocked(model, null);
             }
@@ -1289,7 +1323,7 @@
      * @param modelData Model data to be used for recognition
      * @return True if device state allows recognition to run, false if not.
      */
-    boolean isRecognitionAllowedByPowerState(ModelData modelData) {
+    private boolean isRecognitionAllowedByPowerState(ModelData modelData) {
         return mSoundTriggerPowerSaveMode == PowerManager.SOUND_TRIGGER_MODE_ALL_ENABLED
                 || (mSoundTriggerPowerSaveMode == PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY
                 && modelData.shouldRunInBatterySaverMode());
@@ -1324,11 +1358,16 @@
             // Notify of error if needed.
             if (notifyClientOnError) {
                 try {
+                    mEventLogger.enqueue(new SessionEvent(Type.RESUME_FAILED,
+                                modelData.getModelId(), String.valueOf(status))
+                            .printLog(ALOGW, TAG));
                     callback.onResumeFailed(status);
-                } catch (DeadObjectException e) {
-                    forceStopAndUnloadModelLocked(modelData, e);
                 } catch (RemoteException e) {
-                    Slog.w(TAG, "RemoteException in onResumeFailed", e);
+                    mEventLogger.enqueue(new SessionEvent(Type.RESUME_FAILED,
+                                modelData.getModelId(),
+                                String.valueOf(status) + " - RemoteException")
+                            .printLog(ALOGW, TAG));
+                    forceStopAndUnloadModelLocked(modelData, e);
                 }
             }
         } else {
@@ -1338,17 +1377,16 @@
             // Notify of resume if needed.
             if (notifyClientOnError) {
                 try {
+                    mEventLogger.enqueue(new SessionEvent(Type.RESUME,
+                                modelData.getModelId()));
                     callback.onRecognitionResumed();
-                } catch (DeadObjectException e) {
-                    forceStopAndUnloadModelLocked(modelData, e);
                 } catch (RemoteException e) {
-                    Slog.w(TAG, "RemoteException in onRecognitionResumed", e);
+                    mEventLogger.enqueue(new SessionEvent(Type.RESUME,
+                                modelData.getModelId(), "RemoteException").printLog(ALOGW, TAG));
+                    forceStopAndUnloadModelLocked(modelData, e);
                 }
             }
         }
-        if (DBG) {
-            Slog.d(TAG, "Model being started :" + modelData.toString());
-        }
         return status;
     }
 
@@ -1368,11 +1406,16 @@
             MetricsLogger.count(mContext, "sth_stop_recognition_error", 1);
             if (notify) {
                 try {
+                    mEventLogger.enqueue(new SessionEvent(Type.PAUSE_FAILED,
+                                modelData.getModelId(), String.valueOf(status))
+                            .printLog(ALOGW, TAG));
                     callback.onPauseFailed(status);
-                } catch (DeadObjectException e) {
-                    forceStopAndUnloadModelLocked(modelData, e);
                 } catch (RemoteException e) {
-                    Slog.w(TAG, "RemoteException in onPauseFailed", e);
+                    mEventLogger.enqueue(new SessionEvent(Type.PAUSE_FAILED,
+                                modelData.getModelId(),
+                                String.valueOf(status) + " - RemoteException")
+                            .printLog(ALOGW, TAG));
+                    forceStopAndUnloadModelLocked(modelData, e);
                 }
             }
         } else {
@@ -1381,27 +1424,19 @@
             // Notify of pause if needed.
             if (notify) {
                 try {
+                    mEventLogger.enqueue(new SessionEvent(Type.PAUSE,
+                                modelData.getModelId()));
                     callback.onRecognitionPaused();
-                } catch (DeadObjectException e) {
-                    forceStopAndUnloadModelLocked(modelData, e);
                 } catch (RemoteException e) {
-                    Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
+                    mEventLogger.enqueue(new SessionEvent(Type.PAUSE,
+                                modelData.getModelId(), "RemoteException").printLog(ALOGW, TAG));
+                    forceStopAndUnloadModelLocked(modelData, e);
                 }
             }
         }
-        if (DBG) {
-            Slog.d(TAG, "Model being stopped :" + modelData.toString());
-        }
         return status;
     }
 
-    private void dumpModelStateLocked() {
-        for (UUID modelId : mModelDataMap.keySet()) {
-            ModelData modelData = mModelDataMap.get(modelId);
-            Slog.i(TAG, "Model :" + modelData.toString());
-        }
-    }
-
     // Computes whether we have any recognition running at all (voice or generic). Sets
     // the mRecognitionRequested variable with the result.
     private boolean computeRecognitionRequestedLocked() {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 790be8d..913535e 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -31,6 +31,9 @@
 import static android.provider.Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY;
 import static android.provider.Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT;
 
+import static com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent.Type;
+import static com.android.server.utils.EventLogger.Event.ALOGW;
+
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.Manifest;
@@ -54,6 +57,7 @@
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.hardware.soundtrigger.SoundTrigger.SoundModel;
+import android.hardware.soundtrigger.SoundTriggerModule;
 import android.media.AudioAttributes;
 import android.media.AudioFormat;
 import android.media.AudioRecord;
@@ -83,6 +87,7 @@
 import android.provider.Settings;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.SparseArray;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -90,6 +95,9 @@
 import com.android.internal.app.ISoundTriggerSession;
 import com.android.server.SoundTriggerInternal;
 import com.android.server.SystemService;
+import com.android.server.soundtrigger.SoundTriggerEvent.ServiceEvent;
+import com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent;
+import com.android.server.utils.EventLogger.Event;
 import com.android.server.utils.EventLogger;
 
 import java.io.FileDescriptor;
@@ -97,11 +105,16 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
+import java.util.Deque;
 import java.util.Map;
 import java.util.Objects;
 import java.util.TreeMap;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 /**
@@ -116,13 +129,22 @@
 public class SoundTriggerService extends SystemService {
     private static final String TAG = "SoundTriggerService";
     private static final boolean DEBUG = true;
+    private static final int SESSION_MAX_EVENT_SIZE = 128;
 
     final Context mContext;
     private Object mLock;
     private final SoundTriggerServiceStub mServiceStub;
     private final LocalSoundTriggerService mLocalSoundTriggerService;
+
+    private ISoundTriggerMiddlewareService mMiddlewareService;
     private SoundTriggerDbHelper mDbHelper;
 
+    private final EventLogger mServiceEventLogger = new EventLogger(256, "Service");
+
+    private final Set<EventLogger> mSessionEventLoggers = ConcurrentHashMap.newKeySet(4);
+    private final Deque<EventLogger> mDetachedSessionEventLoggers = new LinkedBlockingDeque<>(4);
+    private AtomicInteger mSessionIdCounter = new AtomicInteger(0);
+
     class SoundModelStatTracker {
         private class SoundModelStat {
             SoundModelStat() {
@@ -164,7 +186,7 @@
         public synchronized void onStop(UUID id) {
             SoundModelStat stat = mModelStats.get(id);
             if (stat == null) {
-                Slog.w(TAG, "error onStop(): Model " + id + " has no stats available");
+                Slog.i(TAG, "error onStop(): Model " + id + " has no stats available");
                 return;
             }
 
@@ -222,17 +244,18 @@
         if (PHASE_THIRD_PARTY_APPS_CAN_START == phase) {
             mDbHelper = new SoundTriggerDbHelper(mContext);
         }
+        mMiddlewareService = ISoundTriggerMiddlewareService.Stub.asInterface(
+                ServiceManager.waitForService(Context.SOUND_TRIGGER_MIDDLEWARE_SERVICE));
+
     }
 
     // Must be called with cleared binder context.
-    private static List<ModuleProperties> listUnderlyingModuleProperties(
+    private List<ModuleProperties> listUnderlyingModuleProperties(
             Identity originatorIdentity) {
         Identity middlemanIdentity = new Identity();
         middlemanIdentity.packageName = ActivityThread.currentOpPackageName();
-        var service = ISoundTriggerMiddlewareService.Stub.asInterface(
-                ServiceManager.waitForService(Context.SOUND_TRIGGER_MIDDLEWARE_SERVICE));
         try {
-            return Arrays.stream(service.listModulesAsMiddleman(middlemanIdentity,
+            return Arrays.stream(mMiddlewareService.listModulesAsMiddleman(middlemanIdentity,
                                                                 originatorIdentity))
                     .map(desc -> ConversionUtil.aidl2apiModuleDescriptor(desc))
                     .collect(Collectors.toList());
@@ -241,7 +264,9 @@
         }
     }
 
-    private SoundTriggerHelper newSoundTriggerHelper(ModuleProperties moduleProperties) {
+    private SoundTriggerHelper newSoundTriggerHelper(
+            ModuleProperties moduleProperties, EventLogger eventLogger) {
+
         Identity middlemanIdentity = new Identity();
         middlemanIdentity.packageName = ActivityThread.currentOpPackageName();
         Identity originatorIdentity = IdentityContext.getNonNull();
@@ -260,23 +285,45 @@
 
         return new SoundTriggerHelper(
                 mContext,
-                (SoundTrigger.StatusListener statusListener) ->
-                                        SoundTrigger.attachModuleAsMiddleman(
-                                        moduleId, statusListener, null /* handler */,
-                                        middlemanIdentity, originatorIdentity),
+                eventLogger,
+                (SoundTrigger.StatusListener statusListener) -> new SoundTriggerModule(
+                        mMiddlewareService, moduleId, statusListener,
+                        Looper.getMainLooper(), middlemanIdentity, originatorIdentity),
                 moduleId,
                 () -> listUnderlyingModuleProperties(originatorIdentity)
                 );
     }
 
+    // Helper to add session logger to the capacity limited detached list.
+    // If we are at capacity, remove the oldest, and retry
+    private void detachSessionLogger(EventLogger logger) {
+        if (!mSessionEventLoggers.remove(logger)) {
+            return;
+        }
+        // Attempt to push to the top of the queue
+        while (!mDetachedSessionEventLoggers.offerFirst(logger)) {
+            // Remove the oldest element, if one still exists
+            mDetachedSessionEventLoggers.pollLast();
+        }
+    }
+
     class SoundTriggerServiceStub extends ISoundTriggerService.Stub {
         @Override
         public ISoundTriggerSession attachAsOriginator(@NonNull Identity originatorIdentity,
                 @NonNull ModuleProperties moduleProperties,
                 @NonNull IBinder client) {
+
+            int sessionId = mSessionIdCounter.getAndIncrement();
+            mServiceEventLogger.enqueue(new ServiceEvent(
+                    ServiceEvent.Type.ATTACH, originatorIdentity.packageName + "#" + sessionId));
             try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
                     originatorIdentity)) {
-                return new SoundTriggerSessionStub(client, newSoundTriggerHelper(moduleProperties));
+                var eventLogger = new EventLogger(SESSION_MAX_EVENT_SIZE,
+                        "SoundTriggerSessionLogs for package: "
+                        + Objects.requireNonNull(originatorIdentity.packageName)
+                        + "#" + sessionId);
+                return new SoundTriggerSessionStub(client,
+                        newSoundTriggerHelper(moduleProperties, eventLogger), eventLogger);
             }
         }
 
@@ -285,15 +332,26 @@
                 @NonNull Identity middlemanIdentity,
                 @NonNull ModuleProperties moduleProperties,
                 @NonNull IBinder client) {
+
+            int sessionId = mSessionIdCounter.getAndIncrement();
+            mServiceEventLogger.enqueue(new ServiceEvent(
+                    ServiceEvent.Type.ATTACH, originatorIdentity.packageName + "#" + sessionId));
             try (SafeCloseable ignored = PermissionUtil.establishIdentityIndirect(mContext,
                     SOUNDTRIGGER_DELEGATE_IDENTITY, middlemanIdentity,
                     originatorIdentity)) {
-                return new SoundTriggerSessionStub(client, newSoundTriggerHelper(moduleProperties));
+                var eventLogger = new EventLogger(SESSION_MAX_EVENT_SIZE,
+                        "SoundTriggerSessionLogs for package: "
+                        + Objects.requireNonNull(originatorIdentity.packageName) + "#"
+                        + sessionId);
+                return new SoundTriggerSessionStub(client,
+                        newSoundTriggerHelper(moduleProperties, eventLogger), eventLogger);
             }
         }
 
         @Override
         public List<ModuleProperties> listModuleProperties(@NonNull Identity originatorIdentity) {
+            mServiceEventLogger.enqueue(new ServiceEvent(
+                    ServiceEvent.Type.LIST_MODULE, originatorIdentity.packageName));
             try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
                     originatorIdentity)) {
                 return listUnderlyingModuleProperties(originatorIdentity);
@@ -316,6 +374,31 @@
                 throw e.rethrowFromSystemServer();
             }
         }
+
+        @Override
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            // Event loggers
+            pw.println("##Service-Wide logs:");
+            mServiceEventLogger.dump(pw, /* indent = */ "  ");
+
+            pw.println("\n##Active Session dumps:\n");
+            for (var sessionLogger : mSessionEventLoggers) {
+                sessionLogger.dump(pw, /* indent= */ "  ");
+                pw.println("");
+            }
+            pw.println("##Detached Session dumps:\n");
+            for (var sessionLogger : mDetachedSessionEventLoggers) {
+                sessionLogger.dump(pw, /* indent= */ "  ");
+                pw.println("");
+            }
+            // enrolled models
+            pw.println("##Enrolled db dump:\n");
+            mDbHelper.dump(pw);
+
+            // stats
+            pw.println("\n##Sound Model Stats dump:\n");
+            mSoundModelStatTracker.dump(pw);
+        }
     }
 
     class SoundTriggerSessionStub extends ISoundTriggerSession.Stub {
@@ -326,17 +409,20 @@
         private final TreeMap<UUID, SoundModel> mLoadedModels = new TreeMap<>();
         private final Object mCallbacksLock = new Object();
         private final TreeMap<UUID, IRecognitionStatusCallback> mCallbacks = new TreeMap<>();
+        private final EventLogger mEventLogger;
 
-        SoundTriggerSessionStub(@NonNull IBinder client, SoundTriggerHelper soundTriggerHelper) {
+        SoundTriggerSessionStub(@NonNull IBinder client,
+                SoundTriggerHelper soundTriggerHelper, EventLogger eventLogger) {
             mSoundTriggerHelper = soundTriggerHelper;
             mClient = client;
             mOriginatorIdentity = IdentityContext.getNonNull();
+            mEventLogger = eventLogger;
+            mSessionEventLoggers.add(mEventLogger);
+
             try {
-                mClient.linkToDeath(() -> {
-                    clientDied();
-                }, 0);
+                mClient.linkToDeath(() -> clientDied(), 0);
             } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to register death listener.", e);
+                clientDied();
             }
         }
 
@@ -344,11 +430,14 @@
         public int startRecognition(GenericSoundModel soundModel,
                 IRecognitionStatusCallback callback,
                 RecognitionConfig config, boolean runInBatterySaverMode) {
+            mEventLogger.enqueue(new SessionEvent(Type.START_RECOGNITION, getUuid(soundModel)));
+
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
 
                 if (soundModel == null) {
-                    Slog.e(TAG, "Null model passed to startRecognition");
+                    mEventLogger.enqueue(new SessionEvent(Type.START_RECOGNITION,
+                                getUuid(soundModel), "Invalid sound model").printLog(ALOGW, TAG));
                     return STATUS_ERROR;
                 }
 
@@ -356,13 +445,6 @@
                     enforceCallingPermission(Manifest.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER);
                 }
 
-                if (DEBUG) {
-                    Slog.i(TAG, "startRecognition(): Uuid : " + soundModel.toString());
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(
-                        "startRecognition(): Uuid : " + soundModel.getUuid().toString()));
-
                 int ret = mSoundTriggerHelper.startGenericRecognition(soundModel.getUuid(),
                         soundModel,
                         callback, config, runInBatterySaverMode);
@@ -375,15 +457,9 @@
 
         @Override
         public int stopRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback) {
+            mEventLogger.enqueue(new SessionEvent(Type.STOP_RECOGNITION, getUuid(parcelUuid)));
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.i(TAG, "stopRecognition(): Uuid : " + parcelUuid);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent("stopRecognition(): Uuid : "
-                        + parcelUuid));
-
                 int ret = mSoundTriggerHelper.stopGenericRecognition(parcelUuid.getUuid(),
                         callback);
                 if (ret == STATUS_OK) {
@@ -397,13 +473,6 @@
         public SoundTrigger.GenericSoundModel getSoundModel(ParcelUuid soundModelId) {
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.i(TAG, "getSoundModel(): id = " + soundModelId);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent("getSoundModel(): id = "
-                        + soundModelId));
-
                 SoundTrigger.GenericSoundModel model = mDbHelper.getGenericSoundModel(
                         soundModelId.getUuid());
                 return model;
@@ -412,29 +481,18 @@
 
         @Override
         public void updateSoundModel(SoundTrigger.GenericSoundModel soundModel) {
+            mEventLogger.enqueue(new SessionEvent(Type.UPDATE_MODEL, getUuid(soundModel)));
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.i(TAG, "updateSoundModel(): model = " + soundModel);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent("updateSoundModel(): model = "
-                        + soundModel));
-               mDbHelper.updateGenericSoundModel(soundModel);
+                mDbHelper.updateGenericSoundModel(soundModel);
             }
         }
 
         @Override
         public void deleteSoundModel(ParcelUuid soundModelId) {
+            mEventLogger.enqueue(new SessionEvent(Type.DELETE_MODEL, getUuid(soundModelId)));
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.i(TAG, "deleteSoundModel(): id = " + soundModelId);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent("deleteSoundModel(): id = "
-                        + soundModelId));
-
                 // Unload the model if it is loaded.
                 mSoundTriggerHelper.unloadGenericSoundModel(soundModelId.getUuid());
 
@@ -447,22 +505,14 @@
 
         @Override
         public int loadGenericSoundModel(GenericSoundModel soundModel) {
+            mEventLogger.enqueue(new SessionEvent(Type.LOAD_MODEL, getUuid(soundModel)));
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
                 if (soundModel == null || soundModel.getUuid() == null) {
-                    Slog.w(TAG, "Invalid sound model");
-
-                    sEventLogger.enqueue(new EventLogger.StringEvent(
-                            "loadGenericSoundModel(): Invalid sound model"));
-
+                    mEventLogger.enqueue(new SessionEvent(Type.LOAD_MODEL,
+                                getUuid(soundModel), "Invalid sound model").printLog(ALOGW, TAG));
                     return STATUS_ERROR;
                 }
-                if (DEBUG) {
-                    Slog.i(TAG, "loadGenericSoundModel(): id = " + soundModel.getUuid());
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent("loadGenericSoundModel(): id = "
-                        + soundModel.getUuid()));
 
                 synchronized (mLock) {
                     SoundModel oldModel = mLoadedModels.get(soundModel.getUuid());
@@ -483,32 +533,22 @@
 
         @Override
         public int loadKeyphraseSoundModel(KeyphraseSoundModel soundModel) {
+            mEventLogger.enqueue(new SessionEvent(Type.LOAD_MODEL, getUuid(soundModel)));
+
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
                 if (soundModel == null || soundModel.getUuid() == null) {
-                    Slog.w(TAG, "Invalid sound model");
-
-                    sEventLogger.enqueue(new EventLogger.StringEvent(
-                            "loadKeyphraseSoundModel(): Invalid sound model"));
+                    mEventLogger.enqueue(new SessionEvent(Type.LOAD_MODEL, getUuid(soundModel),
+                                "Invalid sound model").printLog(ALOGW, TAG));
 
                     return STATUS_ERROR;
                 }
                 if (soundModel.getKeyphrases() == null || soundModel.getKeyphrases().length != 1) {
-                    Slog.w(TAG, "Only one keyphrase per model is currently supported.");
-
-                    sEventLogger.enqueue(new EventLogger.StringEvent(
-                            "loadKeyphraseSoundModel(): Only one keyphrase per model"
-                                    + " is currently supported."));
-
+                    mEventLogger.enqueue(new SessionEvent(Type.LOAD_MODEL, getUuid(soundModel),
+                                "Only one keyphrase supported").printLog(ALOGW, TAG));
                     return STATUS_ERROR;
                 }
-                if (DEBUG) {
-                    Slog.i(TAG, "loadKeyphraseSoundModel(): id = " + soundModel.getUuid());
-                }
 
-                sEventLogger.enqueue(
-                        new EventLogger.StringEvent("loadKeyphraseSoundModel(): id = "
-                                + soundModel.getUuid()));
 
                 synchronized (mLock) {
                     SoundModel oldModel = mLoadedModels.get(soundModel.getUuid());
@@ -530,23 +570,17 @@
 
         @Override
         public int startRecognitionForService(ParcelUuid soundModelId, Bundle params,
-            ComponentName detectionService, SoundTrigger.RecognitionConfig config) {
+                ComponentName detectionService, SoundTrigger.RecognitionConfig config) {
+            mEventLogger.enqueue(new SessionEvent(Type.START_RECOGNITION_SERVICE,
+                        getUuid(soundModelId)));
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 Objects.requireNonNull(soundModelId);
                 Objects.requireNonNull(detectionService);
                 Objects.requireNonNull(config);
 
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-
                 enforceDetectionPermissions(detectionService);
 
-                if (DEBUG) {
-                    Slog.i(TAG, "startRecognition(): id = " + soundModelId);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(
-                        "startRecognitionForService(): id = " + soundModelId));
-
                 IRecognitionStatusCallback callback =
                         new RemoteSoundTriggerDetectionService(soundModelId.getUuid(), params,
                                 detectionService, Binder.getCallingUserHandle(), config);
@@ -554,10 +588,10 @@
                 synchronized (mLock) {
                     SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
                     if (soundModel == null) {
-                        Slog.w(TAG, soundModelId + " is not loaded");
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "startRecognitionForService():" + soundModelId + " is not loaded"));
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.START_RECOGNITION_SERVICE,
+                                    getUuid(soundModelId),
+                                    "Model not loaded").printLog(ALOGW, TAG));
 
                         return STATUS_ERROR;
                     }
@@ -566,12 +600,10 @@
                         existingCallback = mCallbacks.get(soundModelId.getUuid());
                     }
                     if (existingCallback != null) {
-                        Slog.w(TAG, soundModelId + " is already running");
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "startRecognitionForService():"
-                                        + soundModelId + " is already running"));
-
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.START_RECOGNITION_SERVICE,
+                                    getUuid(soundModelId),
+                                    "Model already running").printLog(ALOGW, TAG));
                         return STATUS_ERROR;
                     }
                     int ret;
@@ -581,20 +613,18 @@
                                     (GenericSoundModel) soundModel, callback, config, false);
                             break;
                         default:
-                            Slog.e(TAG, "Unknown model type");
-
-                            sEventLogger.enqueue(new EventLogger.StringEvent(
-                                    "startRecognitionForService(): Unknown model type"));
-
+                            mEventLogger.enqueue(new SessionEvent(
+                                        Type.START_RECOGNITION_SERVICE,
+                                        getUuid(soundModelId),
+                                        "Unsupported model type").printLog(ALOGW, TAG));
                             return STATUS_ERROR;
                     }
 
                     if (ret != STATUS_OK) {
-                        Slog.e(TAG, "Failed to start model: " + ret);
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "startRecognitionForService(): Failed to start model:"));
-
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.START_RECOGNITION_SERVICE,
+                                    getUuid(soundModelId),
+                                    "Model start fail").printLog(ALOGW, TAG));
                         return ret;
                     }
                     synchronized (mCallbacksLock) {
@@ -609,23 +639,20 @@
 
         @Override
         public int stopRecognitionForService(ParcelUuid soundModelId) {
+            mEventLogger.enqueue(new SessionEvent(Type.STOP_RECOGNITION_SERVICE,
+                        getUuid(soundModelId)));
+
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.i(TAG, "stopRecognition(): id = " + soundModelId);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(
-                        "stopRecognitionForService(): id = " + soundModelId));
 
                 synchronized (mLock) {
                     SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
                     if (soundModel == null) {
-                        Slog.w(TAG, soundModelId + " is not loaded");
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "stopRecognitionForService(): " + soundModelId
-                                        + " is not loaded"));
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.STOP_RECOGNITION_SERVICE,
+                                    getUuid(soundModelId),
+                                    "Model not loaded")
+                                .printLog(ALOGW, TAG));
 
                         return STATUS_ERROR;
                     }
@@ -634,12 +661,11 @@
                         callback = mCallbacks.get(soundModelId.getUuid());
                     }
                     if (callback == null) {
-                        Slog.w(TAG, soundModelId + " is not running");
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "stopRecognitionForService(): " + soundModelId
-                                        + " is not running"));
-
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.STOP_RECOGNITION_SERVICE,
+                                    getUuid(soundModelId),
+                                    "Model not running")
+                                .printLog(ALOGW, TAG));
                         return STATUS_ERROR;
                     }
                     int ret;
@@ -649,20 +675,21 @@
                                     soundModel.getUuid(), callback);
                             break;
                         default:
-                            Slog.e(TAG, "Unknown model type");
-
-                            sEventLogger.enqueue(new EventLogger.StringEvent(
-                                    "stopRecognitionForService(): Unknown model type"));
+                            mEventLogger.enqueue(new SessionEvent(
+                                        Type.STOP_RECOGNITION_SERVICE,
+                                        getUuid(soundModelId),
+                                        "Unknown model type")
+                                    .printLog(ALOGW, TAG));
 
                             return STATUS_ERROR;
                     }
 
                     if (ret != STATUS_OK) {
-                        Slog.e(TAG, "Failed to stop model: " + ret);
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "stopRecognitionForService(): Failed to stop model: " + ret));
-
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.STOP_RECOGNITION_SERVICE,
+                                    getUuid(soundModelId),
+                                    "Failed to stop model")
+                                .printLog(ALOGW, TAG));
                         return ret;
                     }
                     synchronized (mCallbacksLock) {
@@ -677,23 +704,18 @@
 
         @Override
         public int unloadSoundModel(ParcelUuid soundModelId) {
+            mEventLogger.enqueue(new SessionEvent(Type.UNLOAD_MODEL, getUuid(soundModelId)));
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.i(TAG, "unloadSoundModel(): id = " + soundModelId);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent("unloadSoundModel(): id = "
-                        + soundModelId));
 
                 synchronized (mLock) {
                     SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
                     if (soundModel == null) {
-                        Slog.w(TAG, soundModelId + " is not loaded");
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "unloadSoundModel(): " + soundModelId + " is not loaded"));
-
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.UNLOAD_MODEL,
+                                    getUuid(soundModelId),
+                                    "Model not loaded")
+                                .printLog(ALOGW, TAG));
                         return STATUS_ERROR;
                     }
                     int ret;
@@ -706,19 +728,19 @@
                             ret = mSoundTriggerHelper.unloadGenericSoundModel(soundModel.getUuid());
                             break;
                         default:
-                            Slog.e(TAG, "Unknown model type");
-
-                            sEventLogger.enqueue(new EventLogger.StringEvent(
-                                    "unloadSoundModel(): Unknown model type"));
-
+                            mEventLogger.enqueue(new SessionEvent(
+                                        Type.UNLOAD_MODEL,
+                                        getUuid(soundModelId),
+                                        "Unknown model type")
+                                    .printLog(ALOGW, TAG));
                             return STATUS_ERROR;
                     }
                     if (ret != STATUS_OK) {
-                        Slog.e(TAG, "Failed to unload model");
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "unloadSoundModel(): Failed to unload model"));
-
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.UNLOAD_MODEL,
+                                    getUuid(soundModelId),
+                                    "Failed to unload model")
+                                .printLog(ALOGW, TAG));
                         return ret;
                     }
                     mLoadedModels.remove(soundModelId.getUuid());
@@ -743,24 +765,19 @@
 
         @Override
         public int getModelState(ParcelUuid soundModelId) {
+            mEventLogger.enqueue(new SessionEvent(Type.GET_MODEL_STATE, getUuid(soundModelId)));
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
                 int ret = STATUS_ERROR;
-                if (DEBUG) {
-                    Slog.i(TAG, "getModelState(): id = " + soundModelId);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent("getModelState(): id = "
-                        + soundModelId));
 
                 synchronized (mLock) {
                     SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
                     if (soundModel == null) {
-                        Slog.w(TAG, soundModelId + " is not loaded");
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent("getModelState(): "
-                                + soundModelId + " is not loaded"));
-
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.GET_MODEL_STATE,
+                                    getUuid(soundModelId),
+                                    "Model is not loaded")
+                                .printLog(ALOGW, TAG));
                         return ret;
                     }
                     switch (soundModel.getType()) {
@@ -769,13 +786,13 @@
                             break;
                         default:
                             // SoundModel.TYPE_KEYPHRASE is not supported to increase privacy.
-                            Slog.e(TAG, "Unsupported model type, " + soundModel.getType());
-                            sEventLogger.enqueue(new EventLogger.StringEvent(
-                                    "getModelState(): Unsupported model type, "
-                                            + soundModel.getType()));
+                            mEventLogger.enqueue(new SessionEvent(
+                                        Type.GET_MODEL_STATE,
+                                        getUuid(soundModelId),
+                                        "Unsupported model type")
+                                .printLog(ALOGW, TAG));
                             break;
                     }
-
                     return ret;
                 }
             }
@@ -784,16 +801,11 @@
         @Override
         @Nullable
         public ModuleProperties getModuleProperties() {
+            mEventLogger.enqueue(new SessionEvent(Type.GET_MODULE_PROPERTIES, null));
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.i(TAG, "getModuleProperties()");
-                }
-
                 synchronized (mLock) {
                     ModuleProperties properties = mSoundTriggerHelper.getModuleProperties();
-                    sEventLogger.enqueue(new EventLogger.StringEvent(
-                            "getModuleProperties(): " + properties));
                     return properties;
                 }
             }
@@ -802,33 +814,21 @@
         @Override
         public int setParameter(ParcelUuid soundModelId,
                 @ModelParams int modelParam, int value) {
+            mEventLogger.enqueue(new SessionEvent(Type.SET_PARAMETER, getUuid(soundModelId)));
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.d(TAG, "setParameter(): id=" + soundModelId
-                            + ", param=" + modelParam
-                            + ", value=" + value);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(
-                        "setParameter(): id=" + soundModelId
-                                + ", param=" + modelParam
-                                + ", value=" + value));
-
                 synchronized (mLock) {
                     SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
                     if (soundModel == null) {
-                        Slog.w(TAG, soundModelId + " is not loaded. Loaded models: "
-                                + mLoadedModels.toString());
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent("setParameter(): "
-                                + soundModelId + " is not loaded"));
-
+                        mEventLogger.enqueue(new SessionEvent(
+                                    Type.SET_PARAMETER,
+                                    getUuid(soundModelId),
+                                    "Model not loaded")
+                                .printLog(ALOGW, TAG));
                         return STATUS_BAD_VALUE;
                     }
-
-                    return mSoundTriggerHelper.setParameter(soundModel.getUuid(), modelParam,
-                            value);
+                    return mSoundTriggerHelper.setParameter(
+                            soundModel.getUuid(), modelParam, value);
                 }
             }
         }
@@ -839,26 +839,11 @@
                 throws UnsupportedOperationException, IllegalArgumentException {
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.d(TAG, "getParameter(): id=" + soundModelId
-                            + ", param=" + modelParam);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(
-                        "getParameter(): id=" + soundModelId
-                                + ", param=" + modelParam));
-
                 synchronized (mLock) {
                     SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
                     if (soundModel == null) {
-                        Slog.w(TAG, soundModelId + " is not loaded");
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent("getParameter(): "
-                                + soundModelId + " is not loaded"));
-
                         throw new IllegalArgumentException("sound model is not loaded");
                     }
-
                     return mSoundTriggerHelper.getParameter(soundModel.getUuid(), modelParam);
                 }
             }
@@ -870,37 +855,27 @@
                 @ModelParams int modelParam) {
             try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
                 enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
-                if (DEBUG) {
-                    Slog.d(TAG, "queryParameter(): id=" + soundModelId
-                            + ", param=" + modelParam);
-                }
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(
-                        "queryParameter(): id=" + soundModelId
-                                + ", param=" + modelParam));
-
                 synchronized (mLock) {
                     SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
                     if (soundModel == null) {
-                        Slog.w(TAG, soundModelId + " is not loaded");
-
-                        sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "queryParameter(): "
-                                        + soundModelId + " is not loaded"));
-
                         return null;
                     }
-
                     return mSoundTriggerHelper.queryParameter(soundModel.getUuid(), modelParam);
                 }
             }
         }
 
         private void clientDied() {
-            Slog.w(TAG, "Client died, cleaning up session.");
-            sEventLogger.enqueue(new EventLogger.StringEvent(
-                    "Client died, cleaning up session."));
+            mEventLogger.enqueue(new SessionEvent(Type.DETACH, null));
+            mServiceEventLogger.enqueue(new ServiceEvent(
+                        ServiceEvent.Type.DETACH, mOriginatorIdentity.packageName, "Client died")
+                    .printLog(ALOGW, TAG));
+            detach();
+        }
+
+        private void detach() {
             mSoundTriggerHelper.detach();
+            detachSessionLogger(mEventLogger);
         }
 
         private void enforceCallingPermission(String permission) {
@@ -922,6 +897,14 @@
             }
         }
 
+        private UUID getUuid(ParcelUuid uuid) {
+            return (uuid != null) ? uuid.getUuid() : null;
+        }
+
+        private UUID getUuid(SoundModel model) {
+            return (model != null) ? model.getUuid() : null;
+        }
+
         /**
          * Local end for a {@link SoundTriggerDetectionService}. Operations are queued up and
          * executed when the service connects.
@@ -1068,7 +1051,7 @@
                     } catch (Exception e) {
                         Slog.e(TAG, mPuuid + ": Cannot remove client", e);
 
-                        sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                        mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                 + ": Cannot remove client"));
 
                     }
@@ -1091,9 +1074,7 @@
              * dropped.
              */
             private void destroy() {
-                if (DEBUG) Slog.v(TAG, mPuuid + ": destroy");
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid + ": destroy"));
+                mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid + ": destroy"));
 
                 synchronized (mRemoteServiceLock) {
                     disconnectLocked();
@@ -1127,7 +1108,7 @@
                                 Slog.e(TAG, mPuuid + ": Could not stop operation "
                                         + mRunningOpIds.valueAt(i), e);
 
-                                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                                mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                         + ": Could not stop operation " + mRunningOpIds.valueAt(
                                         i)));
 
@@ -1157,7 +1138,7 @@
                     if (ri == null) {
                         Slog.w(TAG, mPuuid + ": " + mServiceName + " not found");
 
-                        sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                        mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                 + ": " + mServiceName + " not found"));
 
                         return;
@@ -1168,7 +1149,7 @@
                         Slog.w(TAG, mPuuid + ": " + mServiceName + " does not require "
                                 + BIND_SOUND_TRIGGER_DETECTION_SERVICE);
 
-                        sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                        mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                 + ": " + mServiceName + " does not require "
                                 + BIND_SOUND_TRIGGER_DETECTION_SERVICE));
 
@@ -1184,7 +1165,7 @@
                     } else {
                         Slog.w(TAG, mPuuid + ": Could not bind to " + mServiceName);
 
-                        sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                        mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                 + ": Could not bind to " + mServiceName));
 
                     }
@@ -1206,7 +1187,7 @@
                                 mPuuid + ": Dropped operation as already destroyed or marked for "
                                         + "destruction");
 
-                        sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                        mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                 + ":Dropped operation as already destroyed or marked for "
                                 + "destruction"));
 
@@ -1238,7 +1219,7 @@
                                             mPuuid + ": Dropped operation as too many operations "
                                                     + "were run in last 24 hours");
 
-                                    sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                                    mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                             + ": Dropped operation as too many operations "
                                             + "were run in last 24 hours"));
 
@@ -1248,7 +1229,7 @@
                             } catch (Exception e) {
                                 Slog.e(TAG, mPuuid + ": Could not drop operation", e);
 
-                                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                                mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                         + ": Could not drop operation"));
 
                             }
@@ -1265,7 +1246,7 @@
                             try {
                                 if (DEBUG) Slog.v(TAG, mPuuid + ": runOp " + opId);
 
-                                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                                mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                         + ": runOp " + opId));
 
                                 op.run(opId, mService);
@@ -1273,7 +1254,7 @@
                             } catch (Exception e) {
                                 Slog.e(TAG, mPuuid + ": Could not run operation " + opId, e);
 
-                                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                                mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                                         + ": Could not run operation " + opId));
 
                             }
@@ -1303,11 +1284,6 @@
 
             @Override
             public void onKeyphraseDetected(SoundTrigger.KeyphraseRecognitionEvent event) {
-                Slog.w(TAG, mPuuid + "->" + mServiceName + ": IGNORED onKeyphraseDetected(" + event
-                        + ")");
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid + "->" + mServiceName
-                        + ": IGNORED onKeyphraseDetected(" + event + ")"));
             }
 
             /**
@@ -1325,7 +1301,7 @@
 
                 AudioFormat originalFormat = event.getCaptureFormat();
 
-                sEventLogger.enqueue(new EventLogger.StringEvent("createAudioRecordForEvent"));
+                mEventLogger.enqueue(new EventLogger.StringEvent("createAudioRecordForEvent"));
 
                 return (new AudioRecord.Builder())
                             .setAudioAttributes(attributes)
@@ -1340,11 +1316,6 @@
 
             @Override
             public void onGenericSoundTriggerDetected(SoundTrigger.GenericRecognitionEvent event) {
-                if (DEBUG) Slog.v(TAG, mPuuid + ": Generic sound trigger event: " + event);
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
-                        + ": Generic sound trigger event: " + event));
-
                 runOrAddOperation(new Operation(
                         // always execute:
                         () -> {
@@ -1376,7 +1347,7 @@
             private void onError(int status) {
                 if (DEBUG) Slog.v(TAG, mPuuid + ": onError: " + status);
 
-                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                         + ": onError: " + status));
 
                 runOrAddOperation(
@@ -1421,27 +1392,17 @@
 
             @Override
             public void onRecognitionPaused() {
-                Slog.i(TAG, mPuuid + "->" + mServiceName + ": IGNORED onRecognitionPaused");
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
-                        + "->" + mServiceName + ": IGNORED onRecognitionPaused"));
-
             }
 
             @Override
             public void onRecognitionResumed() {
-                Slog.i(TAG, mPuuid + "->" + mServiceName + ": IGNORED onRecognitionResumed");
-
-                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
-                        + "->" + mServiceName + ": IGNORED onRecognitionResumed"));
-
             }
 
             @Override
             public void onServiceConnected(ComponentName name, IBinder service) {
                 if (DEBUG) Slog.v(TAG, mPuuid + ": onServiceConnected(" + service + ")");
 
-                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                         + ": onServiceConnected(" + service + ")"));
 
                 synchronized (mRemoteServiceLock) {
@@ -1464,7 +1425,7 @@
             public void onServiceDisconnected(ComponentName name) {
                 if (DEBUG) Slog.v(TAG, mPuuid + ": onServiceDisconnected");
 
-                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                         + ": onServiceDisconnected"));
 
                 synchronized (mRemoteServiceLock) {
@@ -1476,7 +1437,7 @@
             public void onBindingDied(ComponentName name) {
                 if (DEBUG) Slog.v(TAG, mPuuid + ": onBindingDied");
 
-                sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
+                mEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
                         + ": onBindingDied"));
 
                 synchronized (mRemoteServiceLock) {
@@ -1488,7 +1449,7 @@
             public void onNullBinding(ComponentName name) {
                 Slog.w(TAG, name + " for model " + mPuuid + " returned a null binding");
 
-                sEventLogger.enqueue(new EventLogger.StringEvent(name + " for model "
+                mEventLogger.enqueue(new EventLogger.StringEvent(name + " for model "
                         + mPuuid + " returned a null binding"));
 
                 synchronized (mRemoteServiceLock) {
@@ -1613,17 +1574,25 @@
         private class SessionImpl implements Session {
             private final @NonNull SoundTriggerHelper mSoundTriggerHelper;
             private final @NonNull IBinder mClient;
+            private final EventLogger mEventLogger;
+            private final Identity mOriginatorIdentity;
 
-            private SessionImpl(
-                    @NonNull SoundTriggerHelper soundTriggerHelper, @NonNull IBinder client) {
+            private final SparseArray<UUID> mModelUuid = new SparseArray<>(1);
+
+            private SessionImpl(@NonNull SoundTriggerHelper soundTriggerHelper,
+                    @NonNull IBinder client,
+                    @NonNull EventLogger eventLogger, @NonNull Identity originatorIdentity) {
+
                 mSoundTriggerHelper = soundTriggerHelper;
                 mClient = client;
+                mOriginatorIdentity = originatorIdentity;
+                mEventLogger = eventLogger;
+
+                mSessionEventLoggers.add(mEventLogger);
                 try {
-                    mClient.linkToDeath(() -> {
-                        clientDied();
-                    }, 0);
+                    mClient.linkToDeath(() -> clientDied(), 0);
                 } catch (RemoteException e) {
-                    Slog.e(TAG, "Failed to register death listener.", e);
+                    clientDied();
                 }
             }
 
@@ -1631,6 +1600,9 @@
             public int startRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
                     IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig,
                     boolean runInBatterySaverMode) {
+                mModelUuid.put(keyphraseId, soundModel.getUuid());
+                mEventLogger.enqueue(new SessionEvent(Type.START_RECOGNITION,
+                            soundModel.getUuid()));
                 return mSoundTriggerHelper.startKeyphraseRecognition(keyphraseId, soundModel,
                         listener, recognitionConfig, runInBatterySaverMode);
             }
@@ -1638,16 +1610,21 @@
             @Override
             public synchronized int stopRecognition(int keyphraseId,
                     IRecognitionStatusCallback listener) {
+                var uuid = mModelUuid.get(keyphraseId);
+                mEventLogger.enqueue(new SessionEvent(Type.STOP_RECOGNITION, uuid));
                 return mSoundTriggerHelper.stopKeyphraseRecognition(keyphraseId, listener);
             }
 
             @Override
             public ModuleProperties getModuleProperties() {
+                mEventLogger.enqueue(new SessionEvent(Type.GET_MODULE_PROPERTIES, null));
                 return mSoundTriggerHelper.getModuleProperties();
             }
 
             @Override
             public int setParameter(int keyphraseId, @ModelParams int modelParam, int value) {
+                var uuid = mModelUuid.get(keyphraseId);
+                mEventLogger.enqueue(new SessionEvent(Type.SET_PARAMETER, uuid));
                 return mSoundTriggerHelper.setKeyphraseParameter(keyphraseId, modelParam, value);
             }
 
@@ -1663,53 +1640,54 @@
             }
 
             @Override
-            public int unloadKeyphraseModel(int keyphraseId) {
-                return mSoundTriggerHelper.unloadKeyphraseSoundModel(keyphraseId);
+            public void detach() {
+                detachInternal();
             }
 
             @Override
-            public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-                mSoundTriggerHelper.dump(fd, pw, args);
+            public int unloadKeyphraseModel(int keyphraseId) {
+                var uuid = mModelUuid.get(keyphraseId);
+                mEventLogger.enqueue(new SessionEvent(Type.UNLOAD_MODEL, uuid));
+                return mSoundTriggerHelper.unloadKeyphraseSoundModel(keyphraseId);
             }
 
             private void clientDied() {
-                Slog.w(TAG, "Client died, cleaning up session.");
-                sEventLogger.enqueue(new EventLogger.StringEvent(
-                        "Client died, cleaning up session."));
+                mServiceEventLogger.enqueue(new ServiceEvent(
+                            ServiceEvent.Type.DETACH, mOriginatorIdentity.packageName,
+                            "Client died")
+                        .printLog(ALOGW, TAG));
+                detachInternal();
+            }
+
+            private void detachInternal() {
+                mEventLogger.enqueue(new SessionEvent(Type.DETACH, null));
+                detachSessionLogger(mEventLogger);
                 mSoundTriggerHelper.detach();
             }
         }
 
         @Override
         public Session attach(@NonNull IBinder client, ModuleProperties underlyingModule) {
-            return new SessionImpl(newSoundTriggerHelper(underlyingModule), client);
+            var identity = IdentityContext.getNonNull();
+            int sessionId = mSessionIdCounter.getAndIncrement();
+            mServiceEventLogger.enqueue(new ServiceEvent(
+                        ServiceEvent.Type.ATTACH, identity.packageName + "#" + sessionId));
+            var eventLogger = new EventLogger(SESSION_MAX_EVENT_SIZE,
+                    "LocalSoundTriggerEventLogger for package: " +
+                    identity.packageName + "#" + sessionId);
+
+            return new SessionImpl(newSoundTriggerHelper(underlyingModule, eventLogger),
+                    client, eventLogger, identity);
         }
 
         @Override
         public List<ModuleProperties> listModuleProperties(Identity originatorIdentity) {
+            mServiceEventLogger.enqueue(new ServiceEvent(
+                    ServiceEvent.Type.LIST_MODULE, originatorIdentity.packageName));
             try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
                     originatorIdentity)) {
                 return listUnderlyingModuleProperties(originatorIdentity);
             }
         }
-
-        @Override
-        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            // log
-            sEventLogger.dump(pw);
-
-            // enrolled models
-            mDbHelper.dump(pw);
-
-            // stats
-            mSoundModelStatTracker.dump(pw);
-        }
     }
-
-    //=================================================================
-    // For logging
-
-    private static final EventLogger sEventLogger = new EventLogger(200,
-            "SoundTrigger activity");
-
 }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/ObjectPrinter.java b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/ObjectPrinter.java
index fba0fb4..cbc959c 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/ObjectPrinter.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/ObjectPrinter.java
@@ -45,6 +45,16 @@
     }
 
     /**
+     * Same as {@link #print(StringBuilder, Object, int)} with default max length.
+     *
+     * @param builder             StringBuilder to print into.
+     * @param obj                 The object to print.
+     */
+    static void print(@NonNull StringBuilder builder, @Nullable Object obj) {
+        print(builder, obj, kDefaultMaxCollectionLength);
+    }
+
+    /**
      * A version of {@link #print(Object, int)} that uses a {@link StringBuilder}.
      *
      * @param builder             StringBuilder to print into.
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java
index 4c134af..0e796d1 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java
@@ -16,6 +16,10 @@
 
 package com.android.server.soundtrigger_middleware;
 
+import static com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareLogging.SessionEvent.Type.*;
+import static com.android.server.utils.EventLogger.Event.ALOGI;
+import static com.android.server.utils.EventLogger.Event.ALOGW;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -41,13 +45,20 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.LatencyTracker;
 import com.android.server.LocalServices;
+import com.android.server.utils.EventLogger.Event;
+import com.android.server.utils.EventLogger;
+
 
 import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.LinkedList;
+import java.util.Arrays;
 import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Supplier;
+import java.util.Deque;
+
 
 /**
  * An ISoundTriggerMiddlewareService decorator, which adds logging of all API calls (and
@@ -74,9 +85,17 @@
  */
 public class SoundTriggerMiddlewareLogging implements ISoundTriggerMiddlewareInternal, Dumpable {
     private static final String TAG = "SoundTriggerMiddlewareLogging";
+    private static final int SESSION_MAX_EVENT_SIZE = 128;
     private final @NonNull ISoundTriggerMiddlewareInternal mDelegate;
     private final @NonNull LatencyTracker mLatencyTracker;
     private final @NonNull Supplier<BatteryStatsInternal> mBatteryStatsInternalSupplier;
+    private final @NonNull EventLogger mServiceEventLogger = new EventLogger(256,
+            "Service Events");
+
+    private final Set<EventLogger> mSessionEventLoggers = ConcurrentHashMap.newKeySet(4);
+    private final Deque<EventLogger> mDetachedSessionEventLoggers = new LinkedBlockingDeque<>(4);
+    private final AtomicInteger mSessionCount = new AtomicInteger(0);
+
 
     public SoundTriggerMiddlewareLogging(@NonNull Context context,
             @NonNull ISoundTriggerMiddlewareInternal delegate) {
@@ -99,10 +118,19 @@
     SoundTriggerModuleDescriptor[] listModules() {
         try {
             SoundTriggerModuleDescriptor[] result = mDelegate.listModules();
-            logReturn("listModules", result);
+            var moduleSummary = Arrays.stream(result).map((descriptor) ->
+                    new ModulePropertySummary(descriptor.handle,
+                        descriptor.properties.implementor,
+                        descriptor.properties.version)).toArray(ModulePropertySummary[]::new);
+
+            mServiceEventLogger.enqueue(ServiceEvent.createForReturn(
+                        ServiceEvent.Type.LIST_MODULE,
+                        IdentityContext.get().packageName, moduleSummary).printLog(ALOGI, TAG));
             return result;
         } catch (Exception e) {
-            logException("listModules", e);
+            mServiceEventLogger.enqueue(ServiceEvent.createForException(
+                        ServiceEvent.Type.LIST_MODULE,
+                        IdentityContext.get().packageName, e).printLog(ALOGW, TAG));
             throw e;
         }
     }
@@ -111,12 +139,29 @@
     public @NonNull
     ISoundTriggerModule attach(int handle, ISoundTriggerCallback callback) {
         try {
-            ModuleLogging result = new ModuleLogging(callback);
-            result.attach(mDelegate.attach(handle, result.getCallbackWrapper()));
-            logReturn("attach", result, handle, callback);
+            var originatorIdentity = IdentityContext.getNonNull();
+            String packageIdentification = originatorIdentity.packageName
+                    + mSessionCount.getAndIncrement();
+            ModuleLogging result = new ModuleLogging();
+            var eventLogger = new EventLogger(SESSION_MAX_EVENT_SIZE,
+                "Session logger for: " + packageIdentification);
+
+            var callbackWrapper = new CallbackLogging(callback, eventLogger, originatorIdentity);
+
+            result.attach(mDelegate.attach(handle, callbackWrapper), eventLogger);
+
+            mServiceEventLogger.enqueue(ServiceEvent.createForReturn(
+                        ServiceEvent.Type.ATTACH,
+                        packageIdentification, result, handle, callback)
+                    .printLog(ALOGI, TAG));
+
+            mSessionEventLoggers.add(eventLogger);
             return result;
         } catch (Exception e) {
-            logException("attach", e, handle, callback);
+            mServiceEventLogger.enqueue(ServiceEvent.createForException(
+                        ServiceEvent.Type.ATTACH,
+                        IdentityContext.get().packageName, e, handle, callback)
+                    .printLog(ALOGW, TAG));
             throw e;
         }
     }
@@ -127,44 +172,27 @@
         return mDelegate.toString();
     }
 
-    private void logException(String methodName, Exception ex, Object... args) {
-        logExceptionWithObject(this, IdentityContext.get(), methodName, ex, args);
-    }
-
-    private void logReturn(String methodName, Object retVal, Object... args) {
-        logReturnWithObject(this, IdentityContext.get(), methodName, retVal, args);
-    }
-
-    private void logVoidReturn(String methodName, Object... args) {
-        logVoidReturnWithObject(this, IdentityContext.get(), methodName, args);
-    }
-
     private class ModuleLogging implements ISoundTriggerModule {
         private ISoundTriggerModule mDelegate;
-        private final @NonNull CallbackLogging mCallbackWrapper;
-        private final @NonNull Identity mOriginatorIdentity;
+        private EventLogger mEventLogger;
 
-        ModuleLogging(@NonNull ISoundTriggerCallback callback) {
-            mCallbackWrapper = new CallbackLogging(callback);
-            mOriginatorIdentity = IdentityContext.getNonNull();
-        }
-
-        void attach(@NonNull ISoundTriggerModule delegate) {
+        void attach(@NonNull ISoundTriggerModule delegate, EventLogger eventLogger) {
             mDelegate = delegate;
-        }
-
-        ISoundTriggerCallback getCallbackWrapper() {
-            return mCallbackWrapper;
+            mEventLogger = eventLogger;
         }
 
         @Override
         public int loadModel(SoundModel model) throws RemoteException {
             try {
                 int result = mDelegate.loadModel(model);
-                logReturn("loadModel", result, model);
+                mEventLogger.enqueue(SessionEvent.createForReturn(
+                            LOAD_MODEL, result, model.uuid)
+                        .printLog(ALOGI, TAG));
                 return result;
             } catch (Exception e) {
-                logException("loadModel", e, model);
+                mEventLogger.enqueue(SessionEvent.createForReturn(
+                            LOAD_MODEL, e, model.uuid)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -173,10 +201,14 @@
         public int loadPhraseModel(PhraseSoundModel model) throws RemoteException {
             try {
                 int result = mDelegate.loadPhraseModel(model);
-                logReturn("loadPhraseModel", result, model);
+                mEventLogger.enqueue(SessionEvent.createForReturn(
+                            LOAD_PHRASE_MODEL, result, model.common.uuid)
+                        .printLog(ALOGI, TAG));
                 return result;
             } catch (Exception e) {
-                logException("loadPhraseModel", e, model);
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            LOAD_PHRASE_MODEL, e, model.common.uuid)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -185,9 +217,13 @@
         public void unloadModel(int modelHandle) throws RemoteException {
             try {
                 mDelegate.unloadModel(modelHandle);
-                logVoidReturn("unloadModel", modelHandle);
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            UNLOAD_MODEL, modelHandle)
+                        .printLog(ALOGI, TAG));
             } catch (Exception e) {
-                logException("unloadModel", e, modelHandle);
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            UNLOAD_MODEL, e, modelHandle)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -197,9 +233,13 @@
                 throws RemoteException {
             try {
                 mDelegate.startRecognition(modelHandle, config);
-                logVoidReturn("startRecognition", modelHandle, config);
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            START_RECOGNITION, modelHandle, config)
+                        .printLog(ALOGI, TAG));
             } catch (Exception e) {
-                logException("startRecognition", e, modelHandle, config);
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            START_RECOGNITION, e, modelHandle, config)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -208,9 +248,13 @@
         public void stopRecognition(int modelHandle) throws RemoteException {
             try {
                 mDelegate.stopRecognition(modelHandle);
-                logVoidReturn("stopRecognition", modelHandle);
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            STOP_RECOGNITION, modelHandle)
+                        .printLog(ALOGI, TAG));
             } catch (Exception e) {
-                logException("stopRecognition", e, modelHandle);
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            STOP_RECOGNITION, e, modelHandle)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -219,9 +263,13 @@
         public void forceRecognitionEvent(int modelHandle) throws RemoteException {
             try {
                 mDelegate.forceRecognitionEvent(modelHandle);
-                logVoidReturn("forceRecognitionEvent", modelHandle);
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            FORCE_RECOGNITION, modelHandle)
+                        .printLog(ALOGI, TAG));
             } catch (Exception e) {
-                logException("forceRecognitionEvent", e, modelHandle);
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            FORCE_RECOGNITION, e, modelHandle)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -231,9 +279,13 @@
                 throws RemoteException {
             try {
                 mDelegate.setModelParameter(modelHandle, modelParam, value);
-                logVoidReturn("setModelParameter", modelHandle, modelParam, value);
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            SET_MODEL_PARAMETER, modelHandle, modelParam, value)
+                        .printLog(ALOGI, TAG));
             } catch (Exception e) {
-                logException("setModelParameter", e, modelHandle, modelParam, value);
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            SET_MODEL_PARAMETER, e, modelHandle, modelParam, value)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -242,10 +294,14 @@
         public int getModelParameter(int modelHandle, int modelParam) throws RemoteException {
             try {
                 int result = mDelegate.getModelParameter(modelHandle, modelParam);
-                logReturn("getModelParameter", result, modelHandle, modelParam);
+                mEventLogger.enqueue(SessionEvent.createForReturn(
+                            GET_MODEL_PARAMETER, result, modelHandle, modelParam)
+                        .printLog(ALOGI, TAG));
                 return result;
             } catch (Exception e) {
-                logException("getModelParameter", e, modelHandle, modelParam);
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            GET_MODEL_PARAMETER, e, modelHandle, modelParam)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -256,10 +312,14 @@
             try {
                 ModelParameterRange result = mDelegate.queryModelParameterSupport(modelHandle,
                         modelParam);
-                logReturn("queryModelParameterSupport", result, modelHandle, modelParam);
+                mEventLogger.enqueue(SessionEvent.createForReturn(
+                            QUERY_MODEL_PARAMETER, result, modelHandle, modelParam)
+                        .printLog(ALOGI, TAG));
                 return result;
             } catch (Exception e) {
-                logException("queryModelParameterSupport", e, modelHandle, modelParam);
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            QUERY_MODEL_PARAMETER, e, modelHandle, modelParam)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -267,10 +327,20 @@
         @Override
         public void detach() throws RemoteException {
             try {
+                if (mSessionEventLoggers.remove(mEventLogger)) {
+                    while (!mDetachedSessionEventLoggers.offerFirst(mEventLogger)) {
+                        // Remove the oldest element, if one still exists
+                        mDetachedSessionEventLoggers.pollLast();
+                    }
+                }
                 mDelegate.detach();
-                logVoidReturn("detach");
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            DETACH)
+                        .printLog(ALOGI, TAG));
             } catch (Exception e) {
-                logException("detach", e);
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            DETACH, e)
+                        .printLog(ALOGW, TAG));
                 throw e;
             }
         }
@@ -285,107 +355,112 @@
         public String toString() {
             return Objects.toString(mDelegate);
         }
+    }
 
-        private void logException(String methodName, Exception ex, Object... args) {
-            logExceptionWithObject(this, mOriginatorIdentity, methodName, ex, args);
+    private class CallbackLogging implements ISoundTriggerCallback {
+        private final ISoundTriggerCallback mCallbackDelegate;
+        private final EventLogger mEventLogger;
+        private final Identity mOriginatorIdentity;
+
+        private CallbackLogging(ISoundTriggerCallback delegate,
+                EventLogger eventLogger, Identity originatorIdentity) {
+            mCallbackDelegate = Objects.requireNonNull(delegate);
+            mEventLogger = Objects.requireNonNull(eventLogger);
+            mOriginatorIdentity = originatorIdentity;
         }
 
-        private void logReturn(String methodName, Object retVal, Object... args) {
-            logReturnWithObject(this, mOriginatorIdentity, methodName, retVal, args);
+        @Override
+        public void onRecognition(int modelHandle, RecognitionEvent event, int captureSession)
+                throws RemoteException {
+            try {
+                mBatteryStatsInternalSupplier.get().noteWakingSoundTrigger(
+                        SystemClock.elapsedRealtime(), mOriginatorIdentity.uid);
+                mCallbackDelegate.onRecognition(modelHandle, event, captureSession);
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            RECOGNITION, modelHandle, event, captureSession)
+                        .printLog(ALOGI, TAG));
+            } catch (Exception e) {
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            RECOGNITION, e, modelHandle, event, captureSession)
+                        .printLog(ALOGW, TAG));
+                throw e;
+            }
         }
 
-        private void logVoidReturn(String methodName, Object... args) {
-            logVoidReturnWithObject(this, mOriginatorIdentity, methodName, args);
+        @Override
+        public void onPhraseRecognition(int modelHandle, PhraseRecognitionEvent event,
+                int captureSession)
+                throws RemoteException {
+            try {
+                mBatteryStatsInternalSupplier.get().noteWakingSoundTrigger(
+                        SystemClock.elapsedRealtime(), mOriginatorIdentity.uid);
+                startKeyphraseEventLatencyTracking(event);
+                mCallbackDelegate.onPhraseRecognition(modelHandle, event, captureSession);
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            RECOGNITION, modelHandle, event, captureSession)
+                        .printLog(ALOGI, TAG));
+            } catch (Exception e) {
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            RECOGNITION, e, modelHandle, event, captureSession)
+                        .printLog(ALOGW, TAG));
+                throw e;
+            }
         }
 
-        private class CallbackLogging implements ISoundTriggerCallback {
-            private final ISoundTriggerCallback mCallbackDelegate;
-
-            private CallbackLogging(ISoundTriggerCallback delegate) {
-                mCallbackDelegate = delegate;
+        @Override
+        public void onModelUnloaded(int modelHandle) throws RemoteException {
+            try {
+                mCallbackDelegate.onModelUnloaded(modelHandle);
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            MODEL_UNLOADED, modelHandle)
+                        .printLog(ALOGI, TAG));
+            } catch (Exception e) {
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            MODEL_UNLOADED, e, modelHandle)
+                        .printLog(ALOGW, TAG));
+                throw e;
             }
+        }
 
-            @Override
-            public void onRecognition(int modelHandle, RecognitionEvent event, int captureSession)
-                    throws RemoteException {
-                try {
-                    mBatteryStatsInternalSupplier.get().noteWakingSoundTrigger(
-                            SystemClock.elapsedRealtime(), mOriginatorIdentity.uid);
-                    mCallbackDelegate.onRecognition(modelHandle, event, captureSession);
-                    logVoidReturn("onRecognition", modelHandle, event);
-                } catch (Exception e) {
-                    logException("onRecognition", e, modelHandle, event);
-                    throw e;
-                }
+        @Override
+        public void onResourcesAvailable() throws RemoteException {
+            try {
+                mCallbackDelegate.onResourcesAvailable();
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            RESOURCES_AVAILABLE)
+                        .printLog(ALOGI, TAG));
+            } catch (Exception e) {
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            RESOURCES_AVAILABLE, e)
+                        .printLog(ALOGW, TAG));
+                throw e;
             }
+        }
 
-            @Override
-            public void onPhraseRecognition(int modelHandle, PhraseRecognitionEvent event,
-                    int captureSession)
-                    throws RemoteException {
-                try {
-                    mBatteryStatsInternalSupplier.get().noteWakingSoundTrigger(
-                            SystemClock.elapsedRealtime(), mOriginatorIdentity.uid);
-                    startKeyphraseEventLatencyTracking(event);
-                    mCallbackDelegate.onPhraseRecognition(modelHandle, event, captureSession);
-                    logVoidReturn("onPhraseRecognition", modelHandle, event);
-                } catch (Exception e) {
-                    logException("onPhraseRecognition", e, modelHandle, event);
-                    throw e;
-                }
+        @Override
+        public void onModuleDied() throws RemoteException {
+            try {
+                mCallbackDelegate.onModuleDied();
+                mEventLogger.enqueue(SessionEvent.createForVoid(
+                            MODULE_DIED)
+                        .printLog(ALOGW, TAG));
+            } catch (Exception e) {
+                mEventLogger.enqueue(SessionEvent.createForException(
+                            MODULE_DIED, e)
+                        .printLog(ALOGW, TAG));
+                throw e;
             }
+        }
 
-            @Override
-            public void onModelUnloaded(int modelHandle) throws RemoteException {
-                try {
-                    mCallbackDelegate.onModelUnloaded(modelHandle);
-                    logVoidReturn("onModelUnloaded", modelHandle);
-                } catch (Exception e) {
-                    logException("onModelUnloaded", e, modelHandle);
-                    throw e;
-                }
-            }
+        @Override
+        public IBinder asBinder() {
+            return mCallbackDelegate.asBinder();
+        }
 
-            @Override
-            public void onResourcesAvailable() throws RemoteException {
-                try {
-                    mCallbackDelegate.onResourcesAvailable();
-                    logVoidReturn("onResourcesAvailable");
-                } catch (Exception e) {
-                    logException("onResourcesAvailable", e);
-                    throw e;
-                }
-            }
-
-            @Override
-            public void onModuleDied() throws RemoteException {
-                try {
-                    mCallbackDelegate.onModuleDied();
-                    logVoidReturn("onModuleDied");
-                } catch (Exception e) {
-                    logException("onModuleDied", e);
-                    throw e;
-                }
-            }
-
-            private void logException(String methodName, Exception ex, Object... args) {
-                logExceptionWithObject(this, mOriginatorIdentity, methodName, ex, args);
-            }
-
-            private void logVoidReturn(String methodName, Object... args) {
-                logVoidReturnWithObject(this, mOriginatorIdentity, methodName, args);
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return mCallbackDelegate.asBinder();
-            }
-
-            // Override toString() in order to have the delegate's ID in it.
-            @Override
-            public String toString() {
-                return Objects.toString(mCallbackDelegate);
-            }
+        // Override toString() in order to have the delegate's ID in it.
+        @Override
+        public String toString() {
+            return Objects.toString(mCallbackDelegate);
         }
     }
 
@@ -418,105 +493,193 @@
                 latencyTrackerTag);
     }
 
-    ////////////////////////////////////////////////////////////////////////////////////////////////
-    // Actual logging logic below.
-    private static final int NUM_EVENTS_TO_DUMP = 64;
-    private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
-    private final @NonNull LinkedList<Event> mLastEvents = new LinkedList<>();
-
-    static private class Event {
-        public final long timestamp = System.currentTimeMillis();
-        public final String message;
-
-        private Event(String message) {
-            this.message = message;
-        }
-    }
-
-    private static String printArgs(@NonNull Object[] args) {
-        StringBuilder result = new StringBuilder();
+    private static StringBuilder printArgs(StringBuilder builder, @NonNull Object[] args) {
         for (int i = 0; i < args.length; ++i) {
             if (i > 0) {
-                result.append(", ");
+                builder.append(", ");
             }
-            printObject(result, args[i]);
+            ObjectPrinter.print(builder, args[i]);
         }
-        return result.toString();
-    }
-
-    private static void printObject(@NonNull StringBuilder builder, @Nullable Object obj) {
-        ObjectPrinter.print(builder, obj, 16);
-    }
-
-    private static String printObject(@Nullable Object obj) {
-        StringBuilder builder = new StringBuilder();
-        printObject(builder, obj);
-        return builder.toString();
-    }
-
-    private void logReturnWithObject(@NonNull Object object, @Nullable Identity originatorIdentity,
-            String methodName,
-            @Nullable Object retVal,
-            @NonNull Object[] args) {
-        final String message = String.format("%s[this=%s, client=%s](%s) -> %s", methodName,
-                object,
-                printObject(originatorIdentity),
-                printArgs(args),
-                printObject(retVal));
-        Slog.i(TAG, message);
-        appendMessage(message);
-    }
-
-    private void logVoidReturnWithObject(@NonNull Object object,
-            @Nullable Identity originatorIdentity, @NonNull String methodName,
-            @NonNull Object[] args) {
-        final String message = String.format("%s[this=%s, client=%s](%s)", methodName,
-                object,
-                printObject(originatorIdentity),
-                printArgs(args));
-        Slog.i(TAG, message);
-        appendMessage(message);
-    }
-
-    private void logExceptionWithObject(@NonNull Object object,
-            @Nullable Identity originatorIdentity, @NonNull String methodName,
-            @NonNull Exception ex,
-            Object[] args) {
-        final String message = String.format("%s[this=%s, client=%s](%s) threw", methodName,
-                object,
-                printObject(originatorIdentity),
-                printArgs(args));
-        Slog.e(TAG, message, ex);
-        appendMessage(message + " " + ex.toString());
-    }
-
-    private void appendMessage(@NonNull String message) {
-        Event event = new Event(message);
-        synchronized (mLastEvents) {
-            if (mLastEvents.size() > NUM_EVENTS_TO_DUMP) {
-                mLastEvents.remove();
-            }
-            mLastEvents.add(event);
-        }
+        return builder;
     }
 
     @Override
     public void dump(PrintWriter pw) {
-        pw.println();
-        pw.println("=========================================");
-        pw.println("Last events");
-        pw.println("=========================================");
-        synchronized (mLastEvents) {
-            for (Event event : mLastEvents) {
-                pw.print(DATE_FORMAT.format(new Date(event.timestamp)));
-                pw.print('\t');
-                pw.println(event.message);
-            }
+        // Event loggers
+        pw.println("##Service-Wide logs:");
+        mServiceEventLogger.dump(pw, /* indent = */ "  ");
+
+        pw.println("\n##Active Session dumps:\n");
+        for (var sessionLogger : mSessionEventLoggers) {
+            sessionLogger.dump(pw, /* indent= */ "  ");
+            pw.println("");
         }
-        pw.println();
+        pw.println("##Detached Session dumps:\n");
+        for (var sessionLogger : mDetachedSessionEventLoggers) {
+            sessionLogger.dump(pw, /* indent= */ "  ");
+            pw.println("");
+        }
 
         if (mDelegate instanceof Dumpable) {
             ((Dumpable) mDelegate).dump(pw);
         }
     }
+
+    public static void printSystemLog(int type, String tag, String message, Exception e) {
+        switch (type) {
+            case Event.ALOGI:
+                Slog.i(tag, message, e);
+                break;
+            case Event.ALOGE:
+                Slog.e(tag, message, e);
+                break;
+            case Event.ALOGW:
+                Slog.w(tag, message, e);
+                break;
+            case Event.ALOGV:
+            default:
+                Slog.v(tag, message, e);
+        }
+    }
+
+    public static class ServiceEvent extends Event {
+        private final Type mType;
+        private final String mPackageName;
+        private final Object mReturnValue;
+        private final Object[] mParams;
+        private final Exception mException;
+
+        public enum Type {
+            ATTACH,
+            LIST_MODULE,
+        }
+
+        public static ServiceEvent createForException(Type type, String packageName,
+                Exception exception, Object... params) {
+            return new ServiceEvent(exception, type, packageName, null, params);
+        }
+
+        public static ServiceEvent createForReturn(Type type, String packageName,
+                Object returnValue, Object... params) {
+            return new ServiceEvent(null , type, packageName, returnValue, params);
+        }
+
+        private ServiceEvent(Exception exception, Type type, String packageName, Object returnValue,
+                Object... params) {
+            mException = exception;
+            mType = type;
+            mPackageName = packageName;
+            mReturnValue = returnValue;
+            mParams = params;
+        }
+
+        @Override
+        public Event printLog(int type, String tag) {
+            printSystemLog(type, tag, eventToString(), mException);
+            return this;
+        }
+
+        @Override
+        public String eventToString() {
+            var sb = new StringBuilder(mType.name()).append(" [client= ");
+            ObjectPrinter.print(sb, mPackageName);
+            sb.append("] (");
+            printArgs(sb, mParams);
+            sb.append(") -> ");
+            if (mException != null) {
+                sb.append("ERROR: ");
+                ObjectPrinter.print(sb, mException);
+            } else {
+                ObjectPrinter.print(sb, mReturnValue);
+            }
+            return sb.toString();
+        }
+    }
+
+    public static class SessionEvent extends Event {
+        public enum Type {
+            LOAD_MODEL,
+            LOAD_PHRASE_MODEL,
+            START_RECOGNITION,
+            STOP_RECOGNITION,
+            FORCE_RECOGNITION,
+            UNLOAD_MODEL,
+            GET_MODEL_PARAMETER,
+            SET_MODEL_PARAMETER,
+            QUERY_MODEL_PARAMETER,
+            DETACH,
+            RECOGNITION,
+            MODEL_UNLOADED,
+            MODULE_DIED,
+            RESOURCES_AVAILABLE,
+        }
+
+        private final Type mType;
+        private final Exception mException;
+        private final Object mReturnValue;
+        private final Object[] mParams;
+
+        public static SessionEvent createForException(Type type, Exception exception,
+                Object... params) {
+            return new SessionEvent(exception, type, null, params);
+        }
+
+        public static SessionEvent createForReturn(Type type,
+                Object returnValue, Object... params) {
+            return new SessionEvent(null , type, returnValue, params);
+        }
+
+        public static SessionEvent createForVoid(Type type, Object... params) {
+            return new SessionEvent(null, type, null, params);
+        }
+
+
+        private SessionEvent(Exception exception, Type type, Object returnValue,
+                Object... params) {
+            mException = exception;
+            mType = type;
+            mReturnValue = returnValue;
+            mParams = params;
+        }
+
+        @Override
+        public Event printLog(int type, String tag) {
+            printSystemLog(type, tag, eventToString(), mException);
+            return this;
+        }
+
+        @Override
+        public String eventToString() {
+            var sb = new StringBuilder(mType.name());
+            sb.append(" (");
+            printArgs(sb, mParams);
+            sb.append(")");
+            if (mException != null) {
+                sb.append(" -> ERROR: ");
+                ObjectPrinter.print(sb, mException);
+            } else if (mReturnValue != null) {
+                sb.append(" -> ");
+                ObjectPrinter.print(sb, mReturnValue);
+            }
+            return sb.toString();
+        }
+    }
+
+    private static final class ModulePropertySummary {
+        private int mId;
+        private String mImplementor;
+        private int mVersion;
+
+        ModulePropertySummary(int id, String implementor, int version) {
+            mId = id;
+            mImplementor = implementor;
+            mVersion = version;
+        }
+
+        @Override
+       public String toString() {
+           return "{Id: " + mId + ", Implementor: " + mImplementor
+               + ", Version: " + mVersion + "}";
+       }
+    }
 }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
index 13fe14c..00cedd7 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
@@ -78,7 +78,7 @@
     public @NonNull
     SoundTriggerModuleDescriptor[] listModules() {
         Identity identity = getIdentity();
-        enforcePermissionsForPreflight(identity);
+        enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD);
         return mDelegate.listModules();
     }
 
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java
index 2413072..65c95d1 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordAudioStreamCopier.java
@@ -339,7 +339,11 @@
             } catch (IOException e) {
                 mAudioSource.closeWithError(e.getMessage());
                 mAudioSink.closeWithError(e.getMessage());
-                Slog.e(TAG, mStreamTaskId + ": Failed to copy audio stream", e);
+                // This is expected when VIS closes the read side of the pipe on their end,
+                // so when the HotwordAudioStreamCopier tries to write, we will get that broken
+                // pipe error. HDS is also closing the write side of the pipe (the system is on the
+                // read end of that pipe).
+                Slog.i(TAG, mStreamTaskId + ": Failed to copy audio stream", e);
                 HotwordMetricsLogger.writeAudioEgressEvent(mDetectorType,
                         HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__EVENT__CLOSE_ERROR_FROM_SYSTEM,
                         mUid, /* streamSizeBytes= */ 0, /* bundleSizeBytes= */ 0,
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 486945d..edaaf3f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -913,8 +913,10 @@
         }
         // Handle case where all hotword detector sessions are destroyed with only the visual
         // detector session left
-        if (mDetectorSessions.size() == 1
-                && mDetectorSessions.get(0) instanceof VisualQueryDetectorSession) {
+        boolean allHotwordDetectionServiceSessionsRemoved = mDetectorSessions.size() == 0
+                || (mDetectorSessions.size() == 1 && mDetectorSessions.get(0)
+                instanceof VisualQueryDetectorSession);
+        if (allHotwordDetectionServiceSessionsRemoved) {
             unbindHotwordDetectionService();
         }
     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionBinderProxy.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionBinderProxy.java
index dd9fee3..0ef2f06 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionBinderProxy.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionBinderProxy.java
@@ -69,4 +69,9 @@
     public SoundTrigger.ModelParamRange queryParameter(int i, int i1) throws RemoteException {
         return mDelegate.queryParameter(i, i1);
     }
+
+    @Override
+    public void detach() throws RemoteException {
+        mDelegate.detach();
+    }
 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
index c0c3e6f..0f8a945 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
@@ -113,6 +113,15 @@
                 "This object isn't intended to be used as a Binder.");
     }
 
+    @Override
+    public void detach() {
+        try {
+            mDelegate.detach();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
     // TODO: Share this code with SoundTriggerMiddlewarePermission.
     private boolean isHoldingPermissions() {
         try {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 1d7b966..27f3fb3 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1856,6 +1856,11 @@
                         "This object isn't intended to be used as a Binder.");
             }
 
+            @Override
+            public void detach() {
+                mSession.detach();
+            }
+
             private int unloadKeyphraseModel(int keyphraseId) {
                 final long caller = Binder.clearCallingIdentity();
                 try {
@@ -2133,8 +2138,6 @@
                     mImpl.dumpLocked(fd, pw, args);
                 }
             }
-
-            mSoundTriggerInternal.dump(fd, pw, args);
         }
 
         @Override
diff --git a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/RemoteWallpaperEffectsGenerationService.java b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/RemoteWallpaperEffectsGenerationService.java
index c228daf..61f34c2 100644
--- a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/RemoteWallpaperEffectsGenerationService.java
+++ b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/RemoteWallpaperEffectsGenerationService.java
@@ -40,6 +40,8 @@
 
     private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.SECOND_IN_MILLIS;
 
+    private static final long TIMEOUT_IDLE_BIND_MILLIS = 120 * DateUtils.SECOND_IN_MILLIS;
+
     private final RemoteWallpaperEffectsGenerationServiceCallback mCallback;
 
     public RemoteWallpaperEffectsGenerationService(Context context,
@@ -62,7 +64,7 @@
 
     @Override
     protected long getTimeoutIdleBindMillis() {
-        return PERMANENT_BOUND_TIMEOUT_MS;
+        return TIMEOUT_IDLE_BIND_MILLIS;
     }
 
     @Override
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 9dd2a61..26590c4 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -744,10 +744,6 @@
      * state of calls in the self-managed {@link ConnectionService}.  An example use-case is
      * exposing these calls to an automotive device via its companion app.
      * <p>
-     * This meta-data can only be set for an {@link InCallService} which also sets
-     * {@link #METADATA_IN_CALL_SERVICE_UI}. Only the default phone/dialer app, or a car-mode
-     * {@link InCallService} can see self-managed calls.
-     * <p>
      * See also {@link Connection#PROPERTY_SELF_MANAGED}.
      */
     public static final String METADATA_INCLUDE_SELF_MANAGED_CALLS =
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index f27c23b..1888943 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -5773,14 +5773,15 @@
          * </ul>
          * @hide
          */
-        public static final String KEY_SA_DISABLE_POLICY_INT = KEY_PREFIX + "sa_disable_policy_int";
+        public static final String KEY_NR_SA_DISABLE_POLICY_INT =
+                KEY_PREFIX + "sa_disable_policy_int";
 
         /** @hide */
         @IntDef({
-                SA_DISABLE_POLICY_NONE,
-                SA_DISABLE_POLICY_WFC_ESTABLISHED,
-                SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED,
-                SA_DISABLE_POLICY_VOWIFI_REGISTERED
+                NR_SA_DISABLE_POLICY_NONE,
+                NR_SA_DISABLE_POLICY_WFC_ESTABLISHED,
+                NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED,
+                NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED
         })
         public @interface NrSaDisablePolicy {}
 
@@ -5788,14 +5789,14 @@
          * Do not disables NR SA mode.
          * @hide
          */
-        public static final int SA_DISABLE_POLICY_NONE = 0;
+        public static final int NR_SA_DISABLE_POLICY_NONE = 0;
 
         /**
          * Disables NR SA mode when VoWiFi call is established in order to improve the delay or
          * voice mute when the handover from ePDG to NR is not supported in UE or network.
          * @hide
          */
-        public static final int SA_DISABLE_POLICY_WFC_ESTABLISHED = 1;
+        public static final int NR_SA_DISABLE_POLICY_WFC_ESTABLISHED = 1;
 
         /**
          * Disables NR SA mode when VoWiFi call is established when VoNR is disabled in order to
@@ -5803,14 +5804,14 @@
          * in UE or network.
          * @hide
          */
-        public static final int SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED = 2;
+        public static final int NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED = 2;
 
         /**
          * Disables NR SA mode when IMS is registered over WiFi in order to improve the delay or
          * voice mute when the handover from ePDG to NR is not supported in UE or network.
          * @hide
          */
-        public static final int SA_DISABLE_POLICY_VOWIFI_REGISTERED = 3;
+        public static final int NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED = 3;
 
         private Ims() {}
 
@@ -5883,7 +5884,7 @@
             defaults.putInt(KEY_REGISTRATION_RETRY_BASE_TIMER_MILLIS_INT, 30000);
             defaults.putInt(KEY_REGISTRATION_RETRY_MAX_TIMER_MILLIS_INT, 1800000);
             defaults.putInt(KEY_REGISTRATION_SUBSCRIBE_EXPIRY_TIMER_SEC_INT, 600000);
-            defaults.putInt(KEY_SA_DISABLE_POLICY_INT, SA_DISABLE_POLICY_NONE);
+            defaults.putInt(KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_NONE);
 
             defaults.putIntArray(
                     KEY_IPSEC_AUTHENTICATION_ALGORITHMS_INT_ARRAY,
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 1ce85ba..28ea5a6 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1186,6 +1186,7 @@
         ApnSetting other = (ApnSetting) o;
 
         return mEntryName.equals(other.mEntryName)
+                && Objects.equals(mId, other.mId)
                 && Objects.equals(mOperatorNumeric, other.mOperatorNumeric)
                 && Objects.equals(mApnName, other.mApnName)
                 && Objects.equals(mProxyAddress, other.mProxyAddress)
@@ -1337,6 +1338,14 @@
     public ContentValues toContentValues() {
         ContentValues apnValue = new ContentValues();
         apnValue.put(Telephony.Carriers.NUMERIC, nullToEmpty(mOperatorNumeric));
+        // If the APN is editable, the user may be able to set an invalid numeric. The numeric must
+        // always be 5 or 6 characters (depending on the length of the MNC), so skip if it is
+        // potentially invalid.
+        if (!TextUtils.isEmpty(mOperatorNumeric)
+                && (mOperatorNumeric.length() == 5 || mOperatorNumeric.length() == 6)) {
+            apnValue.put(Telephony.Carriers.MCC, mOperatorNumeric.substring(0, 3));
+            apnValue.put(Telephony.Carriers.MNC, mOperatorNumeric.substring(3));
+        }
         apnValue.put(Telephony.Carriers.NAME, nullToEmpty(mEntryName));
         apnValue.put(Telephony.Carriers.APN, nullToEmpty(mApnName));
         apnValue.put(Telephony.Carriers.PROXY, nullToEmpty(mProxyAddress));
@@ -1356,6 +1365,7 @@
                 getProtocolStringFromInt(mRoamingProtocol));
         apnValue.put(Telephony.Carriers.CARRIER_ENABLED, mCarrierEnabled);
         apnValue.put(Telephony.Carriers.MVNO_TYPE, getMvnoTypeStringFromInt(mMvnoType));
+        apnValue.put(Telephony.Carriers.MVNO_MATCH_DATA, nullToEmpty(mMvnoMatchData));
         apnValue.put(Telephony.Carriers.NETWORK_TYPE_BITMASK, mNetworkTypeBitmask);
         apnValue.put(Telephony.Carriers.LINGERING_NETWORK_TYPE_BITMASK,
                 mLingeringNetworkTypeBitmask);
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index c5830b8..431e9e6 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -1503,6 +1503,31 @@
         }
     }
 
+    /**
+     * Inform whether the device is aligned with the satellite for demo mode.
+     *
+     * @param isAligned {@true} Device is aligned with the satellite for demo mode
+     *                  {@false} Device is not aligned with the satellite for demo mode
+     *
+     * @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 onDeviceAlignedWithSatellite(boolean isAligned) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                telephony.onDeviceAlignedWithSatellite(mSubId, isAligned);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("informDeviceAlignedToSatellite() RemoteException:" + ex);
+            ex.rethrowFromSystemServer();
+        }
+    }
+
     private static ITelephony getITelephony() {
         ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
                 .getTelephonyServiceManager()
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 282b64d..21aad73 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2982,6 +2982,16 @@
     void requestTimeForNextSatelliteVisibility(int subId, in ResultReceiver receiver);
 
     /**
+     * Inform whether the device is aligned with the satellite within in margin for demo mode.
+     *
+     * @param isAligned {@true} Device is aligned with the satellite for demo mode
+     *                  {@false} Device is not aligned with the satellite for demo mode
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void onDeviceAlignedWithSatellite(int subId, in boolean isAligned);
+
+    /**
      * This API can be used by only CTS to update satellite vendor service package name.
      *
      * @param servicePackageName The package name of the satellite vendor service.
@@ -3008,4 +3018,23 @@
      * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
      */
     boolean setSatelliteListeningTimeoutDuration(in long timeoutMillis);
+
+    /**
+     * This API can be used by only CTS to update satellite pointing UI app package and class names.
+     *
+     * @param packageName The package name of the satellite pointing UI app.
+     * @param className The class name of the satellite pointing UI app.
+     * @return {@code true} if the satellite pointing UI app package and class is set successfully,
+     * {@code false} otherwise.
+     */
+    boolean setSatellitePointingUiClassName(in String packageName, in String className);
+
+    /**
+     * This API can be used by only CTS to update the timeout duration in milliseconds whether
+     * the device is aligned with the satellite for demo mode
+     *
+     * @param timeoutMillis The timeout duration in millisecond.
+     * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+     */
+    boolean setSatelliteDeviceAlignedTimeoutDuration(long timeoutMillis);
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 8ed60c1..b273ba2 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -571,6 +571,7 @@
     int RIL_REQUEST_UPDATE_IMS_CALL_STATUS = 240;
     int RIL_REQUEST_SET_N1_MODE_ENABLED = 241;
     int RIL_REQUEST_IS_N1_MODE_ENABLED = 242;
+    int RIL_REQUEST_IS_NULL_CIPHER_AND_INTEGRITY_ENABLED = 259;
 
     /* Responses begin */
     int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
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 4e3ae0c..efd9b00 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
@@ -18,7 +18,7 @@
 
 import android.app.Instrumentation
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerBuilderProvider
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 f389e13..1f120d4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -19,9 +19,9 @@
 package com.android.server.wm.flicker
 
 import android.tools.common.PlatformConsts
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.IComponentNameMatcher
 import android.tools.common.flicker.subject.region.RegionSubject
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.IComponentNameMatcher
 import android.tools.common.traces.wm.WindowManagerTrace
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.helpers.WindowUtils
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
index c3cbb84..8638288 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.activityembedding
 
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index 5dc2dd7..10b71ff 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -40,20 +40,27 @@
  *     Launch an app [testApp] and wait animation to complete
  *     Press back button
  * ```
+ *
  * To run only the presubmit assertions add: `--
+ *
  * ```
  *      --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
  *      --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Presubmit`
  * ```
+ *
  * To run only the postsubmit assertions add: `--
+ *
  * ```
  *      --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
  *      --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Postsubmit`
  * ```
+ *
  * To run only the flaky assertions add: `--
+ *
  * ```
  *      --module-arg FlickerTests:include-annotation:androidx.test.filters.FlakyTest`
  * ```
+ *
  * Notes:
  * ```
  *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index b042a14..e5bd350 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -40,20 +40,27 @@
  *     Launch an app [testApp] and wait animation to complete
  *     Press home button
  * ```
+ *
  * To run only the presubmit assertions add: `--
+ *
  * ```
  *      --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
  *      --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Presubmit`
  * ```
+ *
  * To run only the postsubmit assertions add: `--
+ *
  * ```
  *      --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
  *      --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Postsubmit`
  * ```
+ *
  * To run only the flaky assertions add: `--
+ *
  * ```
  *      --module-arg FlickerTests:include-annotation:androidx.test.filters.FlakyTest`
  * ```
+ *
  * Notes:
  * ```
  *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
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 c4628aa..4570fa2 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.close
 
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher.Companion.LAUNCHER
+import android.tools.common.traces.component.ComponentNameMatcher.Companion.LAUNCHER
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 e531bc0..6053f1d 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.common.traces.wm.WindowManagerState.Companion.STATE_RESUMED
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.helpers.FIND_TIMEOUT
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 afb9fbf..94ac1a6 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 android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 
 class AppPairsHelper(
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 47dd4e9..c6fa1bb 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.traces.parsers.toFlickerComponent
 import com.android.server.wm.flicker.testapp.ActivityOptions
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 d4f48fe..747cf37 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import android.tools.device.traces.parsers.toFlickerComponent
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 73effbd..d172252 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.helpers.FIND_TIMEOUT
 import android.tools.device.traces.parsers.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 a6e57d5..7a8d780 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.helpers.FIND_TIMEOUT
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import android.tools.device.traces.parsers.toFlickerComponent
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 d61a500..83a41ab 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
@@ -18,10 +18,10 @@
 
 import android.app.Instrumentation
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.IComponentMatcher
 import android.tools.common.traces.Condition
 import android.tools.common.traces.DeviceStateDump
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.IComponentMatcher
 import android.tools.device.helpers.FIND_TIMEOUT
 import android.tools.device.helpers.IME_PACKAGE
 import android.tools.device.traces.parsers.WindowManagerStateHelper
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 fb5e1d2..b2aeb14 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.traces.parsers.toFlickerComponent
 import com.android.server.wm.flicker.testapp.ActivityOptions
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
index 1ccac13..a670d68 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
@@ -17,15 +17,15 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import androidx.test.uiautomator.By
-import androidx.test.uiautomator.Until
-import com.android.server.wm.flicker.testapp.ActivityOptions
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.device.traces.parsers.toFlickerComponent
-import android.tools.device.traces.parsers.WindowManagerStateHelper
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.helpers.FIND_TIMEOUT
 import android.tools.device.helpers.SYSTEMUI_PACKAGE
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import android.tools.device.traces.parsers.toFlickerComponent
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.Until
+import com.android.server.wm.flicker.testapp.ActivityOptions
 
 class LetterboxAppHelper
 @JvmOverloads
@@ -37,13 +37,21 @@
 ) : StandardAppHelper(instr, launcherName, component) {
 
     fun clickRestart(wmHelper: WindowManagerStateHelper) {
-        val restartButton = uiDevice.wait(Until.findObject(By.res(
-            SYSTEMUI_PACKAGE, "size_compat_restart_button")), FIND_TIMEOUT)
+        val restartButton =
+            uiDevice.wait(
+                Until.findObject(By.res(SYSTEMUI_PACKAGE, "size_compat_restart_button")),
+                FIND_TIMEOUT
+            )
         restartButton?.run { restartButton.click() } ?: error("Restart button not found")
 
         // size compat mode restart confirmation dialog button
-        val restartDialogButton = uiDevice.wait(Until.findObject(By.res(
-            SYSTEMUI_PACKAGE, "letterbox_restart_dialog_restart_button")), FIND_TIMEOUT)
+        val restartDialogButton =
+            uiDevice.wait(
+                Until.findObject(
+                    By.res(SYSTEMUI_PACKAGE, "letterbox_restart_dialog_restart_button")
+                ),
+                FIND_TIMEOUT
+            )
         restartDialogButton?.run { restartDialogButton.click() }
             ?: error("Restart dialog button not found")
         wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
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 ab91685..c98f1c4 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.helpers.FIND_TIMEOUT
 import android.tools.device.traces.parsers.toFlickerComponent
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 e93e9c8..65175ef 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
@@ -19,7 +19,7 @@
 import android.app.Instrumentation
 import android.content.Context
 import android.provider.Settings
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.util.Log
 import com.android.compatibility.common.util.SystemUtil
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 c547ad0..5b3d308 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.helpers.FIND_TIMEOUT
 import android.tools.device.traces.parsers.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 20ee3b9..ee65004 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.traces.parsers.toFlickerComponent
 import com.android.server.wm.flicker.testapp.ActivityOptions
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 78f8bcf..7665690 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.helpers.FIND_TIMEOUT
 import android.tools.device.traces.parsers.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 c5a21a8..24e231c 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
@@ -21,8 +21,8 @@
 import android.media.session.MediaSessionManager
 import android.tools.common.datatypes.Rect
 import android.tools.common.datatypes.Region
-import android.tools.common.datatypes.component.IComponentMatcher
 import android.tools.common.traces.ConditionsFactory
+import android.tools.common.traces.component.IComponentMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.helpers.FIND_TIMEOUT
 import android.tools.device.helpers.SYSTEMUI_PACKAGE
@@ -250,7 +250,8 @@
             waitConditions = arrayOf(ConditionsFactory.hasPipWindow())
         )
 
-        wmHelper.StateSyncBuilder()
+        wmHelper
+            .StateSyncBuilder()
             .withWindowSurfaceAppeared(this)
             .withPipShown()
             .waitForAndVerify()
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 06e668e..cac3530 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.traces.parsers.toFlickerComponent
 import com.android.server.wm.flicker.testapp.ActivityOptions
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 94c90da..8366a7a 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.traces.parsers.toFlickerComponent
 import com.android.server.wm.flicker.testapp.ActivityOptions
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 64af811..89c6c35 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.traces.parsers.toFlickerComponent
 import com.android.server.wm.flicker.testapp.ActivityOptions
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 316766a..895725c 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.helpers.FIND_TIMEOUT
 import android.tools.device.traces.parsers.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 34fa921..7e0632d 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
@@ -18,8 +18,8 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
 import android.tools.common.flicker.subject.region.RegionSubject
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 823328a..7f496d8 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
@@ -19,7 +19,7 @@
 import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 df9d33b..cbe03dc 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 7954dd1..82c390b 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 10ce5ea..c693ca7 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 579c10f..8e33719 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
@@ -18,7 +18,7 @@
 
 package com.android.server.wm.flicker.ime
 
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.legacy.FlickerTest
 
 fun FlickerTest.imeLayerBecomesVisible() {
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 3f87aef..19bbf0c 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
@@ -18,8 +18,8 @@
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
 import android.tools.common.flicker.subject.region.RegionSubject
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt
index a3fb73b..496165a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt
@@ -18,6 +18,11 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
+import android.platform.test.annotations.Postsubmit
+import android.tools.common.Timestamp
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.flicker.subject.exceptions.ExceptionMessageBuilder
+import android.tools.common.flicker.subject.exceptions.InvalidPropertyException
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
@@ -36,7 +41,7 @@
 /**
  * Test IME window layer will become visible when switching from the fixed orientation activity
  * (e.g. Launcher activity). To run this test: `atest
- * FlickerTests:OpenImeWindowFromFixedOrientationAppTest`
+ * FlickerTests:ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest`
  */
 @RequiresDevice
 @RunWith(Parameterized::class)
@@ -77,6 +82,49 @@
         flicker.snapshotStartingWindowLayerCoversExactlyOnApp(imeTestApp)
     }
 
+    @Postsubmit
+    @Test
+    fun imeLayerAlphaOneAfterSnapshotStartingWindowRemoval() {
+        // Check if the snapshot appeared during the trace
+        var imeSnapshotRemovedTimestamp: Timestamp? = null
+
+        val layerTrace = flicker.reader.readLayersTrace()
+        val layerTraceEntries = layerTrace?.entries?.toList() ?: emptyList()
+
+        layerTraceEntries.zipWithNext { prev, next ->
+            val prevSnapshotLayerVisible =
+                    ComponentNameMatcher.SNAPSHOT.layerMatchesAnyOf(prev.visibleLayers)
+            val nextSnapshotLayerVisible =
+                    ComponentNameMatcher.SNAPSHOT.layerMatchesAnyOf(next.visibleLayers)
+
+            if (imeSnapshotRemovedTimestamp == null &&
+                    (prevSnapshotLayerVisible && !nextSnapshotLayerVisible)) {
+                imeSnapshotRemovedTimestamp = next.timestamp
+            }
+        }
+
+        // if so, make an assertion
+        imeSnapshotRemovedTimestamp?.let { timestamp ->
+            val stateAfterSnapshot = layerTrace?.getEntryAt(timestamp)
+                    ?: error("State not found for $timestamp")
+
+            val imeLayers = ComponentNameMatcher.IME
+                    .filterLayers(stateAfterSnapshot.visibleLayers.toList())
+
+            require(imeLayers.isNotEmpty()) { "IME layer not found" }
+            if (imeLayers.any { it.color.a != 1.0f }) {
+                val errorMsgBuilder = ExceptionMessageBuilder()
+                        .setTimestamp(timestamp)
+                        .forInvalidProperty("IME layer alpha")
+                        .setExpected("is 1.0")
+                        .setActual("not 1.0")
+                        .addExtraDescription("Filter",
+                                ComponentNameMatcher.IME.toLayerIdentifier())
+                throw InvalidPropertyException(errorMsgBuilder)
+            }
+        }
+    }
+
     companion object {
         /**
          * Creates the test configurations.
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 6179fc2..f64ad53 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 690ed53..11bc7b9 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
@@ -19,7 +19,7 @@
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 866e858..46967db 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 6f22589..277b9155 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 231d0d7..9275d6a 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
@@ -17,8 +17,8 @@
 package com.android.server.wm.flicker.ime
 
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
 import android.tools.common.traces.ConditionsFactory
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 3c577ac..e6594c9 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.launch
 
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt
index 3289bc6..ac05c76 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt
@@ -41,4 +41,4 @@
             return FlickerTestFactory.nonRotationTests()
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
index 360a233..a658293 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
@@ -16,7 +16,6 @@
 
 package com.android.server.wm.flicker.launch
 
-import android.tools.common.NavBar
 import android.tools.common.Rotation
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
@@ -87,10 +86,7 @@
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
         fun getParams(): Collection<FlickerTest> {
-            // TAPL fails on landscape mode b/240916028
-            return FlickerTestFactory.nonRotationTests(
-                supportedNavigationModes = listOf(NavBar.MODE_3BUTTON)
-            )
+            return FlickerTestFactory.nonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
index ccbe74f..d33a272 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
@@ -17,7 +17,6 @@
 package com.android.server.wm.flicker.launch
 
 import android.platform.test.annotations.FlakyTest
-import android.tools.common.NavBar
 import android.tools.device.flicker.annotation.FlickerServiceCompatible
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerTest
@@ -50,10 +49,7 @@
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
         fun getParams(): Collection<FlickerTest> {
-            // TAPL fails on landscape mode b/240916028
-            return FlickerTestFactory.nonRotationTests(
-                supportedNavigationModes = listOf(NavBar.MODE_3BUTTON)
-            )
+            return FlickerTestFactory.nonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index d0dc42f..26f88d2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -23,9 +23,9 @@
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.helpers.setRotation
-import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -42,6 +42,7 @@
  *     Make sure no apps are running on the device
  *     Launch an app [testApp] and wait animation to complete
  * ```
+ *
  * Notes:
  * ```
  *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt
index f75d9ee..d9a99da 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt
@@ -49,4 +49,4 @@
             return FlickerTestFactory.nonRotationTests()
         }
     }
-}
\ No newline at end of file
+}
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 1a1d403..3d5a8e3 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.launch
 
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.legacy.FlickerTest
 import com.android.server.wm.flicker.replacesLayer
 import org.junit.Test
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 b1a267a..b21777b 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
@@ -78,9 +78,7 @@
     override fun taskBarLayerIsVisibleAtStartAndEnd() {}
 
     /** {@inheritDoc} */
-    @Test
-    @Ignore("Display is off at the start")
-    override fun taskBarWindowIsAlwaysVisible() {}
+    @Test @Ignore("Display is off at the start") override fun taskBarWindowIsAlwaysVisible() {}
 
     /** {@inheritDoc} */
     @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 e414325..ec92ca6 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
@@ -20,7 +20,7 @@
 import android.platform.test.annotations.Presubmit
 import android.platform.test.rule.SettingOverrideRule
 import android.provider.Settings
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 0b09e24..009d617 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
@@ -19,7 +19,7 @@
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
@@ -113,9 +113,7 @@
     @Test
     override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
 
-    @Presubmit
-    @Test
-    override fun entireScreenCovered() = super.entireScreenCovered()
+    @Presubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
 
     @FlakyTest(bugId = 278227468)
     @Test
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 730f78f..eae9ca1 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import com.android.server.wm.flicker.navBarLayerPositionAtEnd
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 9c16b79..7bcb910 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt
index 4aa78d4..8b4a613 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt
@@ -44,4 +44,4 @@
             return FlickerTestFactory.nonRotationTests()
         }
     }
-}
\ No newline at end of file
+}
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 23cb1d4..425e674d 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index 00d7544..8e1b059 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -44,6 +44,7 @@
  *     Relaunch an app [testApp] by selecting it in the overview screen, and wait animation to
  *     complete (only this action is traced)
  * ```
+ *
  * Notes:
  * ```
  *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
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 17f5638..1383ae3 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
@@ -20,7 +20,7 @@
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.annotation.FlickerServiceCompatible
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerTest
@@ -47,6 +47,7 @@
  *     Lock the device.
  *     Launch an app on top of the lock screen [testApp] and wait animation to complete
  * ```
+ *
  * Notes:
  * ```
  *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
@@ -161,9 +162,7 @@
         super.appWindowBecomesFirstAndOnlyTopWindow()
 
     /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
+    @Presubmit @Test override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
 
     /** Checks the [ComponentNameMatcher.NAV_BAR] is visible at the end of the transition */
     @Presubmit
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 e0db96f..87a14c6 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.launch
 
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index cdd2d45..3385830 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -42,6 +42,7 @@
  *     Press home
  *     Relaunch an app [testApp] and wait animation to complete (only this action is traced)
  * ```
+ *
  * Notes:
  * ```
  *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt
index 9679059..d8b38b3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt
@@ -43,4 +43,4 @@
             return FlickerTestFactory.nonRotationTests()
         }
     }
-}
\ No newline at end of file
+}
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 b848e63..b48611e 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
@@ -20,20 +20,20 @@
 import android.os.Bundle
 import android.os.Handler
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
 import android.tools.common.traces.ConditionsFactory
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerBuilderProvider
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
 import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
+import android.tools.device.helpers.wakeUpAndGoToHomeScreen
 import androidx.test.filters.RequiresDevice
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.server.wm.flicker.R
-import com.android.server.wm.flicker.helpers.setRotation
-import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
-import android.tools.device.helpers.wakeUpAndGoToHomeScreen
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.helpers.setRotation
 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/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index be73547..d0fd732 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
@@ -21,11 +21,11 @@
 import android.content.res.Resources
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.ComponentNameMatcher.Companion.SPLASH_SCREEN
-import android.tools.common.datatypes.component.ComponentNameMatcher.Companion.WALLPAPER_BBQ_WRAPPER
-import android.tools.common.datatypes.component.ComponentSplashScreenMatcher
-import android.tools.common.datatypes.component.IComponentMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher.Companion.SPLASH_SCREEN
+import android.tools.common.traces.component.ComponentNameMatcher.Companion.WALLPAPER_BBQ_WRAPPER
+import android.tools.common.traces.component.ComponentSplashScreenMatcher
+import android.tools.common.traces.component.IComponentMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 eadeef5..a8b80ad 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
@@ -20,7 +20,7 @@
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.common.datatypes.Rect
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 1360495..96cd8ff 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
@@ -20,7 +20,7 @@
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.common.datatypes.Rect
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 d49f035..7e935f0 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
@@ -21,7 +21,7 @@
 import android.tools.common.NavBar
 import android.tools.common.Rotation
 import android.tools.common.datatypes.Rect
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 fe789a7..855ea3e 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
@@ -18,7 +18,7 @@
 
 import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 3c0bbd6..fe9da33 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
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.rotation
 
 import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
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 4d010f3..0cbbb83 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
@@ -19,7 +19,7 @@
 import android.platform.test.annotations.IwTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.ScenarioBuilder
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
 import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/SilkFX/res/layout/gainmap_image.xml b/tests/SilkFX/res/layout/gainmap_image.xml
index 89bbb70..b0ed914 100644
--- a/tests/SilkFX/res/layout/gainmap_image.xml
+++ b/tests/SilkFX/res/layout/gainmap_image.xml
@@ -34,7 +34,7 @@
                          android:layout_width="wrap_content"
                          android:layout_weight="1"
                          android:layout_height="wrap_content"
-                         android:text="SDR original" />
+                         android:text="SDR" />
 
             <RadioButton android:id="@+id/output_gainmap"
                          android:layout_width="wrap_content"
@@ -46,13 +46,34 @@
                          android:layout_width="wrap_content"
                          android:layout_weight="1"
                          android:layout_height="wrap_content"
-                         android:text="HDR (sdr+gainmap)" />
+                         android:text="HDR" />
+
+            <RadioButton android:id="@+id/output_hdr_test"
+                         android:layout_width="wrap_content"
+                         android:layout_weight="1"
+                         android:layout_height="wrap_content"
+                         android:text="HDR (test)" />
         </RadioGroup>
 
-        <Spinner
-            android:id="@+id/image_selection"
+        <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Spinner
+                android:id="@+id/image_selection"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content" />
+
+            <Button
+                android:id="@+id/gainmap_metadata"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Gainmap Metadata..." />
+
+        </LinearLayout>
 
         <TextView
             android:id="@+id/error_msg"
@@ -67,4 +88,4 @@
 
     </LinearLayout>
 
-</com.android.test.silkfx.hdr.GainmapImage>
\ No newline at end of file
+</com.android.test.silkfx.hdr.GainmapImage>
diff --git a/tests/SilkFX/res/layout/gainmap_metadata.xml b/tests/SilkFX/res/layout/gainmap_metadata.xml
new file mode 100644
index 0000000..0dabaca
--- /dev/null
+++ b/tests/SilkFX/res/layout/gainmap_metadata.xml
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        android:layout_width="350dp"
+        android:layout_height="300dp"
+        android:layout_centerHorizontal="true"
+        android:padding="8dp"
+        android:orientation="vertical"
+        android:background="#444444">
+
+        <TextView
+            android:id="@+id/gainmap_metadata_title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:text="Metadata for &quot;HDR (test)&quot; (values in linear space):" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/gainmap_metadata_gainmapmin_text"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Gain Map Min:" />
+
+            <TextView
+                android:id="@+id/gainmap_metadata_gainmapmin_val"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="4"
+                android:text="TODO" />
+
+            <SeekBar
+                android:id="@+id/gainmap_metadata_gainmapmin"
+                android:min="0"
+                android:max="100"
+                android:layout_width="150dp"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/gainmap_metadata_gainmapmax_text"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Gain Map Max:" />
+
+            <TextView
+                android:id="@+id/gainmap_metadata_gainmapmax_val"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="4"
+                android:text="TODO" />
+
+            <SeekBar
+                android:id="@+id/gainmap_metadata_gainmapmax"
+                android:min="0"
+                android:max="100"
+                android:layout_width="150dp"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/gainmap_metadata_capacitymin_text"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Capacity Min:" />
+
+            <TextView
+                android:id="@+id/gainmap_metadata_capacitymin_val"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="4"
+                android:text="TODO" />
+
+            <SeekBar
+                android:id="@+id/gainmap_metadata_capacitymin"
+                android:min="0"
+                android:max="100"
+                android:layout_width="150dp"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/gainmap_metadata_capacitymax_text"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Capacity Max:" />
+
+            <TextView
+                android:id="@+id/gainmap_metadata_capacitymax_val"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="4"
+                android:text="TODO" />
+
+            <SeekBar
+                android:id="@+id/gainmap_metadata_capacitymax"
+                android:min="0"
+                android:max="100"
+                android:layout_width="150dp"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/gainmap_metadata_gamma_text"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Gamma:" />
+
+            <TextView
+                android:id="@+id/gainmap_metadata_gamma_val"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="4"
+                android:text="TODO" />
+
+            <SeekBar
+                android:id="@+id/gainmap_metadata_gamma"
+                android:min="0"
+                android:max="100"
+                android:layout_width="150dp"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/gainmap_metadata_offsetsdr_text"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Offset SDR:" />
+
+            <TextView
+                android:id="@+id/gainmap_metadata_offsetsdr_val"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="4"
+                android:text="TODO" />
+
+            <SeekBar
+                android:id="@+id/gainmap_metadata_offsetsdr"
+                android:min="0"
+                android:max="100"
+                android:layout_width="150dp"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/gainmap_metadata_offsethdr_text"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Offset HDR:" />
+
+            <TextView
+                android:id="@+id/gainmap_metadata_offsethdr_val"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="4"
+                android:text="TODO" />
+
+            <SeekBar
+                android:id="@+id/gainmap_metadata_offsethdr"
+                android:min="0"
+                android:max="100"
+                android:layout_width="150dp"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Button
+                android:id="@+id/gainmap_metadata_reset"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Reset" />
+
+            <Button
+                android:id="@+id/gainmap_metadata_done"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:text="Done" />
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+</RelativeLayout>
diff --git a/tests/SilkFX/src/com/android/test/silkfx/hdr/GainmapImage.kt b/tests/SilkFX/src/com/android/test/silkfx/hdr/GainmapImage.kt
index 78bc4c4..7cf69b7 100644
--- a/tests/SilkFX/src/com/android/test/silkfx/hdr/GainmapImage.kt
+++ b/tests/SilkFX/src/com/android/test/silkfx/hdr/GainmapImage.kt
@@ -27,6 +27,7 @@
 import android.view.View
 import android.widget.AdapterView
 import android.widget.ArrayAdapter
+import android.widget.Button
 import android.widget.FrameLayout
 import android.widget.RadioGroup
 import android.widget.Spinner
@@ -44,6 +45,7 @@
     private var gainmap: Gainmap? = null
     private var gainmapVisualizer: Bitmap? = null
     private lateinit var imageView: SubsamplingScaleImageView
+    private lateinit var gainmapMetadataEditor: GainmapMetadataEditor
 
     init {
         gainmapImages = context.assets.list("gainmaps")!!
@@ -58,6 +60,7 @@
         super.onFinishInflate()
 
         imageView = findViewById(R.id.image)!!
+        gainmapMetadataEditor = GainmapMetadataEditor(this, imageView)
 
         findViewById<RadioGroup>(R.id.output_mode)!!.also {
             it.check(outputMode)
@@ -92,6 +95,10 @@
             }
         }
 
+        findViewById<Button>(R.id.gainmap_metadata)!!.setOnClickListener {
+            gainmapMetadataEditor.openEditor()
+        }
+
         setImage(0)
 
         imageView.apply {
@@ -132,6 +139,7 @@
             findViewById<RadioGroup>(R.id.output_mode)!!.visibility = View.VISIBLE
 
             gainmap = bitmap!!.gainmap
+            gainmapMetadataEditor.setGainmap(gainmap)
             val map = gainmap!!.gainmapContents
             if (map.config != Bitmap.Config.ALPHA_8) {
                 gainmapVisualizer = map
@@ -175,7 +183,15 @@
 
         imageView.setImage(ImageSource.cachedBitmap(when (outputMode) {
             R.id.output_hdr -> {
-                bitmap!!.gainmap = gainmap; bitmap!!
+                gainmapMetadataEditor.useOriginalMetadata()
+                bitmap!!.gainmap = gainmap
+                bitmap!!
+            }
+
+            R.id.output_hdr_test -> {
+                gainmapMetadataEditor.useEditMetadata()
+                bitmap!!.gainmap = gainmap
+                bitmap!!
             }
 
             R.id.output_sdr -> {
@@ -186,4 +202,4 @@
             else -> throw IllegalStateException()
         }))
     }
-}
\ No newline at end of file
+}
diff --git a/tests/SilkFX/src/com/android/test/silkfx/hdr/GainmapMetadataEditor.kt b/tests/SilkFX/src/com/android/test/silkfx/hdr/GainmapMetadataEditor.kt
new file mode 100644
index 0000000..8a65304
--- /dev/null
+++ b/tests/SilkFX/src/com/android/test/silkfx/hdr/GainmapMetadataEditor.kt
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.silkfx.hdr
+
+import android.graphics.Gainmap
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.PopupWindow
+import android.widget.SeekBar
+import android.widget.TextView
+import com.android.test.silkfx.R
+
+data class GainmapMetadata(
+    var ratioMin: Float,
+    var ratioMax: Float,
+    var capacityMin: Float,
+    var capacityMax: Float,
+    var gamma: Float,
+    var offsetSdr: Float,
+    var offsetHdr: Float
+)
+
+class GainmapMetadataEditor(val parent: ViewGroup, val renderView: View) {
+    private var gainmap: Gainmap? = null
+    private var showingEdits = false
+
+    private var metadataPopup: PopupWindow? = null
+
+    private var originalMetadata: GainmapMetadata = GainmapMetadata(
+        1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f)
+    private var currentMetadata: GainmapMetadata = originalMetadata.copy()
+
+    private val maxProgress = 100.0f
+
+    private val minRatioMin = .001f
+    private val maxRatioMin = 1.0f
+    private val minRatioMax = 1.0f
+    private val maxRatioMax = 16.0f
+    private val minCapacityMin = 1.0f
+    private val maxCapacityMin = maxRatioMax
+    private val minCapacityMax = 1.001f
+    private val maxCapacityMax = maxRatioMax
+    private val minGamma = 0.1f
+    private val maxGamma = 3.0f
+    // Min and max offsets are 0.0 and 1.0 respectively
+
+    fun setGainmap(newGainmap: Gainmap?) {
+        gainmap = newGainmap
+        originalMetadata = GainmapMetadata(gainmap!!.getRatioMin()[0],
+            gainmap!!.getRatioMax()[0], gainmap!!.getMinDisplayRatioForHdrTransition(),
+            gainmap!!.getDisplayRatioForFullHdr(), gainmap!!.getGamma()[0],
+            gainmap!!.getEpsilonSdr()[0], gainmap!!.getEpsilonHdr()[0])
+        currentMetadata = originalMetadata.copy()
+    }
+
+    fun useOriginalMetadata() {
+        showingEdits = false
+        applyMetadata(originalMetadata)
+    }
+
+    fun useEditMetadata() {
+        showingEdits = true
+        applyMetadata(currentMetadata)
+    }
+
+    fun closeEditor() {
+        metadataPopup?.let {
+            it.dismiss()
+            metadataPopup = null
+        }
+    }
+
+    fun openEditor() {
+        if (metadataPopup != null) return
+
+        val view = LayoutInflater.from(parent.getContext()).inflate(R.layout.gainmap_metadata, null)
+
+        metadataPopup = PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT,
+            ViewGroup.LayoutParams.WRAP_CONTENT)
+        metadataPopup!!.showAtLocation(view, Gravity.CENTER, 0, 0)
+
+        (view.getParent() as ViewGroup).removeView(view)
+        parent.addView(view)
+
+        view.findViewById<Button>(R.id.gainmap_metadata_done)!!.setOnClickListener {
+            closeEditor()
+        }
+
+        view.findViewById<Button>(R.id.gainmap_metadata_reset)!!.setOnClickListener {
+            resetGainmapMetadata()
+        }
+
+        updateMetadataUi()
+
+        val gainmapMinSeek = view.findViewById<SeekBar>(R.id.gainmap_metadata_gainmapmin)
+        val gainmapMaxSeek = view.findViewById<SeekBar>(R.id.gainmap_metadata_gainmapmax)
+        val capacityMinSeek = view.findViewById<SeekBar>(R.id.gainmap_metadata_capacitymin)
+        val capacityMaxSeek = view.findViewById<SeekBar>(R.id.gainmap_metadata_capacitymax)
+        val gammaSeek = view.findViewById<SeekBar>(R.id.gainmap_metadata_gamma)
+        val offsetSdrSeek = view.findViewById<SeekBar>(R.id.gainmap_metadata_offsetsdr)
+        val offsetHdrSeek = view.findViewById<SeekBar>(R.id.gainmap_metadata_offsethdr)
+        arrayOf(gainmapMinSeek, gainmapMaxSeek, capacityMinSeek, capacityMaxSeek, gammaSeek,
+            offsetSdrSeek, offsetHdrSeek).forEach {
+            it.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
+                override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
+                    if (!fromUser) return
+                    val normalized = progress.toFloat() / maxProgress
+                    when (seekBar) {
+                        gainmapMinSeek -> updateGainmapMin(normalized)
+                        gainmapMaxSeek -> updateGainmapMax(normalized)
+                        capacityMinSeek -> updateCapacityMin(normalized)
+                        capacityMaxSeek -> updateCapacityMax(normalized)
+                        gammaSeek -> updateGamma(normalized)
+                        offsetSdrSeek -> updateOffsetSdr(normalized)
+                        offsetHdrSeek -> updateOffsetHdr(normalized)
+                    }
+                }
+
+                override fun onStartTrackingTouch(seekBar: SeekBar) {}
+                override fun onStopTrackingTouch(seekBar: SeekBar) {}
+            })
+        }
+    }
+
+    private fun updateMetadataUi() {
+        val gainmapMinSeek = parent.findViewById<SeekBar>(R.id.gainmap_metadata_gainmapmin)
+        val gainmapMaxSeek = parent.findViewById<SeekBar>(R.id.gainmap_metadata_gainmapmax)
+        val capacityMinSeek = parent.findViewById<SeekBar>(R.id.gainmap_metadata_capacitymin)
+        val capacityMaxSeek = parent.findViewById<SeekBar>(R.id.gainmap_metadata_capacitymax)
+        val gammaSeek = parent.findViewById<SeekBar>(R.id.gainmap_metadata_gamma)
+        val offsetSdrSeek = parent.findViewById<SeekBar>(R.id.gainmap_metadata_offsetsdr)
+        val offsetHdrSeek = parent.findViewById<SeekBar>(R.id.gainmap_metadata_offsethdr)
+
+        gainmapMinSeek.setProgress(
+            ((currentMetadata.ratioMin - minRatioMin) / maxRatioMin * maxProgress).toInt())
+        gainmapMaxSeek.setProgress(
+            ((currentMetadata.ratioMax - minRatioMax) / maxRatioMax * maxProgress).toInt())
+        capacityMinSeek.setProgress(
+            ((currentMetadata.capacityMin - minCapacityMin) / maxCapacityMin * maxProgress).toInt())
+        capacityMaxSeek.setProgress(
+            ((currentMetadata.capacityMax - minCapacityMax) / maxCapacityMax * maxProgress).toInt())
+        gammaSeek.setProgress(
+            ((currentMetadata.gamma - minGamma) / maxGamma * maxProgress).toInt())
+        // Log base 3 via: log_b(x) = log_y(x) / log_y(b)
+        offsetSdrSeek.setProgress(
+            ((1.0 - Math.log(currentMetadata.offsetSdr.toDouble() / Math.log(3.0)) / -11.0)
+             .toFloat() * maxProgress).toInt())
+        offsetHdrSeek.setProgress(
+            ((1.0 - Math.log(currentMetadata.offsetHdr.toDouble() / Math.log(3.0)) / -11.0)
+             .toFloat() * maxProgress).toInt())
+
+        parent.findViewById<TextView>(R.id.gainmap_metadata_gainmapmin_val)!!.setText(
+            "%.3f".format(currentMetadata.ratioMin))
+        parent.findViewById<TextView>(R.id.gainmap_metadata_gainmapmax_val)!!.setText(
+            "%.3f".format(currentMetadata.ratioMax))
+        parent.findViewById<TextView>(R.id.gainmap_metadata_capacitymin_val)!!.setText(
+            "%.3f".format(currentMetadata.capacityMin))
+        parent.findViewById<TextView>(R.id.gainmap_metadata_capacitymax_val)!!.setText(
+            "%.3f".format(currentMetadata.capacityMax))
+        parent.findViewById<TextView>(R.id.gainmap_metadata_gamma_val)!!.setText(
+            "%.3f".format(currentMetadata.gamma))
+        parent.findViewById<TextView>(R.id.gainmap_metadata_offsetsdr_val)!!.setText(
+            "%.5f".format(currentMetadata.offsetSdr))
+        parent.findViewById<TextView>(R.id.gainmap_metadata_offsethdr_val)!!.setText(
+            "%.5f".format(currentMetadata.offsetHdr))
+    }
+
+    private fun resetGainmapMetadata() {
+        currentMetadata = originalMetadata.copy()
+        applyMetadata(currentMetadata)
+        updateMetadataUi()
+    }
+
+    private fun applyMetadata(newMetadata: GainmapMetadata) {
+        gainmap!!.setRatioMin(newMetadata.ratioMin, newMetadata.ratioMin, newMetadata.ratioMin)
+        gainmap!!.setRatioMax(newMetadata.ratioMax, newMetadata.ratioMax, newMetadata.ratioMax)
+        gainmap!!.setMinDisplayRatioForHdrTransition(newMetadata.capacityMin)
+        gainmap!!.setDisplayRatioForFullHdr(newMetadata.capacityMax)
+        gainmap!!.setGamma(newMetadata.gamma, newMetadata.gamma, newMetadata.gamma)
+        gainmap!!.setEpsilonSdr(newMetadata.offsetSdr, newMetadata.offsetSdr, newMetadata.offsetSdr)
+        gainmap!!.setEpsilonHdr(newMetadata.offsetHdr, newMetadata.offsetHdr, newMetadata.offsetHdr)
+        renderView.invalidate()
+    }
+
+    private fun updateGainmapMin(normalized: Float) {
+        val newValue = minRatioMin + normalized * (maxRatioMin - minRatioMin)
+        parent.findViewById<TextView>(R.id.gainmap_metadata_gainmapmin_val)!!.setText(
+            "%.3f".format(newValue))
+        currentMetadata.ratioMin = newValue
+        if (showingEdits) {
+            gainmap!!.setRatioMin(newValue, newValue, newValue)
+            renderView.invalidate()
+        }
+    }
+
+    private fun updateGainmapMax(normalized: Float) {
+        val newValue = minRatioMax + normalized * (maxRatioMax - minRatioMax)
+        parent.findViewById<TextView>(R.id.gainmap_metadata_gainmapmax_val)!!.setText(
+            "%.3f".format(newValue))
+        currentMetadata.ratioMax = newValue
+        if (showingEdits) {
+            gainmap!!.setRatioMax(newValue, newValue, newValue)
+            renderView.invalidate()
+        }
+    }
+
+    private fun updateCapacityMin(normalized: Float) {
+        val newValue = minCapacityMin + normalized * (maxCapacityMin - minCapacityMin)
+        parent.findViewById<TextView>(R.id.gainmap_metadata_capacitymin_val)!!.setText(
+            "%.3f".format(newValue))
+        currentMetadata.capacityMin = newValue
+        if (showingEdits) {
+            gainmap!!.setMinDisplayRatioForHdrTransition(newValue)
+            renderView.invalidate()
+        }
+    }
+
+    private fun updateCapacityMax(normalized: Float) {
+        val newValue = minCapacityMax + normalized * (maxCapacityMax - minCapacityMax)
+        parent.findViewById<TextView>(R.id.gainmap_metadata_capacitymax_val)!!.setText(
+            "%.3f".format(newValue))
+        currentMetadata.capacityMax = newValue
+        if (showingEdits) {
+            gainmap!!.setDisplayRatioForFullHdr(newValue)
+            renderView.invalidate()
+        }
+    }
+
+    private fun updateGamma(normalized: Float) {
+        val newValue = minGamma + normalized * (maxGamma - minGamma)
+        parent.findViewById<TextView>(R.id.gainmap_metadata_gamma_val)!!.setText(
+            "%.3f".format(newValue))
+        currentMetadata.gamma = newValue
+        if (showingEdits) {
+            gainmap!!.setGamma(newValue, newValue, newValue)
+            renderView.invalidate()
+        }
+    }
+
+    private fun updateOffsetSdr(normalized: Float) {
+        var newValue = 0.0f
+        if (normalized > 0.0f ) {
+            newValue = Math.pow(3.0, (1.0 - normalized.toDouble()) * -11.0).toFloat()
+        }
+        parent.findViewById<TextView>(R.id.gainmap_metadata_offsetsdr_val)!!.setText(
+            "%.5f".format(newValue))
+        currentMetadata.offsetSdr = newValue
+        if (showingEdits) {
+            gainmap!!.setEpsilonSdr(newValue, newValue, newValue)
+            renderView.invalidate()
+        }
+    }
+
+    private fun updateOffsetHdr(normalized: Float) {
+        var newValue = 0.0f
+        if (normalized > 0.0f ) {
+            newValue = Math.pow(3.0, (1.0 - normalized.toDouble()) * -11.0).toFloat()
+        }
+        parent.findViewById<TextView>(R.id.gainmap_metadata_offsethdr_val)!!.setText(
+            "%.5f".format(newValue))
+        currentMetadata.offsetHdr = newValue
+        if (showingEdits) {
+            gainmap!!.setEpsilonHdr(newValue, newValue, newValue)
+            renderView.invalidate()
+        }
+    }
+}
diff --git a/tests/TouchLatency/app/build.gradle b/tests/TouchLatency/app/build.gradle
index 129baab..07f6bca 100644
--- a/tests/TouchLatency/app/build.gradle
+++ b/tests/TouchLatency/app/build.gradle
@@ -2,7 +2,6 @@
 
 android {
     compileSdkVersion 33
-    buildToolsVersion '28.0.3'
 
     defaultConfig {
         applicationId "com.prefabulated.touchlatency"
diff --git a/tests/TouchLatency/app/src/main/AndroidManifest.xml b/tests/TouchLatency/app/src/main/AndroidManifest.xml
index 25bb5d9..5743b25 100644
--- a/tests/TouchLatency/app/src/main/AndroidManifest.xml
+++ b/tests/TouchLatency/app/src/main/AndroidManifest.xml
@@ -30,12 +30,6 @@
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
-
-        <activity android:name=".TouchLatencyActivityPresentation"
-            android:label="@string/app_name"
-            android:parentActivityName=".TouchLatencyActivity"
-            android:exported="true">
-        </activity>
     </application>
 
 </manifest>
diff --git a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
index 3a520bc..7678633 100644
--- a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
+++ b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
@@ -16,8 +16,6 @@
 
 package com.prefabulated.touchlatency;
 
-import android.app.ActivityOptions;
-import android.content.Intent;
 import android.hardware.display.DisplayManager;
 import android.os.Bundle;
 import android.os.Handler;
@@ -105,7 +103,6 @@
             updateDisplayMode(menuItem, currentMode);
         }
         updateRefreshRateMenu(mMenu.findItem(R.id.frame_rate));
-        updateMultiDisplayMenu(mMenu.findItem(R.id.multi_display));
     }
 
     @Override
@@ -186,20 +183,6 @@
         mCurrentModeIndex = modeIndex;
     }
 
-    private void changeMultipleDisplays() {
-        Intent intent = new Intent(this, TouchLatencyActivityPresentation.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK);
-        ActivityOptions options = ActivityOptions.makeBasic();
-        for (int i = 1; i < mDisplayManager.getDisplays().length; ++i) {
-            // We assume the first display is already displaying the TouchLatencyActivity
-            int displayId = mDisplayManager.getDisplays()[i].getDisplayId();
-            options.setLaunchDisplayId(displayId);
-            intent.putExtra(TouchLatencyActivityPresentation.DISPLAY_ID, displayId);
-            startActivity(intent, options.toBundle());
-        }
-    }
-
-
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         Trace.beginSection("TouchLatencyActivity onOptionsItemSelected");
@@ -218,10 +201,6 @@
                 changeDisplayMode(item);
                 break;
             }
-            case R.id.multi_display: {
-                changeMultipleDisplays();
-                break;
-            }
         }
 
         Trace.endSection();
diff --git a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivityPresentation.java b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivityPresentation.java
deleted file mode 100644
index 2602e6b..0000000
--- a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivityPresentation.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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 com.prefabulated.touchlatency;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.Trace;
-import android.view.Display;
-import android.view.Display.Mode;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.Window;
-import android.view.WindowManager;
-
-public class TouchLatencyActivityPresentation extends Activity {
-    public static final String DISPLAY_ID = "DISPLAY_ID";
-    private Mode[] mDisplayModes;
-    private int mCurrentModeIndex;
-    private int mDisplayId;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        if (getIntent().hasExtra(DISPLAY_ID)) {
-            mDisplayId = (int) getIntent().getExtras().get(DISPLAY_ID);
-        }
-        Trace.beginSection(
-                "TouchLatencyActivityPresentation::DisplayId::" + mDisplayId + " onCreate");
-        setContentView(R.layout.activity_touch_latency);
-
-        mTouchView = findViewById(R.id.canvasView);
-
-        WindowManager wm = getWindowManager();
-        Display display = wm.getDefaultDisplay();
-        mDisplayModes = display.getSupportedModes();
-        Mode currentMode = getWindowManager().getDefaultDisplay().getMode();
-
-        for (int i = 0; i < mDisplayModes.length; i++) {
-            if (currentMode.getModeId() == mDisplayModes[i].getModeId()) {
-                mCurrentModeIndex = i;
-                break;
-            }
-        }
-        Trace.endSection();
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        Trace.beginSection(
-                "TouchLatencyActivityPresentation::DisplayId:: "
-                        + mDisplayId + "  onCreateOptionsMenu");
-        // Inflate the menu; this adds items to the action bar if it is present.
-        getMenuInflater().inflate(R.menu.menu_touch_latency, menu);
-        if (mDisplayModes.length > 1) {
-            MenuItem menuItem = menu.findItem(R.id.display_mode);
-            Mode currentMode = getWindowManager().getDefaultDisplay().getMode();
-            updateDisplayMode(menuItem, currentMode);
-        }
-        Trace.endSection();
-        return true;
-    }
-
-    private void updateDisplayMode(MenuItem menuItem, Mode displayMode) {
-        int fps = (int) displayMode.getRefreshRate();
-        menuItem.setTitle(fps + "hz");
-        menuItem.setVisible(true);
-    }
-
-    public void changeDisplayMode(MenuItem item) {
-        Window w = getWindow();
-        WindowManager.LayoutParams params = w.getAttributes();
-
-        int modeIndex = (mCurrentModeIndex + 1) % mDisplayModes.length;
-        params.preferredDisplayModeId = mDisplayModes[modeIndex].getModeId();
-        w.setAttributes(params);
-
-        updateDisplayMode(item, mDisplayModes[modeIndex]);
-        mCurrentModeIndex = modeIndex;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        Trace.beginSection(
-                "TouchLatencyActivityPresentation::DisplayId::"
-                        + mDisplayId + "  onOptionsItemSelected");
-        // Handle action bar item clicks here. The action bar will
-        // automatically handle clicks on the Home/Up button, so long
-        // as you specify a parent activity in AndroidManifest.xml.
-        int id = item.getItemId();
-
-        //noinspection SimplifiableIfStatement
-        switch (id) {
-            case R.id.action_settings: {
-                mTouchView.changeMode(item);
-                break;
-            }
-            case R.id.display_mode: {
-                changeDisplayMode(item);
-                break;
-            }
-        }
-
-        Trace.endSection();
-        return super.onOptionsItemSelected(item);
-    }
-
-    private TouchLatencyView mTouchView;
-}
diff --git a/tests/TouchLatency/app/src/main/res/menu/menu_touch_latency.xml b/tests/TouchLatency/app/src/main/res/menu/menu_touch_latency.xml
index 7169021..f637f71 100644
--- a/tests/TouchLatency/app/src/main/res/menu/menu_touch_latency.xml
+++ b/tests/TouchLatency/app/src/main/res/menu/menu_touch_latency.xml
@@ -30,9 +30,4 @@
         android:title="@string/display_mode"
         android:visible="false"
         app:showAsAction="always" />
-    <item
-        android:id="@+id/multi_display"
-        android:title="@string/multi_display"
-        android:visible="false"
-        app:showAsAction="ifRoom" />
 </menu>
diff --git a/tests/TouchLatency/build.gradle b/tests/TouchLatency/build.gradle
index 381e55e..f52935b 100644
--- a/tests/TouchLatency/build.gradle
+++ b/tests/TouchLatency/build.gradle
@@ -6,7 +6,7 @@
         google()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:4.2.2'
+        classpath 'com.android.tools.build:gradle:7.4.2'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git a/tests/TouchLatency/gradle/wrapper/gradle-wrapper.jar b/tests/TouchLatency/gradle/wrapper/gradle-wrapper.jar
index 758de96..7454180 100644
--- a/tests/TouchLatency/gradle/wrapper/gradle-wrapper.jar
+++ b/tests/TouchLatency/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/tests/TouchLatency/gradle/wrapper/gradle-wrapper.properties b/tests/TouchLatency/gradle/wrapper/gradle-wrapper.properties
index 4d9ca16..8049c68 100644
--- a/tests/TouchLatency/gradle/wrapper/gradle-wrapper.properties
+++ b/tests/TouchLatency/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/tests/TouchLatency/gradlew b/tests/TouchLatency/gradlew
index cccdd3d..1b6c787 100755
--- a/tests/TouchLatency/gradlew
+++ b/tests/TouchLatency/gradlew
@@ -1,78 +1,129 @@
-#!/usr/bin/env sh
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 
 ##############################################################################
-##
-##  Gradle start up script for UN*X
-##
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
 ##############################################################################
 
 # Attempt to set APP_HOME
+
 # Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
 done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
 
 APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
+APP_BASE_NAME=${0##*/}
 
 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
 
 warn () {
     echo "$*"
-}
+} >&2
 
 die () {
     echo
     echo "$*"
     echo
     exit 1
-}
+} >&2
 
 # OS specific support (must be 'true' or 'false').
 cygwin=false
 msys=false
 darwin=false
 nonstop=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MINGW* )
-    msys=true
-    ;;
-  NONSTOP* )
-    nonstop=true
-    ;;
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
 esac
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
+
 # Determine the Java command to use to start the JVM.
 if [ -n "$JAVA_HOME" ] ; then
     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
         # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
+        JAVACMD=$JAVA_HOME/jre/sh/java
     else
-        JAVACMD="$JAVA_HOME/bin/java"
+        JAVACMD=$JAVA_HOME/bin/java
     fi
     if [ ! -x "$JAVACMD" ] ; then
         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -81,7 +132,7 @@
 location of your Java installation."
     fi
 else
-    JAVACMD="java"
+    JAVACMD=java
     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 
 Please set the JAVA_HOME variable in your environment to match the
@@ -89,84 +140,95 @@
 fi
 
 # Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-    JAVACMD=`cygpath --unix "$JAVACMD"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
-    # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
-        fi
-        i=$((i+1))
-    done
-    case $i in
-        (0) set -- ;;
-        (1) set -- "$args0" ;;
-        (2) set -- "$args0" "$args1" ;;
-        (3) set -- "$args0" "$args1" "$args2" ;;
-        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
     esac
 fi
 
-# Escape application args
-save () {
-    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
-    echo " "
-}
-APP_ARGS=$(save "$@")
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
 
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
 
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
-  cd "$(dirname "$0")"
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
 fi
 
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
 exec "$JAVACMD" "$@"
diff --git a/tests/TouchLatency/gradlew.bat b/tests/TouchLatency/gradlew.bat
index e95643d..ac1b06f 100644
--- a/tests/TouchLatency/gradlew.bat
+++ b/tests/TouchLatency/gradlew.bat
@@ -1,3 +1,19 @@
+@rem

+@rem Copyright 2015 the original author or authors.

+@rem

+@rem Licensed under the Apache License, Version 2.0 (the "License");

+@rem you may not use this file except in compliance with the License.

+@rem You may obtain a copy of the License at

+@rem

+@rem      https://www.apache.org/licenses/LICENSE-2.0

+@rem

+@rem Unless required by applicable law or agreed to in writing, software

+@rem distributed under the License is distributed on an "AS IS" BASIS,

+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+@rem See the License for the specific language governing permissions and

+@rem limitations under the License.

+@rem

+

 @if "%DEBUG%" == "" @echo off

 @rem ##########################################################################

 @rem

@@ -13,15 +29,18 @@
 set APP_BASE_NAME=%~n0

 set APP_HOME=%DIRNAME%

 

+@rem Resolve any "." and ".." in APP_HOME to make it shorter.

+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

+

 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

-set DEFAULT_JVM_OPTS=

+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

 

 @rem Find java.exe

 if defined JAVA_HOME goto findJavaFromJavaHome

 

 set JAVA_EXE=java.exe

 %JAVA_EXE% -version >NUL 2>&1

-if "%ERRORLEVEL%" == "0" goto init

+if "%ERRORLEVEL%" == "0" goto execute

 

 echo.

 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

@@ -35,7 +54,7 @@
 set JAVA_HOME=%JAVA_HOME:"=%

 set JAVA_EXE=%JAVA_HOME%/bin/java.exe

 

-if exist "%JAVA_EXE%" goto init

+if exist "%JAVA_EXE%" goto execute

 

 echo.

 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

@@ -45,28 +64,14 @@
 

 goto fail

 

-:init

-@rem Get command-line arguments, handling Windows variants

-

-if not "%OS%" == "Windows_NT" goto win9xME_args

-

-:win9xME_args

-@rem Slurp the command line arguments.

-set CMD_LINE_ARGS=

-set _SKIP=2

-

-:win9xME_args_slurp

-if "x%~1" == "x" goto execute

-

-set CMD_LINE_ARGS=%*

-

 :execute

 @rem Setup the command line

 

 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

 

+

 @rem Execute Gradle

-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*

 

 :end

 @rem End local scope for the variables with windows NT shell

diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java
index c6e675a..e207b01 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java
@@ -185,6 +185,7 @@
          */
         @NonNull
         public Builder setExtras(@NonNull Bundle extras) {
+            Objects.requireNonNull(extras);
             mExtras = extras;
             return this;
         }
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java
deleted file mode 100644
index b18ab50..0000000
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java
+++ /dev/null
@@ -1,139 +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 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.HotspotNetwork.NETWORK_TYPE_CELLULAR;
-import static android.net.wifi.sharedconnectivity.app.HotspotNetworkConnectionStatus.CONNECTION_STATUS_ENABLING_HOTSPOT;
-import static android.net.wifi.sharedconnectivity.app.HotspotNetworkConnectionStatus.CONNECTION_STATUS_TETHERING_TIMEOUT;
-import static android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.DEVICE_TYPE_TABLET;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Bundle;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link HotspotNetworkConnectionStatus}.
- */
-@SmallTest
-public class HotspotNetworkConnectionStatusTest {
-    private static final long DEVICE_ID = 11L;
-    private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
-            new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
-                    .setDeviceType(DEVICE_TYPE_TABLET).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 String BUNDLE_KEY = "INT-KEY";
-    private static final int BUNDLE_VALUE = 1;
-
-    /**
-     * Verifies parcel serialization/deserialization.
-     */
-    @Test
-    public void testParcelOperation() {
-        HotspotNetworkConnectionStatus status = buildConnectionStatusBuilder().build();
-
-        Parcel parcelW = Parcel.obtain();
-        status.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        HotspotNetworkConnectionStatus fromParcel =
-                HotspotNetworkConnectionStatus.CREATOR.createFromParcel(parcelR);
-
-        assertThat(fromParcel).isEqualTo(status);
-        assertThat(fromParcel.hashCode()).isEqualTo(status.hashCode());
-    }
-
-    /**
-     * Verifies the Equals operation
-     */
-    @Test
-    public void testEqualsOperation() {
-        HotspotNetworkConnectionStatus status1 = buildConnectionStatusBuilder().build();
-        HotspotNetworkConnectionStatus status2 = buildConnectionStatusBuilder().build();
-        assertThat(status1).isEqualTo(status2);
-
-        HotspotNetworkConnectionStatus.Builder builder = buildConnectionStatusBuilder()
-                .setStatus(CONNECTION_STATUS_TETHERING_TIMEOUT);
-        assertThat(builder.build()).isNotEqualTo(status1);
-
-        builder = buildConnectionStatusBuilder()
-                .setHotspotNetwork(buildHotspotNetworkBuilder().setDeviceId(DEVICE_ID_1).build());
-        assertThat(builder.build()).isNotEqualTo(status1);
-    }
-
-    /**
-     * Verifies the get methods return the expected data.
-     */
-    @Test
-    public void testGetMethods() {
-        HotspotNetworkConnectionStatus status = buildConnectionStatusBuilder().build();
-        assertThat(status.getStatus()).isEqualTo(CONNECTION_STATUS_ENABLING_HOTSPOT);
-        assertThat(status.getHotspotNetwork()).isEqualTo(buildHotspotNetworkBuilder().build());
-        assertThat(status.getExtras().getInt(BUNDLE_KEY)).isEqualTo(BUNDLE_VALUE);
-    }
-
-    @Test
-    public void testHashCode() {
-        HotspotNetworkConnectionStatus status1 = buildConnectionStatusBuilder().build();
-        HotspotNetworkConnectionStatus status2 = buildConnectionStatusBuilder().build();
-
-        assertThat(status1.hashCode()).isEqualTo(status2.hashCode());
-    }
-
-    private HotspotNetworkConnectionStatus.Builder buildConnectionStatusBuilder() {
-        return new HotspotNetworkConnectionStatus.Builder()
-                .setStatus(CONNECTION_STATUS_ENABLING_HOTSPOT)
-                .setHotspotNetwork(buildHotspotNetworkBuilder().build())
-                .setExtras(buildBundle());
-    }
-
-    private Bundle buildBundle() {
-        Bundle bundle = new Bundle();
-        bundle.putInt(BUNDLE_KEY, BUNDLE_VALUE);
-        return bundle;
-    }
-
-    private HotspotNetwork.Builder buildHotspotNetworkBuilder() {
-        HotspotNetwork.Builder builder = new HotspotNetwork.Builder()
-                .setDeviceId(DEVICE_ID)
-                .setNetworkProviderInfo(NETWORK_PROVIDER_INFO)
-                .setHostNetworkType(NETWORK_TYPE)
-                .setNetworkName(NETWORK_NAME)
-                .setHotspotSsid(HOTSPOT_SSID)
-                .setHotspotBssid(HOTSPOT_BSSID);
-        Arrays.stream(HOTSPOT_SECURITY_TYPES).forEach(builder::addHotspotSecurityType);
-        return builder;
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java
deleted file mode 100644
index 0827ffa..0000000
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java
+++ /dev/null
@@ -1,182 +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 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.HotspotNetwork.NETWORK_TYPE_CELLULAR;
-import static android.net.wifi.sharedconnectivity.app.HotspotNetwork.NETWORK_TYPE_WIFI;
-import static android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.DEVICE_TYPE_PHONE;
-import static android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.DEVICE_TYPE_TABLET;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-
-import android.os.Bundle;
-import android.os.Parcel;
-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.Arrays;
-
-/**
- * Unit tests for {@link HotspotNetwork}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class HotspotNetworkTest {
-    private static final long DEVICE_ID = 11L;
-    private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
-            new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
-                    .setDeviceType(DEVICE_TYPE_TABLET).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 String BUNDLE_KEY = "INT-KEY";
-    private static final int BUNDLE_VALUE = 1;
-
-    private static final long DEVICE_ID_1 = 111L;
-    private static final NetworkProviderInfo NETWORK_PROVIDER_INFO1 =
-            new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
-                    .setDeviceType(DEVICE_TYPE_PHONE).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() {
-        HotspotNetwork network = buildHotspotNetworkBuilder(true).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);
-        HotspotNetwork fromParcel = HotspotNetwork.CREATOR.createFromParcel(parcelR);
-
-        assertThat(fromParcel).isEqualTo(network);
-        assertThat(fromParcel.hashCode()).isEqualTo(network.hashCode());
-    }
-
-    /**
-     * Verifies the Equals operation
-     */
-    @Test
-    public void testEqualsOperation() {
-        HotspotNetwork network1 = buildHotspotNetworkBuilder(true).build();
-        HotspotNetwork network2 = buildHotspotNetworkBuilder(true).build();
-        assertThat(network1).isEqualTo(network2);
-
-        HotspotNetwork.Builder builder = buildHotspotNetworkBuilder(true).setDeviceId(DEVICE_ID_1);
-        assertThat(builder.build()).isNotEqualTo(network1);
-
-        builder = buildHotspotNetworkBuilder(true).setNetworkProviderInfo(NETWORK_PROVIDER_INFO1);
-        assertThat(builder.build()).isNotEqualTo(network1);
-
-        builder = buildHotspotNetworkBuilder(true).setHostNetworkType(NETWORK_TYPE_1);
-        assertThat(builder.build()).isNotEqualTo(network1);
-
-        builder = buildHotspotNetworkBuilder(true).setNetworkName(NETWORK_NAME_1);
-        assertThat(builder.build()).isNotEqualTo(network1);
-
-        builder = buildHotspotNetworkBuilder(true).setHotspotSsid(HOTSPOT_SSID_1);
-        assertThat(builder.build()).isNotEqualTo(network1);
-
-        builder = buildHotspotNetworkBuilder(true).setHotspotBssid(HOTSPOT_BSSID_1);
-        assertThat(builder.build()).isNotEqualTo(network1);
-
-        builder = buildHotspotNetworkBuilder(true);
-        HotspotNetwork.Builder builder1 = buildHotspotNetworkBuilder(true);
-        Arrays.stream(HOTSPOT_SECURITY_TYPES_1).forEach(builder1::addHotspotSecurityType);
-
-        assertThat(builder1.build()).isNotEqualTo(builder.build());
-    }
-
-    /**
-     * Verifies the get methods return the expected data.
-     */
-    @Test
-    public void testGetMethods() {
-        HotspotNetwork network = buildHotspotNetworkBuilder(true).build();
-        ArraySet<Integer> securityTypes = new ArraySet<>();
-        Arrays.stream(HOTSPOT_SECURITY_TYPES).forEach(securityTypes::add);
-
-        assertThat(network.getDeviceId()).isEqualTo(DEVICE_ID);
-        assertThat(network.getNetworkProviderInfo()).isEqualTo(NETWORK_PROVIDER_INFO);
-        assertThat(network.getHostNetworkType()).isEqualTo(NETWORK_TYPE);
-        assertThat(network.getNetworkName()).isEqualTo(NETWORK_NAME);
-        assertThat(network.getHotspotSsid()).isEqualTo(HOTSPOT_SSID);
-        assertThat(network.getHotspotBssid()).isEqualTo(HOTSPOT_BSSID);
-        assertThat(network.getHotspotSecurityTypes()).containsExactlyElementsIn(securityTypes);
-        assertThat(network.getExtras().getInt(BUNDLE_KEY)).isEqualTo(BUNDLE_VALUE);
-    }
-
-    @Test
-    public void testHashCode() {
-        HotspotNetwork network1 = buildHotspotNetworkBuilder(true).build();
-        HotspotNetwork network2 = buildHotspotNetworkBuilder(true).build();
-
-        assertThat(network1.hashCode()).isEqualTo(network2.hashCode());
-    }
-
-    @Test
-    public void networkProviderInfoNotSet_shouldThrowException() {
-        Exception e = assertThrows(IllegalArgumentException.class,
-                () -> buildHotspotNetworkBuilder(false).build());
-        assertThat(e.getMessage()).contains("NetworkProviderInfo");
-    }
-
-    private HotspotNetwork.Builder buildHotspotNetworkBuilder(boolean withNetworkProviderInfo) {
-        HotspotNetwork.Builder builder = new HotspotNetwork.Builder()
-                .setDeviceId(DEVICE_ID)
-                .setHostNetworkType(NETWORK_TYPE)
-                .setNetworkName(NETWORK_NAME)
-                .setHotspotSsid(HOTSPOT_SSID)
-                .setHotspotBssid(HOTSPOT_BSSID)
-                .setExtras(buildBundle());
-        Arrays.stream(HOTSPOT_SECURITY_TYPES).forEach(builder::addHotspotSecurityType);
-        if (withNetworkProviderInfo) {
-            builder.setNetworkProviderInfo(NETWORK_PROVIDER_INFO);
-        }
-        return builder;
-    }
-
-    private Bundle buildBundle() {
-        Bundle bundle = new Bundle();
-        bundle.putInt(BUNDLE_KEY, BUNDLE_VALUE);
-        return bundle;
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java
deleted file mode 100644
index f98a0fc..0000000
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java
+++ /dev/null
@@ -1,131 +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 android.net.wifi.sharedconnectivity.app;
-
-import static android.net.wifi.WifiInfo.SECURITY_TYPE_WEP;
-import static android.net.wifi.sharedconnectivity.app.KnownNetwork.NETWORK_SOURCE_NEARBY_SELF;
-import static android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus.CONNECTION_STATUS_SAVED;
-import static android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus.CONNECTION_STATUS_SAVE_FAILED;
-import static android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.DEVICE_TYPE_TABLET;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Bundle;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link KnownNetworkConnectionStatus}.
- */
-@SmallTest
-public class KnownNetworkConnectionStatusTest {
-    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 NetworkProviderInfo NETWORK_PROVIDER_INFO =
-            new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
-                    .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
-                    .setBatteryPercentage(50).build();
-    private static final String SSID_1 = "TEST_SSID1";
-    private static final String BUNDLE_KEY = "INT-KEY";
-    private static final int BUNDLE_VALUE = 1;
-
-    /**
-     * Verifies parcel serialization/deserialization.
-     */
-    @Test
-    public void testParcelOperation() {
-        KnownNetworkConnectionStatus status = buildConnectionStatusBuilder().build();
-
-        Parcel parcelW = Parcel.obtain();
-        status.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        KnownNetworkConnectionStatus fromParcel =
-                KnownNetworkConnectionStatus.CREATOR.createFromParcel(parcelR);
-
-        assertThat(fromParcel).isEqualTo(status);
-        assertThat(fromParcel.hashCode()).isEqualTo(status.hashCode());
-    }
-
-    /**
-     * Verifies the Equals operation
-     */
-    @Test
-    public void testEqualsOperation() {
-        KnownNetworkConnectionStatus status1 = buildConnectionStatusBuilder().build();
-        KnownNetworkConnectionStatus status2 = buildConnectionStatusBuilder().build();
-        assertThat(status1).isEqualTo(status2);
-
-        KnownNetworkConnectionStatus.Builder builder = buildConnectionStatusBuilder()
-                .setStatus(CONNECTION_STATUS_SAVE_FAILED);
-        assertThat(builder.build()).isNotEqualTo(status1);
-
-        builder = buildConnectionStatusBuilder()
-                .setKnownNetwork(buildKnownNetworkBuilder().setSsid(SSID_1).build());
-        assertThat(builder.build()).isNotEqualTo(status1);
-    }
-
-    /**
-     * Verifies the get methods return the expected data.
-     */
-    @Test
-    public void testGetMethods() {
-        KnownNetworkConnectionStatus status = buildConnectionStatusBuilder().build();
-        assertThat(status.getStatus()).isEqualTo(CONNECTION_STATUS_SAVED);
-        assertThat(status.getKnownNetwork()).isEqualTo(buildKnownNetworkBuilder().build());
-        assertThat(status.getExtras().getInt(BUNDLE_KEY)).isEqualTo(BUNDLE_VALUE);
-    }
-
-    @Test
-    public void testHashCode() {
-        KnownNetworkConnectionStatus status1 = buildConnectionStatusBuilder().build();
-        KnownNetworkConnectionStatus status2 = buildConnectionStatusBuilder().build();
-
-        assertThat(status1.hashCode()).isEqualTo(status2.hashCode());
-    }
-
-    private KnownNetworkConnectionStatus.Builder buildConnectionStatusBuilder() {
-        return new KnownNetworkConnectionStatus.Builder()
-                .setStatus(CONNECTION_STATUS_SAVED)
-                .setKnownNetwork(buildKnownNetworkBuilder().build())
-                .setExtras(buildBundle());
-    }
-
-    private Bundle buildBundle() {
-        Bundle bundle = new Bundle();
-        bundle.putInt(BUNDLE_KEY, BUNDLE_VALUE);
-        return bundle;
-    }
-
-    private KnownNetwork.Builder buildKnownNetworkBuilder() {
-        KnownNetwork.Builder builder = new KnownNetwork.Builder().setNetworkSource(NETWORK_SOURCE)
-                .setSsid(SSID).setNetworkProviderInfo(NETWORK_PROVIDER_INFO);
-        Arrays.stream(SECURITY_TYPES).forEach(builder::addSecurityType);
-        return builder;
-    }
-
-}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
deleted file mode 100644
index 81d7b44..0000000
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
+++ /dev/null
@@ -1,144 +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 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.KnownNetwork.NETWORK_SOURCE_CLOUD_SELF;
-import static android.net.wifi.sharedconnectivity.app.KnownNetwork.NETWORK_SOURCE_NEARBY_SELF;
-import static android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.DEVICE_TYPE_PHONE;
-import static android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.DEVICE_TYPE_TABLET;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.util.ArraySet;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link 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 NetworkProviderInfo NETWORK_PROVIDER_INFO =
-            new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
-                    .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
-                    .setBatteryPercentage(50).build();
-    private static final String BUNDLE_KEY = "INT-KEY";
-    private static final int BUNDLE_VALUE = 1;
-
-    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 NetworkProviderInfo NETWORK_PROVIDER_INFO1 =
-            new NetworkProviderInfo.Builder("TEST_NAME_1", "TEST_MODEL_1")
-                    .setDeviceType(DEVICE_TYPE_PHONE).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);
-
-        assertThat(fromParcel).isEqualTo(network);
-        assertThat(fromParcel.hashCode()).isEqualTo(network.hashCode());
-    }
-
-    /**
-     * Verifies the Equals operation
-     */
-    @Test
-    public void testEqualsOperation() {
-        KnownNetwork network1 = buildKnownNetworkBuilder().build();
-        KnownNetwork network2 = buildKnownNetworkBuilder().build();
-        assertThat(network1).isEqualTo(network2);
-
-        KnownNetwork.Builder builder = buildKnownNetworkBuilder()
-                .setNetworkSource(NETWORK_SOURCE_1);
-        assertThat(builder.build()).isNotEqualTo(network1);
-
-        builder = buildKnownNetworkBuilder().setSsid(SSID_1);
-        assertThat(builder.build()).isNotEqualTo(network1);
-
-        builder = buildKnownNetworkBuilder();
-        Arrays.stream(SECURITY_TYPES_1).forEach(builder::addSecurityType);
-        assertThat(builder.build()).isNotEqualTo(network1);
-
-        builder = buildKnownNetworkBuilder().setNetworkProviderInfo(NETWORK_PROVIDER_INFO1);
-        assertThat(builder.build()).isNotEqualTo(network1);
-    }
-
-    /**
-     * Verifies the get methods return the expected data.
-     */
-    @Test
-    public void testGetMethods() {
-        KnownNetwork network = buildKnownNetworkBuilder().build();
-        ArraySet<Integer> securityTypes = new ArraySet<>();
-        Arrays.stream(SECURITY_TYPES).forEach(securityTypes::add);
-
-        assertThat(network.getNetworkSource()).isEqualTo(NETWORK_SOURCE);
-        assertThat(network.getSsid()).isEqualTo(SSID);
-        assertThat(network.getSecurityTypes()).containsExactlyElementsIn(securityTypes);
-        assertThat(network.getNetworkProviderInfo()).isEqualTo(NETWORK_PROVIDER_INFO);
-        assertThat(network.getExtras().getInt(BUNDLE_KEY)).isEqualTo(BUNDLE_VALUE);
-    }
-
-    @Test
-    public void testHashCode() {
-        KnownNetwork network1 = buildKnownNetworkBuilder().build();
-        KnownNetwork network2 = buildKnownNetworkBuilder().build();
-
-        assertThat(network1.hashCode()).isEqualTo(network2.hashCode());
-    }
-
-    private KnownNetwork.Builder buildKnownNetworkBuilder() {
-        KnownNetwork.Builder builder = new KnownNetwork.Builder().setNetworkSource(NETWORK_SOURCE)
-                .setSsid(SSID).setNetworkProviderInfo(NETWORK_PROVIDER_INFO)
-                .setExtras(buildBundle());
-        Arrays.stream(SECURITY_TYPES).forEach(builder::addSecurityType);
-        return builder;
-    }
-
-    private Bundle buildBundle() {
-        Bundle bundle = new Bundle();
-        bundle.putInt(BUNDLE_KEY, BUNDLE_VALUE);
-        return bundle;
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java
deleted file mode 100644
index 4aa9ca6..0000000
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java
+++ /dev/null
@@ -1,134 +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 android.net.wifi.sharedconnectivity.app;
-
-import static android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.DEVICE_TYPE_LAPTOP;
-import static android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.DEVICE_TYPE_PHONE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Bundle;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link NetworkProviderInfo}.
- */
-@SmallTest
-public class NetworkProviderInfoTest {
-
-    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 String BUNDLE_KEY = "INT-KEY";
-    private static final int BUNDLE_VALUE = 1;
-
-    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() {
-        NetworkProviderInfo info = buildNetworkProviderInfoBuilder().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);
-        NetworkProviderInfo fromParcel = NetworkProviderInfo.CREATOR.createFromParcel(parcelR);
-
-        assertThat(fromParcel).isEqualTo(info);
-        assertThat(fromParcel.hashCode()).isEqualTo(info.hashCode());
-    }
-
-    /**
-     * Verifies the Equals operation
-     */
-    @Test
-    public void testEqualsOperation() {
-        NetworkProviderInfo info1 = buildNetworkProviderInfoBuilder().build();
-        NetworkProviderInfo info2 = buildNetworkProviderInfoBuilder().build();
-        assertThat(info1).isEqualTo(info2);
-
-        NetworkProviderInfo.Builder builder = buildNetworkProviderInfoBuilder().setDeviceType(
-                DEVICE_TYPE_1);
-        assertThat(builder.build()).isNotEqualTo(info1);
-
-        builder = buildNetworkProviderInfoBuilder().setDeviceName(DEVICE_NAME_1);
-        assertThat(builder.build()).isNotEqualTo(info1);
-
-        builder = buildNetworkProviderInfoBuilder().setModelName(DEVICE_MODEL_1);
-        assertThat(builder.build()).isNotEqualTo(info1);
-
-        builder = buildNetworkProviderInfoBuilder()
-                .setBatteryPercentage(BATTERY_PERCENTAGE_1);
-        assertThat(builder.build()).isNotEqualTo(info1);
-
-        builder = buildNetworkProviderInfoBuilder()
-                .setConnectionStrength(CONNECTION_STRENGTH_1);
-        assertThat(builder.build()).isNotEqualTo(info1);
-    }
-
-    /**
-     * Verifies the get methods return the expected data.
-     */
-    @Test
-    public void testGetMethods() {
-        NetworkProviderInfo info = buildNetworkProviderInfoBuilder().build();
-        assertThat(info.getDeviceType()).isEqualTo(DEVICE_TYPE);
-        assertThat(info.getDeviceName()).isEqualTo(DEVICE_NAME);
-        assertThat(info.getModelName()).isEqualTo(DEVICE_MODEL);
-        assertThat(info.getBatteryPercentage()).isEqualTo(BATTERY_PERCENTAGE);
-        assertThat(info.getConnectionStrength()).isEqualTo(CONNECTION_STRENGTH);
-        assertThat(info.getExtras().getInt(BUNDLE_KEY)).isEqualTo(BUNDLE_VALUE);
-    }
-
-    @Test
-    public void testHashCode() {
-        NetworkProviderInfo info1 = buildNetworkProviderInfoBuilder().build();
-        NetworkProviderInfo info2 = buildNetworkProviderInfoBuilder().build();
-
-        assertThat(info1.hashCode()).isEqualTo(info2.hashCode());
-    }
-
-    private NetworkProviderInfo.Builder buildNetworkProviderInfoBuilder() {
-        return new NetworkProviderInfo.Builder(DEVICE_NAME, DEVICE_MODEL).setDeviceType(DEVICE_TYPE)
-                .setBatteryPercentage(BATTERY_PERCENTAGE)
-                .setConnectionStrength(CONNECTION_STRENGTH)
-                .setExtras(buildBundle());
-    }
-
-    private Bundle buildBundle() {
-        Bundle bundle = new Bundle();
-        bundle.putInt(BUNDLE_KEY, BUNDLE_VALUE);
-        return bundle;
-    }
-}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
deleted file mode 100644
index a03a6c2..0000000
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
+++ /dev/null
@@ -1,566 +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 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.HotspotNetwork.NETWORK_TYPE_CELLULAR;
-import static android.net.wifi.sharedconnectivity.app.KnownNetwork.NETWORK_SOURCE_NEARBY_SELF;
-import static android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.DEVICE_TYPE_TABLET;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-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.ISharedConnectivityService;
-import android.os.Bundle;
-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.Arrays;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Unit tests for {@link SharedConnectivityManager}.
- */
-@SmallTest
-public class SharedConnectivityManagerTest {
-    private static final long DEVICE_ID = 11L;
-    private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
-            new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
-                    .setDeviceType(DEVICE_TYPE_TABLET).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 String SERVICE_PACKAGE_NAME = "TEST_PACKAGE";
-    private static final String SERVICE_INTENT_ACTION = "TEST_INTENT_ACTION";
-
-
-    @Mock
-    Context mContext;
-    @Mock
-    ISharedConnectivityService mService;
-    @Mock
-    Executor mExecutor;
-    @Mock
-    SharedConnectivityClientCallback mClientCallback, mClientCallback2;
-    @Mock
-    Resources mResources;
-    @Mock
-    ISharedConnectivityService.Stub mIBinder;
-
-    private static final ComponentName COMPONENT_NAME =
-            new ComponentName("dummypkg", "dummycls");
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        setResources(mContext);
-    }
-
-    @Test
-    public void resourcesNotDefined_createShouldReturnNull() {
-        when(mResources.getString(anyInt())).thenThrow(new Resources.NotFoundException());
-
-        assertThat(SharedConnectivityManager.create(mContext)).isNull();
-    }
-
-    @Test
-    public void resourceStringsAreEmpty_createShouldReturnNull() {
-        when(mResources.getString(anyInt())).thenReturn("");
-
-        assertThat(SharedConnectivityManager.create(mContext)).isNull();
-    }
-
-    @Test
-    public void bindingToServiceOnFirstCallbackRegistration() {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.registerCallback(mExecutor, mClientCallback);
-
-        verify(mContext).bindService(any(Intent.class), any(ServiceConnection.class), anyInt());
-    }
-
-    @Test
-    public void bindIsCalledOnceOnMultipleCallbackRegistrations() throws Exception {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-        verify(mContext, times(1)).bindService(any(Intent.class), any(ServiceConnection.class),
-                anyInt());
-
-        manager.registerCallback(mExecutor, mClientCallback2);
-        verify(mContext, times(1)).bindService(any(Intent.class), any(ServiceConnection.class),
-                anyInt());
-    }
-
-    @Test
-    public void unbindIsCalledOnLastCallbackUnregistrations() throws Exception {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-        manager.registerCallback(mExecutor, mClientCallback2);
-        manager.unregisterCallback(mClientCallback);
-        verify(mContext, never()).unbindService(
-                any(ServiceConnection.class));
-
-        manager.unregisterCallback(mClientCallback2);
-        verify(mContext, times(1)).unbindService(
-                any(ServiceConnection.class));
-    }
-
-    @Test
-    public void registerCallback_serviceNotConnected_canUnregisterAndReregister() {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-        manager.unregisterCallback(mClientCallback);
-        manager.registerCallback(mExecutor, mClientCallback);
-
-        verify(mClientCallback, never()).onRegisterCallbackFailed(any(Exception.class));
-    }
-
-    @Test
-    public void registerCallback_serviceConnected() throws Exception {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-
-        verify(mService).registerCallback(any());
-        verify(mClientCallback, never()).onRegisterCallbackFailed(any(Exception.class));
-    }
-
-    @Test
-    public void registerCallback_doubleRegistration_shouldFail() throws Exception {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-        manager.registerCallback(mExecutor, mClientCallback);
-
-        verify(mClientCallback).onRegisterCallbackFailed(any(IllegalStateException.class));
-    }
-
-    @Test
-    public void registerCallback_remoteException_shouldFail() throws Exception {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).registerCallback(any());
-
-        manager.registerCallback(mExecutor, mClientCallback);
-
-        verify(mClientCallback).onRegisterCallbackFailed(any(RemoteException.class));
-    }
-
-    @Test
-    public void unregisterCallback_withoutRegisteringFirst_serviceNotConnected_shouldFail() {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.unregisterCallback(mClientCallback)).isFalse();
-    }
-
-    @Test
-    public void unregisterCallback_withoutRegisteringFirst_serviceConnected_shouldFail() {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        assertThat(manager.unregisterCallback(mClientCallback)).isFalse();
-    }
-
-    @Test
-    public void unregisterCallback() throws Exception {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-
-        assertThat(manager.unregisterCallback(mClientCallback)).isTrue();
-        verify(mService).unregisterCallback(any());
-    }
-
-    @Test
-    public void unregisterCallback_doubleUnregistration_serviceConnected_shouldFail() {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-        manager.unregisterCallback(mClientCallback);
-
-        assertThat(manager.unregisterCallback(mClientCallback)).isFalse();
-    }
-
-    @Test
-    public void unregisterCallback_doubleUnregistration_serviceNotConnected_shouldFail() {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-        manager.unregisterCallback(mClientCallback);
-
-        assertThat(manager.unregisterCallback(mClientCallback)).isFalse();
-    }
-
-    @Test
-    public void unregisterCallback_remoteException_shouldFail() throws Exception {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        doThrow(new RemoteException()).when(mService).unregisterCallback(any());
-
-        assertThat(manager.unregisterCallback(mClientCallback)).isFalse();
-    }
-
-    @Test
-    public void onServiceConnected() {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-        manager.getServiceConnection().onServiceConnected(COMPONENT_NAME, mIBinder);
-
-        verify(mClientCallback).onServiceConnected();
-    }
-
-    @Test
-    public void onServiceDisconnected() {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-
-        manager.registerCallback(mExecutor, mClientCallback);
-        manager.getServiceConnection().onServiceConnected(COMPONENT_NAME, mIBinder);
-        manager.getServiceConnection().onServiceDisconnected(COMPONENT_NAME);
-
-        verify(mClientCallback).onServiceDisconnected();
-    }
-
-
-    @Test
-    public void connectHotspotNetwork_serviceNotConnected_shouldFail() {
-        HotspotNetwork network = buildHotspotNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.connectHotspotNetwork(network)).isFalse();
-    }
-
-    @Test
-    public void connectHotspotNetwork() throws RemoteException {
-        HotspotNetwork network = buildHotspotNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        manager.connectHotspotNetwork(network);
-
-        verify(mService).connectHotspotNetwork(network);
-    }
-
-    @Test
-    public void connectHotspotNetwork_remoteException_shouldFail() throws RemoteException {
-        HotspotNetwork network = buildHotspotNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).connectHotspotNetwork(network);
-
-        assertThat(manager.connectHotspotNetwork(network)).isFalse();
-    }
-
-    @Test
-    public void disconnectHotspotNetwork_serviceNotConnected_shouldFail() {
-        HotspotNetwork network = buildHotspotNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.disconnectHotspotNetwork(network)).isFalse();
-    }
-
-    @Test
-    public void disconnectHotspotNetwork() throws RemoteException {
-        HotspotNetwork network = buildHotspotNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        manager.disconnectHotspotNetwork(network);
-
-        verify(mService).disconnectHotspotNetwork(network);
-    }
-
-    @Test
-    public void disconnectHotspotNetwork_remoteException_shouldFail() throws RemoteException {
-        HotspotNetwork network = buildHotspotNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).disconnectHotspotNetwork(any());
-
-        assertThat(manager.disconnectHotspotNetwork(network)).isFalse();
-    }
-
-    @Test
-    public void connectKnownNetwork_serviceNotConnected_shouldFail() throws RemoteException {
-        KnownNetwork network = buildKnownNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.connectKnownNetwork(network)).isFalse();
-    }
-
-    @Test
-    public void connectKnownNetwork() throws RemoteException {
-        KnownNetwork network = buildKnownNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        manager.connectKnownNetwork(network);
-
-        verify(mService).connectKnownNetwork(network);
-    }
-
-    @Test
-    public void connectKnownNetwork_remoteException_shouldFail() throws RemoteException {
-        KnownNetwork network = buildKnownNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).connectKnownNetwork(network);
-
-        assertThat(manager.connectKnownNetwork(network)).isFalse();
-    }
-
-    @Test
-    public void forgetKnownNetwork_serviceNotConnected_shouldFail() {
-        KnownNetwork network = buildKnownNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.forgetKnownNetwork(network)).isFalse();
-    }
-
-    @Test
-    public void forgetKnownNetwork_serviceConnected() throws RemoteException {
-        KnownNetwork network = buildKnownNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-
-        manager.forgetKnownNetwork(network);
-
-        verify(mService).forgetKnownNetwork(network);
-    }
-
-    @Test
-    public void forgetKnownNetwork_remoteException_shouldFail() throws RemoteException {
-        KnownNetwork network = buildKnownNetwork();
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).forgetKnownNetwork(network);
-
-        assertThat(manager.forgetKnownNetwork(network)).isFalse();
-    }
-
-    @Test
-    public void getHotspotNetworks_serviceNotConnected_shouldReturnNull() {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.getHotspotNetworks()).isNull();
-    }
-
-    @Test
-    public void getHotspotNetworks_remoteException_shouldReturnNull() throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).getHotspotNetworks();
-
-        assertThat(manager.getHotspotNetworks()).isNull();
-    }
-
-    @Test
-    public void getHotspotNetworks_shouldReturnNetworksList() throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        List<HotspotNetwork> networks = List.of(buildHotspotNetwork());
-        manager.setService(mService);
-        when(mService.getHotspotNetworks()).thenReturn(networks);
-
-        assertThat(manager.getHotspotNetworks()).containsExactly(buildHotspotNetwork());
-    }
-
-    @Test
-    public void getKnownNetworks_serviceNotConnected_shouldReturnNull()
-            throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.getKnownNetworks()).isNull();
-    }
-
-    @Test
-    public void getKnownNetworks_remoteException_shouldReturnNull() throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).getKnownNetworks();
-
-        assertThat(manager.getKnownNetworks()).isNull();
-    }
-
-    @Test
-    public void getKnownNetworks_shouldReturnNetworksList() throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        List<KnownNetwork> networks = List.of(buildKnownNetwork());
-        manager.setService(mService);
-        when(mService.getKnownNetworks()).thenReturn(networks);
-
-        assertThat(manager.getKnownNetworks()).containsExactly(buildKnownNetwork());
-    }
-
-    @Test
-    public void getSettingsState_serviceNotConnected_shouldReturnNull() throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.getSettingsState()).isNull();
-    }
-
-    @Test
-    public void getSettingsState_remoteException_shouldReturnNull() throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).getSettingsState();
-
-        assertThat(manager.getSettingsState()).isNull();
-    }
-
-    @Test
-    public void getSettingsState_serviceConnected_shouldReturnState() throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        SharedConnectivitySettingsState state =
-                new SharedConnectivitySettingsState.Builder().setInstantTetherEnabled(true)
-                        .setExtras(new Bundle()).build();
-        manager.setService(mService);
-        when(mService.getSettingsState()).thenReturn(state);
-
-        assertThat(manager.getSettingsState()).isEqualTo(state);
-    }
-
-    @Test
-    public void getHotspotNetworkConnectionStatus_serviceNotConnected_shouldReturnNull()
-            throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.getHotspotNetworkConnectionStatus()).isNull();
-    }
-
-    @Test
-    public void getHotspotNetworkConnectionStatus_remoteException_shouldReturnNull()
-            throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).getHotspotNetworkConnectionStatus();
-
-        assertThat(manager.getHotspotNetworkConnectionStatus()).isNull();
-    }
-
-    @Test
-    public void getHotspotNetworkConnectionStatus_serviceConnected_shouldReturnStatus()
-            throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        HotspotNetworkConnectionStatus status = new HotspotNetworkConnectionStatus.Builder()
-                .setStatus(HotspotNetworkConnectionStatus.CONNECTION_STATUS_ENABLING_HOTSPOT)
-                .setExtras(new Bundle()).build();
-        manager.setService(mService);
-        when(mService.getHotspotNetworkConnectionStatus()).thenReturn(status);
-
-        assertThat(manager.getHotspotNetworkConnectionStatus()).isEqualTo(status);
-    }
-
-    @Test
-    public void getKnownNetworkConnectionStatus_serviceNotConnected_shouldReturnNull()
-            throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(null);
-
-        assertThat(manager.getKnownNetworkConnectionStatus()).isNull();
-    }
-
-    @Test
-    public void getKnownNetworkConnectionStatus_remoteException_shouldReturnNull()
-            throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        manager.setService(mService);
-        doThrow(new RemoteException()).when(mService).getKnownNetworkConnectionStatus();
-
-        assertThat(manager.getKnownNetworkConnectionStatus()).isNull();
-    }
-
-    @Test
-    public void getKnownNetworkConnectionStatus_serviceConnected_shouldReturnStatus()
-            throws RemoteException {
-        SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
-        KnownNetworkConnectionStatus status = new KnownNetworkConnectionStatus.Builder()
-                .setStatus(KnownNetworkConnectionStatus.CONNECTION_STATUS_SAVED)
-                .setExtras(new Bundle()).build();
-        manager.setService(mService);
-        when(mService.getKnownNetworkConnectionStatus()).thenReturn(status);
-
-        assertThat(manager.getKnownNetworkConnectionStatus()).isEqualTo(status);
-    }
-
-    private void setResources(@Mock Context context) {
-        when(context.getResources()).thenReturn(mResources);
-        when(mResources.getString(anyInt()))
-                .thenReturn(SERVICE_PACKAGE_NAME, SERVICE_INTENT_ACTION);
-    }
-
-    private HotspotNetwork buildHotspotNetwork() {
-        HotspotNetwork.Builder builder = new HotspotNetwork.Builder()
-                .setDeviceId(DEVICE_ID)
-                .setNetworkProviderInfo(NETWORK_PROVIDER_INFO)
-                .setHostNetworkType(NETWORK_TYPE)
-                .setNetworkName(NETWORK_NAME)
-                .setHotspotSsid(HOTSPOT_SSID);
-        Arrays.stream(HOTSPOT_SECURITY_TYPES).forEach(builder::addHotspotSecurityType);
-        return builder.build();
-    }
-
-    private KnownNetwork buildKnownNetwork() {
-        KnownNetwork.Builder builder = new KnownNetwork.Builder().setNetworkSource(NETWORK_SOURCE)
-                .setSsid(SSID).setNetworkProviderInfo(NETWORK_PROVIDER_INFO);
-        Arrays.stream(SECURITY_TYPES).forEach(builder::addSecurityType);
-        return builder.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
deleted file mode 100644
index d6e7138..0000000
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsStateTest.java
+++ /dev/null
@@ -1,115 +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 android.net.wifi.sharedconnectivity.app;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Parcel;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link SharedConnectivitySettingsState}.
- */
-@SmallTest
-public class SharedConnectivitySettingsStateTest {
-    private static final boolean INSTANT_TETHER_STATE = true;
-    private static final String INTENT_ACTION = "instant.tether.settings";
-
-    private static final boolean INSTANT_TETHER_STATE_1 = false;
-    private static final String INTENT_ACTION_1 = "instant.tether.settings1";
-
-    @Test
-    public void pendingIntentMutable_buildShouldThrow() {
-        SharedConnectivitySettingsState.Builder builder =
-                new SharedConnectivitySettingsState.Builder()
-                        .setInstantTetherEnabled(INSTANT_TETHER_STATE)
-                        .setInstantTetherSettingsPendingIntent(PendingIntent.getActivity(
-                                ApplicationProvider.getApplicationContext(), 0,
-                                new Intent(INTENT_ACTION).setComponent(new ComponentName(
-                                        "com.test.package", "TestClass")),
-                                PendingIntent.FLAG_MUTABLE));
-
-        Exception e = assertThrows(IllegalArgumentException.class, builder::build);
-        assertThat(e.getMessage()).contains("Pending intent must be immutable");
-    }
-
-    @Test
-    public void parcelOperation() {
-        SharedConnectivitySettingsState state = buildSettingsStateBuilder(INTENT_ACTION).build();
-
-        Parcel parcel = Parcel.obtain();
-        state.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        SharedConnectivitySettingsState fromParcel =
-                SharedConnectivitySettingsState.CREATOR.createFromParcel(parcel);
-
-        assertThat(fromParcel).isEqualTo(state);
-        assertThat(fromParcel.hashCode()).isEqualTo(state.hashCode());
-    }
-
-    @Test
-    public void equalsOperation() {
-        SharedConnectivitySettingsState state1 = buildSettingsStateBuilder(INTENT_ACTION).build();
-        SharedConnectivitySettingsState state2 = buildSettingsStateBuilder(INTENT_ACTION).build();
-        assertThat(state1).isEqualTo(state2);
-
-        SharedConnectivitySettingsState.Builder builder = buildSettingsStateBuilder(INTENT_ACTION)
-                .setInstantTetherEnabled(INSTANT_TETHER_STATE_1);
-        assertThat(builder.build()).isNotEqualTo(state1);
-
-        builder = buildSettingsStateBuilder(INTENT_ACTION_1);
-        assertThat(builder.build()).isNotEqualTo(state1);
-    }
-
-    @Test
-    public void getMethods() {
-        SharedConnectivitySettingsState state = buildSettingsStateBuilder(INTENT_ACTION).build();
-
-        assertThat(state.isInstantTetherEnabled()).isEqualTo(INSTANT_TETHER_STATE);
-        assertThat(state.getInstantTetherSettingsPendingIntent())
-                .isEqualTo(buildPendingIntent(INTENT_ACTION));
-    }
-
-    @Test
-    public void hashCodeCalculation() {
-        SharedConnectivitySettingsState state1 = buildSettingsStateBuilder(INTENT_ACTION).build();
-        SharedConnectivitySettingsState state2 = buildSettingsStateBuilder(INTENT_ACTION).build();
-
-        assertThat(state1.hashCode()).isEqualTo(state2.hashCode());
-    }
-
-    private SharedConnectivitySettingsState.Builder buildSettingsStateBuilder(String intentAction) {
-        return new SharedConnectivitySettingsState.Builder()
-                .setInstantTetherEnabled(INSTANT_TETHER_STATE)
-                .setInstantTetherSettingsPendingIntent(buildPendingIntent(intentAction));
-    }
-
-    private PendingIntent buildPendingIntent(String intentAction) {
-        return PendingIntent.getActivity(
-                ApplicationProvider.getApplicationContext(), 0,
-                new Intent(intentAction), PendingIntent.FLAG_IMMUTABLE);
-    }
-}