Merge "Throw the SecurityException only on V+ builds." into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index c80f2ea..1fb5f34 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -55,6 +55,8 @@
     ":android.app.flags-aconfig-java{.generated_srcjars}",
     ":android.credentials.flags-aconfig-java{.generated_srcjars}",
     ":android.view.contentprotection.flags-aconfig-java{.generated_srcjars}",
+    ":com.android.server.flags.pinner-aconfig-java{.generated_srcjars}",
+    ":android.service.controls.flags-aconfig-java{.generated_srcjars}",
     ":android.service.voice.flags-aconfig-java{.generated_srcjars}",
     ":android.media.tv.flags-aconfig-java{.generated_srcjars}",
     ":android.service.autofill.flags-aconfig-java{.generated_srcjars}",
@@ -584,6 +586,32 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+// Pinner Service
+aconfig_declarations {
+    name: "com.android.server.flags.pinner-aconfig",
+    package: "com.android.server.flags",
+    srcs: ["services/core/java/com/android/server/flags/pinner.aconfig"],
+}
+
+java_aconfig_library {
+    name: "com.android.server.flags.pinner-aconfig-java",
+    aconfig_declarations: "com.android.server.flags.pinner-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
+// Controls
+aconfig_declarations {
+    name: "android.service.controls.flags-aconfig",
+    package: "android.service.controls.flags",
+    srcs: ["core/java/android/service/controls/flags/*.aconfig"],
+}
+
+java_aconfig_library {
+    name: "android.service.controls.flags-aconfig-java",
+    aconfig_declarations: "android.service.controls.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 // Voice
 aconfig_declarations {
     name: "android.service.voice.flags-aconfig",
diff --git a/Ravenwood.bp b/Ravenwood.bp
index ca73378..03f3f0f 100644
--- a/Ravenwood.bp
+++ b/Ravenwood.bp
@@ -32,6 +32,8 @@
     cmd: "$(location hoststubgen) " +
         "@$(location ravenwood/ravenwood-standard-options.txt) " +
 
+        "--debug-log $(location hoststubgen_framework-minus-apex.log) " +
+
         "--out-impl-jar $(location ravenwood.jar) " +
 
         "--gen-keep-all-file $(location hoststubgen_keep_all.txt) " +
@@ -52,6 +54,8 @@
         // Following files are created just as FYI.
         "hoststubgen_keep_all.txt",
         "hoststubgen_dump.txt",
+
+        "hoststubgen_framework-minus-apex.log",
     ],
     visibility: ["//visibility:private"],
 }
@@ -80,7 +84,7 @@
         "junit",
         "truth",
         "ravenwood-junit-impl",
-        "android.test.mock",
+        "android.test.mock.ravenwood",
     ],
 }
 
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 158d914..6383ed8 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -32,6 +32,7 @@
 import android.app.AlarmManager;
 import android.app.BroadcastOptions;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IIntentReceiver;
 import android.content.Intent;
@@ -41,6 +42,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
@@ -81,6 +83,7 @@
 import android.os.UserHandle;
 import android.os.WearModeManagerInternal;
 import android.provider.DeviceConfig;
+import android.provider.Settings;
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
@@ -109,6 +112,7 @@
 import com.android.server.deviceidle.IDeviceIdleConstraint;
 import com.android.server.deviceidle.TvConstraintController;
 import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.utils.UserSettingDeviceConfigMediator;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -1020,7 +1024,8 @@
      * global Settings. Any access to this class or its fields should be done while
      * holding the DeviceIdleController lock.
      */
-    public final class Constants implements DeviceConfig.OnPropertiesChangedListener {
+    public final class Constants extends ContentObserver
+            implements DeviceConfig.OnPropertiesChangedListener {
         // Key names stored in the settings value.
         private static final String KEY_FLEX_TIME_SHORT = "flex_time_short";
         private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT =
@@ -1102,7 +1107,7 @@
         private long mDefaultInactiveTimeout =
                 (30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
         private static final long DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY =
-                (15 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
+                (60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
         private long mDefaultSensingTimeout =
                 !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L;
         private long mDefaultLocatingTimeout =
@@ -1115,7 +1120,7 @@
         private long mDefaultIdleAfterInactiveTimeout =
                 (30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
         private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY =
-                (15 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
+                (60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
         private long mDefaultIdlePendingTimeout =
                 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L;
         private long mDefaultMaxIdlePendingTimeout =
@@ -1396,6 +1401,7 @@
         /**
          * Amount of time we would like to whitelist an app that is handling a
          * {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}.
+         *
          * @see #KEY_NOTIFICATION_ALLOWLIST_DURATION_MS
          */
         public long NOTIFICATION_ALLOWLIST_DURATION_MS = mDefaultNotificationAllowlistDurationMs;
@@ -1413,9 +1419,14 @@
          */
         public boolean USE_MODE_MANAGER = mDefaultUseModeManager;
 
+        private final ContentResolver mResolver;
         private final boolean mSmallBatteryDevice;
+        private final UserSettingDeviceConfigMediator mUserSettingDeviceConfigMediator =
+                new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
 
-        public Constants() {
+        public Constants(Handler handler, ContentResolver resolver) {
+            super(handler);
+            mResolver = resolver;
             initDefault();
             mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice();
             if (mSmallBatteryDevice) {
@@ -1424,8 +1435,14 @@
             }
             DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DEVICE_IDLE,
                     AppSchedulingModuleThread.getExecutor(), this);
+            mResolver.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS),
+                    false, this);
             // Load all the constants.
-            onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_DEVICE_IDLE));
+            updateSettingsConstantLocked();
+            mUserSettingDeviceConfigMediator.setDeviceConfigProperties(
+                    DeviceConfig.getProperties(DeviceConfig.NAMESPACE_DEVICE_IDLE));
+            updateConstantsLocked();
         }
 
         private void initDefault() {
@@ -1574,188 +1591,166 @@
             return (!COMPRESS_TIME || defTimeout < compTimeout) ? defTimeout : compTimeout;
         }
 
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            synchronized (DeviceIdleController.this) {
+                updateSettingsConstantLocked();
+                updateConstantsLocked();
+            }
+        }
+
+        private void updateSettingsConstantLocked() {
+            try {
+                mUserSettingDeviceConfigMediator.setSettingsString(
+                        Settings.Global.getString(mResolver,
+                                Settings.Global.DEVICE_IDLE_CONSTANTS));
+            } catch (IllegalArgumentException e) {
+                // Failed to parse the settings string, log this and move on with previous values.
+                Slog.e(TAG, "Bad device idle settings", e);
+            }
+        }
 
         @Override
         public void onPropertiesChanged(DeviceConfig.Properties properties) {
             synchronized (DeviceIdleController.this) {
-                for (String name : properties.getKeyset()) {
-                    if (name == null) {
-                        continue;
-                    }
-                    switch (name) {
-                        case KEY_FLEX_TIME_SHORT:
-                            FLEX_TIME_SHORT = properties.getLong(
-                                    KEY_FLEX_TIME_SHORT, mDefaultFlexTimeShort);
-                            break;
-                        case KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT:
-                            LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
-                                    KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
-                                    mDefaultLightIdleAfterInactiveTimeout);
-                            break;
-                        case KEY_LIGHT_IDLE_TIMEOUT:
-                            LIGHT_IDLE_TIMEOUT = properties.getLong(
-                                    KEY_LIGHT_IDLE_TIMEOUT, mDefaultLightIdleTimeout);
-                            break;
-                        case KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX:
-                            LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = properties.getLong(
-                                    KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX,
-                                    mDefaultLightIdleTimeoutInitialFlex);
-                            break;
-                        case KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX:
-                            LIGHT_IDLE_TIMEOUT_MAX_FLEX = properties.getLong(
-                                    KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX,
-                                    mDefaultLightIdleTimeoutMaxFlex);
-                            break;
-                        case KEY_LIGHT_IDLE_FACTOR:
-                            LIGHT_IDLE_FACTOR = Math.max(1, properties.getFloat(
-                                    KEY_LIGHT_IDLE_FACTOR, mDefaultLightIdleFactor));
-                            break;
-                        case KEY_LIGHT_IDLE_INCREASE_LINEARLY:
-                            LIGHT_IDLE_INCREASE_LINEARLY = properties.getBoolean(
-                                    KEY_LIGHT_IDLE_INCREASE_LINEARLY,
-                                    mDefaultLightIdleIncreaseLinearly);
-                            break;
-                        case KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS:
-                            LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = properties.getLong(
-                                    KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS,
-                                    mDefaultLightIdleLinearIncreaseFactorMs);
-                            break;
-                        case KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS:
-                            LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = properties.getLong(
-                                    KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS,
-                                    mDefaultLightIdleFlexLinearIncreaseFactorMs);
-                            break;
-                        case KEY_LIGHT_MAX_IDLE_TIMEOUT:
-                            LIGHT_MAX_IDLE_TIMEOUT = properties.getLong(
-                                    KEY_LIGHT_MAX_IDLE_TIMEOUT, mDefaultLightMaxIdleTimeout);
-                            break;
-                        case KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET:
-                            LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = properties.getLong(
-                                    KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
-                                    mDefaultLightIdleMaintenanceMinBudget);
-                            break;
-                        case KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET:
-                            LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = properties.getLong(
-                                    KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
-                                    mDefaultLightIdleMaintenanceMaxBudget);
-                            break;
-                        case KEY_MIN_LIGHT_MAINTENANCE_TIME:
-                            MIN_LIGHT_MAINTENANCE_TIME = properties.getLong(
-                                    KEY_MIN_LIGHT_MAINTENANCE_TIME,
-                                    mDefaultMinLightMaintenanceTime);
-                            break;
-                        case KEY_MIN_DEEP_MAINTENANCE_TIME:
-                            MIN_DEEP_MAINTENANCE_TIME = properties.getLong(
-                                    KEY_MIN_DEEP_MAINTENANCE_TIME,
-                                    mDefaultMinDeepMaintenanceTime);
-                            break;
-                        case KEY_INACTIVE_TIMEOUT:
-                            final long defaultInactiveTimeout = mSmallBatteryDevice
-                                    ? DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY
-                                    : mDefaultInactiveTimeout;
-                            INACTIVE_TIMEOUT = properties.getLong(
-                                    KEY_INACTIVE_TIMEOUT, defaultInactiveTimeout);
-                            break;
-                        case KEY_SENSING_TIMEOUT:
-                            SENSING_TIMEOUT = properties.getLong(
-                                    KEY_SENSING_TIMEOUT, mDefaultSensingTimeout);
-                            break;
-                        case KEY_LOCATING_TIMEOUT:
-                            LOCATING_TIMEOUT = properties.getLong(
-                                    KEY_LOCATING_TIMEOUT, mDefaultLocatingTimeout);
-                            break;
-                        case KEY_LOCATION_ACCURACY:
-                            LOCATION_ACCURACY = properties.getFloat(
-                                    KEY_LOCATION_ACCURACY, mDefaultLocationAccuracy);
-                            break;
-                        case KEY_MOTION_INACTIVE_TIMEOUT:
-                            MOTION_INACTIVE_TIMEOUT = properties.getLong(
-                                    KEY_MOTION_INACTIVE_TIMEOUT, mDefaultMotionInactiveTimeout);
-                            break;
-                        case KEY_MOTION_INACTIVE_TIMEOUT_FLEX:
-                            MOTION_INACTIVE_TIMEOUT_FLEX = properties.getLong(
-                                    KEY_MOTION_INACTIVE_TIMEOUT_FLEX,
-                                    mDefaultMotionInactiveTimeoutFlex);
-                            break;
-                        case KEY_IDLE_AFTER_INACTIVE_TIMEOUT:
-                            final long defaultIdleAfterInactiveTimeout = mSmallBatteryDevice
-                                    ? DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY
-                                    : mDefaultIdleAfterInactiveTimeout;
-                            IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
-                                    KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
-                                    defaultIdleAfterInactiveTimeout);
-                            break;
-                        case KEY_IDLE_PENDING_TIMEOUT:
-                            IDLE_PENDING_TIMEOUT = properties.getLong(
-                                    KEY_IDLE_PENDING_TIMEOUT, mDefaultIdlePendingTimeout);
-                            break;
-                        case KEY_MAX_IDLE_PENDING_TIMEOUT:
-                            MAX_IDLE_PENDING_TIMEOUT = properties.getLong(
-                                    KEY_MAX_IDLE_PENDING_TIMEOUT, mDefaultMaxIdlePendingTimeout);
-                            break;
-                        case KEY_IDLE_PENDING_FACTOR:
-                            IDLE_PENDING_FACTOR = properties.getFloat(
-                                    KEY_IDLE_PENDING_FACTOR, mDefaultIdlePendingFactor);
-                            break;
-                        case KEY_QUICK_DOZE_DELAY_TIMEOUT:
-                            QUICK_DOZE_DELAY_TIMEOUT = properties.getLong(
-                                    KEY_QUICK_DOZE_DELAY_TIMEOUT, mDefaultQuickDozeDelayTimeout);
-                            break;
-                        case KEY_IDLE_TIMEOUT:
-                            IDLE_TIMEOUT = properties.getLong(
-                                    KEY_IDLE_TIMEOUT, mDefaultIdleTimeout);
-                            break;
-                        case KEY_MAX_IDLE_TIMEOUT:
-                            MAX_IDLE_TIMEOUT = properties.getLong(
-                                    KEY_MAX_IDLE_TIMEOUT, mDefaultMaxIdleTimeout);
-                            break;
-                        case KEY_IDLE_FACTOR:
-                            IDLE_FACTOR = properties.getFloat(KEY_IDLE_FACTOR, mDefaultIdleFactor);
-                            break;
-                        case KEY_MIN_TIME_TO_ALARM:
-                            MIN_TIME_TO_ALARM = properties.getLong(
-                                    KEY_MIN_TIME_TO_ALARM, mDefaultMinTimeToAlarm);
-                            break;
-                        case KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS:
-                            MAX_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong(
-                                    KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS,
-                                    mDefaultMaxTempAppAllowlistDurationMs);
-                            break;
-                        case KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS:
-                            MMS_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong(
-                                    KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS,
-                                    mDefaultMmsTempAppAllowlistDurationMs);
-                            break;
-                        case KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS:
-                            SMS_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong(
-                                    KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS,
-                                    mDefaultSmsTempAppAllowlistDurationMs);
-                            break;
-                        case KEY_NOTIFICATION_ALLOWLIST_DURATION_MS:
-                            NOTIFICATION_ALLOWLIST_DURATION_MS = properties.getLong(
-                                    KEY_NOTIFICATION_ALLOWLIST_DURATION_MS,
-                                    mDefaultNotificationAllowlistDurationMs);
-                            break;
-                        case KEY_WAIT_FOR_UNLOCK:
-                            WAIT_FOR_UNLOCK = properties.getBoolean(
-                                    KEY_WAIT_FOR_UNLOCK, mDefaultWaitForUnlock);
-                            break;
-                        case KEY_USE_WINDOW_ALARMS:
-                            USE_WINDOW_ALARMS = properties.getBoolean(
-                                    KEY_USE_WINDOW_ALARMS, mDefaultUseWindowAlarms);
-                            break;
-                        case KEY_USE_MODE_MANAGER:
-                            USE_MODE_MANAGER = properties.getBoolean(
-                                    KEY_USE_MODE_MANAGER, mDefaultUseModeManager);
-                            break;
-                        default:
-                            Slog.e(TAG, "Unknown configuration key: " + name);
-                            break;
-                    }
-                }
+                mUserSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
+                updateConstantsLocked();
             }
         }
 
+        private void updateConstantsLocked() {
+            if (mSmallBatteryDevice) return;
+            FLEX_TIME_SHORT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_FLEX_TIME_SHORT, mDefaultFlexTimeShort);
+
+            LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
+                    mDefaultLightIdleAfterInactiveTimeout);
+
+            LIGHT_IDLE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LIGHT_IDLE_TIMEOUT, mDefaultLightIdleTimeout);
+
+            LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LIGHT_IDLE_TIMEOUT_INITIAL_FLEX,
+                    mDefaultLightIdleTimeoutInitialFlex);
+
+            LIGHT_IDLE_TIMEOUT_MAX_FLEX = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX,
+                    mDefaultLightIdleTimeoutMaxFlex);
+
+            LIGHT_IDLE_FACTOR = Math.max(1, mUserSettingDeviceConfigMediator.getFloat(
+                    KEY_LIGHT_IDLE_FACTOR, mDefaultLightIdleFactor));
+
+            LIGHT_IDLE_INCREASE_LINEARLY = mUserSettingDeviceConfigMediator.getBoolean(
+                    KEY_LIGHT_IDLE_INCREASE_LINEARLY,
+                    mDefaultLightIdleIncreaseLinearly);
+
+            LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS,
+                    mDefaultLightIdleLinearIncreaseFactorMs);
+
+            LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS,
+                    mDefaultLightIdleFlexLinearIncreaseFactorMs);
+
+            LIGHT_MAX_IDLE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LIGHT_MAX_IDLE_TIMEOUT, mDefaultLightMaxIdleTimeout);
+
+            LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
+                    mDefaultLightIdleMaintenanceMinBudget);
+
+            LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
+                    mDefaultLightIdleMaintenanceMaxBudget);
+
+            MIN_LIGHT_MAINTENANCE_TIME = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_MIN_LIGHT_MAINTENANCE_TIME,
+                    mDefaultMinLightMaintenanceTime);
+
+            MIN_DEEP_MAINTENANCE_TIME = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_MIN_DEEP_MAINTENANCE_TIME,
+                    mDefaultMinDeepMaintenanceTime);
+
+            final long defaultInactiveTimeout = mSmallBatteryDevice
+                    ? DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY
+                    : mDefaultInactiveTimeout;
+            INACTIVE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_INACTIVE_TIMEOUT, defaultInactiveTimeout);
+
+            SENSING_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_SENSING_TIMEOUT, mDefaultSensingTimeout);
+
+            LOCATING_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_LOCATING_TIMEOUT, mDefaultLocatingTimeout);
+
+            LOCATION_ACCURACY = mUserSettingDeviceConfigMediator.getFloat(
+                    KEY_LOCATION_ACCURACY, mDefaultLocationAccuracy);
+
+            MOTION_INACTIVE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_MOTION_INACTIVE_TIMEOUT, mDefaultMotionInactiveTimeout);
+
+            MOTION_INACTIVE_TIMEOUT_FLEX = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_MOTION_INACTIVE_TIMEOUT_FLEX,
+                    mDefaultMotionInactiveTimeoutFlex);
+
+            final long defaultIdleAfterInactiveTimeout = mSmallBatteryDevice
+                    ? DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY
+                    : mDefaultIdleAfterInactiveTimeout;
+            IDLE_AFTER_INACTIVE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
+                    defaultIdleAfterInactiveTimeout);
+
+            IDLE_PENDING_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_IDLE_PENDING_TIMEOUT, mDefaultIdlePendingTimeout);
+
+            MAX_IDLE_PENDING_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_MAX_IDLE_PENDING_TIMEOUT, mDefaultMaxIdlePendingTimeout);
+
+            IDLE_PENDING_FACTOR = mUserSettingDeviceConfigMediator.getFloat(
+                    KEY_IDLE_PENDING_FACTOR, mDefaultIdlePendingFactor);
+
+            QUICK_DOZE_DELAY_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_QUICK_DOZE_DELAY_TIMEOUT, mDefaultQuickDozeDelayTimeout);
+
+            IDLE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_IDLE_TIMEOUT, mDefaultIdleTimeout);
+
+            MAX_IDLE_TIMEOUT = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_MAX_IDLE_TIMEOUT, mDefaultMaxIdleTimeout);
+
+            IDLE_FACTOR = mUserSettingDeviceConfigMediator.getFloat(KEY_IDLE_FACTOR,
+                    mDefaultIdleFactor);
+
+            MIN_TIME_TO_ALARM = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_MIN_TIME_TO_ALARM, mDefaultMinTimeToAlarm);
+
+            MAX_TEMP_APP_ALLOWLIST_DURATION_MS = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS,
+                    mDefaultMaxTempAppAllowlistDurationMs);
+
+            MMS_TEMP_APP_ALLOWLIST_DURATION_MS = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS,
+                    mDefaultMmsTempAppAllowlistDurationMs);
+
+            SMS_TEMP_APP_ALLOWLIST_DURATION_MS = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS,
+                    mDefaultSmsTempAppAllowlistDurationMs);
+
+            NOTIFICATION_ALLOWLIST_DURATION_MS = mUserSettingDeviceConfigMediator.getLong(
+                    KEY_NOTIFICATION_ALLOWLIST_DURATION_MS,
+                    mDefaultNotificationAllowlistDurationMs);
+
+            WAIT_FOR_UNLOCK = mUserSettingDeviceConfigMediator.getBoolean(
+                    KEY_WAIT_FOR_UNLOCK, mDefaultWaitForUnlock);
+
+            USE_WINDOW_ALARMS = mUserSettingDeviceConfigMediator.getBoolean(
+                    KEY_USE_WINDOW_ALARMS, mDefaultUseWindowAlarms);
+
+            USE_MODE_MANAGER = mUserSettingDeviceConfigMediator.getBoolean(
+                    KEY_USE_MODE_MANAGER, mDefaultUseModeManager);
+        }
+
         void dump(PrintWriter pw) {
             pw.println("  Settings:");
 
@@ -2490,9 +2485,10 @@
             return mConnectivityManager;
         }
 
-        Constants getConstants(DeviceIdleController controller) {
+        Constants getConstants(DeviceIdleController controller, Handler handler,
+                ContentResolver resolver) {
             if (mConstants == null) {
-                mConstants = controller.new Constants();
+                mConstants = controller.new Constants(handler, resolver);
             }
             return mConstants;
         }
@@ -2650,7 +2646,7 @@
                 }
             }
 
-            mConstants = mInjector.getConstants(this);
+            mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver());
 
             readConfigFileLocked();
             updateWhitelistAppIdsLocked();
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 1bd8da82..5a32a02 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -2163,6 +2163,8 @@
                     mActivityManagerInternal.getBootTimeTempAllowListDuration(),
                     TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                     PowerExemptionManager.REASON_TIMEZONE_CHANGED, "");
+            mOptsTimeBroadcast.setDeliveryGroupPolicy(
+                    BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
             getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
                     null /* receiverPermission */, mOptsTimeBroadcast.toBundle());
         }
@@ -4608,6 +4610,8 @@
                                 mActivityManagerInternal.getBootTimeTempAllowListDuration(),
                                 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                                 PowerExemptionManager.REASON_TIME_CHANGED, "");
+                        mOptsTimeBroadcast.setDeliveryGroupPolicy(
+                                BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
                         getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
                                 null /* receiverPermission */, mOptsTimeBroadcast.toBundle());
                         // The world has changed on us, so we need to re-evaluate alarms
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
index d2150b8..8381d1a 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
@@ -109,7 +109,6 @@
 import android.content.ContentResolver;
 import android.provider.DeviceConfig;
 import android.util.IndentingPrintWriter;
-import android.util.KeyValueListParser;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -154,7 +153,6 @@
     private long mMinSatiatedConsumptionLimit;
     private long mMaxSatiatedConsumptionLimit;
 
-    private final KeyValueListParser mParser = new KeyValueListParser(',');
     private final Injector mInjector;
 
     private final SparseArray<Action> mActions = new SparseArray<>();
@@ -241,35 +239,36 @@
         mRewards.clear();
 
         try {
-            mParser.setString(policyValuesString);
+            mUserSettingDeviceConfigMediator.setSettingsString(policyValuesString);
+            mUserSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
         } catch (IllegalArgumentException e) {
             Slog.e(TAG, "Global setting key incorrect: ", e);
         }
 
-        mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
+        mMinSatiatedBalanceOther = getConstantAsCake(
             KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
-        mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(mParser, properties,
+        mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(
                 KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
                 DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
                 mMinSatiatedBalanceOther);
-        mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
+        mMinSatiatedBalanceExempted = getConstantAsCake(
                 KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
                 DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
                 mMinSatiatedBalanceHeadlessSystemApp);
-        mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
+        mMaxSatiatedBalance = getConstantAsCake(
             KEY_AM_MAX_SATIATED_BALANCE, DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
             Math.max(arcToCake(1), mMinSatiatedBalanceExempted));
-        mMinSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+        mMinSatiatedConsumptionLimit = getConstantAsCake(
                 KEY_AM_MIN_CONSUMPTION_LIMIT, DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES,
                 arcToCake(1));
-        mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+        mInitialSatiatedConsumptionLimit = getConstantAsCake(
                 KEY_AM_INITIAL_CONSUMPTION_LIMIT, DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES,
                 mMinSatiatedConsumptionLimit);
-        mMaxSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+        mMaxSatiatedConsumptionLimit = getConstantAsCake(
                 KEY_AM_MAX_CONSUMPTION_LIMIT, DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES,
                 mInitialSatiatedConsumptionLimit);
 
-        final long exactAllowWhileIdleWakeupBasePrice = getConstantAsCake(mParser, properties,
+        final long exactAllowWhileIdleWakeupBasePrice = getConstantAsCake(
                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
                 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES);
 
@@ -279,49 +278,49 @@
         // run out of credits, and not when the system has run out of stock.
         mActions.put(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
                 new Action(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP,
                                 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES),
                         exactAllowWhileIdleWakeupBasePrice,
                         /* respectsStockLimit */ false));
         mActions.put(ACTION_ALARM_WAKEUP_EXACT,
                 new Action(ACTION_ALARM_WAKEUP_EXACT,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
                                 DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
                                 DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES),
                         /* respectsStockLimit */ false));
 
         final long inexactAllowWhileIdleWakeupBasePrice =
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE,
                         DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES);
 
         mActions.put(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
                 new Action(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP,
                                 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES),
                         inexactAllowWhileIdleWakeupBasePrice,
                         /* respectsStockLimit */ false));
         mActions.put(ACTION_ALARM_WAKEUP_INEXACT,
                 new Action(ACTION_ALARM_WAKEUP_INEXACT,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP,
                                 DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE,
                                 DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES),
                         /* respectsStockLimit */ false));
 
-        final long exactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties,
+        final long exactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(
                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
                 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
         mActions.put(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
                 new Action(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP,
                                 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES),
                         exactAllowWhileIdleNonWakeupBasePrice,
@@ -329,18 +328,18 @@
 
         mActions.put(ACTION_ALARM_NONWAKEUP_EXACT,
                 new Action(ACTION_ALARM_NONWAKEUP_EXACT,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP,
                                 DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE,
                                 DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES),
                         /* respectsStockLimit */ false));
 
-        final long inexactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(mParser, properties,
+        final long inexactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(
                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
                 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
-        final long inexactAllowWhileIdleNonWakeupCtp = getConstantAsCake(mParser, properties,
+        final long inexactAllowWhileIdleNonWakeupCtp = getConstantAsCake(
                 KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
                 DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES);
         mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
@@ -350,72 +349,72 @@
 
         mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT,
                 new Action(ACTION_ALARM_NONWAKEUP_INEXACT,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP,
                                 DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE,
                                 DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES)));
         mActions.put(ACTION_ALARM_CLOCK,
                 new Action(ACTION_ALARM_CLOCK,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP,
                                 DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE,
                                 DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES),
                         /* respectsStockLimit */ false));
 
         mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
                         DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
                         DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_REWARD_TOP_ACTIVITY_MAX,
                         DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES)));
         mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
                         DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
                         DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
                         DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
         mRewards.put(REWARD_NOTIFICATION_INTERACTION,
                 new Reward(REWARD_NOTIFICATION_INTERACTION,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT,
                                 DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING,
                                 DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX,
                                 DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
         mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
                         DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
                         DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
                         DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
         mRewards.put(REWARD_OTHER_USER_INTERACTION,
                 new Reward(REWARD_OTHER_USER_INTERACTION,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
                                 DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING,
                                 DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX,
                                 DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
     }
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
index a4043dd..61096b9 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
@@ -33,9 +33,9 @@
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.util.IndentingPrintWriter;
-import android.util.KeyValueListParser;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.utils.UserSettingDeviceConfigMediator;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -197,10 +197,17 @@
     }
 
     protected final InternalResourceService mIrs;
+    protected final UserSettingDeviceConfigMediator mUserSettingDeviceConfigMediator;
     private static final Modifier[] COST_MODIFIER_BY_INDEX = new Modifier[NUM_COST_MODIFIERS];
 
     EconomicPolicy(@NonNull InternalResourceService irs) {
         mIrs = irs;
+        // Don't cross the streams! Mixing Settings/local user config changes with DeviceConfig
+        // config can cause issues since the scales may be different, so use one or the other.
+        // If user settings exist, then just stick with the Settings constants, even if there
+        // are invalid values.
+        mUserSettingDeviceConfigMediator =
+                new UserSettingDeviceConfigMediator.SettingsOverridesAllMediator(',');
         for (int mId : getCostModifiers()) {
             initModifier(mId, irs);
         }
@@ -464,28 +471,14 @@
         return "UNKNOWN_REWARD:" + Integer.toHexString(eventId);
     }
 
-    protected long getConstantAsCake(@NonNull KeyValueListParser parser,
-            @Nullable DeviceConfig.Properties properties, String key, long defaultValCake) {
-        return getConstantAsCake(parser, properties, key, defaultValCake, 0);
+    protected long getConstantAsCake(String key, long defaultValCake) {
+        return getConstantAsCake(key, defaultValCake, 0);
     }
 
-    protected long getConstantAsCake(@NonNull KeyValueListParser parser,
-            @Nullable DeviceConfig.Properties properties, String key, long defaultValCake,
-            long minValCake) {
-        // Don't cross the streams! Mixing Settings/local user config changes with DeviceConfig
-        // config can cause issues since the scales may be different, so use one or the other.
-        if (parser.size() > 0) {
-            // User settings take precedence. Just stick with the Settings constants, even if there
-            // are invalid values. It's not worth the time to evaluate all the key/value pairs to
-            // make sure there are valid ones before deciding.
-            return Math.max(minValCake,
-                parseCreditValue(parser.getString(key, null), defaultValCake));
-        }
-        if (properties != null) {
-            return Math.max(minValCake,
-                parseCreditValue(properties.getString(key, null), defaultValCake));
-        }
-        return Math.max(minValCake, defaultValCake);
+    protected long getConstantAsCake(String key, long defaultValCake, long minValCake) {
+        return Math.max(minValCake,
+                parseCreditValue(
+                        mUserSettingDeviceConfigMediator.getString(key, null), defaultValCake));
     }
 
     @VisibleForTesting
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
index 91a291f..69e5736 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
@@ -127,7 +127,6 @@
 import android.content.ContentResolver;
 import android.provider.DeviceConfig;
 import android.util.IndentingPrintWriter;
-import android.util.KeyValueListParser;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -168,7 +167,6 @@
     private long mMinSatiatedConsumptionLimit;
     private long mMaxSatiatedConsumptionLimit;
 
-    private final KeyValueListParser mParser = new KeyValueListParser(',');
     private final Injector mInjector;
 
     private final SparseArray<Action> mActions = new SparseArray<>();
@@ -274,176 +272,177 @@
         mRewards.clear();
 
         try {
-            mParser.setString(policyValuesString);
+            mUserSettingDeviceConfigMediator.setSettingsString(policyValuesString);
+            mUserSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
         } catch (IllegalArgumentException e) {
             Slog.e(TAG, "Global setting key incorrect: ", e);
         }
 
-        mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
+        mMinSatiatedBalanceOther = getConstantAsCake(
             KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
-        mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(mParser, properties,
+        mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(
                 KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
                 DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
                 mMinSatiatedBalanceOther);
-        mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
+        mMinSatiatedBalanceExempted = getConstantAsCake(
                 KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
                 DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
                 mMinSatiatedBalanceHeadlessSystemApp);
-        mMinSatiatedBalanceIncrementalAppUpdater = getConstantAsCake(mParser, properties,
+        mMinSatiatedBalanceIncrementalAppUpdater = getConstantAsCake(
                 KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
                 DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES);
-        mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
+        mMaxSatiatedBalance = getConstantAsCake(
             KEY_JS_MAX_SATIATED_BALANCE, DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
             Math.max(arcToCake(1), mMinSatiatedBalanceExempted));
-        mMinSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+        mMinSatiatedConsumptionLimit = getConstantAsCake(
                 KEY_JS_MIN_CONSUMPTION_LIMIT, DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES,
                 arcToCake(1));
-        mInitialSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+        mInitialSatiatedConsumptionLimit = getConstantAsCake(
                 KEY_JS_INITIAL_CONSUMPTION_LIMIT, DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES,
                 mMinSatiatedConsumptionLimit);
-        mMaxSatiatedConsumptionLimit = getConstantAsCake(mParser, properties,
+        mMaxSatiatedConsumptionLimit = getConstantAsCake(
                 KEY_JS_MAX_CONSUMPTION_LIMIT, DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES,
                 mInitialSatiatedConsumptionLimit);
 
         mActions.put(ACTION_JOB_MAX_START, new Action(ACTION_JOB_MAX_START,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_MAX_START_CTP,
                         DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_MAX_RUNNING, new Action(ACTION_JOB_MAX_RUNNING,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
                         DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_HIGH_START, new Action(ACTION_JOB_HIGH_START,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_HIGH_START_CTP,
                         DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_HIGH_RUNNING, new Action(ACTION_JOB_HIGH_RUNNING,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
                         DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_DEFAULT_START, new Action(ACTION_JOB_DEFAULT_START,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
                         DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_DEFAULT_RUNNING, new Action(ACTION_JOB_DEFAULT_RUNNING,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
                         DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_LOW_START, new Action(ACTION_JOB_LOW_START,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_LOW_START_CTP,
                         DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_LOW_RUNNING, new Action(ACTION_JOB_LOW_RUNNING,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
                         DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_MIN_START, new Action(ACTION_JOB_MIN_START,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_MIN_START_CTP,
                         DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_MIN_RUNNING, new Action(ACTION_JOB_MIN_RUNNING,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
                         DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES)));
         mActions.put(ACTION_JOB_TIMEOUT, new Action(ACTION_JOB_TIMEOUT,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
                         DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
                         DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES)));
 
         mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
                         DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
                         DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_REWARD_TOP_ACTIVITY_MAX,
                         DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES)));
         mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
                         DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
                         DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
                         DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
         mRewards.put(REWARD_NOTIFICATION_INTERACTION,
                 new Reward(REWARD_NOTIFICATION_INTERACTION,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
                                 DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
                                 DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
                                 DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
         mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
                         DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
                         DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
-                getConstantAsCake(mParser, properties,
+                getConstantAsCake(
                         KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
                         DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
         mRewards.put(REWARD_OTHER_USER_INTERACTION,
                 new Reward(REWARD_OTHER_USER_INTERACTION,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
                                 DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING,
                                 DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
                                 DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
         mRewards.put(REWARD_APP_INSTALL,
                 new Reward(REWARD_APP_INSTALL,
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_JS_REWARD_APP_INSTALL_INSTANT,
                                 DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_JS_REWARD_APP_INSTALL_ONGOING,
                                 DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES),
-                        getConstantAsCake(mParser, properties,
+                        getConstantAsCake(
                                 KEY_JS_REWARD_APP_INSTALL_MAX,
                                 DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES)));
     }
diff --git a/core/api/current.txt b/core/api/current.txt
index 9d13d8a..f01563a 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9342,6 +9342,7 @@
     method public String getClassName();
     method public android.content.res.Configuration getConfiguration();
     method public int getEventType();
+    method @FlaggedApi("android.app.usage.user_interaction_type_api") @NonNull public android.os.PersistableBundle getExtras();
     method public String getPackageName();
     method public String getShortcutId();
     method public long getTimeStamp();
@@ -9407,6 +9408,8 @@
     method @FlaggedApi("android.app.usage.filter_based_event_query_api") @NonNull @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public android.app.usage.UsageEvents queryEvents(@NonNull android.app.usage.UsageEventsQuery);
     method public android.app.usage.UsageEvents queryEventsForSelf(long, long);
     method public java.util.List<android.app.usage.UsageStats> queryUsageStats(int, long, long);
+    field @FlaggedApi("android.app.usage.user_interaction_type_api") public static final String EXTRA_EVENT_ACTION = "android.app.usage.extra.EVENT_ACTION";
+    field @FlaggedApi("android.app.usage.user_interaction_type_api") public static final String EXTRA_EVENT_CATEGORY = "android.app.usage.extra.EVENT_CATEGORY";
     field public static final int INTERVAL_BEST = 4; // 0x4
     field public static final int INTERVAL_DAILY = 0; // 0x0
     field public static final int INTERVAL_MONTHLY = 2; // 0x2
@@ -9673,6 +9676,7 @@
     method @Deprecated @NonNull public java.util.List<java.lang.String> getAssociations();
     method @NonNull public java.util.List<android.companion.AssociationInfo> getMyAssociations();
     method @Deprecated public boolean hasNotificationAccess(android.content.ComponentName);
+    method @FlaggedApi("android.companion.perm_sync_user_consent") public boolean isPermissionTransferUserConsented(int);
     method public void requestNotificationAccess(android.content.ComponentName);
     method @FlaggedApi("android.companion.association_tag") public void setAssociationTag(int, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
@@ -9851,7 +9855,7 @@
     method @NonNull public android.content.AttributionSource build();
     method @NonNull public android.content.AttributionSource.Builder setAttributionTag(@Nullable String);
     method @FlaggedApi("android.permission.flags.device_aware_permission_apis") @NonNull public android.content.AttributionSource.Builder setDeviceId(int);
-    method @Deprecated @NonNull public android.content.AttributionSource.Builder setNext(@Nullable android.content.AttributionSource);
+    method @NonNull public android.content.AttributionSource.Builder setNext(@Nullable android.content.AttributionSource);
     method @FlaggedApi("android.permission.flags.set_next_attribution_source") @NonNull public android.content.AttributionSource.Builder setNextAttributionSource(@NonNull android.content.AttributionSource);
     method @NonNull public android.content.AttributionSource.Builder setPackageName(@Nullable String);
     method @NonNull public android.content.AttributionSource.Builder setPid(int);
@@ -10598,6 +10602,7 @@
     field public static final String RESTRICTIONS_SERVICE = "restrictions";
     field public static final String ROLE_SERVICE = "role";
     field public static final String SEARCH_SERVICE = "search";
+    field @FlaggedApi("android.os.security_state_service") public static final String SECURITY_STATE_SERVICE = "security_state";
     field public static final String SENSOR_SERVICE = "sensor";
     field public static final String SHORTCUT_SERVICE = "shortcut";
     field public static final String STATUS_BAR_SERVICE = "statusbar";
@@ -10610,6 +10615,7 @@
     field public static final String TELEPHONY_SUBSCRIPTION_SERVICE = "telephony_subscription_service";
     field public static final String TEXT_CLASSIFICATION_SERVICE = "textclassification";
     field public static final String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
+    field @FlaggedApi("android.media.tv.flags.enable_ad_service_fw") public static final String TV_AD_SERVICE = "tv_ad";
     field public static final String TV_INPUT_SERVICE = "tv_input";
     field public static final String TV_INTERACTIVE_APP_SERVICE = "tv_interactive_app";
     field public static final String UI_MODE_SERVICE = "uimode";
@@ -11098,6 +11104,7 @@
     field public static final String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED";
     field @Deprecated public static final String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED";
     field @Deprecated public static final String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED";
+    field @FlaggedApi("android.content.pm.archiving") public static final String ACTION_UNARCHIVE_PACKAGE = "android.intent.action.UNARCHIVE_PACKAGE";
     field @Deprecated public static final String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
     field public static final String ACTION_USER_BACKGROUND = "android.intent.action.USER_BACKGROUND";
     field public static final String ACTION_USER_FOREGROUND = "android.intent.action.USER_FOREGROUND";
@@ -12363,6 +12370,7 @@
   public class PackageInfo implements android.os.Parcelable {
     ctor public PackageInfo();
     method public int describeContents();
+    method @FlaggedApi("android.content.pm.archiving") public long getArchiveTimeMillis();
     method public long getLongVersionCode();
     method public void setLongVersionCode(long);
     method public void writeToParcel(android.os.Parcel, int);
@@ -12419,6 +12427,9 @@
     method @NonNull public android.content.pm.PackageInstaller.Session openSession(int) throws java.io.IOException;
     method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback);
     method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback, @NonNull android.os.Handler);
+    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void reportUnarchivalStatus(int, int, long, @Nullable android.app.PendingIntent) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void requestArchive(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void requestUnarchive(@NonNull String, @NonNull android.content.IntentSender) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
     method @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void uninstall(@NonNull String, @NonNull android.content.IntentSender);
     method @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void uninstall(@NonNull android.content.pm.VersionedPackage, @NonNull android.content.IntentSender);
     method @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void uninstall(@NonNull android.content.pm.VersionedPackage, int, @NonNull android.content.IntentSender);
@@ -12440,6 +12451,10 @@
     field public static final String EXTRA_STATUS = "android.content.pm.extra.STATUS";
     field public static final String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
     field public static final String EXTRA_STORAGE_PATH = "android.content.pm.extra.STORAGE_PATH";
+    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS";
+    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ID = "android.content.pm.extra.UNARCHIVE_ID";
+    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
+    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_STATUS = "android.content.pm.extra.UNARCHIVE_STATUS";
     field public static final int PACKAGE_SOURCE_DOWNLOADED_FILE = 4; // 0x4
     field public static final int PACKAGE_SOURCE_LOCAL_FILE = 3; // 0x3
     field public static final int PACKAGE_SOURCE_OTHER = 1; // 0x1
@@ -12455,6 +12470,13 @@
     field public static final int STATUS_FAILURE_TIMEOUT = 8; // 0x8
     field public static final int STATUS_PENDING_USER_ACTION = -1; // 0xffffffff
     field public static final int STATUS_SUCCESS = 0; // 0x0
+    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSTALLER_DISABLED = 4; // 0x4
+    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSTALLER_UNINSTALLED = 5; // 0x5
+    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE = 2; // 0x2
+    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_NO_CONNECTIVITY = 3; // 0x3
+    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_USER_ACTION_NEEDED = 1; // 0x1
+    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_GENERIC_ERROR = 100; // 0x64
+    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_OK = 0; // 0x0
   }
 
   public static final class PackageInstaller.InstallConstraints implements android.os.Parcelable {
@@ -12618,6 +12640,7 @@
     method @RequiresPermission(android.Manifest.permission.ENFORCE_UPDATE_OWNERSHIP) public void setRequestUpdateOwnership(boolean);
     method public void setRequireUserAction(int);
     method public void setSize(long);
+    method @FlaggedApi("android.content.pm.archiving") public void setUnarchiveId(int);
     method public void setWhitelistedRestrictedPermissions(@Nullable java.util.Set<java.lang.String>);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.pm.PackageInstaller.SessionParams> CREATOR;
@@ -12647,6 +12670,7 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public int banner;
     field public int icon;
+    field @FlaggedApi("android.content.pm.archiving") public boolean isArchived;
     field public int labelRes;
     field public int logo;
     field public android.os.Bundle metaData;
@@ -12769,6 +12793,7 @@
     method public boolean hasSigningCertificate(int, @NonNull byte[], int);
     method public abstract boolean hasSystemFeature(@NonNull String);
     method public abstract boolean hasSystemFeature(@NonNull String, int);
+    method @FlaggedApi("android.content.pm.archiving") public boolean isAppArchivable(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
     method @RequiresPermission(value="android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS", conditional=true) public boolean isAutoRevokeWhitelisted(@NonNull String);
     method public boolean isAutoRevokeWhitelisted();
     method public boolean isDefaultApplicationIcon(@NonNull android.graphics.drawable.Drawable);
@@ -13010,6 +13035,7 @@
     field public static final int INSTALL_SCENARIO_FAST = 1; // 0x1
     field public static final int MATCH_ALL = 131072; // 0x20000
     field public static final int MATCH_APEX = 1073741824; // 0x40000000
+    field @FlaggedApi("android.content.pm.archiving") public static final long MATCH_ARCHIVED_PACKAGES = 4294967296L; // 0x100000000L
     field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
     field public static final int MATCH_DIRECT_BOOT_AUTO = 268435456; // 0x10000000
     field public static final int MATCH_DIRECT_BOOT_AWARE = 524288; // 0x80000
@@ -22031,6 +22057,19 @@
     method public void onJetUserIdUpdate(android.media.JetPlayer, int, int);
   }
 
+  @FlaggedApi("android.media.audio.loudness_configurator_api") public class LoudnessCodecConfigurator {
+    method @FlaggedApi("android.media.audio.loudness_configurator_api") public void addMediaCodec(@NonNull android.media.MediaCodec);
+    method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public static android.media.LoudnessCodecConfigurator create();
+    method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public static android.media.LoudnessCodecConfigurator create(@NonNull java.util.concurrent.Executor, @NonNull android.media.LoudnessCodecConfigurator.OnLoudnessCodecUpdateListener);
+    method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public android.os.Bundle getLoudnessCodecParams(@NonNull android.media.AudioTrack, @NonNull android.media.MediaCodec);
+    method @FlaggedApi("android.media.audio.loudness_configurator_api") public void removeMediaCodec(@NonNull android.media.MediaCodec);
+    method @FlaggedApi("android.media.audio.loudness_configurator_api") public void setAudioTrack(@Nullable android.media.AudioTrack);
+  }
+
+  @FlaggedApi("android.media.audio.loudness_configurator_api") public static interface LoudnessCodecConfigurator.OnLoudnessCodecUpdateListener {
+    method @FlaggedApi("android.media.audio.loudness_configurator_api") @NonNull public default android.os.Bundle onLoudnessCodecUpdate(@NonNull android.media.MediaCodec, @NonNull android.os.Bundle);
+  }
+
   public class MediaActionSound {
     ctor public MediaActionSound();
     method public void load(int);
@@ -27299,6 +27338,13 @@
 
 }
 
+package android.media.tv.ad {
+
+  @FlaggedApi("android.media.tv.flags.enable_ad_service_fw") public class TvAdManager {
+  }
+
+}
+
 package android.media.tv.interactive {
 
   public final class AppLinkInfo implements android.os.Parcelable {
@@ -32837,7 +32883,7 @@
     method public static android.os.Message obtain(android.os.Handler, int, Object);
     method public static android.os.Message obtain(android.os.Handler, int, int, int);
     method public static android.os.Message obtain(android.os.Handler, int, int, int, Object);
-    method public android.os.Bundle peekData();
+    method @Nullable public android.os.Bundle peekData();
     method public void recycle();
     method public void sendToTarget();
     method public void setAsynchronous(boolean);
@@ -33376,6 +33422,13 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.os.ResultReceiver> CREATOR;
   }
 
+  @FlaggedApi("android.os.security_state_service") public class SecurityStateManager {
+    method @FlaggedApi("android.os.security_state_service") @NonNull public android.os.Bundle getGlobalSecurityState();
+    field public static final String KEY_KERNEL_VERSION = "kernel_version";
+    field public static final String KEY_SYSTEM_SPL = "system_spl";
+    field public static final String KEY_VENDOR_SPL = "vendor_spl";
+  }
+
   public final class SharedMemory implements java.io.Closeable android.os.Parcelable {
     method public void close();
     method @NonNull public static android.os.SharedMemory create(@Nullable String, int) throws android.system.ErrnoException;
@@ -36770,7 +36823,7 @@
     field public static final String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS";
     field public static final String ACTION_CHANNEL_NOTIFICATION_SETTINGS = "android.settings.CHANNEL_NOTIFICATION_SETTINGS";
     field public static final String ACTION_CONDITION_PROVIDER_SETTINGS = "android.settings.ACTION_CONDITION_PROVIDER_SETTINGS";
-    field public static final String ACTION_CREDENTIAL_PROVIDER = "android.settings.CREDENTIAL_PROVIDER";
+    field @FlaggedApi("android.credentials.flags.new_settings_intents") public static final String ACTION_CREDENTIAL_PROVIDER = "android.settings.CREDENTIAL_PROVIDER";
     field public static final String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
     field public static final String ACTION_DATA_USAGE_SETTINGS = "android.settings.DATA_USAGE_SETTINGS";
     field public static final String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
@@ -39211,7 +39264,7 @@
     method @Nullable public java.util.Date getKeyValidityStart();
     method @NonNull public String getKeystoreAlias();
     method public int getMaxUsageCount();
-    method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public java.util.Set<java.lang.String> getMgf1Digests();
+    method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public java.util.Set<java.lang.String> getMgf1Digests();
     method public int getPurposes();
     method @NonNull public String[] getSignaturePaddings();
     method public int getUserAuthenticationType();
@@ -39219,7 +39272,7 @@
     method public boolean isDevicePropertiesAttestationIncluded();
     method @NonNull public boolean isDigestsSpecified();
     method public boolean isInvalidatedByBiometricEnrollment();
-    method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public boolean isMgf1DigestsSpecified();
+    method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public boolean isMgf1DigestsSpecified();
     method public boolean isRandomizedEncryptionRequired();
     method public boolean isStrongBoxBacked();
     method public boolean isUnlockedDeviceRequired();
@@ -39251,7 +39304,7 @@
     method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
     method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityStart(java.util.Date);
     method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMaxUsageCount(int);
-    method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMgf1Digests(@NonNull java.lang.String...);
+    method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMgf1Digests(@NonNull java.lang.String...);
     method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean);
     method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...);
     method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean);
@@ -39356,14 +39409,14 @@
     method @Nullable public java.util.Date getKeyValidityForOriginationEnd();
     method @Nullable public java.util.Date getKeyValidityStart();
     method public int getMaxUsageCount();
-    method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public java.util.Set<java.lang.String> getMgf1Digests();
+    method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public java.util.Set<java.lang.String> getMgf1Digests();
     method public int getPurposes();
     method @NonNull public String[] getSignaturePaddings();
     method public int getUserAuthenticationType();
     method public int getUserAuthenticationValidityDurationSeconds();
     method public boolean isDigestsSpecified();
     method public boolean isInvalidatedByBiometricEnrollment();
-    method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public boolean isMgf1DigestsSpecified();
+    method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public boolean isMgf1DigestsSpecified();
     method public boolean isRandomizedEncryptionRequired();
     method public boolean isUnlockedDeviceRequired();
     method public boolean isUserAuthenticationRequired();
@@ -39385,7 +39438,7 @@
     method @NonNull public android.security.keystore.KeyProtection.Builder setKeyValidityForOriginationEnd(java.util.Date);
     method @NonNull public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date);
     method @NonNull public android.security.keystore.KeyProtection.Builder setMaxUsageCount(int);
-    method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public android.security.keystore.KeyProtection.Builder setMgf1Digests(@Nullable java.lang.String...);
+    method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public android.security.keystore.KeyProtection.Builder setMgf1Digests(@Nullable java.lang.String...);
     method @NonNull public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean);
     method @NonNull public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...);
     method @NonNull public android.security.keystore.KeyProtection.Builder setUnlockedDeviceRequired(boolean);
@@ -40056,6 +40109,9 @@
     method public final boolean onUnbind(@NonNull android.content.Intent);
     method public abstract void performControlAction(@NonNull String, @NonNull android.service.controls.actions.ControlAction, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method public static void requestAddControl(@NonNull android.content.Context, @NonNull android.content.ComponentName, @NonNull android.service.controls.Control);
+    field @FlaggedApi("android.service.controls.flags.home_panel_dream") public static final int CONTROLS_SURFACE_ACTIVITY_PANEL = 0; // 0x0
+    field @FlaggedApi("android.service.controls.flags.home_panel_dream") public static final int CONTROLS_SURFACE_DREAM = 1; // 0x1
+    field @FlaggedApi("android.service.controls.flags.home_panel_dream") public static final String EXTRA_CONTROLS_SURFACE = "android.service.controls.extra.CONTROLS_SURFACE";
     field public static final String EXTRA_LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS = "android.service.controls.extra.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS";
     field public static final String META_DATA_PANEL_ACTIVITY = "android.service.controls.META_DATA_PANEL_ACTIVITY";
     field public static final String SERVICE_CONTROLS = "android.service.controls.ControlsProviderService";
@@ -43080,8 +43136,8 @@
     field public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrq_thresholds_int_array";
     field public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY = "5g_nr_sssinr_thresholds_int_array";
     field public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
-    field public static final String KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL = "additional_settings_caller_id_visibility_bool";
-    field public static final String KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL = "additional_settings_call_waiting_visibility_bool";
+    field @FlaggedApi("com.android.internal.telephony.flags.show_call_id_and_call_waiting_in_additional_settings_menu") public static final String KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL = "additional_settings_caller_id_visibility_bool";
+    field @FlaggedApi("com.android.internal.telephony.flags.show_call_id_and_call_waiting_in_additional_settings_menu") public static final String KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL = "additional_settings_call_waiting_visibility_bool";
     field public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
     field public static final String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool";
@@ -51998,6 +52054,7 @@
     method public float getHandwritingBoundsOffsetLeft();
     method public float getHandwritingBoundsOffsetRight();
     method public float getHandwritingBoundsOffsetTop();
+    method @FlaggedApi("android.view.inputmethod.home_screen_handwriting_delegator") public int getHandwritingDelegateFlags();
     method @Nullable public Runnable getHandwritingDelegatorCallback();
     method public final boolean getHasOverlappingRendering();
     method public final int getHeight();
@@ -52371,6 +52428,7 @@
     method public void setForegroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
     method @FlaggedApi("android.view.flags.view_velocity_api") public void setFrameContentVelocity(float);
     method public void setHandwritingBoundsOffsets(float, float, float, float);
+    method @FlaggedApi("android.view.inputmethod.home_screen_handwriting_delegator") public void setHandwritingDelegateFlags(int);
     method public void setHandwritingDelegatorCallback(@Nullable Runnable);
     method public void setHapticFeedbackEnabled(boolean);
     method public void setHasTransientState(boolean);
@@ -55626,6 +55684,7 @@
   public final class InputMethodManager {
     method public boolean acceptStylusHandwritingDelegation(@NonNull android.view.View);
     method public boolean acceptStylusHandwritingDelegation(@NonNull android.view.View, @NonNull String);
+    method @FlaggedApi("android.view.inputmethod.home_screen_handwriting_delegator") public boolean acceptStylusHandwritingDelegation(@NonNull android.view.View, @NonNull String, int);
     method public void dispatchKeyEventFromInputMethod(@Nullable android.view.View, @NonNull android.view.KeyEvent);
     method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]);
     method @Nullable public android.view.inputmethod.InputMethodInfo getCurrentInputMethodInfo();
@@ -55673,6 +55732,7 @@
     method public void updateExtractedText(android.view.View, int, android.view.inputmethod.ExtractedText);
     method public void updateSelection(android.view.View, int, int, int, int);
     method @Deprecated public void viewClicked(android.view.View);
+    field @FlaggedApi("android.view.inputmethod.home_screen_handwriting_delegator") public static final int HANDWRITING_DELEGATE_FLAG_HOME_DELEGATOR_ALLOWED = 1; // 0x1
     field public static final int HIDE_IMPLICIT_ONLY = 1; // 0x1
     field public static final int HIDE_NOT_ALWAYS = 2; // 0x2
     field public static final int RESULT_HIDDEN = 3; // 0x3
@@ -59490,6 +59550,7 @@
     method public void setOnClickFillInIntent(@IdRes int, android.content.Intent);
     method public void setOnClickPendingIntent(@IdRes int, android.app.PendingIntent);
     method public void setOnClickResponse(@IdRes int, @NonNull android.widget.RemoteViews.RemoteResponse);
+    method @FlaggedApi("android.view.inputmethod.home_screen_handwriting_delegator") public void setOnStylusHandwritingPendingIntent(@IdRes int, @Nullable android.app.PendingIntent);
     method public void setPendingIntentTemplate(@IdRes int, android.app.PendingIntent);
     method public void setProgressBar(@IdRes int, int, int, boolean);
     method public void setRadioGroupChecked(@IdRes int, @IdRes int);
diff --git a/core/api/module-lib-lint-baseline.txt b/core/api/module-lib-lint-baseline.txt
index e49d6e3..a6a948c 100644
--- a/core/api/module-lib-lint-baseline.txt
+++ b/core/api/module-lib-lint-baseline.txt
@@ -1745,6 +1745,10 @@
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.session.MediaSessionManager.setOnMediaKeyListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 SamShouldBeLast: android.media.session.MediaSessionManager#setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, android.os.Handler):
     SAM-compatible parameters (such as parameter 1, "listener", in android.media.session.MediaSessionManager.setOnVolumeKeyLongPressListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.view.accessibility.AccessibilityManager#addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, android.os.Handler):
+    SAM-compatible parameters (such as parameter 1, "listener", in android.view.accessibility.AccessibilityManager.addAccessibilityStateChangeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+SamShouldBeLast: android.view.accessibility.AccessibilityManager#addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener, android.os.Handler):
+    SAM-compatible parameters (such as parameter 1, "listener", in android.view.accessibility.AccessibilityManager.addTouchExplorationStateChangeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
 
 
 SdkConstant: android.content.Intent#ACTION_BATTERY_LEVEL_CHANGED:
diff --git a/core/api/removed.txt b/core/api/removed.txt
index 285dcc6a..b7714f1 100644
--- a/core/api/removed.txt
+++ b/core/api/removed.txt
@@ -30,36 +30,6 @@
 
 }
 
-package android.app.slice {
-
-  public final class Slice implements android.os.Parcelable {
-    field @Deprecated public static final String EXTRA_SLIDER_VALUE = "android.app.slice.extra.SLIDER_VALUE";
-    field @Deprecated public static final String SUBTYPE_SLIDER = "slider";
-  }
-
-  public static class Slice.Builder {
-    ctor @Deprecated public Slice.Builder(@NonNull android.net.Uri);
-    method @Deprecated public android.app.slice.Slice.Builder addTimestamp(long, @Nullable String, java.util.List<java.lang.String>);
-    method @Deprecated public android.app.slice.Slice.Builder setSpec(android.app.slice.SliceSpec);
-  }
-
-  public final class SliceItem implements android.os.Parcelable {
-    method @Deprecated public long getTimestamp();
-    field @Deprecated public static final String FORMAT_TIMESTAMP = "long";
-  }
-
-  public class SliceManager {
-    method @Deprecated @Nullable public android.app.slice.Slice bindSlice(@NonNull android.net.Uri, @NonNull java.util.List<android.app.slice.SliceSpec>);
-    method @Deprecated @Nullable public android.app.slice.Slice bindSlice(@NonNull android.content.Intent, @NonNull java.util.List<android.app.slice.SliceSpec>);
-    method @Deprecated public void pinSlice(@NonNull android.net.Uri, @NonNull java.util.List<android.app.slice.SliceSpec>);
-  }
-
-  public abstract class SliceProvider extends android.content.ContentProvider {
-    method @Deprecated public android.app.slice.Slice onBindSlice(android.net.Uri, java.util.List<android.app.slice.SliceSpec>);
-  }
-
-}
-
 package android.app.usage {
 
   public class StorageStatsManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ce5752f..847edd1 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -258,6 +258,7 @@
     field public static final String PERFORM_IMS_SINGLE_REGISTRATION = "android.permission.PERFORM_IMS_SINGLE_REGISTRATION";
     field public static final String PERFORM_SIM_ACTIVATION = "android.permission.PERFORM_SIM_ACTIVATION";
     field public static final String POWER_SAVER = "android.permission.POWER_SAVER";
+    field @FlaggedApi("android.permission.flags.factory_reset_prep_permission_apis") public static final String PREPARE_FACTORY_RESET = "android.permission.PREPARE_FACTORY_RESET";
     field public static final String PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE = "android.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE";
     field public static final String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
     field public static final String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
@@ -3613,7 +3614,6 @@
     field public static final String ACTION_SHOW_SUSPENDED_APP_DETAILS = "android.intent.action.SHOW_SUSPENDED_APP_DETAILS";
     field @Deprecated public static final String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
     field public static final String ACTION_SPLIT_CONFIGURATION_CHANGED = "android.intent.action.SPLIT_CONFIGURATION_CHANGED";
-    field @FlaggedApi("android.content.pm.archiving") public static final String ACTION_UNARCHIVE_PACKAGE = "android.intent.action.UNARCHIVE_PACKAGE";
     field public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP";
     field public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED";
     field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED";
@@ -3861,16 +3861,9 @@
     field @RequiresPermission(android.Manifest.permission.ACCESS_SHORTCUTS) public static final int FLAG_GET_PERSONS_DATA = 2048; // 0x800
   }
 
-  public class PackageInfo implements android.os.Parcelable {
-    method @FlaggedApi("android.content.pm.archiving") public long getArchiveTimeMillis();
-  }
-
   public class PackageInstaller {
     method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull java.io.File, int) throws android.content.pm.PackageInstaller.PackageParsingException;
     method @FlaggedApi("android.content.pm.read_install_info") @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull android.os.ParcelFileDescriptor, @Nullable String, int) throws android.content.pm.PackageInstaller.PackageParsingException;
-    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void reportUnarchivalStatus(int, int, long, @Nullable android.app.PendingIntent) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void requestArchive(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void requestUnarchive(@NonNull String, @NonNull android.content.IntentSender) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
     field public static final String ACTION_CONFIRM_INSTALL = "android.content.pm.action.CONFIRM_INSTALL";
     field public static final String ACTION_CONFIRM_PRE_APPROVAL = "android.content.pm.action.CONFIRM_PRE_APPROVAL";
@@ -3881,23 +3874,12 @@
     field public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
     field public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
     field @Deprecated public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH";
-    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS";
-    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ID = "android.content.pm.extra.UNARCHIVE_ID";
-    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
-    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_STATUS = "android.content.pm.extra.UNARCHIVE_STATUS";
     field public static final int LOCATION_DATA_APP = 0; // 0x0
     field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
     field public static final int LOCATION_MEDIA_OBB = 1; // 0x1
     field public static final int REASON_CONFIRM_PACKAGE_CHANGE = 0; // 0x0
     field public static final int REASON_OWNERSHIP_CHANGED = 1; // 0x1
     field public static final int REASON_REMIND_OWNERSHIP = 2; // 0x2
-    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSTALLER_DISABLED = 4; // 0x4
-    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSTALLER_UNINSTALLED = 5; // 0x5
-    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE = 2; // 0x2
-    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_NO_CONNECTIVITY = 3; // 0x3
-    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_ERROR_USER_ACTION_NEEDED = 1; // 0x1
-    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_GENERIC_ERROR = 100; // 0x64
-    field @FlaggedApi("android.content.pm.archiving") public static final int UNARCHIVAL_OK = 0; // 0x0
   }
 
   public static class PackageInstaller.InstallInfo {
@@ -3947,14 +3929,12 @@
     method public void setRequestDowngrade(boolean);
     method @FlaggedApi("android.content.pm.rollback_lifetime") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackLifetimeMillis(long);
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
-    method @FlaggedApi("android.content.pm.archiving") public void setUnarchiveId(int);
   }
 
   public class PackageItemInfo {
     method public static void forceSafeLabels();
     method @Deprecated @NonNull public CharSequence loadSafeLabel(@NonNull android.content.pm.PackageManager);
     method @NonNull public CharSequence loadSafeLabel(@NonNull android.content.pm.PackageManager, @FloatRange(from=0) float, int);
-    field @FlaggedApi("android.content.pm.archiving") public boolean isArchived;
   }
 
   public abstract class PackageManager {
@@ -3986,7 +3966,6 @@
     method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
     method @Deprecated public abstract int installExistingPackage(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
     method @Deprecated public abstract int installExistingPackage(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @FlaggedApi("android.content.pm.archiving") public boolean isAppArchivable(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
     method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(@NonNull android.content.Intent, int, android.os.UserHandle);
     method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(@NonNull android.content.Intent, @NonNull android.content.pm.PackageManager.ResolveInfoFlags, @NonNull android.os.UserHandle);
     method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentActivitiesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
@@ -4104,7 +4083,6 @@
     field @Deprecated public static final int INTENT_FILTER_VERIFICATION_SUCCESS = 1; // 0x1
     field @Deprecated public static final int MASK_PERMISSION_FLAGS = 255; // 0xff
     field public static final int MATCH_ANY_USER = 4194304; // 0x400000
-    field @FlaggedApi("android.content.pm.archiving") public static final long MATCH_ARCHIVED_PACKAGES = 4294967296L; // 0x100000000L
     field public static final int MATCH_CLONE_PROFILE = 536870912; // 0x20000000
     field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
     field public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 536870912; // 0x20000000
@@ -10577,6 +10555,7 @@
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.PersistableBundle getSeedAccountOptions();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getSeedAccountType();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public long[] getSerialNumbersOfUsers(boolean);
+    method @NonNull public android.graphics.drawable.Drawable getUserBadge();
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.os.UserHandle> getUserHandles(boolean);
     method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}) public android.graphics.Bitmap getUserIcon();
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public android.content.pm.UserProperties getUserProperties(@NonNull android.os.UserHandle);
@@ -12213,6 +12192,7 @@
     method public boolean hasExpanded();
     method public boolean hasInteracted();
     method public boolean hasSeen();
+    method @FlaggedApi("android.app.lifetime_extension_refactor") public boolean hasSmartReplied();
     method public boolean hasSnoozed();
     method public boolean hasViewedSettings();
     method public void setDirectReplied();
@@ -12220,6 +12200,7 @@
     method public void setDismissalSurface(int);
     method public void setExpanded();
     method public void setSeen();
+    method @FlaggedApi("android.app.lifetime_extension_refactor") public void setSmartReplied();
     method public void setSnoozed();
     method public void setViewedSettings();
     method public void writeToParcel(android.os.Parcel, int);
@@ -12807,6 +12788,7 @@
     field @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public static final int ERROR_CODE_ON_TRAINING_DATA_EGRESS_LIMIT_EXCEEDED = 8; // 0x8
     field @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public static final int ERROR_CODE_ON_TRAINING_DATA_SECURITY_EXCEPTION = 9; // 0x9
     field public static final int ERROR_CODE_REMOTE_EXCEPTION = 7; // 0x7
+    field @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public static final int ERROR_CODE_SHUTDOWN_HDS_ON_VOICE_ACTIVATION_OP_DISABLED = 10; // 0xa
     field public static final int ERROR_CODE_UNKNOWN = 0; // 0x0
   }
 
@@ -16160,8 +16142,10 @@
 
   public interface RegistrationManager {
     field public static final int SUGGESTED_ACTION_NONE = 0; // 0x0
+    field @FlaggedApi("com.android.internal.telephony.flags.add_rat_related_suggested_action_to_ims_registration") public static final int SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK = 4; // 0x4
     field public static final int SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK = 1; // 0x1
     field public static final int SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT = 2; // 0x2
+    field @FlaggedApi("com.android.internal.telephony.flags.add_rat_related_suggested_action_to_ims_registration") public static final int SUGGESTED_ACTION_TRIGGER_RAT_BLOCK = 3; // 0x3
   }
 
   public static class RegistrationManager.RegistrationCallback {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index f3bad3a..f4c8429 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -780,6 +780,25 @@
 
 }
 
+package android.app.pinner {
+
+  @FlaggedApi("android.app.pinner_service_client_api") public final class PinnedFileStat implements android.os.Parcelable {
+    ctor @FlaggedApi("android.app.pinner_service_client_api") public PinnedFileStat(@NonNull String, long, @NonNull String);
+    method @FlaggedApi("android.app.pinner_service_client_api") public int describeContents();
+    method @FlaggedApi("android.app.pinner_service_client_api") public long getBytesPinned();
+    method @FlaggedApi("android.app.pinner_service_client_api") @NonNull public String getFilename();
+    method @FlaggedApi("android.app.pinner_service_client_api") @NonNull public String getGroupName();
+    method @FlaggedApi("android.app.pinner_service_client_api") public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @FlaggedApi("android.app.pinner_service_client_api") @NonNull public static final android.os.Parcelable.Creator<android.app.pinner.PinnedFileStat> CREATOR;
+  }
+
+  @FlaggedApi("android.app.pinner_service_client_api") public class PinnerServiceClient {
+    ctor @FlaggedApi("android.app.pinner_service_client_api") public PinnerServiceClient();
+    method @FlaggedApi("android.app.pinner_service_client_api") @NonNull public java.util.List<android.app.pinner.PinnedFileStat> getPinnerStats();
+  }
+
+}
+
 package android.app.prediction {
 
   public final class AppPredictor {
@@ -4201,8 +4220,13 @@
   public static class WindowInfosListenerForTest.WindowInfo {
     field @NonNull public final android.graphics.Rect bounds;
     field public final int displayId;
+    field public final boolean isDuplicateTouchToWallpaper;
+    field public final boolean isFocusable;
+    field public final boolean isPreventSplitting;
+    field public final boolean isTouchable;
     field public final boolean isTrustedOverlay;
     field public final boolean isVisible;
+    field public final boolean isWatchOutsideTouch;
     field @NonNull public final String name;
     field @NonNull public final android.graphics.Matrix transform;
     field @NonNull public final android.os.IBinder windowToken;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index c5e132f..aec0427 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2391,12 +2391,9 @@
             OP_ACTIVITY_RECOGNITION,
             // Aural
             OP_READ_MEDIA_AUDIO,
-            OP_WRITE_MEDIA_AUDIO,
             // Visual
             OP_READ_MEDIA_VIDEO,
-            OP_WRITE_MEDIA_VIDEO,
             OP_READ_MEDIA_IMAGES,
-            OP_WRITE_MEDIA_IMAGES,
             OP_READ_MEDIA_VISUAL_USER_SELECTED,
             // Nearby devices
             OP_BLUETOOTH_SCAN,
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4f8e8dd..014ddd41 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -3484,9 +3484,20 @@
         // only do this if the user already has more than one preferred locale
         if (android.content.res.Flags.defaultLocale()
                 && r.getConfiguration().getLocales().size() > 1) {
-            LocaleConfig lc = getUserId() < 0
-                    ? LocaleConfig.fromContextIgnoringOverride(this)
-                    : new LocaleConfig(this);
+            LocaleConfig lc;
+            if (getUserId() < 0) {
+                lc = LocaleConfig.fromContextIgnoringOverride(this);
+            } else {
+                // This is needed because the app might have locale config overrides that need to
+                // be read from disk in order for resources to correctly choose which values to
+                // load.
+                StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads();
+                try {
+                    lc = new LocaleConfig(this);
+                } finally {
+                    StrictMode.setThreadPolicy(policy);
+                }
+            }
             mResourcesManager.setLocaleConfig(lc);
         }
     }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 337e3f1..8c5773a 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -745,6 +745,16 @@
     @TestApi
     public static final int FLAG_USER_INITIATED_JOB = 0x00008000;
 
+    /**
+     * Bit to be bitwise-ored into the {@link #flags} field that should be
+     * set if this notification has been lifetime extended due to a direct reply.
+     *
+     * This flag is for internal use only; applications cannot set this flag directly.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR)
+    public static final int FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY = 0x00010000;
+
     private static final List<Class<? extends Style>> PLATFORM_STYLE_CLASSES = Arrays.asList(
             BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class,
             DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class,
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index d8448dc..772b0b4 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -85,6 +85,9 @@
 per-file IInstantAppResolver.aidl = file:/services/core/java/com/android/server/pm/OWNERS
 per-file InstantAppResolveInfo.aidl = file:/services/core/java/com/android/server/pm/OWNERS
 
+# Pinner
+per-file pinner-client.aconfig = file:/core/java/android/app/pinner/OWNERS
+
 # ResourcesManager
 per-file ResourcesManager.java = file:RESOURCES_OWNERS
 
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 6009c29..24a5157 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -159,7 +159,8 @@
      * Loads {@link ApkAssets} and caches them to prevent their garbage collection while the
      * instance is alive and reachable.
      */
-    private class ApkAssetsSupplier {
+    @VisibleForTesting
+    protected class ApkAssetsSupplier {
         final ArrayMap<ApkKey, ApkAssets> mLocalCache = new ArrayMap<>();
 
         /**
@@ -544,7 +545,10 @@
      * from an {@link ApkAssetsSupplier} if non-null; otherwise ApkAssets are loaded using
      * {@link #loadApkAssets(ApkKey)}.
      */
-    private @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key,
+
+    @VisibleForTesting
+    @UnsupportedAppUsage
+    protected @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key,
             @Nullable ApkAssetsSupplier apkSupplier) {
         final AssetManager.Builder builder = new AssetManager.Builder();
 
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 79a5879..9cf732a 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -137,6 +137,8 @@
 import android.media.soundtrigger.SoundTriggerManager;
 import android.media.tv.ITvInputManager;
 import android.media.tv.TvInputManager;
+import android.media.tv.ad.ITvAdManager;
+import android.media.tv.ad.TvAdManager;
 import android.media.tv.interactive.ITvInteractiveAppManager;
 import android.media.tv.interactive.TvInteractiveAppManager;
 import android.media.tv.tunerresourcemanager.ITunerResourceManager;
@@ -174,6 +176,7 @@
 import android.os.IPowerManager;
 import android.os.IPowerStatsService;
 import android.os.IRecoverySystem;
+import android.os.ISecurityStateManager;
 import android.os.ISystemUpdateManager;
 import android.os.IThermalService;
 import android.os.IUserManager;
@@ -182,6 +185,7 @@
 import android.os.PermissionEnforcer;
 import android.os.PowerManager;
 import android.os.RecoverySystem;
+import android.os.SecurityStateManager;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.StatsFrameworkInitializer;
@@ -628,6 +632,17 @@
                         ctx.mMainThread.getHandler());
             }});
 
+        registerService(Context.SECURITY_STATE_SERVICE, SecurityStateManager.class,
+                new CachedServiceFetcher<SecurityStateManager>() {
+                    @Override
+                    public SecurityStateManager createService(ContextImpl ctx)
+                            throws ServiceNotFoundException {
+                        IBinder b = ServiceManager.getServiceOrThrow(
+                                Context.SECURITY_STATE_SERVICE);
+                        ISecurityStateManager service = ISecurityStateManager.Stub.asInterface(b);
+                        return new SecurityStateManager(service);
+                    }});
+
         registerService(Context.SENSOR_SERVICE, SensorManager.class,
                 new CachedServiceFetcher<SensorManager>() {
             @Override
@@ -960,6 +975,18 @@
                 return new TvInteractiveAppManager(service, ctx.getUserId());
             }});
 
+        registerService(Context.TV_AD_SERVICE, TvAdManager.class,
+                new CachedServiceFetcher<TvAdManager>() {
+                    @Override
+                    public TvAdManager createService(ContextImpl ctx)
+                            throws ServiceNotFoundException {
+                        IBinder iBinder =
+                                ServiceManager.getServiceOrThrow(Context.TV_AD_SERVICE);
+                        ITvAdManager service =
+                                ITvAdManager.Stub.asInterface(iBinder);
+                        return new TvAdManager(service, ctx.getUserId());
+                    }});
+
         registerService(Context.TV_INPUT_SERVICE, TvInputManager.class,
                 new CachedServiceFetcher<TvInputManager>() {
             @Override
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 6a03c17..ce1d43d 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -180,6 +180,11 @@
 
     @Override
     public void injectInputEventToInputFilter(InputEvent event) throws RemoteException {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
         mAccessibilityManager.injectInputEventToInputFilter(event);
     }
 
diff --git a/core/java/android/app/pinner-client.aconfig b/core/java/android/app/pinner-client.aconfig
new file mode 100644
index 0000000..b60ad9e
--- /dev/null
+++ b/core/java/android/app/pinner-client.aconfig
@@ -0,0 +1,8 @@
+package: "android.app"
+
+flag {
+     namespace: "system_performance"
+     name: "pinner_service_client_api"
+     description: "Control exposing PinnerService APIs."
+     bug: "307594624"
+}
\ No newline at end of file
diff --git a/core/java/android/app/pinner/IPinnerService.aidl b/core/java/android/app/pinner/IPinnerService.aidl
new file mode 100644
index 0000000..e5d0a05
--- /dev/null
+++ b/core/java/android/app/pinner/IPinnerService.aidl
@@ -0,0 +1,12 @@
+package android.app.pinner;
+
+import android.app.pinner.PinnedFileStat;
+
+/**
+ * Interface for processes to communicate with system's PinnerService.
+ * @hide
+ */
+interface IPinnerService {
+    @EnforcePermission("DUMP")
+    List<PinnedFileStat> getPinnerStats();
+}
\ No newline at end of file
diff --git a/core/java/android/app/pinner/OWNERS b/core/java/android/app/pinner/OWNERS
new file mode 100644
index 0000000..3e3fa66
--- /dev/null
+++ b/core/java/android/app/pinner/OWNERS
@@ -0,0 +1,10 @@
+carmenjackson@google.com
+dualli@google.com
+edgararriaga@google.com
+kevinjeon@google.com
+philipcuadra@google.com
+shombert@google.com
+timmurray@google.com
+wessam@google.com
+jdduke@google.com
+shayba@google.com
\ No newline at end of file
diff --git a/core/java/android/app/pinner/PinnedFileStat.aidl b/core/java/android/app/pinner/PinnedFileStat.aidl
new file mode 100644
index 0000000..44217cf
--- /dev/null
+++ b/core/java/android/app/pinner/PinnedFileStat.aidl
@@ -0,0 +1,3 @@
+package android.app.pinner;
+
+parcelable PinnedFileStat;
\ No newline at end of file
diff --git a/core/java/android/app/pinner/PinnedFileStat.java b/core/java/android/app/pinner/PinnedFileStat.java
new file mode 100644
index 0000000..2e36330
--- /dev/null
+++ b/core/java/android/app/pinner/PinnedFileStat.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.pinner;
+
+import static android.app.Flags.FLAG_PINNER_SERVICE_CLIENT_API;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+@TestApi
+@FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+public final class PinnedFileStat implements Parcelable {
+    private String filename;
+    private long bytesPinned;
+    private String groupName;
+
+    /**
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+    public long getBytesPinned() {
+        return bytesPinned;
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+    public @NonNull String getFilename() {
+        return filename;
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+    public @NonNull String getGroupName() {
+        return groupName;
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+    public PinnedFileStat(@NonNull String filename, long bytesPinned, @NonNull String groupName) {
+        this.filename = filename;
+        this.bytesPinned = bytesPinned;
+        this.groupName = groupName;
+    }
+
+    private PinnedFileStat(Parcel source) {
+        readFromParcel(source);
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString8(filename);
+        dest.writeLong(bytesPinned);
+        dest.writeString8(groupName);
+    }
+
+    private void readFromParcel(@NonNull Parcel source) {
+        filename = source.readString8();
+        bytesPinned = source.readLong();
+        groupName = source.readString8();
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+    public static final @NonNull Creator<PinnedFileStat> CREATOR = new Creator<>() {
+        /**
+         * @hide
+         */
+        @TestApi
+        @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+        @Override
+        public PinnedFileStat createFromParcel(Parcel source) {
+            return new PinnedFileStat(source);
+        }
+
+        /**
+         * @hide
+         */
+        @TestApi
+        @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+        @Override
+        public PinnedFileStat[] newArray(int size) {
+            return new PinnedFileStat[size];
+        }
+    };
+}
diff --git a/core/java/android/app/pinner/PinnerServiceClient.java b/core/java/android/app/pinner/PinnerServiceClient.java
new file mode 100644
index 0000000..8b7c6cc
--- /dev/null
+++ b/core/java/android/app/pinner/PinnerServiceClient.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.pinner;
+
+import static android.app.Flags.FLAG_PINNER_SERVICE_CLIENT_API;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.app.pinner.IPinnerService;
+import android.app.pinner.PinnedFileStat;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Expose PinnerService as an interface to apps.
+ * @hide
+ */
+@TestApi
+@FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+public class PinnerServiceClient {
+    private static String TAG = "PinnerServiceClient";
+    /**
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+    public PinnerServiceClient() {}
+
+    /**
+     * Obtain the pinned file stats used for testing infrastructure.
+     * @return List of pinned files or an empty list if failed to retrieve them.
+     * @throws RuntimeException on failure to retrieve stats.
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_PINNER_SERVICE_CLIENT_API)
+    public @NonNull List<PinnedFileStat> getPinnerStats() {
+        IBinder binder = ServiceManager.getService("pinner");
+        if (binder == null) {
+            Slog.w(TAG,
+                    "Failed to retrieve PinnerService. A common failure reason is due to a lack of selinux permissions.");
+            return new ArrayList<>();
+        }
+        IPinnerService pinnerService = IPinnerService.Stub.asInterface(binder);
+        if (pinnerService == null) {
+            Slog.w(TAG, "Failed to cast PinnerService.");
+            return new ArrayList<>();
+        }
+        List<PinnedFileStat> stats;
+        try {
+            stats = pinnerService.getPinnerStats();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed to retrieve stats from PinnerService");
+        }
+        return stats;
+    }
+}
diff --git a/core/java/android/app/slice/Slice.java b/core/java/android/app/slice/Slice.java
index 823fdd2..475ee7a 100644
--- a/core/java/android/app/slice/Slice.java
+++ b/core/java/android/app/slice/Slice.java
@@ -195,13 +195,6 @@
      */
     public static final String EXTRA_TOGGLE_STATE = "android.app.slice.extra.TOGGLE_STATE";
     /**
-     * Key to retrieve an extra added to an intent when the value of a slider is changed.
-     * @deprecated remove once support lib is update to use EXTRA_RANGE_VALUE instead
-     * @removed
-     */
-    @Deprecated
-    public static final String EXTRA_SLIDER_VALUE = "android.app.slice.extra.SLIDER_VALUE";
-    /**
      * Key to retrieve an extra added to an intent when the value of an input range is changed.
      */
     public static final String EXTRA_RANGE_VALUE = "android.app.slice.extra.RANGE_VALUE";
@@ -223,13 +216,6 @@
      */
     public static final String SUBTYPE_COLOR = "color";
     /**
-     * Subtype to tag an item as representing a slider.
-     * @deprecated remove once support lib is update to use SUBTYPE_RANGE instead
-     * @removed
-     */
-    @Deprecated
-    public static final String SUBTYPE_SLIDER = "slider";
-    /**
      * Subtype to tag an item as representing a range.
      * Expected to be on an item of format {@link SliceItem#FORMAT_SLICE} containing
      * a {@link #SUBTYPE_VALUE} and possibly a {@link #SUBTYPE_MAX}.
@@ -361,15 +347,6 @@
         private SliceSpec mSpec;
 
         /**
-         * @deprecated TO BE REMOVED
-         * @removed
-         */
-        @Deprecated
-        public Builder(@NonNull Uri uri) {
-            mUri = uri;
-        }
-
-        /**
          * Create a builder which will construct a {@link Slice} for the given Uri.
          * @param uri Uri to tag for this slice.
          * @param spec the spec for this slice.
@@ -413,15 +390,6 @@
         }
 
         /**
-         * @deprecated TO BE REMOVED
-         * @removed
-         */
-        public Builder setSpec(SliceSpec spec) {
-            mSpec = spec;
-            return this;
-        }
-
-        /**
          * Add a sub-slice to the slice being constructed
          * @param subType Optional template-specific type information
          * @see SliceItem#getSubType()
@@ -498,16 +466,6 @@
         }
 
         /**
-         * @deprecated TO BE REMOVED.
-         * @removed
-         */
-        @Deprecated
-        public Slice.Builder addTimestamp(long time, @Nullable @SliceSubtype String subType,
-                @SliceHint List<String> hints) {
-            return addLong(time, subType, hints);
-        }
-
-        /**
          * Add a long to the slice being constructed
          * @param subType Optional template-specific type information
          * @see SliceItem#getSubType()
diff --git a/core/java/android/app/slice/SliceItem.java b/core/java/android/app/slice/SliceItem.java
index ed32a1b..2d6f4a6 100644
--- a/core/java/android/app/slice/SliceItem.java
+++ b/core/java/android/app/slice/SliceItem.java
@@ -102,12 +102,6 @@
      */
     public static final String FORMAT_LONG = "long";
     /**
-     * @deprecated TO BE REMOVED
-     * @removed
-     */
-    @Deprecated
-    public static final String FORMAT_TIMESTAMP = FORMAT_LONG;
-    /**
      * A {@link SliceItem} that contains a {@link RemoteInput}.
      */
     public static final String FORMAT_REMOTE_INPUT = "input";
@@ -257,15 +251,6 @@
     }
 
     /**
-     * @deprecated replaced by {@link #getLong()}
-     * @removed
-     */
-    @Deprecated
-    public long getTimestamp() {
-        return (Long) mObj;
-    }
-
-    /**
      * @param hint The hint to check for
      * @return true if this item contains the given hint
      */
@@ -348,7 +333,7 @@
             case FORMAT_INT:
                 dest.writeInt((Integer) obj);
                 break;
-            case FORMAT_TIMESTAMP:
+            case FORMAT_LONG:
                 dest.writeLong((Long) obj);
                 break;
         }
@@ -368,7 +353,7 @@
                         Slice.CREATOR.createFromParcel(in));
             case FORMAT_INT:
                 return in.readInt();
-            case FORMAT_TIMESTAMP:
+            case FORMAT_LONG:
                 return in.readLong();
             case FORMAT_REMOTE_INPUT:
                 return RemoteInput.CREATOR.createFromParcel(in);
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index 1e4934e..2e179d0 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -141,15 +141,6 @@
     }
 
     /**
-     * @deprecated TO BE REMOVED
-     * @removed
-     */
-    @Deprecated
-    public void pinSlice(@NonNull Uri uri, @NonNull List<SliceSpec> specs) {
-        pinSlice(uri, new ArraySet<>(specs));
-    }
-
-    /**
      * Remove a pin for a slice.
      * <p>
      * If the slice has no other pins/callbacks then the slice will be unpinned.
@@ -273,15 +264,6 @@
     }
 
     /**
-     * @deprecated TO BE REMOVED
-     * @removed
-     */
-    @Deprecated
-    public @Nullable Slice bindSlice(@NonNull Uri uri, @NonNull List<SliceSpec> supportedSpecs) {
-        return bindSlice(uri, new ArraySet<>(supportedSpecs));
-    }
-
-    /**
      * Turns a slice intent into a slice uri. Expects an explicit intent.
      * <p>
      * This goes through a several stage resolution process to determine if any slice
@@ -412,17 +394,6 @@
     }
 
     /**
-     * @deprecated TO BE REMOVED.
-     * @removed
-     */
-    @Deprecated
-    @Nullable
-    public Slice bindSlice(@NonNull Intent intent,
-            @NonNull List<SliceSpec> supportedSpecs) {
-        return bindSlice(intent, new ArraySet<>(supportedSpecs));
-    }
-
-    /**
      * Determine whether a particular process and user ID has been granted
      * permission to access a specific slice URI.
      *
diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index 63835cb..42c3aa6 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -209,15 +209,6 @@
      * @see Slice#HINT_PARTIAL
      */
     public Slice onBindSlice(Uri sliceUri, Set<SliceSpec> supportedSpecs) {
-        return onBindSlice(sliceUri, new ArrayList<>(supportedSpecs));
-    }
-
-    /**
-     * @deprecated TO BE REMOVED
-     * @removed
-     */
-    @Deprecated
-    public Slice onBindSlice(Uri sliceUri, List<SliceSpec> supportedSpecs) {
         return null;
     }
 
@@ -479,7 +470,7 @@
         } finally {
             Handler.getMain().removeCallbacks(mAnr);
         }
-        Slice.Builder parent = new Slice.Builder(sliceUri);
+        Slice.Builder parent = new Slice.Builder(sliceUri, null);
         Slice.Builder childAction = new Slice.Builder(parent)
                 .addIcon(Icon.createWithResource(context,
                         com.android.internal.R.drawable.ic_permission), null,
@@ -492,7 +483,8 @@
                 .getTheme().resolveAttribute(android.R.attr.colorAccent, tv, true);
         int deviceDefaultAccent = tv.data;
 
-        parent.addSubSlice(new Slice.Builder(sliceUri.buildUpon().appendPath("permission").build())
+        Uri subSliceUri = sliceUri.buildUpon().appendPath("permission").build();
+        Slice.Builder subSlice = new Slice.Builder(subSliceUri, null)
                 .addIcon(Icon.createWithResource(context,
                         com.android.internal.R.drawable.ic_arrow_forward), null,
                         Collections.emptyList())
@@ -500,8 +492,8 @@
                         Collections.emptyList())
                 .addInt(deviceDefaultAccent, SUBTYPE_COLOR,
                         Collections.emptyList())
-                .addSubSlice(childAction.build(), null)
-                .build(), null);
+                .addSubSlice(childAction.build(), null);
+        parent.addSubSlice(subSlice.build(), null);
         return parent.addHints(Arrays.asList(Slice.HINT_PERMISSION_REQUEST)).build();
     }
 
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index ebd5d64..cf19178 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -22,6 +22,7 @@
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageEventsQuery;
 import android.content.pm.ParceledListSlice;
+import android.os.PersistableBundle;
 
 /**
  * System private API for talking with the UsageStatsManagerService.
@@ -77,6 +78,8 @@
             String callingPackage);
     void reportUsageStop(in IBinder activity, String token, String callingPackage);
     void reportUserInteraction(String packageName, int userId);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.REPORT_USAGE_STATS)")
+    void reportUserInteractionWithBundle(String packageName, int userId, in PersistableBundle eventExtras);
     int getUsageSource();
     void forceUsageSourceSettingRead();
     long getLastTimeAnyComponentUsed(String packageName, String callingPackage);
diff --git a/core/java/android/app/usage/ParcelableUsageEventList.java b/core/java/android/app/usage/ParcelableUsageEventList.java
index aa32392..7bc6cb9 100644
--- a/core/java/android/app/usage/ParcelableUsageEventList.java
+++ b/core/java/android/app/usage/ParcelableUsageEventList.java
@@ -223,6 +223,7 @@
         event.mContentAnnotations = null;
         event.mNotificationChannelId = null;
         event.mLocusId = null;
+        event.mExtras = null;
 
         switch (event.mEventType) {
             case Event.CONFIGURATION_CHANGE -> {
@@ -237,6 +238,11 @@
             case Event.STANDBY_BUCKET_CHANGED -> event.mBucketAndReason = in.readInt();
             case Event.NOTIFICATION_INTERRUPTION -> event.mNotificationChannelId = in.readString();
             case Event.LOCUS_ID_SET -> event.mLocusId = in.readString();
+            case Event.USER_INTERACTION -> {
+                if (in.readInt() != 0) {
+                    event.mExtras = in.readPersistableBundle(getClass().getClassLoader());
+                }
+            }
         }
         event.mFlags = in.readInt();
 
@@ -263,6 +269,14 @@
             case Event.STANDBY_BUCKET_CHANGED -> dest.writeInt(event.mBucketAndReason);
             case Event.NOTIFICATION_INTERRUPTION -> dest.writeString(event.mNotificationChannelId);
             case Event.LOCUS_ID_SET -> dest.writeString(event.mLocusId);
+            case Event.USER_INTERACTION -> {
+                if (event.mExtras != null) {
+                    dest.writeInt(1);
+                    dest.writePersistableBundle(event.mExtras);
+                } else {
+                    dest.writeInt(0);
+                }
+            }
         }
         dest.writeInt(event.mFlags);
     }
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 6c7eba0..9eb73b3 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -16,7 +16,9 @@
 package android.app.usage;
 
 import android.annotation.CurrentTimeMillisLong;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -24,6 +26,7 @@
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.util.Log;
 
 import java.lang.annotation.Retention;
@@ -551,6 +554,22 @@
         public int mLocusIdToken = UNASSIGNED_TOKEN;
 
         /** @hide */
+        public PersistableBundle mExtras = null;
+
+        /** @hide */
+        public static class UserInteractionEventExtrasToken {
+            public int mCategoryToken = UNASSIGNED_TOKEN;
+            public int mActionToken = UNASSIGNED_TOKEN;
+
+            public UserInteractionEventExtrasToken() {
+                // Do nothing.
+            }
+        }
+
+        /** @hide */
+        public UserInteractionEventExtrasToken mUserInteractionExtrasToken = null;
+
+        /** @hide */
         @EventFlags
         public int mFlags;
 
@@ -650,6 +669,21 @@
         }
 
         /**
+         * Retrieves a map of extended data from the event if the event is of type
+         * {@link #USER_INTERACTION}.
+         *
+         * @return the map of all extras that associated with the reported user interaction
+         *         event. The returned {@link PersistableBundle} will contain the extras
+         *         {@link UsageStatsManager#EXTRA_EVENT_CATEGORY} and
+         *         {@link UsageStatsManager#EXTRA_EVENT_ACTION}. {@link PersistableBundle#EMPTY}
+         *         will be returned if the details are not available.
+         */
+        @FlaggedApi(Flags.FLAG_USER_INTERACTION_TYPE_API)
+        public @NonNull PersistableBundle getExtras() {
+            return mExtras == null ? PersistableBundle.EMPTY : mExtras;
+        }
+
+        /**
          * Returns a {@link Configuration} for this event if the event is of type
          * {@link #CONFIGURATION_CHANGE}, otherwise it returns null.
          */
@@ -747,6 +781,7 @@
             mBucketAndReason = orig.mBucketAndReason;
             mNotificationChannelId = orig.mNotificationChannelId;
             mLocusId = orig.mLocusId;
+            mExtras = orig.mExtras;
         }
     }
 
@@ -802,6 +837,7 @@
         if (mEventCount != mEventsToWrite.size()) {
             Log.w(TAG, "Partial usage event list received: " + mEventCount + " != "
                     + mEventsToWrite.size());
+            mEventCount = mEventsToWrite.size();
         }
     }
 
@@ -987,6 +1023,14 @@
             case Event.LOCUS_ID_SET:
                 p.writeString(event.mLocusId);
                 break;
+            case Event.USER_INTERACTION:
+                if (event.mExtras != null) {
+                    p.writeInt(1);
+                    p.writePersistableBundle(event.mExtras);
+                } else {
+                    p.writeInt(0);
+                }
+                break;
         }
         p.writeInt(event.mFlags);
     }
@@ -1036,6 +1080,7 @@
         eventOut.mContentAnnotations = null;
         eventOut.mNotificationChannelId = null;
         eventOut.mLocusId = null;
+        eventOut.mExtras = null;
 
         switch (eventOut.mEventType) {
             case Event.CONFIGURATION_CHANGE:
@@ -1059,6 +1104,11 @@
             case Event.LOCUS_ID_SET:
                 eventOut.mLocusId = p.readString();
                 break;
+            case Event.USER_INTERACTION:
+                if (p.readInt() != 0) {
+                    eventOut.mExtras = p.readPersistableBundle(getClass().getClassLoader());
+                }
+                break;
         }
         eventOut.mFlags = p.readInt();
     }
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 4f1c993..85d223d 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -28,6 +28,7 @@
 import android.annotation.SystemService;
 import android.annotation.TestApi;
 import android.annotation.UserHandleAware;
+import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.BroadcastOptions;
 import android.app.PendingIntent;
@@ -35,6 +36,7 @@
 import android.content.Context;
 import android.content.pm.ParceledListSlice;
 import android.os.Build;
+import android.os.PersistableBundle;
 import android.os.PowerWhitelistManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -392,6 +394,23 @@
     @SystemApi
     public static final String EXTRA_TIME_USED = "android.app.usage.extra.TIME_USED";
 
+    /**
+     * A String extra, when used with {@link UsageEvents.Event#getExtras}, that indicates
+     * the category of the user interaction associated with the event. The category cannot
+     * be more than 127 characters, longer value will be truncated to 127 characters.
+     */
+    @FlaggedApi(Flags.FLAG_USER_INTERACTION_TYPE_API)
+    public static final String EXTRA_EVENT_CATEGORY =
+            "android.app.usage.extra.EVENT_CATEGORY";
+
+    /**
+     * A String extra, when used with {@link UsageEvents.Event#getExtras}, that indicates
+     * the action of the user interaction associated with the event. The action cannot be
+     * more than 127 characters, longer value will be truncated to 127 characters.
+     */
+    @FlaggedApi(Flags.FLAG_USER_INTERACTION_TYPE_API)
+    public static final String EXTRA_EVENT_ACTION =
+            "android.app.usage.extra.EVENT_ACTION";
 
     /**
      * App usage observers will consider the task root package the source of usage.
@@ -562,10 +581,10 @@
      * then {@code null} will be returned.</em>
      *
      * @param beginTime The inclusive beginning of the range of events to include in the results.
-     *                 Defined in terms of "Unix time", see
-     *                 {@link java.lang.System#currentTimeMillis}.
+     *                  Defined in terms of "Unix time", see
+     *                  {@link java.lang.System#currentTimeMillis}.
      * @param endTime The exclusive end of the range of events to include in the results. Defined
-     *               in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
+     *                in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
      * @return A {@link UsageEvents}.
      */
     public UsageEvents queryEvents(long beginTime, long endTime) {
@@ -611,10 +630,10 @@
      * then {@code null} will be returned.</em>
      *
      * @param beginTime The inclusive beginning of the range of events to include in the results.
-     *                 Defined in terms of "Unix time", see
-     *                 {@link java.lang.System#currentTimeMillis}.
+     *                  Defined in terms of "Unix time", see
+     *                  {@link java.lang.System#currentTimeMillis}.
      * @param endTime The exclusive end of the range of events to include in the results. Defined
-     *               in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
+     *                in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
      * @return A {@link UsageEvents} object.
      *
      * @see #queryEvents(long, long)
@@ -1128,6 +1147,7 @@
      * Reports user interaction with a given package in the given user.
      *
      * <p><em>This method is only for use by the system</em>
+     *
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.REPORT_USAGE_STATS)
@@ -1140,6 +1160,38 @@
     }
 
     /**
+     * Reports user interaction with given package and a particular {@code extras}
+     * in the given user.
+     *
+     * <p>
+     * Note: The structure of {@code extras} is a {@link PersistableBundle} with the
+     * category {@link #EXTRA_EVENT_CATEGORY} and the action {@link #EXTRA_EVENT_ACTION}.
+     * Category provides additional detail about the user interaction, the value
+     * is defined in namespace based. Example: android.app.notification could be used to
+     * indicate that the reported user interaction is related to notification. Action
+     * indicates the general action that performed.
+     * </p>
+     *
+     * @param packageName The package name of the app
+     * @param userId The user id who triggers the user interaction
+     * @param extras The {@link PersistableBundle} that will be used to specify the
+     *               extra details for the user interaction event. The {@link PersistableBundle}
+     *               must contain the extras {@link #EXTRA_EVENT_CATEGORY},
+     *               {@link #EXTRA_EVENT_ACTION}. Cannot be empty.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_USER_INTERACTION_TYPE_API)
+    @RequiresPermission(android.Manifest.permission.REPORT_USAGE_STATS)
+    public void reportUserInteraction(@NonNull String packageName, @UserIdInt int userId,
+            @NonNull PersistableBundle extras) {
+        try {
+            mService.reportUserInteractionWithBundle(packageName, userId, extras);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Report usage associated with a particular {@code token} has started. Tokens are app defined
      * strings used to represent usage of in-app features. Apps with the {@link
      * android.Manifest.permission#OBSERVE_APP_USAGE} permission can register time limit observers
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index c6012bb..6e45147 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -52,6 +52,7 @@
 
 import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.FunctionalUtils;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -557,11 +558,45 @@
                             }
                         }).toArray(ComponentName[]::new));
             } catch (Exception e) {
-                Log.e(TAG, "Nofity service of inheritance info", e);
+                Log.e(TAG, "Notify service of inheritance info", e);
             }
         });
     }
 
+    private void tryAdapterConversion(
+            FunctionalUtils.RemoteExceptionIgnoringConsumer<RemoteViews> action,
+            RemoteViews original, String failureMsg) {
+        final boolean isConvertingAdapter = RemoteViews.isAdapterConversionEnabled()
+                && (mHasPostedLegacyLists = mHasPostedLegacyLists
+                        || (original != null && original.hasLegacyLists()));
+
+        if (isConvertingAdapter) {
+            final RemoteViews viewsCopy = new RemoteViews(original);
+            Runnable updateWidgetWithTask = () -> {
+                try {
+                    viewsCopy.collectAllIntents().get();
+                    action.acceptOrThrow(viewsCopy);
+                } catch (Exception e) {
+                    Log.e(TAG, failureMsg, e);
+                }
+            };
+
+            if (Looper.getMainLooper() == Looper.myLooper()) {
+                createUpdateExecutorIfNull().execute(updateWidgetWithTask);
+                return;
+            }
+
+            updateWidgetWithTask.run();
+            return;
+        }
+
+        try {
+            action.acceptOrThrow(original);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
     /**
      * Set the RemoteViews to use for the specified appWidgetIds.
      * <p>
@@ -586,32 +621,8 @@
             return;
         }
 
-        final boolean isConvertingAdapter = RemoteViews.isAdapterConversionEnabled()
-                && (mHasPostedLegacyLists = mHasPostedLegacyLists
-                        || (views != null && views.hasLegacyLists()));
-
-        if (isConvertingAdapter) {
-            views.collectAllIntents();
-
-            if (Looper.getMainLooper() == Looper.myLooper()) {
-                RemoteViews viewsCopy = new RemoteViews(views);
-                createUpdateExecutorIfNull().execute(() -> {
-                    try {
-                        mService.updateAppWidgetIds(mPackageName, appWidgetIds, viewsCopy);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Error updating app widget views in background", e);
-                    }
-                });
-
-                return;
-            }
-        }
-
-        try {
-            mService.updateAppWidgetIds(mPackageName, appWidgetIds, views);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        tryAdapterConversion(view -> mService.updateAppWidgetIds(mPackageName, appWidgetIds,
+                view), views, "Error updating app widget views in background");
     }
 
     /**
@@ -716,32 +727,9 @@
             return;
         }
 
-        final boolean isConvertingAdapter = RemoteViews.isAdapterConversionEnabled()
-                && (mHasPostedLegacyLists = mHasPostedLegacyLists
-                        || (views != null && views.hasLegacyLists()));
-
-        if (isConvertingAdapter) {
-            views.collectAllIntents();
-
-            if (Looper.getMainLooper() == Looper.myLooper()) {
-                RemoteViews viewsCopy = new RemoteViews(views);
-                createUpdateExecutorIfNull().execute(() -> {
-                    try {
-                        mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, viewsCopy);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Error partially updating app widget views in background", e);
-                    }
-                });
-
-                return;
-            }
-        }
-
-        try {
-            mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, views);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        tryAdapterConversion(view -> mService.partiallyUpdateAppWidgetIds(mPackageName,
+                appWidgetIds, view), views,
+                "Error partially updating app widget views in background");
     }
 
     /**
@@ -793,33 +781,8 @@
             return;
         }
 
-        final boolean isConvertingAdapter = RemoteViews.isAdapterConversionEnabled()
-                && (mHasPostedLegacyLists = mHasPostedLegacyLists
-                        || (views != null && views.hasLegacyLists()));
-
-        if (isConvertingAdapter) {
-            views.collectAllIntents();
-
-            if (Looper.getMainLooper() == Looper.myLooper()) {
-                RemoteViews viewsCopy = new RemoteViews(views);
-                createUpdateExecutorIfNull().execute(() -> {
-                    try {
-                        mService.updateAppWidgetProvider(provider, viewsCopy);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Error updating app widget view using provider in background",
-                                e);
-                    }
-                });
-
-                return;
-            }
-        }
-
-        try {
-            mService.updateAppWidgetProvider(provider, views);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        tryAdapterConversion(view -> mService.updateAppWidgetProvider(provider, view), views,
+                "Error updating app widget view using provider in background");
     }
 
     /**
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index e0ce917..e4a03c5 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -1358,6 +1358,36 @@
     }
 
     /**
+     * Return the current state of consent for permission transfer for the association.
+     * True if the user has allowed permission transfer for the association, false otherwise.
+     *
+     * <p>
+     * Note: The initial user consent is collected via
+     * {@link #buildPermissionTransferUserConsentIntent(int) a permission transfer user consent dialog}.
+     * After the user has made their initial selection, they can toggle the permission transfer
+     * feature in the settings.
+     * This method always returns the state of the toggle setting.
+     * </p>
+     *
+     * @param associationId The unique {@link AssociationInfo#getId ID} assigned to the association
+     *                      of the companion device recorded by CompanionDeviceManager
+     * @return True if the user has consented to the permission transfer, or false otherwise.
+     * @throws DeviceNotAssociatedException Exception if the companion device is not associated with
+     *                                      the user or the calling app.
+     */
+    @UserHandleAware
+    @FlaggedApi(Flags.FLAG_PERM_SYNC_USER_CONSENT)
+    public boolean isPermissionTransferUserConsented(int associationId) {
+        try {
+            return mService.isPermissionTransferUserConsented(mContext.getOpPackageName(),
+                    mContext.getUserId(), associationId);
+        } catch (RemoteException e) {
+            ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Start system data transfer which has been previously approved by the user.
      *
      * <p>Before calling this method, the app needs to make sure there's a communication channel
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index c5a1988..22689f3 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -97,6 +97,8 @@
     PendingIntent buildPermissionTransferUserConsentIntent(String callingPackage, int userId,
         int associationId);
 
+    boolean isPermissionTransferUserConsented(String callingPackage, int userId, int associationId);
+
     void startSystemDataTransfer(String packageName, int userId, int associationId,
         in ISystemDataTransferCallback callback);
 
diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig
index 6e33dff..9e410b8 100644
--- a/core/java/android/companion/flags.aconfig
+++ b/core/java/android/companion/flags.aconfig
@@ -27,3 +27,10 @@
     description: "Enable device presence APIs"
     bug: "283000075"
 }
+
+flag {
+    name: "perm_sync_user_consent"
+    namespace: "companion"
+    description: "Expose perm sync user consent API"
+    bug: "309528663"
+}
\ No newline at end of file
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl
index 102cbf3..3520c0b 100644
--- a/core/java/android/companion/virtual/IVirtualDevice.aidl
+++ b/core/java/android/companion/virtual/IVirtualDevice.aidl
@@ -246,4 +246,10 @@
      */
     @EnforcePermission("CREATE_VIRTUAL_DEVICE")
     void unregisterVirtualCamera(in VirtualCameraConfig camera);
+
+    /**
+     * Returns the id of the virtual camera with given config.
+     */
+    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
+    int getVirtualCameraId(in VirtualCameraConfig camera);
 }
diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java
index da8277c..9492a62 100644
--- a/core/java/android/companion/virtual/VirtualDeviceInternal.java
+++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java
@@ -19,6 +19,7 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.UserIdInt;
 import android.app.PendingIntent;
 import android.companion.virtual.audio.VirtualAudioDevice;
@@ -340,12 +341,17 @@
         return mVirtualAudioDevice;
     }
 
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
     @NonNull
     VirtualCamera createVirtualCamera(@NonNull VirtualCameraConfig config) {
-        return new VirtualCamera(mVirtualDevice, config);
+        try {
+            mVirtualDevice.registerVirtualCamera(config);
+            return new VirtualCamera(mVirtualDevice, config);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
-    @NonNull
     void setShowPointerIcon(boolean showPointerIcon) {
         try {
             mVirtualDevice.setShowPointerIcon(showPointerIcon);
diff --git a/core/java/android/companion/virtual/camera/VirtualCamera.java b/core/java/android/companion/virtual/camera/VirtualCamera.java
index beee86f..52afa4e 100644
--- a/core/java/android/companion/virtual/camera/VirtualCamera.java
+++ b/core/java/android/companion/virtual/camera/VirtualCamera.java
@@ -66,15 +66,8 @@
     @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
     public VirtualCamera(
             @NonNull IVirtualDevice virtualDevice, @NonNull VirtualCameraConfig config) {
-        mVirtualDevice = virtualDevice;
+        mVirtualDevice = Objects.requireNonNull(virtualDevice);
         mConfig = Objects.requireNonNull(config);
-        Objects.requireNonNull(virtualDevice);
-        // TODO(b/310857519): Avoid registration inside constructor.
-        try {
-            mVirtualDevice.registerVirtualCamera(config);
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
     }
 
     /** Returns the configuration of this virtual camera instance. */
@@ -83,6 +76,20 @@
         return mConfig;
     }
 
+    /**
+     * Returns the id of this virtual camera instance.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    @NonNull
+    public String getId() {
+        try {
+            return Integer.toString(mVirtualDevice.getVirtualCameraId(mConfig));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     @Override
     @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
     public void close() {
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index 10da8b1..f0477d4 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -32,6 +32,13 @@
 }
 
 flag {
+  name: "consistent_display_flags"
+  namespace: "virtual_devices"
+  description: "Make virtual display flags consistent with display manager"
+  bug: "300905478"
+}
+
+flag {
   name: "vdm_custom_home"
   namespace: "virtual_devices"
   description: "Enable custom home API"
diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java
index 4b2cee6..697c25c 100644
--- a/core/java/android/content/AttributionSource.java
+++ b/core/java/android/content/AttributionSource.java
@@ -730,10 +730,7 @@
 
         /**
          * The next app to receive the permission protected data.
-         *
-         * @deprecated Use {@link #setNextAttributionSource} instead.
          */
-        @Deprecated
         public @NonNull Builder setNext(@Nullable AttributionSource value) {
             checkNotUsed();
             mBuilderFieldsSet |= 0x20;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 1c6c7b5..b75c64d 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -72,6 +72,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.Flags;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.IBinder;
@@ -4214,6 +4215,7 @@
             DEVICE_LOCK_SERVICE,
             VIRTUALIZATION_SERVICE,
             GRAMMATICAL_INFLECTION_SERVICE,
+            SECURITY_STATE_SERVICE,
 
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -5818,6 +5820,17 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.media.tv.ad.TvAdManager} for interacting with TV client-side advertisement
+     * services on the device.
+     *
+     * @see #getSystemService(String)
+     * @see android.media.tv.ad.TvAdManager
+     */
+    @FlaggedApi(android.media.tv.flags.Flags.FLAG_ENABLE_AD_SERVICE_FW)
+    public static final String TV_AD_SERVICE = "tv_ad";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a
      * {@link android.media.tv.TunerResourceManager} for interacting with TV
      * tuner resources on the device.
      *
@@ -6478,6 +6491,16 @@
     public static final String SHARED_CONNECTIVITY_SERVICE = "shared_connectivity";
 
     /**
+     * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.os.SecurityStateManager} for accessing the security state manager service.
+     *
+     * @see #getSystemService(String)
+     * @see android.os.SecurityStateManager
+     */
+    @FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE)
+    public static final String SECURITY_STATE_SERVICE = "security_state";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 4327c7a..0a8029c 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -71,6 +71,7 @@
  * another Context.  Can be subclassed to modify behavior without changing
  * the original Context.
  */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
 public class ContextWrapper extends Context {
     @UnsupportedAppUsage
     Context mBase;
@@ -1430,6 +1431,7 @@
      * @throws IllegalStateException if this method calls before {@link #attachBaseContext(Context)}
      */
     @Override
+    @android.ravenwood.annotation.RavenwoodThrow
     public void registerComponentCallbacks(ComponentCallbacks callback) {
         if (mBase != null) {
             mBase.registerComponentCallbacks(callback);
@@ -1464,6 +1466,7 @@
      * @throws IllegalStateException if this method calls before {@link #attachBaseContext(Context)}
      */
     @Override
+    @android.ravenwood.annotation.RavenwoodThrow
     public void unregisterComponentCallbacks(ComponentCallbacks callback) {
         // It usually means the ComponentCallbacks is registered before this ContextWrapper attaches
         // to a base Context and Application is targeting prior to S-v2. We should unregister the
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c7a86fb..38bcfa2 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5353,11 +5353,11 @@
      * Broadcast Action: Sent to the responsible installer of an archived package when unarchival
      * is requested.
      *
-     * @see android.content.pm.PackageInstaller#requestUnarchive(String)
-     * @hide
+     * @see android.content.pm.PackageInstaller#requestUnarchive
      */
-    @SystemApi
     @FlaggedApi(android.content.pm.Flags.FLAG_ARCHIVING)
+    @BroadcastBehavior(explicitOnly = true)
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_UNARCHIVE_PACKAGE = "android.intent.action.UNARCHIVE_PACKAGE";
 
     // ---------------------------------------------------------------------
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 1cfdb8b..5736a6d 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -20,7 +20,6 @@
 import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
@@ -522,9 +521,7 @@
     /**
      * Returns the time at which the app was archived for the user.  Units are as
      * per {@link System#currentTimeMillis()}.
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public @CurrentTimeMillisLong long getArchiveTimeMillis() {
         return mArchiveTimeMillis;
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 6df1f60..d35c392 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -354,10 +354,7 @@
     /**
      * Extra field for the package name of a package that is requested to be unarchived. Sent as
      * part of the {@link android.content.Intent#ACTION_UNARCHIVE_PACKAGE} intent.
-     *
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final String EXTRA_UNARCHIVE_PACKAGE_NAME =
             "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
@@ -366,22 +363,16 @@
      * Extra field for the unarchive ID. Sent as
      * part of the {@link android.content.Intent#ACTION_UNARCHIVE_PACKAGE} intent.
      *
-     * @see Session#setUnarchiveId(int)
-     *
-     * @hide
+     * @see SessionParams#setUnarchiveId
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final String EXTRA_UNARCHIVE_ID =
             "android.content.pm.extra.UNARCHIVE_ID";
 
     /**
      * If true, the requestor of the unarchival has specified that the app should be unarchived
-     * for {@link android.os.UserHandle#ALL}.
-     *
-     * @hide
+     * for all users.
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final String EXTRA_UNARCHIVE_ALL_USERS =
             "android.content.pm.extra.UNARCHIVE_ALL_USERS";
@@ -398,9 +389,7 @@
      * failure dialog.
      *
      * @see #requestUnarchive
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final String EXTRA_UNARCHIVE_STATUS = "android.content.pm.extra.UNARCHIVE_STATUS";
 
@@ -675,10 +664,7 @@
      *
      * <p> Note that this does not mean that the unarchival has completed. This status should be
      * sent before any longer asynchronous action (e.g. app download) is started.
-     *
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final int UNARCHIVAL_OK = 0;
 
@@ -687,10 +673,7 @@
      *
      * <p> An example use case for this could be that the user needs to login to allow the
      * download for a paid app.
-     *
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final int UNARCHIVAL_ERROR_USER_ACTION_NEEDED = 1;
 
@@ -700,19 +683,13 @@
      * <p> The installer can optionally provide a {@code userActionIntent} for a space-clearing
      * dialog. If no action is provided, then a generic intent
      * {@link android.os.storage.StorageManager#ACTION_MANAGE_STORAGE} is started instead.
-     *
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final int UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE = 2;
 
     /**
      * The device is not connected to the internet
-     *
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final int UNARCHIVAL_ERROR_NO_CONNECTIVITY = 3;
 
@@ -720,10 +697,7 @@
      * The installer responsible for the unarchival is disabled.
      *
      * <p> Should only be used by the system.
-     *
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final int UNARCHIVAL_ERROR_INSTALLER_DISABLED = 4;
 
@@ -731,19 +705,13 @@
      * The installer responsible for the unarchival has been uninstalled
      *
      * <p> Should only be used by the system.
-     *
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final int UNARCHIVAL_ERROR_INSTALLER_UNINSTALLED = 5;
 
     /**
      * Generic error: The app cannot be unarchived.
-     *
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public static final int UNARCHIVAL_GENERIC_ERROR = 100;
 
@@ -2364,12 +2332,10 @@
      * @param statusReceiver Callback used to notify when the operation is completed.
      * @throws PackageManager.NameNotFoundException If {@code packageName} isn't found or not
      *                                              available to the caller or isn't archived.
-     * @hide
      */
     @RequiresPermission(anyOf = {
             Manifest.permission.DELETE_PACKAGES,
             Manifest.permission.REQUEST_DELETE_PACKAGES})
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public void requestArchive(@NonNull String packageName, @NonNull IntentSender statusReceiver)
             throws PackageManager.NameNotFoundException {
@@ -2395,19 +2361,16 @@
      *
      * @param statusReceiver Callback used to notify whether the installer has accepted the
      *                       unarchival request or an error has occurred. The status update will be
-     *                       sent though {@link EXTRA_UNARCHIVE_STATUS}. Only one status will be
+     *                       sent though {@link #EXTRA_UNARCHIVE_STATUS}. Only one status will be
      *                       sent.
      * @throws PackageManager.NameNotFoundException If {@code packageName} isn't found or not
      *                                              visible to the caller or if the package has no
      *                                              installer on the device anymore to unarchive it.
      * @throws IOException If parameters were unsatisfiable, such as lack of disk space.
-     *
-     * @hide
      */
     @RequiresPermission(anyOf = {
             Manifest.permission.INSTALL_PACKAGES,
             Manifest.permission.REQUEST_INSTALL_PACKAGES})
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public void requestUnarchive(@NonNull String packageName, @NonNull IntentSender statusReceiver)
             throws IOException, PackageManager.NameNotFoundException {
@@ -2435,12 +2398,10 @@
      * @param userActionIntent     Optional intent to start a follow up action required to
      *                             facilitate the unarchival flow (e.g. user needs to log in).
      * @throws PackageManager.NameNotFoundException if no unarchival with {@code unarchiveId} exists
-     * @hide
      */
     @RequiresPermission(anyOf = {
             Manifest.permission.INSTALL_PACKAGES,
             Manifest.permission.REQUEST_INSTALL_PACKAGES})
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public void reportUnarchivalStatus(int unarchiveId, @UnarchivalStatus int status,
             long requiredStorageBytes, @Nullable PendingIntent userActionIntent)
@@ -3454,11 +3415,8 @@
          * <p> The ID should be retrieved from the unarchive intent and passed into the
          * session that's being created to unarchive the app in question. Used to link the unarchive
          * intent and the install session to disambiguate.
-         *
-         * @hide
          */
         @FlaggedApi(Flags.FLAG_ARCHIVING)
-        @SystemApi
         public void setUnarchiveId(int unarchiveId) {
             this.unarchiveId = unarchiveId;
         }
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index c7091ad..70e6f98 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -177,12 +177,10 @@
     /**
      * Whether the package is currently in an archived state.
      *
-     * <p>Packages can be archived through {@link PackageArchiver} and do not have any APKs stored
-     * on the device, but do keep the data directory.
-     * @hide
+     * <p>Packages can be archived through {@link PackageInstaller#requestArchive} and do not have
+     * any APKs stored on the device, but do keep the data directory.
+     *
      */
-    // TODO(b/278553670) Unhide and update @links before launch.
-    @SystemApi
     @FlaggedApi(Flags.FLAG_ARCHIVING)
     public boolean isArchived;
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 6775f9b..a22fe3f 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1263,18 +1263,14 @@
 
     /**
      * Flag parameter to also retrieve some information about archived packages.
-     * Packages can be archived through
-     * {@link PackageInstaller#requestArchive(String, IntentSender)} and do not have any APKs stored
-     * on the device, but do keep the data directory.
+     * Packages can be archived through {@link PackageInstaller#requestArchive} and do not have any
+     * APKs stored on the device, but do keep the data directory.
      * <p> Note: Archived apps are a subset of apps returned by {@link #MATCH_UNINSTALLED_PACKAGES}.
      * <p> Note: this flag may cause less information about currently installed
      * applications to be returned.
      * <p> Note: use of this flag requires the android.permission.QUERY_ALL_PACKAGES
      * permission to see uninstalled packages.
-     * @hide
      */
-    // TODO(b/278553670) Unhide and update @links before launch.
-    @SystemApi
     @FlaggedApi(android.content.pm.Flags.FLAG_ARCHIVING)
     public static final long MATCH_ARCHIVED_PACKAGES = 1L << 32;
 
@@ -8969,10 +8965,7 @@
      *
      * @throws NameNotFoundException if the given package name is not available to the caller.
      * @see PackageInstaller#requestArchive(String, IntentSender)
-     *
-     * @hide
      */
-    @SystemApi
     @FlaggedApi(android.content.pm.Flags.FLAG_ARCHIVING)
     public boolean isAppArchivable(@NonNull String packageName) throws NameNotFoundException {
         throw new UnsupportedOperationException("isAppArchivable not implemented");
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index a565f68..1b90570 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -94,3 +94,17 @@
     description: "Feature flag to read install related information from an APK."
     bug: "275658500"
 }
+
+flag {
+    name: "use_pia_v2"
+    namespace: "package_manager_service"
+    description: "Feature flag to enable the refactored Package Installer app with updated UI."
+    bug: "182205982"
+}
+
+flag {
+    name: "improve_install_dont_kill"
+    namespace: "package_manager_service"
+    description: "Feature flag to reduce app crashes caused by split installs with INSTALL_DONT_KILL"
+    bug: "291212866"
+}
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index 1b8eb07..40592a1 100644
--- a/core/java/android/content/res/flags.aconfig
+++ b/core/java/android/content/res/flags.aconfig
@@ -15,3 +15,12 @@
     description: "Feature flag for passing in an AssetFileDescriptor to create an frro"
     bug: "304478666"
 }
+
+flag {
+    name: "manifest_flagging"
+    namespace: "resource_manager"
+    description: "Feature flag for flagging manifest entries"
+    bug: "297373084"
+    # This flag is read in PackageParser at boot time, and in aapt2 which is a build tool.
+    is_fixed_read_only: true
+}
diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java
index d786d9a..18c95bfb 100644
--- a/core/java/android/hardware/SensorPrivacyManager.java
+++ b/core/java/android/hardware/SensorPrivacyManager.java
@@ -66,6 +66,13 @@
             + ".extra.sensor";
 
     /**
+     * An extra containing the notification id that triggered the intent
+     * @hide
+     */
+    public static final String EXTRA_NOTIFICATION_ID = SensorPrivacyManager.class.getName()
+            + ".extra.notification_id";
+
+    /**
      * An extra indicating if all sensors are affected
      * @hide
      */
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index dfc27ca..507e814 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -16,6 +16,7 @@
 
 package android.hardware.camera2;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -24,6 +25,8 @@
 import android.hardware.camera2.impl.SyntheticKey;
 import android.util.Log;
 
+import com.android.internal.camera.flags.Flags;
+
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
diff --git a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
index d4ce0eb..5cbb0bb 100644
--- a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
@@ -16,8 +16,6 @@
 
 package android.hardware.camera2.params;
 
-import static com.android.internal.R.string.hardware;
-
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
diff --git a/core/java/android/hardware/input/InputDeviceSensorManager.java b/core/java/android/hardware/input/InputDeviceSensorManager.java
index 05024ea..8afcc78 100644
--- a/core/java/android/hardware/input/InputDeviceSensorManager.java
+++ b/core/java/android/hardware/input/InputDeviceSensorManager.java
@@ -17,6 +17,7 @@
 package android.hardware.input;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.hardware.HardwareBuffer;
 import android.hardware.Sensor;
 import android.hardware.SensorAdditionalInfo;
@@ -37,7 +38,6 @@
 import android.view.InputDevice;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.os.SomeArgs;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -49,14 +49,14 @@
  * sensors.
  * @hide
  */
-public class InputDeviceSensorManager implements InputManager.InputDeviceListener {
+public class InputDeviceSensorManager {
     private static final String TAG = "InputDeviceSensorManager";
     private static final boolean DEBUG = false;
 
     private static final int MSG_SENSOR_ACCURACY_CHANGED = 1;
     private static final int MSG_SENSOR_CHANGED = 2;
 
-    private InputManagerGlobal mGlobal;
+    private final InputManagerGlobal mGlobal;
 
     // sensor map from device id to sensor list
     @GuardedBy("mInputSensorLock")
@@ -66,19 +66,16 @@
     private InputSensorEventListener mInputServiceSensorListener;
     @GuardedBy("mInputSensorLock")
     private final ArrayList<InputSensorEventListenerDelegate> mInputSensorEventListeners =
-            new ArrayList<InputSensorEventListenerDelegate>();
-    private final HandlerThread mSensorThread;
-    private final Handler mSensorHandler;
+            new ArrayList<>();
+
+    // The sensor thread is only initialized if there is a listener added without a handler.
+    @GuardedBy("mInputSensorLock")
+    @Nullable
+    private HandlerThread mSensorThread;
 
     public InputDeviceSensorManager(InputManagerGlobal inputManagerGlobal) {
         mGlobal = inputManagerGlobal;
 
-        mSensorThread = new HandlerThread("SensorThread");
-        mSensorThread.start();
-        mSensorHandler = new Handler(mSensorThread.getLooper());
-
-        // Register the input device listener
-        mGlobal.registerInputDeviceListener(this, mSensorHandler);
         // Initialize the sensor list
         initializeSensors();
     }
@@ -105,7 +102,6 @@
         }
     }
 
-    @Override
     public void onInputDeviceAdded(int deviceId) {
         synchronized (mInputSensorLock) {
             if (!mSensors.containsKey(deviceId)) {
@@ -117,14 +113,12 @@
         }
     }
 
-    @Override
     public void onInputDeviceRemoved(int deviceId) {
         synchronized (mInputSensorLock) {
             mSensors.remove(deviceId);
         }
     }
 
-    @Override
     public void onInputDeviceChanged(int deviceId) {
         synchronized (mInputSensorLock) {
             mSensors.remove(deviceId);
@@ -133,14 +127,11 @@
     }
 
     private static boolean sensorEquals(@NonNull Sensor lhs, @NonNull Sensor rhs) {
-        if (lhs.getType() == rhs.getType() && lhs.getId() == rhs.getId()) {
-            return true;
-        }
-        return false;
+        return lhs.getType() == rhs.getType() && lhs.getId() == rhs.getId();
     }
 
     private void populateSensorsForInputDeviceLocked(int deviceId, InputSensorInfo[] sensorInfos) {
-        List<Sensor> sensors = new ArrayList<Sensor>();
+        List<Sensor> sensors = new ArrayList<>();
         for (int i = 0; i < sensorInfos.length; i++) {
             Sensor sensor = new Sensor(sensorInfos[i]);
             if (DEBUG) {
@@ -197,6 +188,11 @@
         }
         synchronized (mInputSensorLock) {
             Sensor sensor = getInputDeviceSensorLocked(deviceId, sensorType);
+            if (sensor == null) {
+                Slog.wtf(TAG, "onInputSensorChanged: Got sensor update for device " + deviceId
+                        + " but the sensor was not found.");
+                return;
+            }
             for (int i = 0; i < mInputSensorEventListeners.size(); i++) {
                 InputSensorEventListenerDelegate listener =
                         mInputSensorEventListeners.get(i);
@@ -252,20 +248,16 @@
 
     private static final class InputSensorEventListenerDelegate extends Handler {
         private final SensorEventListener mListener;
-        private final int mDelayUs;
-        private final int mMaxBatchReportLatencyUs;
         // List of sensors being listened to
-        private List<Sensor> mSensors = new ArrayList<Sensor>();
+        private final List<Sensor> mSensors = new ArrayList<>();
         // Sensor event array by sensor type, preallocate sensor events for each sensor of listener
         // to avoid allocation and garbage collection for each listener callback.
-        private final SparseArray<SensorEvent> mSensorEvents = new SparseArray<SensorEvent>();
+        private final SparseArray<SensorEvent> mSensorEvents = new SparseArray<>();
 
         InputSensorEventListenerDelegate(SensorEventListener listener, Sensor sensor,
-                int delayUs, int maxBatchReportLatencyUs, Handler handler) {
-            super(handler != null ? handler.getLooper() : Looper.myLooper());
+                Looper looper) {
+            super(looper);
             mListener = listener;
-            mDelayUs = delayUs;
-            mMaxBatchReportLatencyUs = maxBatchReportLatencyUs;
             addSensor(sensor);
         }
 
@@ -280,12 +272,13 @@
         /**
          * Remove sensor from sensor list for listener
          */
-        public void removeSensor(Sensor sensor) {
+        public void removeSensor(@Nullable Sensor sensor) {
             // If sensor is not specified the listener will be unregistered for all sensors
             // and the sensor list is cleared.
             if (sensor == null) {
                 mSensors.clear();
                 mSensorEvents.clear();
+                return;
             }
             for (Sensor s : mSensors) {
                 if (sensorEquals(s, sensor)) {
@@ -306,7 +299,7 @@
                 }
             }
             mSensors.add(sensor);
-            final int vecLength = sensor.getMaxLengthValuesArray(sensor, Build.VERSION.SDK_INT);
+            final int vecLength = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION.SDK_INT);
             SensorEvent event = new SensorEvent(sensor, SensorManager.SENSOR_STATUS_NO_CONTACT,
                     0 /* timestamp */, new float[vecLength]);
             mSensorEvents.put(sensor.getType(), event);
@@ -345,7 +338,6 @@
          * Send sensor changed message
          */
         public void sendSensorChanged(SensorEvent event) {
-            SomeArgs args = SomeArgs.obtain();
             obtainMessage(MSG_SENSOR_CHANGED, event).sendToTarget();
         }
 
@@ -353,7 +345,6 @@
          * Send sensor accuracy changed message
          */
         public void sendSensorAccuracyChanged(int deviceId, int sensorType, int accuracy) {
-            SomeArgs args = SomeArgs.obtain();
             obtainMessage(MSG_SENSOR_ACCURACY_CHANGED, deviceId, sensorType, accuracy)
                     .sendToTarget();
         }
@@ -442,15 +433,21 @@
             Slog.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
             return false;
         }
+
         if (maxBatchReportLatencyUs < 0 || delayUs < 0) {
             Slog.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");
             return false;
         }
 
-        if (getSensorForInputDevice(sensor.getId(), sensor.getType()) != null) {
-            synchronized (mInputSensorLock) {
+        synchronized (mInputSensorLock) {
+            if (getSensorForInputDevice(sensor.getId(), sensor.getType()) != null) {
                 final int deviceId = sensor.getId();
-                InputDevice inputDevice = InputDevice.getDevice(deviceId);
+                final InputDevice inputDevice = mGlobal.getInputDevice(deviceId);
+                if (inputDevice == null) {
+                    Slog.e(TAG, "input device not found for sensor " + sensor.getId());
+                    return false;
+                }
+
                 if (!inputDevice.hasSensor()) {
                     Slog.e(TAG, "The device doesn't have the sensor:" + sensor);
                     return false;
@@ -461,9 +458,7 @@
                     return false;
                 }
             }
-        }
 
-        synchronized (mInputSensorLock) {
             // Register the InputManagerService sensor listener if not yet.
             if (mInputServiceSensorListener == null) {
                 mInputServiceSensorListener = new InputSensorEventListener();
@@ -476,9 +471,8 @@
             int idx = findSensorEventListenerLocked(listener);
             if (idx < 0) {
                 InputSensorEventListenerDelegate d =
-                        new InputSensorEventListenerDelegate(listener, sensor, delayUs,
-                                maxBatchReportLatencyUs,
-                                handler == null ? mSensorHandler : handler);
+                        new InputSensorEventListenerDelegate(listener, sensor,
+                                getLooperForListenerLocked(handler));
                 mInputSensorEventListeners.add(d);
             } else {
                 // The listener is already registered, see if it wants to listen to more sensors.
@@ -489,6 +483,19 @@
         return true;
     }
 
+    @GuardedBy("mInputSensorLock")
+    @NonNull
+    private Looper getLooperForListenerLocked(@Nullable Handler requestedHandler) {
+        if (requestedHandler != null) {
+            return requestedHandler.getLooper();
+        }
+        if (mSensorThread == null) {
+            mSensorThread = new HandlerThread("SensorThread");
+            mSensorThread.start();
+        }
+        return mSensorThread.getLooper();
+    }
+
     private void unregisterListenerInternal(SensorEventListener listener, Sensor sensor) {
         if (DEBUG) {
             Slog.d(TAG, "unregisterListenerImpl listener=" + listener + " sensor=" + sensor);
@@ -503,7 +510,7 @@
             if (idx >= 0) {
                 InputSensorEventListenerDelegate delegate =
                         mInputSensorEventListeners.get(idx);
-                sensorsRegistered = new ArrayList<Sensor>(delegate.getSensors());
+                sensorsRegistered = new ArrayList<>(delegate.getSensors());
                 // Get the sensor types the listener is listening to
                 delegate.removeSensor(sensor);
                 if (delegate.isEmpty()) {
@@ -515,7 +522,7 @@
                 return;
             }
             // If no delegation remains, unregister the listener to input service
-            if (mInputServiceSensorListener != null && mInputSensorEventListeners.size() == 0) {
+            if (mInputServiceSensorListener != null && mInputSensorEventListeners.isEmpty()) {
                 mGlobal.unregisterSensorListener(mInputServiceSensorListener);
                 mInputServiceSensorListener = null;
             }
@@ -545,7 +552,7 @@
         }
     }
 
-    private boolean flush(SensorEventListener listener) {
+    private boolean flushInternal(SensorEventListener listener) {
         synchronized (mInputSensorLock) {
             int idx = findSensorEventListenerLocked(listener);
             if (idx < 0) {
@@ -601,7 +608,7 @@
 
         @Override
         protected boolean flushImpl(SensorEventListener listener) {
-            return flush(listener);
+            return flushInternal(listener);
         }
 
         @Override
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 7b8419e..abbf954 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -1095,62 +1095,6 @@
     }
 
     /**
-     * Get sensors information as list.
-     *
-     * @hide
-     */
-    public InputSensorInfo[] getSensorList(int deviceId) {
-        return mGlobal.getSensorList(deviceId);
-    }
-
-    /**
-     * Enable input device sensor
-     *
-     * @hide
-     */
-    public boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs,
-            int maxBatchReportLatencyUs) {
-        return mGlobal.enableSensor(deviceId, sensorType, samplingPeriodUs,
-                maxBatchReportLatencyUs);
-    }
-
-    /**
-     * Enable input device sensor
-     *
-     * @hide
-     */
-    public void disableSensor(int deviceId, int sensorType) {
-        mGlobal.disableSensor(deviceId, sensorType);
-    }
-
-    /**
-     * Flush input device sensor
-     *
-     * @hide
-     */
-    public boolean flushSensor(int deviceId, int sensorType) {
-        return mGlobal.flushSensor(deviceId, sensorType);
-    }
-
-    /**
-     * Register input device sensor listener
-     *
-     * @hide
-     */
-    public boolean registerSensorListener(IInputSensorEventListener listener) {
-        return mGlobal.registerSensorListener(listener);
-    }
-
-    /**
-     * Unregister input device sensor listener
-     *
-     * @hide
-     */
-    public void unregisterSensorListener(IInputSensorEventListener listener) {
-        mGlobal.unregisterSensorListener(listener);
-    }
-
-    /**
      * Add a runtime association between the input port and the display port. This overrides any
      * static associations.
      * @param inputPort The port of the input device.
diff --git a/core/java/android/hardware/input/InputManagerGlobal.java b/core/java/android/hardware/input/InputManagerGlobal.java
index 8c598ae..cf1dfe3 100644
--- a/core/java/android/hardware/input/InputManagerGlobal.java
+++ b/core/java/android/hardware/input/InputManagerGlobal.java
@@ -100,6 +100,9 @@
     @GuardedBy("mKeyboardBacklightListenerLock")
     @Nullable private IKeyboardBacklightListener mKeyboardBacklightListener;
 
+    // InputDeviceSensorManager gets notified synchronously from the binder thread when input
+    // devices change, so it must be synchronized with the input device listeners.
+    @GuardedBy("mInputDeviceListeners")
     @Nullable private InputDeviceSensorManager mInputDeviceSensorManager;
 
     private static InputManagerGlobal sInstance;
@@ -250,6 +253,9 @@
                         Log.d(TAG, "Device removed: " + deviceId);
                     }
                     mInputDevices.removeAt(i);
+                    if (mInputDeviceSensorManager != null) {
+                        mInputDeviceSensorManager.onInputDeviceRemoved(deviceId);
+                    }
                     sendMessageToInputDeviceListenersLocked(
                             InputDeviceListenerDelegate.MSG_DEVICE_REMOVED, deviceId);
                 }
@@ -267,6 +273,9 @@
                                 Log.d(TAG, "Device changed: " + deviceId);
                             }
                             mInputDevices.setValueAt(index, null);
+                            if (mInputDeviceSensorManager != null) {
+                                mInputDeviceSensorManager.onInputDeviceChanged(deviceId);
+                            }
                             sendMessageToInputDeviceListenersLocked(
                                     InputDeviceListenerDelegate.MSG_DEVICE_CHANGED, deviceId);
                         }
@@ -276,6 +285,9 @@
                         Log.d(TAG, "Device added: " + deviceId);
                     }
                     mInputDevices.put(deviceId, null);
+                    if (mInputDeviceSensorManager != null) {
+                        mInputDeviceSensorManager.onInputDeviceAdded(deviceId);
+                    }
                     sendMessageToInputDeviceListenersLocked(
                             InputDeviceListenerDelegate.MSG_DEVICE_ADDED, deviceId);
                 }
@@ -930,14 +942,17 @@
      */
     @NonNull
     public SensorManager getInputDeviceSensorManager(int deviceId) {
-        if (mInputDeviceSensorManager == null) {
-            mInputDeviceSensorManager = new InputDeviceSensorManager(this);
+        synchronized (mInputDeviceListeners) {
+            if (mInputDeviceSensorManager == null) {
+                mInputDeviceSensorManager = new InputDeviceSensorManager(this);
+            }
+            return mInputDeviceSensorManager.getSensorManager(deviceId);
         }
-        return mInputDeviceSensorManager.getSensorManager(deviceId);
     }
 
     /**
-     * @see InputManager#getSensorList(int)
+     * Get information about all of the sensors supported by an input device
+     * @see InputDeviceSensorManager
      */
     InputSensorInfo[] getSensorList(int deviceId) {
         try {
@@ -948,7 +963,7 @@
     }
 
     /**
-     * @see InputManager#enableSensor(int, int, int, int)
+     * @see InputDeviceSensorManager
      */
     boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs,
             int maxBatchReportLatencyUs) {
@@ -961,7 +976,7 @@
     }
 
     /**
-     * @see InputManager#disableSensor(int, int)
+     * @see InputDeviceSensorManager
      */
     void disableSensor(int deviceId, int sensorType) {
         try {
@@ -972,7 +987,7 @@
     }
 
     /**
-     * @see InputManager#flushSensor(int, int)
+     * @see InputDeviceSensorManager
      */
     boolean flushSensor(int deviceId, int sensorType) {
         try {
@@ -983,7 +998,7 @@
     }
 
     /**
-     * @see InputManager#registerSensorListener(IInputSensorEventListener)
+     * @see InputDeviceSensorManager
      */
     boolean registerSensorListener(IInputSensorEventListener listener) {
         try {
@@ -994,7 +1009,7 @@
     }
 
     /**
-     * @see InputManager#unregisterSensorListener(IInputSensorEventListener)
+     * @see InputDeviceSensorManager
      */
     void unregisterSensorListener(IInputSensorEventListener listener) {
         try {
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index ca84b35..6a83cee 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -682,6 +682,7 @@
 
     static class BatteryConsumerDataLayout {
         private static final Key[] KEY_ARRAY = new Key[0];
+        public static final int POWER_MODEL_NOT_INCLUDED = -1;
         public final String[] customPowerComponentNames;
         public final int customPowerComponentCount;
         public final boolean powerModelsIncluded;
@@ -713,7 +714,9 @@
                 // Declare the Key for the power component, ignoring other dimensions.
                 perComponentKeys.add(
                         new Key(componentId, PROCESS_STATE_ANY,
-                                powerModelsIncluded ? columnIndex++ : -1,  // power model
+                                powerModelsIncluded
+                                        ? columnIndex++
+                                        : POWER_MODEL_NOT_INCLUDED,  // power model
                                 columnIndex++,      // power
                                 columnIndex++       // usage duration
                         ));
@@ -736,7 +739,9 @@
 
                             perComponentKeys.add(
                                     new Key(componentId, processState,
-                                            powerModelsIncluded ? columnIndex++ : -1, // power model
+                                            powerModelsIncluded
+                                                    ? columnIndex++
+                                                    : POWER_MODEL_NOT_INCLUDED, // power model
                                             columnIndex++,      // power
                                             columnIndex++       // usage duration
                                     ));
@@ -843,11 +848,27 @@
 
         @SuppressWarnings("unchecked")
         @NonNull
+        public T addConsumedPower(@PowerComponent int componentId, double componentPower,
+                @PowerModel int powerModel) {
+            mPowerComponentsBuilder.addConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED),
+                    componentPower, powerModel);
+            return (T) this;
+        }
+
+        @SuppressWarnings("unchecked")
+        @NonNull
         public T setConsumedPower(Key key, double componentPower, @PowerModel int powerModel) {
             mPowerComponentsBuilder.setConsumedPower(key, componentPower, powerModel);
             return (T) this;
         }
 
+        @SuppressWarnings("unchecked")
+        @NonNull
+        public T addConsumedPower(Key key, double componentPower, @PowerModel int powerModel) {
+            mPowerComponentsBuilder.addConsumedPower(key, componentPower, powerModel);
+            return (T) this;
+        }
+
         /**
          * Sets the amount of drain attributed to the specified custom drain type.
          *
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e85b7bf..16ffaef 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -4029,6 +4029,17 @@
     }
 
     /**
+     * A helper object passed to various dump... methods to integrate with such objects
+     * as BatteryUsageStatsProvider.
+     */
+    public interface BatteryStatsDumpHelper {
+        /**
+         * Generates BatteryUsageStats based on the specified BatteryStats.
+         */
+        BatteryUsageStats getBatteryUsageStats(BatteryStats batteryStats, boolean detailed);
+    }
+
+    /**
      * Dumps the ControllerActivityCounter if it has any data worth dumping.
      * The order of the arguments in the final check in line is:
      *
@@ -4390,7 +4401,7 @@
      * NOTE: all times are expressed in microseconds, unless specified otherwise.
      */
     public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
-            boolean wifiOnly) {
+            boolean wifiOnly, BatteryStatsDumpHelper dumpHelper) {
 
         if (which != BatteryStats.STATS_SINCE_CHARGED) {
             dumpLine(pw, 0, STAT_NAMES[which], "err",
@@ -4652,7 +4663,7 @@
             }
         }
 
-        final BatteryUsageStats stats = getBatteryUsageStats(context, true /* detailed */);
+        final BatteryUsageStats stats = dumpHelper.getBatteryUsageStats(this, true /* detailed */);
         dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
                 formatCharge(stats.getBatteryCapacity()),
                 formatCharge(stats.getConsumedPower()),
@@ -5127,7 +5138,7 @@
 
     @SuppressWarnings("unused")
     public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
-            int reqUid, boolean wifiOnly) {
+            int reqUid, boolean wifiOnly, BatteryStatsDumpHelper dumpHelper) {
 
         if (which != BatteryStats.STATS_SINCE_CHARGED) {
             pw.println("ERROR: BatteryStats.dump called for which type " + which
@@ -5854,7 +5865,7 @@
         pw.println();
 
 
-        BatteryUsageStats stats = getBatteryUsageStats(context, true /* detailed */);
+        BatteryUsageStats stats = dumpHelper.getBatteryUsageStats(this, true /* detailed */);
         stats.dump(pw, prefix);
 
         List<UidMobileRadioStats> uidMobileRadioStats =
@@ -7642,10 +7653,11 @@
     /**
      * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
      *
-     * @param pw a Printer to receive the dump output.
+     * @param pw         a Printer to receive the dump output.
      */
     @SuppressWarnings("unused")
-    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
+    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart,
+            BatteryStatsDumpHelper dumpHelper) {
         synchronized (this) {
             prepareForDumpLocked();
         }
@@ -7663,12 +7675,12 @@
         }
 
         synchronized (this) {
-            dumpLocked(context, pw, flags, reqUid, filtering);
+            dumpLocked(context, pw, flags, reqUid, filtering, dumpHelper);
         }
     }
 
     private void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid,
-            boolean filtering) {
+            boolean filtering, BatteryStatsDumpHelper dumpHelper) {
         if (!filtering) {
             SparseArray<? extends Uid> uidStats = getUidStats();
             final int NU = uidStats.size();
@@ -7803,15 +7815,15 @@
             pw.println("  System starts: " + getStartCount()
                     + ", currently on battery: " + getIsOnBattery());
             dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid,
-                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
+                    (flags & DUMP_DEVICE_WIFI_ONLY) != 0, dumpHelper);
             pw.println();
         }
     }
 
     // This is called from BatteryStatsService.
     @SuppressWarnings("unused")
-    public void dumpCheckin(Context context, PrintWriter pw,
-            List<ApplicationInfo> apps, int flags, long histStart) {
+    public void dumpCheckin(Context context, PrintWriter pw, List<ApplicationInfo> apps, int flags,
+            long histStart, BatteryStatsDumpHelper dumpHelper) {
         synchronized (this) {
             prepareForDumpLocked();
 
@@ -7829,12 +7841,12 @@
         }
 
         synchronized (this) {
-            dumpCheckinLocked(context, pw, apps, flags);
+            dumpCheckinLocked(context, pw, apps, flags, dumpHelper);
         }
     }
 
     private void dumpCheckinLocked(Context context, PrintWriter pw, List<ApplicationInfo> apps,
-            int flags) {
+            int flags, BatteryStatsDumpHelper dumpHelper) {
         if (apps != null) {
             SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
             for (int i=0; i<apps.size(); i++) {
@@ -7881,7 +7893,7 @@
                         (Object[])lineArgs);
             }
             dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
-                    (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
+                    (flags & DUMP_DEVICE_WIFI_ONLY) != 0, dumpHelper);
         }
     }
 
@@ -7891,7 +7903,7 @@
      * @hide
      */
     public void dumpProtoLocked(Context context, FileDescriptor fd, List<ApplicationInfo> apps,
-            int flags, long histStart) {
+            int flags, long histStart, BatteryStatsDumpHelper dumpHelper) {
         final ProtoOutputStream proto = new ProtoOutputStream(fd);
         prepareForDumpLocked();
 
@@ -7909,7 +7921,8 @@
         proto.write(BatteryStatsProto.END_PLATFORM_VERSION, getEndPlatformVersion());
 
         if ((flags & DUMP_DAILY_ONLY) == 0) {
-            final BatteryUsageStats stats = getBatteryUsageStats(context, false /* detailed */);
+            final BatteryUsageStats stats =
+                    dumpHelper.getBatteryUsageStats(this, false /* detailed */);
             ProportionalAttributionCalculator proportionalAttributionCalculator =
                     new ProportionalAttributionCalculator(context, stats);
             dumpProtoAppsLocked(proto, stats, apps, proportionalAttributionCalculator);
@@ -8856,8 +8869,6 @@
         return !tm.isDataCapable();
     }
 
-    protected abstract BatteryUsageStats getBatteryUsageStats(Context context, boolean detailed);
-
     private boolean shouldHidePowerComponent(int powerComponent) {
         return powerComponent == BatteryConsumer.POWER_COMPONENT_IDLE
                 || powerComponent == BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index cd52b5c0..eabe13b 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -36,6 +36,7 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -122,6 +123,12 @@
 
     private static final int STATSD_PULL_ATOM_MAX_BYTES = 45000;
 
+    private static final int[] UID_USAGE_TIME_PROCESS_STATES = {
+            BatteryConsumer.PROCESS_STATE_FOREGROUND,
+            BatteryConsumer.PROCESS_STATE_BACKGROUND,
+            BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE
+    };
+
     private final int mDischargePercentage;
     private final double mBatteryCapacityMah;
     private final long mStatsStartTimestampMs;
@@ -515,6 +522,22 @@
             proto.write(
                     BatteryUsageStatsAtomsProto.UidBatteryConsumer.TIME_IN_BACKGROUND_MILLIS,
                     bgMs);
+            for (int processState : UID_USAGE_TIME_PROCESS_STATES) {
+                final long timeInStateMillis = consumer.getTimeInProcessStateMs(processState);
+                if (timeInStateMillis <= 0) {
+                    continue;
+                }
+                final long timeInStateToken = proto.start(
+                        BatteryUsageStatsAtomsProto.UidBatteryConsumer.TIME_IN_STATE);
+                proto.write(
+                        BatteryUsageStatsAtomsProto.UidBatteryConsumer.TimeInState.PROCESS_STATE,
+                        processState);
+                proto.write(
+                        BatteryUsageStatsAtomsProto.UidBatteryConsumer.TimeInState
+                                .TIME_IN_STATE_MILLIS,
+                        timeInStateMillis);
+                proto.end(timeInStateToken);
+            }
             proto.end(token);
 
             if (proto.getRawSize() >= maxRawSize) {
@@ -586,7 +609,8 @@
                             + "(" + BatteryConsumer.processStateToString(key.processState) + ")";
                 }
                 printPowerComponent(pw, prefix, label, devicePowerMah, appsPowerMah,
-                        deviceConsumer.getPowerModel(key),
+                        mIncludesPowerModels ? deviceConsumer.getPowerModel(key)
+                                : BatteryConsumer.POWER_MODEL_UNDEFINED,
                         deviceConsumer.getUsageDurationMillis(key));
             }
         }
@@ -774,6 +798,15 @@
         super.finalize();
     }
 
+    @Override
+    public String toString() {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        dump(pw, "");
+        pw.flush();
+        return sw.toString();
+    }
+
     /**
      * Builder for BatteryUsageStats.
      */
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 5b24dca..3a32b2b 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -52,9 +52,11 @@
 import android.provider.MediaStore;
 import android.system.ErrnoException;
 import android.system.Os;
+import android.system.OsConstants;
 import android.system.StructStat;
 import android.text.TextUtils;
 import android.util.DataUnit;
+import android.util.EmptyArray;
 import android.util.Log;
 import android.util.Slog;
 import android.webkit.MimeTypeMap;
@@ -64,7 +66,6 @@
 import com.android.internal.util.SizedInputStream;
 
 import libcore.io.IoUtils;
-import libcore.util.EmptyArray;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
@@ -94,6 +95,7 @@
 /**
  * Utility methods useful for working with files.
  */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
 public final class FileUtils {
     private static final String TAG = "FileUtils";
 
@@ -116,9 +118,6 @@
     private FileUtils() {
     }
 
-    private static final String CAMERA_DIR_LOWER_CASE = "/storage/emulated/" + UserHandle.myUserId()
-            + "/dcim/camera";
-
     /** Regular expression for safe filenames: no spaces or metacharacters.
       *
       * Use a preload holder so that FileUtils can be compile-time initialized.
@@ -133,6 +132,21 @@
 
     private static final long COPY_CHECKPOINT_BYTES = 524288;
 
+    static {
+        sEnableCopyOptimizations = shouldEnableCopyOptimizations();
+    }
+
+    @android.ravenwood.annotation.RavenwoodReplace
+    private static boolean shouldEnableCopyOptimizations() {
+        // Advanced copy operations enabled by default
+        return true;
+    }
+
+    private static boolean shouldEnableCopyOptimizations$ravenwood() {
+        // Disabled under Ravenwood due to missing kernel support
+        return false;
+    }
+
     /**
      * Listener that is called periodically as progress is made.
      */
@@ -150,6 +164,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
     public static int setPermissions(File path, int mode, int uid, int gid) {
         return setPermissions(path.getAbsolutePath(), mode, uid, gid);
     }
@@ -164,6 +179,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
     public static int setPermissions(String path, int mode, int uid, int gid) {
         try {
             Os.chmod(path, mode);
@@ -194,6 +210,7 @@
      * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
     public static int setPermissions(FileDescriptor fd, int mode, int uid, int gid) {
         try {
             Os.fchmod(fd, mode);
@@ -221,6 +238,7 @@
      * @param to File where attributes should be copied to.
      * @hide
      */
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
     public static void copyPermissions(@NonNull File from, @NonNull File to) throws IOException {
         try {
             final StructStat stat = Os.stat(from.getAbsolutePath());
@@ -236,6 +254,7 @@
      * @hide
      */
     @Deprecated
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
     public static int getUid(String path) {
         try {
             return Os.stat(path).st_uid;
@@ -314,11 +333,7 @@
         }
         try (FileOutputStream out = new FileOutputStream(destFile)) {
             copy(in, out);
-            try {
-                Os.fsync(out.getFD());
-            } catch (ErrnoException e) {
-                throw e.rethrowAsIOException();
-            }
+            sync(out);
         }
     }
 
@@ -475,6 +490,7 @@
      * @hide
      */
     @VisibleForTesting
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
     public static long copyInternalSplice(FileDescriptor in, FileDescriptor out, long count,
             CancellationSignal signal, Executor executor, ProgressListener listener)
             throws ErrnoException {
@@ -516,6 +532,7 @@
      * @hide
      */
     @VisibleForTesting
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
     public static long copyInternalSendfile(FileDescriptor in, FileDescriptor out, long count,
             CancellationSignal signal, Executor executor, ProgressListener listener)
             throws ErrnoException {
@@ -699,6 +716,7 @@
      *
      * @hide
      */
+    @android.ravenwood.annotation.RavenwoodReplace
     public static void bytesToFile(String filename, byte[] content) throws IOException {
         if (filename.startsWith("/proc/")) {
             final int oldMask = StrictMode.allowThreadDiskWritesMask();
@@ -714,6 +732,14 @@
         }
     }
 
+    /** @hide */
+    public static void bytesToFile$ravenwood(String filename, byte[] content) throws IOException {
+        // No StrictMode support, so we can just directly write
+        try (FileOutputStream fos = new FileOutputStream(filename)) {
+            fos.write(content);
+        }
+    }
+
     /**
      * Writes string to file. Basically same as "echo -n $string > $filename"
      *
@@ -1176,6 +1202,7 @@
      *
      * @hide
      */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = MimeTypeMap.class)
     public static String[] splitFileName(String mimeType, String displayName) {
         String name;
         String ext;
@@ -1423,11 +1450,13 @@
      *   indicate a failure to flush bytes to the underlying resource.
      */
     @Deprecated
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires ART support")
     public static void closeQuietly(@Nullable FileDescriptor fd) {
         IoUtils.closeQuietly(fd);
     }
 
     /** {@hide} */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
     public static int translateModeStringToPosix(String mode) {
         // Quick check for invalid chars
         for (int i = 0; i < mode.length(); i++) {
@@ -1462,6 +1491,7 @@
     }
 
     /** {@hide} */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
     public static String translateModePosixToString(int mode) {
         String res = "";
         if ((mode & O_ACCMODE) == O_RDWR) {
@@ -1483,6 +1513,7 @@
     }
 
     /** {@hide} */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
     public static int translateModePosixToPfd(int mode) {
         int res = 0;
         if ((mode & O_ACCMODE) == O_RDWR) {
@@ -1507,6 +1538,7 @@
     }
 
     /** {@hide} */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
     public static int translateModePfdToPosix(int mode) {
         int res = 0;
         if ((mode & MODE_READ_WRITE) == MODE_READ_WRITE) {
@@ -1531,6 +1563,7 @@
     }
 
     /** {@hide} */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = OsConstants.class)
     public static int translateModeAccessToPosix(int mode) {
         if (mode == F_OK) {
             // There's not an exact mapping, so we attempt a read-only open to
@@ -1549,6 +1582,7 @@
 
     /** {@hide} */
     @VisibleForTesting
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
     public static ParcelFileDescriptor convertToModernFd(FileDescriptor fd) {
         Context context = AppGlobals.getInitialApplication();
         if (UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)) {
@@ -1565,6 +1599,7 @@
         }
     }
 
+    @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
     private static int getMediaProviderAppId(Context context) {
         if (sMediaProviderAppId != -1) {
             return sMediaProviderAppId;
@@ -1605,10 +1640,12 @@
             return this;
         }
 
+        @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
         public static MemoryPipe createSource(byte[] data) throws IOException {
             return new MemoryPipe(data, false).startInternal();
         }
 
+        @android.ravenwood.annotation.RavenwoodThrow(reason = "Requires kernel support")
         public static MemoryPipe createSink(byte[] data) throws IOException {
             return new MemoryPipe(data, true).startInternal();
         }
diff --git a/core/java/android/os/ISecurityStateManager.aidl b/core/java/android/os/ISecurityStateManager.aidl
new file mode 100644
index 0000000..8ae624d
--- /dev/null
+++ b/core/java/android/os/ISecurityStateManager.aidl
@@ -0,0 +1,26 @@
+/* //device/java/android/android/os/ISecurityStateManager.aidl
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.os;
+
+import android.os.Bundle;
+import android.os.PersistableBundle;
+
+/** @hide */
+interface ISecurityStateManager {
+    Bundle getGlobalSecurityState();
+}
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index da647e2..161951e 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
@@ -437,6 +438,7 @@
      * @see #getData()
      * @see #setData(Bundle)
      */
+    @Nullable
     public Bundle peekData() {
         return data;
     }
diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java
index 9e5f539..9c11ad4 100644
--- a/core/java/android/os/PowerComponents.java
+++ b/core/java/android/os/PowerComponents.java
@@ -15,6 +15,7 @@
  */
 package android.os;
 
+import static android.os.BatteryConsumer.BatteryConsumerDataLayout.POWER_MODEL_NOT_INCLUDED;
 import static android.os.BatteryConsumer.POWER_COMPONENT_ANY;
 import static android.os.BatteryConsumer.PROCESS_STATE_ANY;
 import static android.os.BatteryConsumer.PROCESS_STATE_UNSPECIFIED;
@@ -118,7 +119,7 @@
 
     @BatteryConsumer.PowerModel
     int getPowerModel(BatteryConsumer.Key key) {
-        if (key.mPowerModelColumnIndex == -1) {
+        if (key.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) {
             throw new IllegalStateException(
                     "Power model IDs were not requested in the BatteryUsageStatsQuery");
         }
@@ -468,7 +469,7 @@
             mMinConsumedPowerThreshold = minConsumedPowerThreshold;
             for (BatteryConsumer.Key[] keys : mData.layout.keys) {
                 for (BatteryConsumer.Key key : keys) {
-                    if (key.mPowerModelColumnIndex != -1) {
+                    if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
                         mData.putInt(key.mPowerModelColumnIndex, POWER_MODEL_UNINITIALIZED);
                     }
                 }
@@ -478,11 +479,19 @@
         @NonNull
         public Builder setConsumedPower(BatteryConsumer.Key key, double componentPower,
                 int powerModel) {
-            if (Math.abs(componentPower) < mMinConsumedPowerThreshold) {
-                componentPower = 0;
-            }
             mData.putDouble(key.mPowerColumnIndex, componentPower);
-            if (key.mPowerModelColumnIndex != -1) {
+            if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
+                mData.putInt(key.mPowerModelColumnIndex, powerModel);
+            }
+            return this;
+        }
+
+        @NonNull
+        public Builder addConsumedPower(BatteryConsumer.Key key, double componentPower,
+                int powerModel) {
+            mData.putDouble(key.mPowerColumnIndex,
+                    mData.getDouble(key.mPowerColumnIndex) + componentPower);
+            if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
                 mData.putInt(key.mPowerModelColumnIndex, powerModel);
             }
             return this;
@@ -496,9 +505,6 @@
          */
         @NonNull
         public Builder setConsumedPowerForCustomComponent(int componentId, double componentPower) {
-            if (Math.abs(componentPower) < mMinConsumedPowerThreshold) {
-                componentPower = 0;
-            }
             final int index = componentId - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
             if (index < 0 || index >= mData.layout.customPowerComponentCount) {
                 throw new IllegalArgumentException(
@@ -575,12 +581,12 @@
                             mData.getLong(key.mDurationColumnIndex)
                                     + otherData.getLong(otherKey.mDurationColumnIndex));
 
-                    if (key.mPowerModelColumnIndex == -1) {
+                    if (key.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) {
                         continue;
                     }
 
                     boolean undefined = false;
-                    if (otherKey.mPowerModelColumnIndex == -1) {
+                    if (otherKey.mPowerModelColumnIndex == POWER_MODEL_NOT_INCLUDED) {
                         undefined = true;
                     } else {
                         final int powerModel = mData.getInt(key.mPowerModelColumnIndex);
@@ -641,19 +647,26 @@
          */
         @NonNull
         public PowerComponents build() {
-            mData.putDouble(mData.layout.totalConsumedPowerColumnIndex, getTotalPower());
-
             for (BatteryConsumer.Key[] keys : mData.layout.keys) {
                 for (BatteryConsumer.Key key : keys) {
-                    if (key.mPowerModelColumnIndex != -1) {
+                    if (key.mPowerModelColumnIndex != POWER_MODEL_NOT_INCLUDED) {
                         if (mData.getInt(key.mPowerModelColumnIndex) == POWER_MODEL_UNINITIALIZED) {
                             mData.putInt(key.mPowerModelColumnIndex,
                                     BatteryConsumer.POWER_MODEL_UNDEFINED);
                         }
                     }
+
+                    if (mMinConsumedPowerThreshold != 0) {
+                        if (mData.getDouble(key.mPowerColumnIndex) < mMinConsumedPowerThreshold) {
+                            mData.putDouble(key.mPowerColumnIndex, 0);
+                        }
+                    }
                 }
             }
 
+            if (mData.getDouble(mData.layout.totalConsumedPowerColumnIndex) == 0) {
+                mData.putDouble(mData.layout.totalConsumedPowerColumnIndex, getTotalPower());
+            }
             return new PowerComponents(this);
         }
     }
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 11bddfb..f4795f8 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import android.annotation.FlaggedApi;
 import android.Manifest.permission;
 import android.annotation.CallbackExecutor;
 import android.annotation.CurrentTimeMillisLong;
@@ -3103,7 +3102,8 @@
 
     /**
      * Intent that is broadcast when Low Power Standby is enabled or disabled.
-     * This broadcast is only sent to registered receivers.
+     * This broadcast is only sent to registered receivers and receivers holding
+     * {@code android.permission.MANAGE_LOW_POWER_STANDBY}.
      *
      * @see #isLowPowerStandbyEnabled()
      */
@@ -3113,7 +3113,8 @@
 
     /**
      * Intent that is broadcast when Low Power Standby policy is changed.
-     * This broadcast is only sent to registered receivers.
+     * This broadcast is only sent to registered receivers and receivers holding
+     * {@code android.permission.MANAGE_LOW_POWER_STANDBY}.
      *
      * @see #isExemptFromLowPowerStandby()
      * @see #isAllowedInLowPowerStandby(int)
@@ -3125,7 +3126,6 @@
 
     /**
      * Intent that is broadcast when Low Power Standby exempt ports change.
-     * This broadcast is only sent to registered receivers.
      *
      * @see #getActiveLowPowerStandbyPorts
      * @hide
diff --git a/core/java/android/os/SecurityStateManager.java b/core/java/android/os/SecurityStateManager.java
new file mode 100644
index 0000000..4fa61e0
--- /dev/null
+++ b/core/java/android/os/SecurityStateManager.java
@@ -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 android.os;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * SecurityStateManager provides the functionality to query the security status of the system and
+ * platform components. For example, this includes the system and vendor security patch level.
+ */
+@FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE)
+@SystemService(Context.SECURITY_STATE_SERVICE)
+public class SecurityStateManager {
+
+    /**
+     * The system SPL key returned as part of the {@code Bundle} from
+     * {@code getGlobalSecurityState}.
+     */
+    public static final String KEY_SYSTEM_SPL = "system_spl";
+
+    /**
+     * The vendor SPL key returned as part of the {@code Bundle} from
+     * {@code getGlobalSecurityState}.
+     */
+    public static final String KEY_VENDOR_SPL = "vendor_spl";
+
+    /**
+     * The kernel version key returned as part of the {@code Bundle} from
+     * {@code getGlobalSecurityState}.
+     */
+    public static final String KEY_KERNEL_VERSION = "kernel_version";
+
+    private final ISecurityStateManager mService;
+
+    /**
+     * @hide
+     */
+    public SecurityStateManager(ISecurityStateManager service) {
+        mService = requireNonNull(service, "missing ISecurityStateManager");
+    }
+
+    /**
+     * Returns the current global security state. Each key-value pair is a mapping of a component
+     * of the global security state to its current version/SPL (security patch level). For example,
+     * the {@code KEY_SYSTEM_SPL} key will map to the SPL of the system as defined in
+     * {@link android.os.Build.VERSION}. The bundle will also include mappings from WebView packages
+     * and packages listed under config {@code config_securityStatePackages} to their respective
+     * versions as defined in {@link android.content.pm.PackageInfo#versionName}.
+     *
+     * @return A {@code Bundle} that contains the global security state information as
+     * string-to-string key-value pairs.
+     */
+    @FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE)
+    @NonNull
+    public Bundle getGlobalSecurityState() {
+        try {
+            return mService.getGlobalSecurityState();
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index ec6d20f..c280d13 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_COLORED;
 import static android.app.admin.DevicePolicyResources.Strings.Core.WORK_PROFILE_BADGED_LABEL;
 import static android.app.admin.DevicePolicyResources.UNDEFINED;
 
@@ -5652,6 +5653,38 @@
     }
 
     /**
+     * Retrieves a user badge associated with the current context user. This is only
+     * applicable to profile users since non-profile users do not have badges.
+     *
+     * @return A {@link Drawable} user badge corresponding to the context user
+     * @throws android.content.res.Resources.NotFoundException if the user is not a profile or
+     * does not have a badge defined.
+     * @hide
+     */
+    @SystemApi
+    @UserHandleAware(
+            requiresAnyOfPermissionsIfNotCallerProfileGroup = {
+                    Manifest.permission.MANAGE_USERS,
+                    Manifest.permission.INTERACT_ACROSS_USERS})
+    @SuppressLint("UnflaggedApi") // b/306636213
+    public @NonNull Drawable getUserBadge() {
+        if (!isProfile(mUserId)) {
+            throw new Resources.NotFoundException("No badge found for this user.");
+        }
+        if (isManagedProfile(mUserId)) {
+            DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+            return dpm.getResources().getDrawable(
+                    android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON_BADGE,
+                    SOLID_COLORED, () -> getDefaultUserBadge(mUserId));
+        }
+        return getDefaultUserBadge(mUserId);
+    }
+
+    private Drawable getDefaultUserBadge(@UserIdInt int userId){
+        return mContext.getResources().getDrawable(getUserBadgeResId(userId), mContext.getTheme());
+    }
+
+    /**
      * If the target user is a profile of the calling user or the caller
      * is itself a profile, then this returns a copy of the label with
      * badging for accessibility services like talkback. E.g. passing in "Email"
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index a78f221..c085f33 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -57,6 +57,13 @@
 }
 
 flag {
+    name: "security_state_service"
+    namespace: "dynamic_spl"
+    description: "Guards the Security State API."
+    bug: "302189431"
+}
+
+flag {
     name: "battery_saver_supported_check_api"
     namespace: "backstage_power"
     description: "Guards a new API in PowerManager to check if battery saver is supported or not."
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 6853892..78a12f7 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1738,23 +1738,6 @@
         return RoSystemProperties.CRYPTO_FILE_ENCRYPTED;
     }
 
-    /** {@hide}
-     * @deprecated Use {@link #isFileEncrypted} instead, since emulated FBE is no longer supported.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Deprecated
-    public static boolean isFileEncryptedNativeOnly() {
-        return isFileEncrypted();
-    }
-
-    /** {@hide}
-     * @deprecated Use {@link #isFileEncrypted} instead, since emulated FBE is no longer supported.
-     */
-    @Deprecated
-    public static boolean isFileEncryptedNativeOrEmulated() {
-        return isFileEncrypted();
-    }
-
     /** {@hide} */
     public static boolean hasAdoptable() {
         switch (SystemProperties.get(PROP_ADOPTABLE)) {
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index dc86e3f5..5cbc18e 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -56,4 +56,11 @@
   namespace: "permissions"
   description: "enables logging of the OP_ENABLE_MOBILE_DATA_BY_USER"
   bug: "222650148"
-}
\ No newline at end of file
+}
+
+flag {
+  name: "factory_reset_prep_permission_apis"
+  namespace: "wallet_integration"
+  description: "enable Permission PREPARE_FACTORY_RESET."
+  bug: "302016478"
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ff6ec29..1a33b768 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2542,6 +2542,7 @@
      * ComponentName)} and only use this action to start an activity if they return {@code false}.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    @FlaggedApi(android.credentials.flags.Flags.FLAG_NEW_SETTINGS_INTENTS)
     public static final String ACTION_CREDENTIAL_PROVIDER =
             "android.settings.CREDENTIAL_PROVIDER";
 
@@ -8845,6 +8846,24 @@
                 "reduce_bright_colors_persist_across_reboots";
 
         /**
+         * Setting that specifies whether Even Dimmer - a feature that allows the brightness
+         * slider to go below what the display can conventionally do, should be enabled.
+         *
+         * @hide
+         */
+        public static final String EVEN_DIMMER_ACTIVATED =
+                "even_dimmer_activated";
+
+        /**
+         * Setting that specifies which nits level Even Dimmer should allow the screen brightness
+         * to go down to.
+         *
+         * @hide
+         */
+        public static final String EVEN_DIMMER_MIN_NITS =
+                "even_dimmer_min_nits";
+
+        /**
          * List of the enabled print services.
          *
          * N and beyond uses {@link #DISABLED_PRINT_SERVICES}. But this might be used in an upgrade
@@ -14975,6 +14994,38 @@
         public static final String APP_OPS_CONSTANTS = "app_ops_constants";
 
         /**
+         * Device Idle (Doze) specific settings.
+         * This is encoded as a key=value list, separated by commas. Ex:
+         *
+         * "inactive_to=60000,sensing_to=400000"
+         *
+         * The following keys are supported:
+         *
+         * <pre>
+         * inactive_to                      (long)
+         * sensing_to                       (long)
+         * motion_inactive_to               (long)
+         * idle_after_inactive_to           (long)
+         * idle_pending_to                  (long)
+         * max_idle_pending_to              (long)
+         * idle_pending_factor              (float)
+         * quick_doze_delay_to              (long)
+         * idle_to                          (long)
+         * max_idle_to                      (long)
+         * idle_factor                      (float)
+         * min_time_to_alarm                (long)
+         * max_temp_app_whitelist_duration  (long)
+         * notification_whitelist_duration  (long)
+         * </pre>
+         *
+         * <p>
+         * Type: string
+         * @hide
+         * @see com.android.server.DeviceIdleController.Constants
+         */
+        public static final String DEVICE_IDLE_CONSTANTS = "device_idle_constants";
+
+        /**
          * Battery Saver specific settings
          * This is encoded as a key=value list, separated by commas. Ex:
          *
diff --git a/core/java/android/security/OWNERS b/core/java/android/security/OWNERS
index 33a67ae..533d459 100644
--- a/core/java/android/security/OWNERS
+++ b/core/java/android/security/OWNERS
@@ -8,4 +8,4 @@
 per-file Confirmation*.java = file:/keystore/OWNERS
 per-file FileIntegrityManager.java = file:platform/system/security:/fsverity/OWNERS
 per-file IFileIntegrityService.aidl = file:platform/system/security:/fsverity/OWNERS
-per-file *.aconfig = victorhsieh@google.com
+per-file *.aconfig = victorhsieh@google.com,eranm@google.com
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 0133bd8..28ef70b 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -8,7 +8,14 @@
 }
 
 flag {
-    name: "fix_unlocked_device_required_keys"
+    name: "mgf1_digest_setter"
+    namespace: "hardware_backed_security"
+    description: "Feature flag for mgf1 digest setter in key generation and import parameters."
+    bug: "308378912"
+}
+
+flag {
+    name: "fix_unlocked_device_required_keys_v2"
     namespace: "hardware_backed_security"
     description: "Fix bugs in behavior of UnlockedDeviceRequired keystore keys"
     bug: "296464083"
diff --git a/core/java/android/service/controls/ControlsProviderService.java b/core/java/android/service/controls/ControlsProviderService.java
index 0272bb9..5cbde9f 100644
--- a/core/java/android/service/controls/ControlsProviderService.java
+++ b/core/java/android/service/controls/ControlsProviderService.java
@@ -16,6 +16,8 @@
 package android.service.controls;
 
 import android.Manifest;
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -33,12 +35,15 @@
 import android.os.RemoteException;
 import android.service.controls.actions.ControlAction;
 import android.service.controls.actions.ControlActionWrapper;
+import android.service.controls.flags.Flags;
 import android.service.controls.templates.ControlTemplate;
 import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 import java.util.concurrent.Flow.Publisher;
 import java.util.concurrent.Flow.Subscriber;
@@ -82,6 +87,40 @@
     public static final String EXTRA_LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS =
             "android.service.controls.extra.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS";
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({CONTROLS_SURFACE_ACTIVITY_PANEL, CONTROLS_SURFACE_DREAM})
+    public @interface ControlsSurface {
+    }
+
+    /**
+     * Controls are being shown on the device controls activity panel.
+     */
+    @FlaggedApi(Flags.FLAG_HOME_PANEL_DREAM)
+    public static final int CONTROLS_SURFACE_ACTIVITY_PANEL = 0;
+
+    /**
+     * Controls are being shown as a dream, while the device is idle.
+     */
+    @FlaggedApi(Flags.FLAG_HOME_PANEL_DREAM)
+    public static final int CONTROLS_SURFACE_DREAM = 1;
+
+    /**
+     * Integer extra whose value specifies the surface which controls are being displayed on.
+     * <p>
+     * The possible values are:
+     * <ul>
+     * <li>{@link #CONTROLS_SURFACE_ACTIVITY_PANEL}
+     * <li>{@link #CONTROLS_SURFACE_DREAM}
+     * </ul>
+     *
+     * This is passed with the intent when the panel specified by {@link #META_DATA_PANEL_ACTIVITY}
+     * is launched.
+     */
+    @FlaggedApi(Flags.FLAG_HOME_PANEL_DREAM)
+    public static final String EXTRA_CONTROLS_SURFACE =
+            "android.service.controls.extra.CONTROLS_SURFACE";
+
     /**
      * @hide
      */
diff --git a/core/java/android/service/controls/flags/flags.aconfig b/core/java/android/service/controls/flags/flags.aconfig
new file mode 100644
index 0000000..3a28844
--- /dev/null
+++ b/core/java/android/service/controls/flags/flags.aconfig
@@ -0,0 +1,8 @@
+package: "android.service.controls.flags"
+
+flag {
+    name: "home_panel_dream"
+    namespace: "systemui"
+    description: "Enables the home controls dream feature."
+    bug: "298025023"
+}
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index 2a4cbaf..7660ed9 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -15,7 +15,6 @@
  */
 package android.service.notification;
 
-import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.Notification;
 import android.os.Bundle;
@@ -26,6 +25,7 @@
 import android.system.OsConstants;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import java.nio.ByteBuffer;
@@ -75,10 +75,6 @@
                 }
                 // We only need read-only access to the shared memory region.
                 buffer = mRankingMapFd.mapReadOnly();
-                if (buffer == null) {
-                    mRankingMap = null;
-                    return;
-                }
                 byte[] payload = new byte[buffer.remaining()];
                 buffer.get(payload);
                 mapParcel.unmarshall(payload, 0, payload.length);
@@ -98,7 +94,7 @@
             } finally {
                 mapParcel.recycle();
                 if (buffer != null && mRankingMapFd != null) {
-                    mRankingMapFd.unmap(buffer);
+                    SharedMemory.unmap(buffer);
                     mRankingMapFd.close();
                 }
             }
@@ -210,6 +206,7 @@
                                     new NotificationListenerService.Ranking[0]
                             )
                     );
+            ByteBuffer buffer = null;
 
             try {
                 // Parcels the ranking map and measures its size.
@@ -217,13 +214,10 @@
                 int mapSize = mapParcel.dataSize();
 
                 // Creates a new SharedMemory object with enough space to hold the ranking map.
-                SharedMemory mRankingMapFd = SharedMemory.create(mSharedMemoryName, mapSize);
-                if (mRankingMapFd == null) {
-                    return;
-                }
+                mRankingMapFd = SharedMemory.create(mSharedMemoryName, mapSize);
 
                 // Gets a read/write buffer mapping the entire shared memory region.
-                final ByteBuffer buffer = mRankingMapFd.mapReadWrite();
+                buffer = mRankingMapFd.mapReadWrite();
                 // Puts the ranking map into the shared memory region buffer.
                 buffer.put(mapParcel.marshall(), 0, mapSize);
                 // Protects the region from being written to, by setting it to be read-only.
@@ -238,6 +232,12 @@
                 throw new RuntimeException(e);
             } finally {
                 mapParcel.recycle();
+                // To prevent memory leaks, we can close the ranking map fd here.
+                // This is safe to do because a reference to this still exists.
+                if (buffer != null && mRankingMapFd != null) {
+                    SharedMemory.unmap(buffer);
+                    mRankingMapFd.close();
+                }
             }
         } else {
             out.writeParcelable(mRankingMap, flags);
@@ -247,7 +247,7 @@
     /**
      * @hide
      */
-    public static final @android.annotation.NonNull Parcelable.Creator<NotificationRankingUpdate> CREATOR
+    public static final @NonNull Parcelable.Creator<NotificationRankingUpdate> CREATOR
             = new Parcelable.Creator<NotificationRankingUpdate>() {
         public NotificationRankingUpdate createFromParcel(Parcel parcel) {
             return new NotificationRankingUpdate(parcel);
diff --git a/core/java/android/service/notification/NotificationStats.java b/core/java/android/service/notification/NotificationStats.java
index e5ad85c..07367df 100644
--- a/core/java/android/service/notification/NotificationStats.java
+++ b/core/java/android/service/notification/NotificationStats.java
@@ -15,10 +15,12 @@
  */
 package android.service.notification;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.app.Flags;
 import android.app.RemoteInput;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -36,6 +38,7 @@
     private boolean mSeen;
     private boolean mExpanded;
     private boolean mDirectReplied;
+    private boolean mSmartReplied;
     private boolean mSnoozed;
     private boolean mViewedSettings;
     private boolean mInteracted;
@@ -125,6 +128,9 @@
         mSeen = in.readByte() != 0;
         mExpanded = in.readByte() != 0;
         mDirectReplied = in.readByte() != 0;
+        if (Flags.lifetimeExtensionRefactor()) {
+            mSmartReplied = in.readByte() != 0;
+        }
         mSnoozed = in.readByte() != 0;
         mViewedSettings = in.readByte() != 0;
         mInteracted = in.readByte() != 0;
@@ -137,6 +143,9 @@
         dest.writeByte((byte) (mSeen ? 1 : 0));
         dest.writeByte((byte) (mExpanded ? 1 : 0));
         dest.writeByte((byte) (mDirectReplied ? 1 : 0));
+        if (Flags.lifetimeExtensionRefactor()) {
+            dest.writeByte((byte) (mSmartReplied ? 1 : 0));
+        }
         dest.writeByte((byte) (mSnoozed ? 1 : 0));
         dest.writeByte((byte) (mViewedSettings ? 1 : 0));
         dest.writeByte((byte) (mInteracted ? 1 : 0));
@@ -210,6 +219,23 @@
     }
 
     /**
+     * Returns whether the user has replied to a notification that has a smart reply at least once.
+     */
+    @FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR)
+    public boolean hasSmartReplied() {
+        return mSmartReplied;
+    }
+
+    /**
+     * Records that the user has replied to a notification that has a smart reply at least once.
+     */
+    @FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR)
+    public void setSmartReplied() {
+        mSmartReplied = true;
+        mInteracted = true;
+    }
+
+    /**
      * Returns whether the user has snoozed this notification at least once.
      */
     public boolean hasSnoozed() {
@@ -286,6 +312,9 @@
         if (mSeen != that.mSeen) return false;
         if (mExpanded != that.mExpanded) return false;
         if (mDirectReplied != that.mDirectReplied) return false;
+        if (Flags.lifetimeExtensionRefactor()) {
+            if (mSmartReplied != that.mSmartReplied) return false;
+        }
         if (mSnoozed != that.mSnoozed) return false;
         if (mViewedSettings != that.mViewedSettings) return false;
         if (mInteracted != that.mInteracted) return false;
@@ -297,6 +326,9 @@
         int result = (mSeen ? 1 : 0);
         result = 31 * result + (mExpanded ? 1 : 0);
         result = 31 * result + (mDirectReplied ? 1 : 0);
+        if (Flags.lifetimeExtensionRefactor()) {
+            result = 31 * result + (mSmartReplied ? 1 : 0);
+        }
         result = 31 * result + (mSnoozed ? 1 : 0);
         result = 31 * result + (mViewedSettings ? 1 : 0);
         result = 31 * result + (mInteracted ? 1 : 0);
@@ -311,6 +343,9 @@
         sb.append("mSeen=").append(mSeen);
         sb.append(", mExpanded=").append(mExpanded);
         sb.append(", mDirectReplied=").append(mDirectReplied);
+        if (Flags.lifetimeExtensionRefactor()) {
+            sb.append(", mSmartReplied=").append(mSmartReplied);
+        }
         sb.append(", mSnoozed=").append(mSnoozed);
         sb.append(", mViewedSettings=").append(mViewedSettings);
         sb.append(", mInteracted=").append(mInteracted);
diff --git a/core/java/android/service/voice/HotwordDetectionServiceFailure.java b/core/java/android/service/voice/HotwordDetectionServiceFailure.java
index 420dac1..c8b60c4 100644
--- a/core/java/android/service/voice/HotwordDetectionServiceFailure.java
+++ b/core/java/android/service/voice/HotwordDetectionServiceFailure.java
@@ -89,6 +89,11 @@
     @FlaggedApi(Flags.FLAG_ALLOW_TRAINING_DATA_EGRESS_FROM_HDS)
     public static final int ERROR_CODE_ON_TRAINING_DATA_SECURITY_EXCEPTION = 9;
 
+    /** Indicates shutdown of {@link HotwordDetectionService} due to voice activation op being
+     * disabled. */
+    @FlaggedApi(Flags.FLAG_ALLOW_TRAINING_DATA_EGRESS_FROM_HDS)
+    public static final int ERROR_CODE_SHUTDOWN_HDS_ON_VOICE_ACTIVATION_OP_DISABLED = 10;
+
     /**
      * @hide
      */
@@ -100,7 +105,10 @@
             ERROR_CODE_DETECT_TIMEOUT,
             ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION,
             ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE,
-            ERROR_CODE_REMOTE_EXCEPTION
+            ERROR_CODE_REMOTE_EXCEPTION,
+            ERROR_CODE_ON_TRAINING_DATA_EGRESS_LIMIT_EXCEEDED,
+            ERROR_CODE_ON_TRAINING_DATA_SECURITY_EXCEPTION,
+            ERROR_CODE_SHUTDOWN_HDS_ON_VOICE_ACTIVATION_OP_DISABLED,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface HotwordDetectionServiceErrorCode {}
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 0063d13..886727e 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -490,16 +490,32 @@
     /**
      * Notify changes to activity state changes on certain subscription.
      *
+     * @param subId for which data activity state changed.
+     * @param dataActivityType indicates the latest data activity type e.g. {@link
+     * TelephonyManager#DATA_ACTIVITY_IN}
+     */
+    public void notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType) {
+        try {
+            sRegistry.notifyDataActivityForSubscriber(subId, dataActivityType);
+        } catch (RemoteException ex) {
+            // system process is dead
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notify changes to activity state changes on certain subscription.
+     *
      * @param slotIndex for which data activity changed. Can be derived from subId except
      * when subId is invalid.
      * @param subId for which data activity state changed.
-     * @param dataActivityType indicates the latest data activity type e.g, {@link
+     * @param dataActivityType indicates the latest data activity type e.g. {@link
      * TelephonyManager#DATA_ACTIVITY_IN}
      */
     public void notifyDataActivityChanged(int slotIndex, int subId,
             @DataActivityType int dataActivityType) {
         try {
-            sRegistry.notifyDataActivityForSubscriber(slotIndex, subId, dataActivityType);
+            sRegistry.notifyDataActivityForSubscriberWithSlot(slotIndex, subId, dataActivityType);
         } catch (RemoteException ex) {
             // system process is dead
             throw ex.rethrowFromSystemServer();
diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java
index d084a9e..36800ea 100644
--- a/core/java/android/util/AtomicFile.java
+++ b/core/java/android/util/AtomicFile.java
@@ -48,6 +48,7 @@
  * be accessed or modified concurrently by multiple threads or processes. The caller is responsible
  * for ensuring appropriate mutual exclusion invariants whenever it accesses the file.
  */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
 public class AtomicFile {
     private static final String LOG_TAG = "AtomicFile";
 
@@ -68,6 +69,8 @@
      * @hide Internal constructor that also allows you to have the class
      * automatically log commit events.
      */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy =
+            SystemConfigFileCommitEventLogger.class)
     public AtomicFile(File baseName, String commitTag) {
         this(baseName, new SystemConfigFileCommitEventLogger(commitTag));
     }
diff --git a/core/java/android/util/LruCache.java b/core/java/android/util/LruCache.java
index 3f7fdd8..be1ec41 100644
--- a/core/java/android/util/LruCache.java
+++ b/core/java/android/util/LruCache.java
@@ -18,6 +18,7 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -61,6 +62,7 @@
  * of <a href="http://developer.android.com/sdk/compatibility-library.html">Android's
  * Support Package</a> for earlier releases.
  */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
 public class LruCache<K, V> {
     @UnsupportedAppUsage
     private final LinkedHashMap<K, V> map;
@@ -208,7 +210,7 @@
                     break;
                 }
 
-                Map.Entry<K, V> toEvict = map.eldest();
+                Map.Entry<K, V> toEvict = eldest();
                 if (toEvict == null) {
                     break;
                 }
@@ -224,6 +226,16 @@
         }
     }
 
+    @android.ravenwood.annotation.RavenwoodReplace
+    private Map.Entry<K, V> eldest() {
+        return map.eldest();
+    }
+
+    private Map.Entry<K, V> eldest$ravenwood() {
+        final Iterator<Map.Entry<K, V>> it = map.entrySet().iterator();
+        return it.hasNext() ? it.next() : null;
+    }
+
     /**
      * Removes the entry for {@code key} if it exists.
      *
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 9f886c8..d131dc9 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -69,6 +69,7 @@
     private final String mName;
     private final int mVendorId;
     private final int mProductId;
+    private final int mDeviceBus;
     private final String mDescriptor;
     private final InputDeviceIdentifier mIdentifier;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
@@ -468,8 +469,8 @@
      * Called by native code
      */
     private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
-            int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
-            KeyCharacterMap keyCharacterMap, @Nullable String keyboardLanguageTag,
+            int productId, int deviceBus, String descriptor, boolean isExternal, int sources,
+            int keyboardType, KeyCharacterMap keyCharacterMap, @Nullable String keyboardLanguageTag,
             @Nullable String keyboardLayoutType, boolean hasVibrator, boolean hasMicrophone,
             boolean hasButtonUnderPad, boolean hasSensor, boolean hasBattery, int usiVersionMajor,
             int usiVersionMinor, int associatedDisplayId) {
@@ -479,6 +480,7 @@
         mName = name;
         mVendorId = vendorId;
         mProductId = productId;
+        mDeviceBus = deviceBus;
         mDescriptor = descriptor;
         mIsExternal = isExternal;
         mSources = sources;
@@ -512,6 +514,7 @@
         mName = in.readString();
         mVendorId = in.readInt();
         mProductId = in.readInt();
+        mDeviceBus = in.readInt();
         mDescriptor = in.readString();
         mIsExternal = in.readInt() != 0;
         mSources = in.readInt();
@@ -551,6 +554,7 @@
         private String mName = "";
         private int mVendorId = 0;
         private int mProductId = 0;
+        private int mDeviceBus = 0;
         private String mDescriptor = "";
         private boolean mIsExternal = false;
         private int mSources = 0;
@@ -604,6 +608,12 @@
             return this;
         }
 
+        /** @see InputDevice#getDeviceBus() */
+        public Builder setDeviceBus(int deviceBus) {
+            mDeviceBus = deviceBus;
+            return this;
+        }
+
         /** @see InputDevice#getDescriptor() */
         public Builder setDescriptor(String descriptor) {
             mDescriptor = descriptor;
@@ -705,6 +715,7 @@
                     mName,
                     mVendorId,
                     mProductId,
+                    mDeviceBus,
                     mDescriptor,
                     mIsExternal,
                     mSources,
@@ -847,6 +858,21 @@
     }
 
     /**
+     * Gets the device bus used by given device, if available.
+     * <p>
+     * The device bus is the communication system used for transferring data
+     * (e.g. USB, Bluetooth etc.). This value comes from the kernel (from input.h).
+     * A value of 0 will be assigned where the device bus is not available.
+     * </p>
+     *
+     * @return The device bus of a given device
+     * @hide
+     */
+    public int getDeviceBus() {
+        return mDeviceBus;
+    }
+
+    /**
      * Gets the input device descriptor, which is a stable identifier for an input device.
      * <p>
      * An input device descriptor uniquely identifies an input device.  Its value
@@ -1448,6 +1474,7 @@
         out.writeString(mName);
         out.writeInt(mVendorId);
         out.writeInt(mProductId);
+        out.writeInt(mDeviceBus);
         out.writeString(mDescriptor);
         out.writeInt(mIsExternal ? 1 : 0);
         out.writeInt(mSources);
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 90663c7..147c15b 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -216,6 +216,14 @@
         default CompatibilityInfo.Translator getTranslator() {
             return null;
         }
+
+        /**
+         * Notifies when the state of running animation is changed. The state is either "running" or
+         * "idle".
+         *
+         * @param running {@code true} if there is any animation running; {@code false} otherwise.
+         */
+        default void notifyAnimationRunningStateChanged(boolean running) {}
     }
 
     private static final String TAG = "InsetsController";
@@ -749,6 +757,9 @@
                     final InsetsAnimationControlRunner runner = new InsetsResizeAnimationRunner(
                             mFrame, state1, mToState, RESIZE_INTERPOLATOR,
                             ANIMATION_DURATION_RESIZE, mTypes, InsetsController.this);
+                    if (mRunningAnimations.isEmpty()) {
+                        mHost.notifyAnimationRunningStateChanged(true);
+                    }
                     mRunningAnimations.add(new RunningAnimation(runner, runner.getAnimationType()));
                 }
             };
@@ -1382,6 +1393,9 @@
             }
         }
         ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING);
+        if (mRunningAnimations.isEmpty()) {
+            mHost.notifyAnimationRunningStateChanged(true);
+        }
         mRunningAnimations.add(new RunningAnimation(runner, animationType));
         if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: "
                 + useInsetsAnimationThread);
@@ -1588,6 +1602,9 @@
                 break;
             }
         }
+        if (mRunningAnimations.isEmpty()) {
+            mHost.notifyAnimationRunningStateChanged(false);
+        }
         onAnimationStateChanged(removedTypes, false /* running */);
     }
 
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index d0a4d1a..ad0bf7c 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -197,7 +197,9 @@
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"FRAME_RATE_COMPATIBILITY_"},
-            value = {FRAME_RATE_COMPATIBILITY_DEFAULT, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE})
+            value = {FRAME_RATE_COMPATIBILITY_DEFAULT, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
+                    FRAME_RATE_COMPATIBILITY_EXACT, FRAME_RATE_COMPATIBILITY_NO_VOTE,
+                    FRAME_RATE_COMPATIBILITY_MIN, FRAME_RATE_COMPATIBILITY_GTE})
     public @interface FrameRateCompatibility {}
 
     // From native_window.h. Keep these in sync.
@@ -242,6 +244,13 @@
      */
     public static final int FRAME_RATE_COMPATIBILITY_MIN = 102;
 
+    // From window.h. Keep these in sync.
+    /**
+     * The surface requests a frame rate that is greater than or equal to {@code frameRate}.
+     * @hide
+     */
+    public static final int FRAME_RATE_COMPATIBILITY_GTE = 103;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"CHANGE_FRAME_RATE_"},
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 8befe8a..cbbe785 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -503,9 +503,6 @@
     // be dumped as additional context
     private static volatile boolean sDebugUsageAfterRelease = false;
 
-    static GlobalTransactionWrapper sGlobalTransaction;
-    static long sTransactionNestCount = 0;
-
     private static final NativeAllocationRegistry sRegistry =
             NativeAllocationRegistry.createMalloced(SurfaceControl.class.getClassLoader(),
                     nativeGetNativeSurfaceControlFinalizer());
@@ -859,33 +856,47 @@
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"FRAME_RATE_SELECTION_STRATEGY_"},
-            value = {FRAME_RATE_SELECTION_STRATEGY_SELF,
-                    FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN})
+            value = {FRAME_RATE_SELECTION_STRATEGY_PROPAGATE,
+                    FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN,
+                    FRAME_RATE_SELECTION_STRATEGY_SELF})
     public @interface FrameRateSelectionStrategy {}
 
     // From window.h. Keep these in sync.
     /**
      * Default value. The layer uses its own frame rate specifications, assuming it has any
-     * specifications, instead of its parent's.
+     * specifications, instead of its parent's. If it does not have its own frame rate
+     * specifications, it will try to use its parent's. It will propagate its specifications to any
+     * descendants that do not have their own.
+     *
      * However, {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} on an ancestor layer
-     * supersedes this behavior, meaning that this layer will inherit the frame rate specifications
-     * of that ancestor layer.
+     * supersedes this behavior, meaning that this layer will inherit frame rate specifications
+     * regardless of whether it has its own.
      * @hide
      */
-    public static final int FRAME_RATE_SELECTION_STRATEGY_SELF = 0;
+    public static final int FRAME_RATE_SELECTION_STRATEGY_PROPAGATE = 0;
 
     /**
      * The layer's frame rate specifications will propagate to and override those of its descendant
      * layers.
-     * The layer with this strategy has the {@link #FRAME_RATE_SELECTION_STRATEGY_SELF} behavior
-     * for itself. This does mean that any parent or ancestor layer that also has the strategy
-     * {@link FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} will override this layer's
+     *
+     * The layer itself has the {@link #FRAME_RATE_SELECTION_STRATEGY_PROPAGATE} behavior.
+     * Thus, ancestor layer that also has the strategy
+     * {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} will override this layer's
      * frame rate specifications.
      * @hide
      */
     public static final int FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN = 1;
 
     /**
+     * The layer's frame rate specifications will not propagate to its descendant
+     * layers, even if the descendant layer has no frame rate specifications.
+     * However, {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} on an ancestor
+     * layer supersedes this behavior.
+     * @hide
+     */
+    public static final int FRAME_RATE_SELECTION_STRATEGY_SELF = 2;
+
+    /**
      * Builder class for {@link SurfaceControl} objects.
      *
      * By default the surface will be hidden, and have "unset" bounds, meaning it can
@@ -1576,54 +1587,30 @@
         return mNativeObject != 0;
     }
 
-    /*
-     * set surface parameters.
-     * needs to be inside open/closeTransaction block
-     */
-
     /** start a transaction
      * @hide
-     */
-    @UnsupportedAppUsage
-    public static void openTransaction() {
-        synchronized (SurfaceControl.class) {
-            if (sGlobalTransaction == null) {
-                sGlobalTransaction = new GlobalTransactionWrapper();
-            }
-            synchronized(SurfaceControl.class) {
-                sTransactionNestCount++;
-            }
-        }
-    }
-
-    /**
-     * Merge the supplied transaction in to the deprecated "global" transaction.
-     * This clears the supplied transaction in an identical fashion to {@link Transaction#merge}.
-     * <p>
-     * This is a utility for interop with legacy-code and will go away with the Global Transaction.
-     * @hide
+     * @deprecated Use regular Transaction instead.
      */
     @Deprecated
-    public static void mergeToGlobalTransaction(Transaction t) {
-        synchronized(SurfaceControl.class) {
-            sGlobalTransaction.merge(t);
-        }
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.VANILLA_ICE_CREAM,
+            publicAlternatives = "Use {@code SurfaceControl.Transaction} instead",
+            trackingBug = 247078497)
+    public static void openTransaction() {
+        // TODO(b/247078497): It was used for global transaction (all usages are removed).
+        //  Keep the method declaration to avoid breaking reference from legacy access.
     }
 
     /** end a transaction
      * @hide
+     * @deprecated Use regular Transaction instead.
      */
-    @UnsupportedAppUsage
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.VANILLA_ICE_CREAM,
+            publicAlternatives = "Use {@code SurfaceControl.Transaction} instead",
+            trackingBug = 247078497)
     public static void closeTransaction() {
-        synchronized(SurfaceControl.class) {
-            if (sTransactionNestCount == 0) {
-                Log.e(TAG,
-                        "Call to SurfaceControl.closeTransaction without matching openTransaction");
-            } else if (--sTransactionNestCount > 0) {
-                return;
-            }
-            sGlobalTransaction.applyGlobalTransaction(false);
-        }
+        // TODO(b/247078497): It was used for global transaction (all usages are removed).
+        //  Keep the method declaration to avoid breaking reference from legacy access.
     }
 
     /**
@@ -4499,39 +4486,6 @@
     }
 
     /**
-     * As part of eliminating usage of the global Transaction we expose
-     * a SurfaceControl.getGlobalTransaction function. However calling
-     * apply on this global transaction (rather than using closeTransaction)
-     * would be very dangerous. So for the global transaction we use this
-     * subclass of Transaction where the normal apply throws an exception.
-     */
-    private static class GlobalTransactionWrapper extends SurfaceControl.Transaction {
-        void applyGlobalTransaction(boolean sync) {
-            applyResizedSurfaces();
-            notifyReparentedSurfaces();
-            nativeApplyTransaction(mNativeObject, sync, /*oneWay*/ false);
-        }
-
-        @Override
-        public void apply(boolean sync) {
-            throw new RuntimeException("Global transaction must be applied from closeTransaction");
-        }
-    }
-
-    /**
-     * This is a refactoring utility function to enable lower levels of code to be refactored
-     * from using the global transaction (and instead use a passed in Transaction) without
-     * having to refactor the higher levels at the same time.
-     * The returned global transaction can't be applied, it must be applied from closeTransaction
-     * Unless you are working on removing Global Transaction usage in the WindowManager, this
-     * probably isn't a good function to use.
-     * @hide
-     */
-    public static Transaction getGlobalTransaction() {
-        return sGlobalTransaction;
-    }
-
-    /**
      * @hide
      */
     public void resize(int w, int h) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d591f89..a268bca 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -34,6 +34,7 @@
 import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
 import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
 import static android.view.flags.Flags.viewVelocityApi;
+import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
 
 import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS;
 import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS;
@@ -5154,9 +5155,10 @@
     private Runnable mHandwritingDelegatorCallback;
     private String mAllowedHandwritingDelegatePackageName;
 
-    // These two fields are set if the view is a handwriting delegate.
+    // These three fields are set if the view is a handwriting delegate.
     private boolean mIsHandwritingDelegate;
     private String mAllowedHandwritingDelegatorPackageName;
+    private @InputMethodManager.HandwritingDelegateFlags int mHandwritingDelegateFlags;
 
     /**
      * Solid color to use as a background when creating the drawing cache. Enables
@@ -12747,6 +12749,30 @@
     }
 
     /**
+     * Sets flags configuring the handwriting delegation behavior for this delegate editor view.
+     *
+     * <p>This method has no effect unless {@link #setIsHandwritingDelegate} is also called to
+     * configure this view to act as a handwriting delegate.
+     *
+     * @param flags {@link InputMethodManager#HANDWRITING_DELEGATE_FLAG_HOME_DELEGATOR_ALLOWED} or
+     *     {@code 0}
+     */
+    @FlaggedApi(FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR)
+    public void setHandwritingDelegateFlags(
+            @InputMethodManager.HandwritingDelegateFlags int flags) {
+        mHandwritingDelegateFlags = flags;
+    }
+
+    /**
+     * Returns flags configuring the handwriting delegation behavior for this delegate editor view,
+     * as set by {@link #setHandwritingDelegateFlags}.
+     */
+    @FlaggedApi(FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR)
+    public @InputMethodManager.HandwritingDelegateFlags int getHandwritingDelegateFlags() {
+        return mHandwritingDelegateFlags;
+    }
+
+    /**
      * Gets the coordinates of this view in the coordinate space of the
      * {@link Surface} that contains the view.
      *
@@ -33018,7 +33044,7 @@
     }
 
     private float getSizePercentage() {
-        if (mResources == null || getAlpha() == 0 || getVisibility() != VISIBLE) {
+        if (mResources == null || getVisibility() != VISIBLE) {
             return 0;
         }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 7a6c292..9d2ab1f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -92,6 +92,7 @@
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
 import static android.view.accessibility.Flags.forceInvertColor;
+import static android.view.accessibility.Flags.reduceWindowContentChangedEventThrottle;
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER;
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INSETS_CONTROLLER;
 import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
@@ -816,6 +817,8 @@
     private long mFpsPrevTime = -1;
     private int mFpsNumFrames;
 
+    private boolean mInsetsAnimationRunning;
+
     /**
      * The resolved pointer icon type requested by this window.
      * A null value indicates the resolved pointer icon has not yet been calculated.
@@ -991,7 +994,7 @@
     // for idleness handling.
     private boolean mHasIdledMessage = false;
     // time for touch boost period.
-    private static final int FRAME_RATE_TOUCH_BOOST_TIME = 1500;
+    private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000;
     // time for checking idle status periodically.
     private static final int FRAME_RATE_IDLENESS_CHECK_TIME_MILLIS = 500;
     // time for revaluating the idle status before lowering the frame rate.
@@ -2179,6 +2182,10 @@
         }
     }
 
+    void notifyInsetsAnimationRunningStateChanged(boolean running) {
+        mInsetsAnimationRunning = running;
+    }
+
     @Override
     public void requestLayout() {
         if (!mHandlingLayoutInLayoutRequest) {
@@ -11355,6 +11362,10 @@
         }
 
         private boolean canContinueThrottle(View source, int changeType) {
+            if (!reduceWindowContentChangedEventThrottle()) {
+                // Old behavior. Always throttle.
+                return true;
+            }
             if (mSource == null) {
                 // We don't have a pending event.
                 return true;
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index a2708ee..40730e8 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -279,6 +279,13 @@
         return null;
     }
 
+    @Override
+    public void notifyAnimationRunningStateChanged(boolean running) {
+        if (mViewRoot != null) {
+            mViewRoot.notifyInsetsAnimationRunningStateChanged(running);
+        }
+    }
+
     private boolean isVisibleToUser() {
         return mViewRoot.getHostVisibility() == View.VISIBLE;
     }
diff --git a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
index a11c6d0..a404bd6 100644
--- a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
+++ b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
@@ -54,7 +54,7 @@
      * @param displayId the logical display id.
      * @param scale magnification scale.
      */
-    void setScale(int displayId, float scale);
+    void setScaleForWindowMagnification(int displayId, float scale);
 
      /**
      * Disables window magnification on specified display with animation.
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index c337cb4..aa4275d6 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -53,7 +53,21 @@
 
 flag {
     namespace: "accessibility"
+    name: "reduce_window_content_changed_event_throttle"
+    description: "Reduces the throttle of AccessibilityEvent of TYPE_WINDOW_CONTENT_CHANGED"
+    bug: "277305460"
+}
+
+flag {
+    namespace: "accessibility"
     name: "update_always_on_a11y_service"
     description: "Updates the Always-On A11yService state when the user changes the enablement of the shortcut."
     bug: "298869916"
 }
+
+flag {
+    name: "enable_system_pinch_zoom_gesture"
+    namespace: "accessibility"
+    description: "Feature flag for system pinch zoom gesture detector and related opt-out apis"
+    bug: "283323770"
+}
\ No newline at end of file
diff --git a/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java b/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
index 614102b..c244287 100644
--- a/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
+++ b/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
@@ -514,14 +514,15 @@
             @NonNull IInputMethodClient client,
             @UserIdInt int userId,
             @NonNull String delegatePackageName,
-            @NonNull String delegatorPackageName) {
+            @NonNull String delegatorPackageName,
+            @InputMethodManager.HandwritingDelegateFlags int flags) {
         final IInputMethodManager service = getService();
         if (service == null) {
             return false;
         }
         try {
             return service.acceptStylusHandwritingDelegation(
-                    client, userId, delegatePackageName, delegatorPackageName);
+                    client, userId, delegatePackageName, delegatorPackageName, flags);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 589b7a3..6d7a543 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -17,6 +17,7 @@
 package android.view.inputmethod;
 
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
 import static android.view.inputmethod.InputConnection.CURSOR_UPDATE_IMMEDIATE;
 import static android.view.inputmethod.InputConnection.CURSOR_UPDATE_MONITOR;
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.DISPLAY_ID;
@@ -425,6 +426,23 @@
     private static final boolean OPTIMIZE_NONEDITABLE_VIEWS =
             SystemProperties.getBoolean("debug.imm.optimize_noneditable_views", true);
 
+    /** @hide */
+    @IntDef(flag = true, prefix = { "HANDWRITING_DELEGATE_FLAG_" }, value = {
+            HANDWRITING_DELEGATE_FLAG_HOME_DELEGATOR_ALLOWED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface HandwritingDelegateFlags {}
+
+    /**
+     * Flag indicating that views from the default home screen ({@link Intent#CATEGORY_HOME}) may
+     * act as a handwriting delegator for the delegate editor view. If set, views from the home
+     * screen package will be trusted for handwriting delegation, in addition to views in the {@code
+     * delegatorPackageName} passed to {@link #acceptStylusHandwritingDelegation(View, String,
+     * int)}.
+     */
+    @FlaggedApi(FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR)
+    public static final int HANDWRITING_DELEGATE_FLAG_HOME_DELEGATOR_ALLOWED = 0x0001;
+
     /**
      * @deprecated Use {@link IInputMethodManagerGlobalInvoker} instead.
      */
@@ -2345,17 +2363,20 @@
      * @see #isStylusHandwritingAvailable()
      */
     public void startStylusHandwriting(@NonNull View view) {
-        startStylusHandwritingInternal(view, null /* delegatorPackageName */);
+        startStylusHandwritingInternal(
+                view, /* delegatorPackageName= */ null, /* handwritingDelegateFlags= */ 0);
     }
 
     private boolean startStylusHandwritingInternal(
-            @NonNull View view, @Nullable String delegatorPackageName) {
+            @NonNull View view, @Nullable String delegatorPackageName,
+            @HandwritingDelegateFlags int handwritingDelegateFlags) {
         Objects.requireNonNull(view);
 
         // Re-dispatch if there is a context mismatch.
         final InputMethodManager fallbackImm = getFallbackInputMethodManagerIfNecessary(view);
         if (fallbackImm != null) {
-            fallbackImm.startStylusHandwritingInternal(view, delegatorPackageName);
+            fallbackImm.startStylusHandwritingInternal(
+                    view, delegatorPackageName, handwritingDelegateFlags);
         }
 
         boolean useDelegation = !TextUtils.isEmpty(delegatorPackageName);
@@ -2375,7 +2396,7 @@
             if (useDelegation) {
                 return IInputMethodManagerGlobalInvoker.acceptStylusHandwritingDelegation(
                         mClient, UserHandle.myUserId(), view.getContext().getOpPackageName(),
-                        delegatorPackageName);
+                        delegatorPackageName, handwritingDelegateFlags);
             } else {
                 IInputMethodManagerGlobalInvoker.startStylusHandwriting(mClient);
             }
@@ -2470,16 +2491,17 @@
      */
     public boolean acceptStylusHandwritingDelegation(@NonNull View delegateView) {
         return startStylusHandwritingInternal(
-                delegateView, delegateView.getContext().getOpPackageName());
+                delegateView, delegateView.getContext().getOpPackageName(),
+                delegateView.getHandwritingDelegateFlags());
     }
 
     /**
      * Accepts and starts a stylus handwriting session on the delegate view, if handwriting
      * initiation delegation was previously requested using
-     * {@link #prepareStylusHandwritingDelegation(View, String)} from te delegator and the view
+     * {@link #prepareStylusHandwritingDelegation(View, String)} from the delegator and the view
      * belongs to a specified delegate package.
      *
-     * <p>Note: If delegator and delegate are in same application package use
+     * <p>Note: If delegator and delegate are in the same application package, use
      * {@link #acceptStylusHandwritingDelegation(View)} instead.</p>
      *
      * @param delegateView delegate view capable of receiving input via {@link InputConnection}
@@ -2493,8 +2515,35 @@
     public boolean acceptStylusHandwritingDelegation(
             @NonNull View delegateView, @NonNull String delegatorPackageName) {
         Objects.requireNonNull(delegatorPackageName);
+        return startStylusHandwritingInternal(
+                delegateView, delegatorPackageName, delegateView.getHandwritingDelegateFlags());
+    }
 
-        return startStylusHandwritingInternal(delegateView, delegatorPackageName);
+    /**
+     * Accepts and starts a stylus handwriting session on the delegate view, if handwriting
+     * initiation delegation was previously requested using {@link
+     * #prepareStylusHandwritingDelegation(View, String)} from the delegator and the view belongs to
+     * a specified delegate package.
+     *
+     * <p>Note: If delegator and delegate are in the same application package, use {@link
+     * #acceptStylusHandwritingDelegation(View)} instead.
+     *
+     * @param delegateView delegate view capable of receiving input via {@link InputConnection} on
+     *     which {@link #startStylusHandwriting(View)} will be called.
+     * @param delegatorPackageName package name of the delegator that handled initial stylus stroke.
+     * @param flags {@link #HANDWRITING_DELEGATE_FLAG_HOME_DELEGATOR_ALLOWED} or {@code 0}
+     * @return {@code true} if view belongs to allowed delegate package declared in {@link
+     *     #prepareStylusHandwritingDelegation(View, String)} and handwriting session can start.
+     * @see #prepareStylusHandwritingDelegation(View, String)
+     * @see #acceptStylusHandwritingDelegation(View)
+     */
+    @FlaggedApi(FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR)
+    public boolean acceptStylusHandwritingDelegation(
+            @NonNull View delegateView, @NonNull String delegatorPackageName,
+            @HandwritingDelegateFlags int flags) {
+        Objects.requireNonNull(delegatorPackageName);
+
+        return startStylusHandwritingInternal(delegateView, delegatorPackageName, flags);
     }
 
     /**
diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig
index 7486362..dc6aa6c 100644
--- a/core/java/android/view/inputmethod/flags.aconfig
+++ b/core/java/android/view/inputmethod/flags.aconfig
@@ -31,3 +31,10 @@
     bug: "284527000"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "home_screen_handwriting_delegator"
+    namespace: "input_method"
+    description: "Feature flag for supporting stylus handwriting delegation from RemoteViews on the home screen"
+    bug: "279959705"
+}
diff --git a/core/java/android/webkit/IWebViewUpdateService.aidl b/core/java/android/webkit/IWebViewUpdateService.aidl
index e177731..c6bd20c 100644
--- a/core/java/android/webkit/IWebViewUpdateService.aidl
+++ b/core/java/android/webkit/IWebViewUpdateService.aidl
@@ -79,4 +79,9 @@
      * Used by Settings to enable/disable multiprocess.
      */
     void enableMultiProcess(boolean enable);
+
+    /**
+     * Used by Settings to get the default WebView package.
+     */
+    WebViewProviderInfo getDefaultWebViewPackage();
 }
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index a919c00..da31348 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -16,11 +16,14 @@
 
 package android.widget;
 
+import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
+
 import android.annotation.AttrRes;
 import android.annotation.ColorInt;
 import android.annotation.ColorRes;
 import android.annotation.DimenRes;
 import android.annotation.DrawableRes;
+import android.annotation.FlaggedApi;
 import android.annotation.IdRes;
 import android.annotation.IntDef;
 import android.annotation.LayoutRes;
@@ -92,6 +95,7 @@
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.LayoutInflater.Filter;
+import android.view.MotionEvent;
 import android.view.RemotableViewMethod;
 import android.view.View;
 import android.view.ViewGroup;
@@ -239,6 +243,7 @@
     private static final int SET_REMOTE_COLLECTION_ITEMS_ADAPTER_TAG = 31;
     private static final int ATTRIBUTE_REFLECTION_ACTION_TAG = 32;
     private static final int SET_REMOTE_ADAPTER_TAG = 33;
+    private static final int SET_ON_STYLUS_HANDWRITING_RESPONSE_TAG = 34;
 
     /** @hide **/
     @IntDef(prefix = "MARGIN_", value = {
@@ -1054,8 +1059,7 @@
     }
 
     private class SetRemoteCollectionItemListAdapterAction extends Action {
-        @NonNull
-        private CompletableFuture<RemoteCollectionItems> mItemsFuture;
+        private @Nullable RemoteCollectionItems mItems;
         final Intent mServiceIntent;
         int mIntentId = -1;
         boolean mIsReplacedIntoAction = false;
@@ -1064,92 +1068,46 @@
                 @NonNull RemoteCollectionItems items) {
             mViewId = id;
             items.setHierarchyRootData(getHierarchyRootData());
-            mItemsFuture = CompletableFuture.completedFuture(items);
+            mItems = items;
             mServiceIntent = null;
         }
 
         SetRemoteCollectionItemListAdapterAction(@IdRes int id, Intent intent) {
             mViewId = id;
-            mItemsFuture = getItemsFutureFromIntentWithTimeout(intent);
-            setHierarchyRootData(getHierarchyRootData());
+            mItems = null;
             mServiceIntent = intent;
         }
 
-        private static CompletableFuture<RemoteCollectionItems> getItemsFutureFromIntentWithTimeout(
-                Intent intent) {
-            if (intent == null) {
-                Log.e(LOG_TAG, "Null intent received when generating adapter future");
-                return CompletableFuture.completedFuture(new RemoteCollectionItems
-                        .Builder().build());
-            }
-
-            final Context context = ActivityThread.currentApplication();
-            final CompletableFuture<RemoteCollectionItems> result = new CompletableFuture<>();
-
-            context.bindService(intent, Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
-                    result.defaultExecutor(), new ServiceConnection() {
-                        @Override
-                        public void onServiceConnected(ComponentName componentName,
-                                IBinder iBinder) {
-                            RemoteCollectionItems items;
-                            try {
-                                items = IRemoteViewsFactory.Stub.asInterface(iBinder)
-                                        .getRemoteCollectionItems();
-                            } catch (RemoteException re) {
-                                items = new RemoteCollectionItems.Builder().build();
-                                Log.e(LOG_TAG, "Error getting collection items from the factory",
-                                        re);
-                            } finally {
-                                context.unbindService(this);
-                            }
-
-                            result.complete(items);
-                        }
-
-                        @Override
-                        public void onServiceDisconnected(ComponentName componentName) { }
-                    });
-
-            result.completeOnTimeout(
-                    new RemoteCollectionItems.Builder().build(),
-                    MAX_ADAPTER_CONVERSION_WAITING_TIME_MS, TimeUnit.MILLISECONDS);
-
-            return result;
-        }
-
         SetRemoteCollectionItemListAdapterAction(Parcel parcel) {
             mViewId = parcel.readInt();
             mIntentId = parcel.readInt();
-            mItemsFuture = CompletableFuture.completedFuture(mIntentId != -1
-                    ? null
-                    : new RemoteCollectionItems(parcel, getHierarchyRootData()));
             mServiceIntent = parcel.readTypedObject(Intent.CREATOR);
+            mItems = mServiceIntent != null
+                    ? null
+                    : new RemoteCollectionItems(parcel, getHierarchyRootData());
         }
 
         @Override
         public void setHierarchyRootData(HierarchyRootData rootData) {
-            if (mIntentId == -1) {
-                mItemsFuture = mItemsFuture
-                        .thenApply(rc -> {
-                            rc.setHierarchyRootData(rootData);
-                            return rc;
-                        });
+            if (mItems != null) {
+                mItems.setHierarchyRootData(rootData);
                 return;
             }
 
-            // Set the root data for items in the cache instead
-            mCollectionCache.setHierarchyDataForId(mIntentId, rootData);
+            if (mIntentId != -1) {
+                // Set the root data for items in the cache instead
+                mCollectionCache.setHierarchyDataForId(mIntentId, rootData);
+            }
         }
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(mViewId);
             dest.writeInt(mIntentId);
-            if (mIntentId == -1) {
-                RemoteCollectionItems items = getCollectionItemsFromFuture(mItemsFuture);
-                items.writeToParcel(dest, flags, /* attached= */ true);
-            }
             dest.writeTypedObject(mServiceIntent, flags);
+            if (mItems != null) {
+                mItems.writeToParcel(dest, flags, /* attached= */ true);
+            }
         }
 
         @Override
@@ -1159,7 +1117,9 @@
             if (target == null) return;
 
             RemoteCollectionItems items = mIntentId == -1
-                    ? getCollectionItemsFromFuture(mItemsFuture)
+                    ? mItems == null
+                            ? new RemoteCollectionItems.Builder().build()
+                            : mItems
                     : mCollectionCache.getItemsForId(mIntentId);
 
             // Ensure that we are applying to an AppWidget root
@@ -1216,51 +1176,32 @@
 
         @Override
         public void visitUris(@NonNull Consumer<Uri> visitor) {
-            RemoteCollectionItems items = getCollectionItemsFromFuture(mItemsFuture);
-            items.visitUris(visitor);
-        }
-    }
+            if (mIntentId != -1 || mItems == null) {
+                return;
+            }
 
-    private static RemoteCollectionItems getCollectionItemsFromFuture(
-            CompletableFuture<RemoteCollectionItems> itemsFuture) {
-        RemoteCollectionItems items;
-        try {
-            items = itemsFuture.get();
-        } catch (Exception e) {
-            Log.e(LOG_TAG, "Error getting collection items from future", e);
-            items = new RemoteCollectionItems.Builder().build();
+            mItems.visitUris(visitor);
         }
-
-        return items;
     }
 
     /**
      * @hide
      */
-    public void collectAllIntents() {
-        mCollectionCache.collectAllIntentsNoComplete(this);
+    public CompletableFuture<Void> collectAllIntents() {
+        return mCollectionCache.collectAllIntentsNoComplete(this);
     }
 
     private class RemoteCollectionCache {
         private SparseArray<String> mIdToUriMapping = new SparseArray<>();
         private HashMap<String, RemoteCollectionItems> mUriToCollectionMapping = new HashMap<>();
 
-        // We don't put this into the parcel
-        private HashMap<String, CompletableFuture<RemoteCollectionItems>> mTempUriToFutureMapping =
-                new HashMap<>();
-
         RemoteCollectionCache() { }
 
         RemoteCollectionCache(RemoteCollectionCache src) {
-            boolean isWaitingCache = src.mTempUriToFutureMapping.size() != 0;
             for (int i = 0; i < src.mIdToUriMapping.size(); i++) {
                 String uri = src.mIdToUriMapping.valueAt(i);
                 mIdToUriMapping.put(src.mIdToUriMapping.keyAt(i), uri);
-                if (isWaitingCache) {
-                    mTempUriToFutureMapping.put(uri, src.mTempUriToFutureMapping.get(uri));
-                } else {
-                    mUriToCollectionMapping.put(uri, src.mUriToCollectionMapping.get(uri));
-                }
+                mUriToCollectionMapping.put(uri, src.mUriToCollectionMapping.get(uri));
             }
         }
 
@@ -1281,14 +1222,8 @@
 
         void setHierarchyDataForId(int intentId, HierarchyRootData data) {
             String uri = mIdToUriMapping.get(intentId);
-            if (mTempUriToFutureMapping.get(uri) != null) {
-                CompletableFuture<RemoteCollectionItems> itemsFuture =
-                        mTempUriToFutureMapping.get(uri);
-                mTempUriToFutureMapping.put(uri, itemsFuture.thenApply(rc -> {
-                    rc.setHierarchyRootData(data);
-                    return rc;
-                }));
-
+            if (mUriToCollectionMapping.get(uri) == null) {
+                Log.e(LOG_TAG, "Error setting hierarchy data for id=" + intentId);
                 return;
             }
 
@@ -1301,14 +1236,17 @@
             return mUriToCollectionMapping.get(uri);
         }
 
-        void collectAllIntentsNoComplete(@NonNull RemoteViews inViews) {
+        CompletableFuture<Void> collectAllIntentsNoComplete(@NonNull RemoteViews inViews) {
+            CompletableFuture<Void> collectionFuture = CompletableFuture.completedFuture(null);
             if (inViews.hasSizedRemoteViews()) {
                 for (RemoteViews remoteViews : inViews.mSizedRemoteViews) {
-                    remoteViews.collectAllIntents();
+                    collectionFuture = CompletableFuture.allOf(collectionFuture,
+                            collectAllIntentsNoComplete(remoteViews));
                 }
             } else if (inViews.hasLandscapeAndPortraitLayouts()) {
-                inViews.mLandscape.collectAllIntents();
-                inViews.mPortrait.collectAllIntents();
+                collectionFuture = CompletableFuture.allOf(
+                        collectAllIntentsNoComplete(inViews.mLandscape),
+                        collectAllIntentsNoComplete(inViews.mPortrait));
             } else if (inViews.mActions != null) {
                 for (Action action : inViews.mActions) {
                     if (action instanceof SetRemoteCollectionItemListAdapterAction rca) {
@@ -1318,40 +1256,95 @@
                         }
 
                         if (rca.mIntentId != -1 && rca.mIsReplacedIntoAction) {
-                            String uri = mIdToUriMapping.get(rca.mIntentId);
-                            mTempUriToFutureMapping.put(uri, rca.mItemsFuture);
-                            rca.mItemsFuture = CompletableFuture.completedFuture(null);
+                            final String uri = mIdToUriMapping.get(rca.mIntentId);
+                            collectionFuture = CompletableFuture.allOf(collectionFuture,
+                                    getItemsFutureFromIntentWithTimeout(rca.mServiceIntent)
+                                            .thenAccept(rc -> {
+                                                rc.setHierarchyRootData(getHierarchyRootData());
+                                                mUriToCollectionMapping.put(uri, rc);
+                                            }));
+                            rca.mItems = null;
                             continue;
                         }
 
                         // Differentiate between the normal collection actions and the ones with
                         // intents.
                         if (rca.mServiceIntent != null) {
-                            String uri = rca.mServiceIntent.toUri(0);
+                            final String uri = rca.mServiceIntent.toUri(0);
                             int index = mIdToUriMapping.indexOfValue(uri);
                             if (index == -1) {
                                 int newIntentId = mIdToUriMapping.size();
                                 rca.mIntentId = newIntentId;
                                 mIdToUriMapping.put(newIntentId, uri);
-                                // mUriToIntentMapping.put(uri, mServiceIntent);
-                                mTempUriToFutureMapping.put(uri, rca.mItemsFuture);
                             } else {
                                 rca.mIntentId = mIdToUriMapping.keyAt(index);
+                                rca.mItems = null;
+                                continue;
                             }
-                            rca.mItemsFuture = CompletableFuture.completedFuture(null);
+                            collectionFuture = CompletableFuture.allOf(collectionFuture,
+                                    getItemsFutureFromIntentWithTimeout(rca.mServiceIntent)
+                                            .thenAccept(rc -> {
+                                                rc.setHierarchyRootData(getHierarchyRootData());
+                                                mUriToCollectionMapping.put(uri, rc);
+                                            }));
+                            rca.mItems = null;
                         } else {
-                            RemoteCollectionItems items = getCollectionItemsFromFuture(
-                                    rca.mItemsFuture);
-                            for (RemoteViews views : items.mViews) {
-                                views.collectAllIntents();
+                            for (RemoteViews views : rca.mItems.mViews) {
+                                collectionFuture = CompletableFuture.allOf(collectionFuture,
+                                        collectAllIntentsNoComplete(views));
                             }
                         }
                     } else if (action instanceof ViewGroupActionAdd vgaa
                             && vgaa.mNestedViews != null) {
-                        vgaa.mNestedViews.collectAllIntents();
+                        collectionFuture = CompletableFuture.allOf(collectionFuture,
+                                collectAllIntentsNoComplete(vgaa.mNestedViews));
                     }
                 }
             }
+
+            return collectionFuture;
+        }
+
+        private static CompletableFuture<RemoteCollectionItems> getItemsFutureFromIntentWithTimeout(
+                Intent intent) {
+            if (intent == null) {
+                Log.e(LOG_TAG, "Null intent received when generating adapter future");
+                return CompletableFuture.completedFuture(new RemoteCollectionItems
+                    .Builder().build());
+            }
+
+            final Context context = ActivityThread.currentApplication();
+            final CompletableFuture<RemoteCollectionItems> result = new CompletableFuture<>();
+
+            context.bindService(intent, Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
+                    result.defaultExecutor(), new ServiceConnection() {
+                        @Override
+                        public void onServiceConnected(ComponentName componentName,
+                                IBinder iBinder) {
+                            RemoteCollectionItems items;
+                            try {
+                                items = IRemoteViewsFactory.Stub.asInterface(iBinder)
+                                    .getRemoteCollectionItems();
+                            } catch (RemoteException re) {
+                                items = new RemoteCollectionItems.Builder().build();
+                                Log.e(LOG_TAG, "Error getting collection items from the factory",
+                                        re);
+                            } finally {
+                                context.unbindService(this);
+                            }
+
+                            result.complete(items);
+                        }
+
+                        @Override
+                        public void onServiceDisconnected(ComponentName componentName) { }
+                    });
+
+            result.completeOnTimeout(
+                    new RemoteCollectionItems.Builder().build(),
+                    MAX_ADAPTER_CONVERSION_WAITING_TIME_MS, TimeUnit.MILLISECONDS);
+
+            return result;
         }
 
         public void writeToParcel(Parcel out, int flags) {
@@ -1360,10 +1353,7 @@
                 out.writeInt(mIdToUriMapping.keyAt(i));
                 String intentUri = mIdToUriMapping.valueAt(i);
                 out.writeString8(intentUri);
-                RemoteCollectionItems items = mTempUriToFutureMapping.get(intentUri) != null
-                        ? getCollectionItemsFromFuture(mTempUriToFutureMapping.get(intentUri))
-                        : mUriToCollectionMapping.get(intentUri);
-                items.writeToParcel(out, flags, true);
+                mUriToCollectionMapping.get(intentUri).writeToParcel(out, flags, true);
             }
         }
     }
@@ -1525,6 +1515,53 @@
         }
     }
 
+    /** Helper action to configure handwriting delegation via {@link PendingIntent}. */
+    private class SetOnStylusHandwritingResponse extends Action {
+        final PendingIntent mPendingIntent;
+
+        SetOnStylusHandwritingResponse(@IdRes int id, @Nullable PendingIntent pendingIntent) {
+            this.mViewId = id;
+            this.mPendingIntent = pendingIntent;
+        }
+
+        SetOnStylusHandwritingResponse(@NonNull Parcel parcel) {
+            mViewId = parcel.readInt();
+            mPendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
+        }
+
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeInt(mViewId);
+            PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, dest);
+        }
+
+        @Override
+        public void apply(View root, ViewGroup rootParent, ActionApplyParams params) {
+            final View target = root.findViewById(mViewId);
+            if (target == null) return;
+
+            if (hasFlags(FLAG_WIDGET_IS_COLLECTION_CHILD)) {
+                Log.w(LOG_TAG, "Cannot use setOnStylusHandwritingPendingIntent for collection item "
+                        + "(id: " + mViewId + ")");
+                return;
+            }
+
+            if (mPendingIntent != null) {
+                RemoteResponse response = RemoteResponse.fromPendingIntent(mPendingIntent);
+                target.setHandwritingDelegatorCallback(
+                        () -> response.handleViewInteraction(target, params.handler));
+                target.setAllowedHandwritingDelegatePackage(mPendingIntent.getCreatorPackage());
+            } else {
+                target.setHandwritingDelegatorCallback(null);
+                target.setAllowedHandwritingDelegatePackage(null);
+            }
+        }
+
+        @Override
+        public int getActionTag() {
+            return SET_ON_STYLUS_HANDWRITING_RESPONSE_TAG;
+        }
+    }
+
     /**
      * Equivalent to calling
      * {@link android.widget.CompoundButton#setOnCheckedChangeListener(
@@ -4204,6 +4241,8 @@
                 return new SetRemoteCollectionItemListAdapterAction(parcel);
             case ATTRIBUTE_REFLECTION_ACTION_TAG:
                 return new AttributeReflectionAction(parcel);
+            case SET_ON_STYLUS_HANDWRITING_RESPONSE_TAG:
+                return new SetOnStylusHandwritingResponse(parcel);
             default:
                 throw new ActionException("Tag " + tag + " not found");
         }
@@ -4757,6 +4796,33 @@
     }
 
     /**
+     * Equivalent to calling {@link View#setHandwritingDelegatorCallback(Runnable)} to send the
+     * provided {@link PendingIntent}.
+     *
+     * <p>A common use case is a remote view which looks like a text editor but does not actually
+     * support text editing itself, and clicking on the remote view launches an activity containing
+     * an EditText. To support handwriting initiation in this case, this method can be called on the
+     * remote view to configure it as a handwriting delegator, meaning that stylus movement on the
+     * remote view triggers a {@link PendingIntent} and starts handwriting mode for the delegate
+     * EditText. The {@link PendingIntent} is typically the same as the one passed to {@link
+     * #setOnClickPendingIntent} which launches the activity containing the EditText. The EditText
+     * should call {@link View#setIsHandwritingDelegate} to set it as a delegate, and also use
+     * {@link View#setAllowedHandwritingDelegatorPackage} or {@link
+     * android.view.inputmethod.InputMethodManager#HANDWRITING_DELEGATE_FLAG_HOME_DELEGATOR_ALLOWED}
+     * if necessary to support delegators from the package displaying the remote view.
+     *
+     * @param viewId identifier of the view that will trigger the {@link PendingIntent} when a
+     *     stylus {@link MotionEvent} occurs within the view's bounds
+     * @param pendingIntent the {@link PendingIntent} to send, or {@code null} to clear the
+     *     handwriting delegation
+     */
+    @FlaggedApi(FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR)
+    public void setOnStylusHandwritingPendingIntent(
+            @IdRes int viewId, @Nullable PendingIntent pendingIntent) {
+        addAction(new SetOnStylusHandwritingResponse(viewId, pendingIntent));
+    }
+
+    /**
      * @hide
      * Equivalent to calling
      * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl
index e10f7c8..478aeec 100644
--- a/core/java/android/window/ITaskOrganizerController.aidl
+++ b/core/java/android/window/ITaskOrganizerController.aidl
@@ -70,20 +70,4 @@
 
     /** Updates a state of camera compat control for stretched issues in the viewfinder. */
     void updateCameraCompatControlState(in WindowContainerToken task, int state);
-
-    /**
-     * Controls whether ignore orientation request logic in {@link
-     * com.android.server.wm.DisplayArea} is disabled at runtime and how to optionally map some
-     * requested orientations to others.
-     *
-     * @param isDisabled when {@code true}, the system always ignores the value of {@link
-     *                   com.android.server.wm.DisplayArea#getIgnoreOrientationRequest} and app
-     *                   requested orientation is respected.
-     * @param fromOrientations The orientations we want to map to the correspondent orientations
-     *                        in toOrientation.
-     * @param toOrientations The orientations we map to the ones in fromOrientations at the same
-     *                       index
-     */
-     void setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled,
-            in int[] fromOrientations, in int[] toOrientations);
 }
diff --git a/core/java/android/window/SystemPerformanceHinter.java b/core/java/android/window/SystemPerformanceHinter.java
index 5b0d8d1..cc2329fc 100644
--- a/core/java/android/window/SystemPerformanceHinter.java
+++ b/core/java/android/window/SystemPerformanceHinter.java
@@ -20,7 +20,7 @@
 import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT;
 import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
 import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN;
-import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_SELF;
+import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_PROPAGATE;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -303,7 +303,7 @@
             SurfaceControl displaySurfaceControl = mDisplayRootProvider.getRootForDisplay(
                     session.displayId);
             mTransaction.setFrameRateSelectionStrategy(displaySurfaceControl,
-                    FRAME_RATE_SELECTION_STRATEGY_SELF);
+                    FRAME_RATE_SELECTION_STRATEGY_PROPAGATE);
             // smoothSwitchOnly is false to request a higher framerate, even if it means switching
             // the display mode will cause would jank on non-VRR devices because keeping a lower
             // refresh rate would mean a poorer user experience.
diff --git a/core/java/android/window/TaskFragmentOperation.java b/core/java/android/window/TaskFragmentOperation.java
index 4e0f9a5..0ec9ffe 100644
--- a/core/java/android/window/TaskFragmentOperation.java
+++ b/core/java/android/window/TaskFragmentOperation.java
@@ -108,6 +108,18 @@
      */
     public static final int OP_TYPE_REORDER_TO_TOP_OF_TASK = 13;
 
+    /**
+     * Creates a decor surface in the parent Task of the TaskFragment. The created decor surface
+     * will be provided in {@link TaskFragmentTransaction#TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED}
+     * event callback.
+     */
+    public static final int OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE = 14;
+
+    /**
+     * Removes the decor surface in the parent Task of the TaskFragment.
+     */
+    public static final int OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE = 15;
+
     @IntDef(prefix = { "OP_TYPE_" }, value = {
             OP_TYPE_UNKNOWN,
             OP_TYPE_CREATE_TASK_FRAGMENT,
@@ -124,6 +136,8 @@
             OP_TYPE_SET_ISOLATED_NAVIGATION,
             OP_TYPE_REORDER_TO_BOTTOM_OF_TASK,
             OP_TYPE_REORDER_TO_TOP_OF_TASK,
+            OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE,
+            OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface OperationType {}
diff --git a/core/java/android/window/TaskFragmentParentInfo.java b/core/java/android/window/TaskFragmentParentInfo.java
index e6eeca4..a77c234 100644
--- a/core/java/android/window/TaskFragmentParentInfo.java
+++ b/core/java/android/window/TaskFragmentParentInfo.java
@@ -22,6 +22,9 @@
 import android.content.res.Configuration;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.view.SurfaceControl;
+
+import java.util.Objects;
 
 /**
  * The information about the parent Task of a particular TaskFragment
@@ -37,12 +40,15 @@
 
     private final boolean mHasDirectActivity;
 
+    @Nullable private final SurfaceControl mDecorSurface;
+
     public TaskFragmentParentInfo(@NonNull Configuration configuration, int displayId,
-            boolean visible, boolean hasDirectActivity) {
+            boolean visible, boolean hasDirectActivity, @Nullable SurfaceControl decorSurface) {
         mConfiguration.setTo(configuration);
         mDisplayId = displayId;
         mVisible = visible;
         mHasDirectActivity = hasDirectActivity;
+        mDecorSurface = decorSurface;
     }
 
     public TaskFragmentParentInfo(@NonNull TaskFragmentParentInfo info) {
@@ -50,6 +56,7 @@
         mDisplayId = info.mDisplayId;
         mVisible = info.mVisible;
         mHasDirectActivity = info.mHasDirectActivity;
+        mDecorSurface = info.mDecorSurface;
     }
 
     /** The {@link Configuration} of the parent Task */
@@ -92,7 +99,13 @@
             return false;
         }
         return getWindowingMode() == that.getWindowingMode() && mDisplayId == that.mDisplayId
-                && mVisible == that.mVisible && mHasDirectActivity == that.mHasDirectActivity;
+                && mVisible == that.mVisible && mHasDirectActivity == that.mHasDirectActivity
+                && mDecorSurface == that.mDecorSurface;
+    }
+
+    @Nullable
+    public SurfaceControl getDecorSurface() {
+        return mDecorSurface;
     }
 
     @WindowConfiguration.WindowingMode
@@ -107,6 +120,7 @@
                 + ", displayId=" + mDisplayId
                 + ", visible=" + mVisible
                 + ", hasDirectActivity=" + mHasDirectActivity
+                + ", decorSurface=" + mDecorSurface
                 + "}";
     }
 
@@ -128,7 +142,8 @@
         return mConfiguration.equals(that.mConfiguration)
                 && mDisplayId == that.mDisplayId
                 && mVisible == that.mVisible
-                && mHasDirectActivity == that.mHasDirectActivity;
+                && mHasDirectActivity == that.mHasDirectActivity
+                && mDecorSurface == that.mDecorSurface;
     }
 
     @Override
@@ -137,6 +152,7 @@
         result = 31 * result + mDisplayId;
         result = 31 * result + (mVisible ? 1 : 0);
         result = 31 * result + (mHasDirectActivity ? 1 : 0);
+        result = 31 * result + Objects.hashCode(mDecorSurface);
         return result;
     }
 
@@ -146,6 +162,7 @@
         dest.writeInt(mDisplayId);
         dest.writeBoolean(mVisible);
         dest.writeBoolean(mHasDirectActivity);
+        dest.writeTypedObject(mDecorSurface, flags);
     }
 
     private TaskFragmentParentInfo(Parcel in) {
@@ -153,6 +170,7 @@
         mDisplayId = in.readInt();
         mVisible = in.readBoolean();
         mHasDirectActivity = in.readBoolean();
+        mDecorSurface = in.readTypedObject(SurfaceControl.CREATOR);
     }
 
     public static final Creator<TaskFragmentParentInfo> CREATOR =
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index cd1275c..6d36b57 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -266,31 +266,6 @@
     }
 
     /**
-     * Controls whether ignore orientation request logic in {@link
-     * com.android.server.wm.DisplayArea} is disabled at runtime and how to optionally map some
-     * requested orientation to others.
-     *
-     * @param isIgnoreOrientationRequestDisabled when {@code true}, the system always ignores the
-     *           value of  {@link com.android.server.wm.DisplayArea#getIgnoreOrientationRequest}
-     *           and app requested orientation is respected.
-     * @param fromOrientations The orientations we want to map to the correspondent orientations
-     *                        in toOrientation.
-     * @param toOrientations The orientations we map to the ones in fromOrientations at the same
-     *                       index
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
-    public void setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled,
-            @Nullable int[] fromOrientations, @Nullable int[] toOrientations) {
-        try {
-            mTaskOrganizerController.setOrientationRequestPolicy(isIgnoreOrientationRequestDisabled,
-                    fromOrientations, toOrientations);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Gets the executor to run callbacks on.
      * @hide
      */
diff --git a/core/java/android/window/WindowInfosListenerForTest.java b/core/java/android/window/WindowInfosListenerForTest.java
index 35ce726..34c6399 100644
--- a/core/java/android/window/WindowInfosListenerForTest.java
+++ b/core/java/android/window/WindowInfosListenerForTest.java
@@ -19,6 +19,7 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
 import android.annotation.TestApi;
 import android.graphics.Matrix;
 import android.graphics.Rect;
@@ -87,6 +88,38 @@
         @NonNull
         public final Matrix transform;
 
+        /**
+         * True if the window is touchable.
+         */
+        @SuppressLint("UnflaggedApi") // The API is only used for tests.
+        public final boolean isTouchable;
+
+        /**
+         * True if the window is focusable.
+         */
+        @SuppressLint("UnflaggedApi") // The API is only used for tests.
+        public final boolean isFocusable;
+
+        /**
+         * True if the window is preventing splitting
+         */
+        @SuppressLint("UnflaggedApi") // The API is only used for tests.
+        public final boolean isPreventSplitting;
+
+        /**
+         * True if the window duplicates touches received to wallpaper.
+         */
+        @SuppressLint("UnflaggedApi") // The API is only used for tests.
+        public final boolean isDuplicateTouchToWallpaper;
+
+        /**
+         * True if the window is listening for when there is a touch DOWN event
+         * occurring outside its touchable bounds. When such an event occurs,
+         * this window will receive a MotionEvent with ACTION_OUTSIDE.
+         */
+        @SuppressLint("UnflaggedApi") // The API is only used for tests.
+        public final boolean isWatchOutsideTouch;
+
         WindowInfo(@NonNull IBinder windowToken, @NonNull String name, int displayId,
                 @NonNull Rect bounds, int inputConfig, @NonNull Matrix transform) {
             this.windowToken = windowToken;
@@ -96,6 +129,14 @@
             this.isTrustedOverlay = (inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
             this.isVisible = (inputConfig & InputConfig.NOT_VISIBLE) == 0;
             this.transform = transform;
+            this.isTouchable = (inputConfig & InputConfig.NOT_TOUCHABLE) == 0;
+            this.isFocusable = (inputConfig & InputConfig.NOT_FOCUSABLE) == 0;
+            this.isPreventSplitting = (inputConfig
+                            & InputConfig.PREVENT_SPLITTING) != 0;
+            this.isDuplicateTouchToWallpaper = (inputConfig
+                            & InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER) != 0;
+            this.isWatchOutsideTouch = (inputConfig
+                            & InputConfig.WATCH_OUTSIDE_TOUCH) != 0;
         }
 
         @Override
diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig
index 7f93213..29932f3 100644
--- a/core/java/android/window/flags/window_surfaces.aconfig
+++ b/core/java/android/window/flags/window_surfaces.aconfig
@@ -48,3 +48,11 @@
     is_fixed_read_only: true
     bug: "262477923"
 }
+
+flag {
+    namespace: "window_surfaces"
+    name: "secure_window_state"
+    description: "Move SC secure flag to WindowState level"
+    is_fixed_read_only: true
+    bug: "308662081"
+}
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
index 7c4252e..6b074a6 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
@@ -33,6 +33,7 @@
 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_FLOATING_MENU;
 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_GESTURE;
 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TRIPLE_TAP;
+import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TWO_FINGER_TRIPLE_TAP;
 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__UNKNOWN_TYPE;
 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY;
 import static com.android.internal.util.FrameworkStatsLog.MAGNIFICATION_USAGE_REPORTED__ACTIVATED_MODE__MAGNIFICATION_ALL;
@@ -131,6 +132,18 @@
     }
 
     /**
+     * Logs magnification that is assigned to the two finger triple tap shortcut. Calls this when
+     * triggering the magnification two finger triple tap shortcut.
+     */
+    public static void logMagnificationTwoFingerTripleTap(boolean enabled) {
+        FrameworkStatsLog.write(FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED,
+                MAGNIFICATION_COMPONENT_NAME.flattenToString(),
+                // jean update
+                ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__TWO_FINGER_TRIPLE_TAP,
+                convertToLoggingServiceStatus(enabled));
+    }
+
+    /**
      * Logs accessibility feature name that is assigned to the long pressed accessibility button
      * shortcut. Calls this when clicking the long pressed accessibility button shortcut.
      *
diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
index 7be27be..1bd0982 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
@@ -87,10 +87,6 @@
         public static final Flag NOTIF_COOLDOWN_RULE = devFlag(
                 "persist.debug.sysui.notification.notif_cooldown_rule", "rule1");
 
-        /** b/301242692: Visit extra URIs used in notifications to prevent security issues. */
-        public static final Flag VISIT_RISKY_URIS = devFlag(
-                "persist.sysui.notification.visit_risky_uris");
-
         /** b/303716154: For debugging only: use short bitmap duration. */
         public static final Flag DEBUG_SHORT_BITMAP_DURATION = devFlag(
                 "persist.sysui.notification.debug_short_bitmap_duration");
diff --git a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
index f5fe12e..e55c641 100644
--- a/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
+++ b/core/java/com/android/internal/display/RefreshRateSettingsUtils.java
@@ -37,22 +37,11 @@
      * @return The highest refresh rate
      */
     public static float findHighestRefreshRateForDefaultDisplay(Context context) {
-        return findHighestRefreshRate(context, Display.DEFAULT_DISPLAY);
-    }
-
-    /**
-     * Find the highest refresh rate among all the modes of the specified display.
-     *
-     * @param context The context
-     * @param displayId The display ID
-     * @return The highest refresh rate
-     */
-    public static float findHighestRefreshRate(Context context, int displayId) {
         final DisplayManager dm = context.getSystemService(DisplayManager.class);
-        final Display display = dm.getDisplay(displayId);
+        final Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
 
         if (display == null) {
-            Log.w(TAG, "No valid display device with ID = " + displayId);
+            Log.w(TAG, "No valid default display device");
             return DEFAULT_REFRESH_RATE;
         }
 
diff --git a/core/java/com/android/internal/os/MonotonicClock.java b/core/java/com/android/internal/os/MonotonicClock.java
index d0d2354..661628a 100644
--- a/core/java/com/android/internal/os/MonotonicClock.java
+++ b/core/java/com/android/internal/os/MonotonicClock.java
@@ -50,6 +50,8 @@
     private final Clock mClock;
     private long mTimeshift;
 
+    public static final long UNDEFINED = -1;
+
     public MonotonicClock(File file) {
         mFile = new AtomicFile(file);
         mClock = Clock.SYSTEM_CLOCK;
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index dadeb2b..aab2242 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -60,7 +60,8 @@
     @UnsupportedAppUsage(maxTargetSdk = 28)
     void notifyCallForwardingChanged(boolean cfi);
     void notifyCallForwardingChangedForSubscriber(in int subId, boolean cfi);
-    void notifyDataActivityForSubscriber(int phoneId, int subId, int state);
+    void notifyDataActivityForSubscriber(int subId, int state);
+    void notifyDataActivityForSubscriberWithSlot(int phoneId, int subId, int state);
     void notifyDataConnectionForSubscriber(
             int phoneId, int subId, in PreciseDataConnectionState preciseState);
     // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 1c3fd93..595bf3b 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -152,8 +152,8 @@
                 in String delegatorPackageName);
 
     /** Accepts and starts a stylus handwriting session for the delegate view **/
-    boolean acceptStylusHandwritingDelegation(in IInputMethodClient client,
-                in int userId, in String delegatePackageName, in String delegatorPackageName);
+    boolean acceptStylusHandwritingDelegation(in IInputMethodClient client, in int userId,
+            in String delegatePackageName, in String delegatorPackageName, int flags);
 
     /** Returns {@code true} if currently selected IME supports Stylus handwriting. */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 440a332..f365dbb 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -462,9 +462,4 @@
             ],
         },
     },
-
-    // Workaround Clang LTO crash.
-    lto: {
-        never: true,
-    },
 }
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index 262f5e8..239c626 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -81,7 +81,8 @@
                                           deviceInfo.getId(), deviceInfo.getGeneration(),
                                           deviceInfo.getControllerNumber(), nameObj.get(),
                                           static_cast<int32_t>(ident.vendor),
-                                          static_cast<int32_t>(ident.product), descriptorObj.get(),
+                                          static_cast<int32_t>(ident.product),
+                                          static_cast<int32_t>(ident.bus), descriptorObj.get(),
                                           deviceInfo.isExternal(), deviceInfo.getSources(),
                                           deviceInfo.getKeyboardType(), kcmObj.get(),
                                           keyboardLanguageTagObj.get(), keyboardLayoutTypeObj.get(),
@@ -111,7 +112,7 @@
     gInputDeviceClassInfo.clazz = MakeGlobalRefOrDie(env, gInputDeviceClassInfo.clazz);
 
     gInputDeviceClassInfo.ctor = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "<init>",
-                                                  "(IIILjava/lang/String;IILjava/lang/"
+                                                  "(IIILjava/lang/String;IIILjava/lang/"
                                                   "String;ZIILandroid/view/KeyCharacterMap;Ljava/"
                                                   "lang/String;Ljava/lang/String;ZZZZZIII)V");
 
diff --git a/core/proto/android/os/batteryusagestats.proto b/core/proto/android/os/batteryusagestats.proto
index 2b74220..11b367b 100644
--- a/core/proto/android/os/batteryusagestats.proto
+++ b/core/proto/android/os/batteryusagestats.proto
@@ -92,8 +92,24 @@
     message UidBatteryConsumer {
         optional int32 uid = 1;
         optional BatteryConsumerData battery_consumer_data = 2;
-        optional int64 time_in_foreground_millis = 3;
-        optional int64 time_in_background_millis = 4;
+        // DEPRECATED Use time_in_state instead.
+        optional int64 time_in_foreground_millis = 3 [deprecated = true];
+        // DEPRECATED Use time_in_state instead.
+        optional int64 time_in_background_millis = 4 [deprecated = true];
+
+        message TimeInState {
+            enum ProcessState {
+                UNSPECIFIED = 0;
+                FOREGROUND = 1;
+                BACKGROUND = 2;
+                FOREGROUND_SERVICE = 3;
+            }
+
+            optional ProcessState process_state = 1;
+            optional int64 time_in_state_millis = 2;
+        }
+
+        repeated TimeInState time_in_state = 5;
     }
     repeated UidBatteryConsumer uid_battery_consumers = 5;
 
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 4d6ed80..3887dd7 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -268,6 +268,13 @@
 
     optional SettingProto enhanced_voice_privacy_enabled = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
+    message EvenDimmer {
+        optional SettingProto even_dimmer_activated = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto even_dimmer_min_nits = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+
+    optional EvenDimmer even_dimmer = 98;
+
     optional SettingProto font_weight_adjustment = 85 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
     message Gesture {
@@ -712,5 +719,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 98;
+    // Next tag = 99;
 }
diff --git a/core/proto/android/server/usagestatsservice_v2.proto b/core/proto/android/server/usagestatsservice_v2.proto
index d5cf60d..c242c9c 100644
--- a/core/proto/android/server/usagestatsservice_v2.proto
+++ b/core/proto/android/server/usagestatsservice_v2.proto
@@ -110,6 +110,7 @@
   optional int32 task_root_package_token = 11;
   optional int32 task_root_class_token = 12;
   optional int32 locus_id_token = 13;
+  optional ObfuscatedUserInteractionExtrasProto interaction_extras = 14;
 }
 
 /**
@@ -129,6 +130,7 @@
   optional string task_root_package = 11;
   optional string task_root_class = 12;
   optional string locus_id = 13 [(.android.privacy).dest = DEST_EXPLICIT];
+  optional bytes extras = 14;
 }
 
 /**
@@ -145,3 +147,11 @@
   // Stores the mappings for every package
   repeated PackagesMap packages_map = 2;
 }
+
+/**
+ * Store the relevant information from extra details for user interaction event.
+ */
+message ObfuscatedUserInteractionExtrasProto {
+  optional int32 category_token = 1;
+  optional int32 action_token = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4d208c6..0021640 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -7817,6 +7817,13 @@
     <permission android:name="android.permission.RESET_HOTWORD_TRAINING_DATA_EGRESS_COUNT"
                 android:protectionLevel="signature" />
 
+    <!-- @SystemApi Allows an app to track all preparations for a complete factory reset.
+     <p>Protection level: signature|privileged
+     @FlaggedApi("android.permission.flags.factory_reset_prep_permission_apis")
+     @hide -->
+    <permission android:name="android.permission.PREPARE_FACTORY_RESET"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Attribution for Geofencing service. -->
     <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
     <!-- Attribution for Country Detector. -->
diff --git a/core/res/OWNERS b/core/res/OWNERS
index f24c3f5..332ad2a 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -47,6 +47,10 @@
 # Wear
 per-file res/*-watch/* = file:/WEAR_OWNERS
 
+# Peformance
+per-file res/values/config.xml = file:/PERFORMANCE_OWNERS
+per-file res/values/symbols.xml = file:/PERFORMANCE_OWNERS
+
 # PowerProfile
 per-file res/xml/power_profile.xml = file:/BATTERY_STATS_OWNERS
 per-file res/xml/power_profile_test.xml = file:/BATTERY_STATS_OWNERS
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index f5b82892..625b1413 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Sleutelborduitleg is gestel op <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> … Tik om dit te verander."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fisieke sleutelborde is opgestel"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tik om sleutelborde te bekyk"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index fbef5011..1ec3ffd 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -2359,4 +2359,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"የቁልፍ ሰሌዳ አቀማመጥ ወደ <xliff:g id="LAYOUT_1">%1$s</xliff:g>፣ <xliff:g id="LAYOUT_2">%2$s</xliff:g>፣ <xliff:g id="LAYOUT_3">%3$s</xliff:g> ተቀናብሯል… ለመቀጠል መታ ያድርጉ።"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"የተዋቀሩ አካላዊ የቁልፍ ሰሌዳዎች"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"የቁልፍ ሰሌዳዎችን ለማየት መታ ያድርጉ"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"የግል"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"አባዛ"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"ሥራ"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"ሥራ 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"ሥራ 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"ሙከራ"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"የጋራ"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 9ca2d199..04fb300 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1694,7 +1694,7 @@
     <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="491875107583931974">"هل تريد مواصلة الاستماع بصوت عالٍ؟\n\nكان مستوى صوت سمّاعة الرأس مرتفعًا لمدة أطول مما يُنصَح به، وقد يضر هذا بسمعك."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"تم رصد صوت مرتفع\n\nكان مستوى صوت سمّاعة الرأس مرتفعًا لمدة أطول مما يُنصَح به، وقد يضر هذا بسمعك."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"تم رصد صوت مرتفع\n\nكان مستوى صوت سمّاعة الرأس أعلى من المستوى الذي يُنصَح به، ما قد يضرّ بسمعك."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"هل تريد استخدام اختصار \"سهولة الاستخدام\"؟"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"عند تفعيل الاختصار، يؤدي الضغط على زرّي التحكّم في مستوى الصوت معًا لمدة 3 ثوانٍ إلى تفعيل إحدى ميزات إمكانية الوصول."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"هل تريد تفعيل الاختصار لميزات إمكانية الوصول؟"</string>
@@ -2363,4 +2363,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"تم ضبط تنسيق لوحة المفاتيح على <xliff:g id="LAYOUT_1">%1$s</xliff:g> و<xliff:g id="LAYOUT_2">%2$s</xliff:g> و<xliff:g id="LAYOUT_3">%3$s</xliff:g>… انقر لتغييره."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"تم إعداد لوحات المفاتيح الخارجية"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"انقر لعرض لوحات المفاتيح."</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 7473f49..826844f 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"কীব’ৰ্ডৰ লে’আউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> হিচাপে ছেট কৰা হৈছে… সলনি কৰিবলৈ টিপক।"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ভৌতিক কীব’ৰ্ড কনফিগাৰ কৰা হৈছে"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"কীব’ৰ্ড চাবলৈ টিপক"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index b1002e2..66a5670 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klaviatura düzəni <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> kimi ayarlanıb… Dəyişmək üçün toxunun."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fiziki klaviaturalar konfiqurasiya edilib"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klaviaturalara baxmaq üçün toxunun"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 196818a..b6121ed 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Raspored tastature je podešen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Dodirnite da biste promenili."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizičke tastature su konfigurisane"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Dodirnite da biste videli tastature"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index d7efa8a..3c01f1b 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -2361,4 +2361,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Раскладка клавіятуры наладжана для наступных моў: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Націсніце, каб змяніць."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Фізічныя клавіятуры наладжаны"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Націсніце, каб праглядзець клавіятуры"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b9e1db4..3b1ff9e 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"За клавиатурната подредба са зададени <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> и <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Докоснете за промяна."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физическите клавиатури са конфигурирани"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Докоснете за преглед на клавиатурите"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 669c99e..58dd7c2 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1710,10 +1710,8 @@
     <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>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"আনইনস্টল করুন"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"কোনও অ্যাপ অনুমতির অনুরোধ আড়াল করছে তাই আপনার উত্তর যাচাই করা যাবে না।"</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"কোনও ফিচার ব্যবহার করা শুরু করতে, সেটিতে ট্যাপ করুন:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"অ্যাক্সেসিবিলিটি বোতামের সাহায্যে আপনি যেসব ফিচার ব্যবহার করতে চান সেগুলি বেছে নিন"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"ভলিউম কী শর্টকাটের সাহায্যে আপনি যেসব ফিচার ব্যবহার করতে চান সেগুলি বেছে নিন"</string>
@@ -2361,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>-এ সেট করা আছে… পালটাতে ট্যাপ করুন।"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ফিজিক্যাল কীবোর্ড কনফিগার করা হয়েছে"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"কীবোর্ড দেখতে ট্যাপ করুন"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 9dcd869..aa66e02 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Raspored tastature je postavljen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Dodirnite da promijenite."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizičke tastature su konfigurirane"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Dodirnite da pregledate tastature"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 66e76ac..be8654d 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Disseny del teclat definit en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toca per canviar-ho."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclats físic configurats"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toca per veure els teclats"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 1acb8d4..ed2f93a 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1712,10 +1712,8 @@
     <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Služba může sledovat vaše interakce s aplikací nebo hardwarovým senzorem a komunikovat s aplikacemi namísto vás."</string>
     <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Povolit"</string>
     <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Zakázat"</string>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Odinstalovat"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Žádost o oprávnění skrývá nějaká aplikace, proto vaši odpověď nelze ověřit."</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Chcete-li některou funkci začít používat, klepněte na ni:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Vyberte funkce, které budete používat s tlačítkem přístupnosti"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Vyberte funkce, které budete používat se zkratkou tlačítka hlasitosti"</string>
@@ -2363,4 +2361,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Rozložení klávesnice je nastaveno na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Klepnutím jej změníte."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fyzické klávesnice byly nakonfigurovány"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klepnutím zobrazíte klávesnice"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Soukromé"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Klonovat"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Práce"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Práce 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Práce 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Komunální"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index bedd941..35def43 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tastaturlayoutet er angivet som <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tryk for at ændre dette."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fysiske tastaturer er konfigureret"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tryk for at se tastaturer"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 2867da9..50501c6 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1711,7 +1711,7 @@
     <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Zulassen"</string>
     <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Ablehnen"</string>
     <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Deinstallieren"</string>
-    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Eine App verdeckt die Berechtigungsanfrage und deine Antwort kann deshalb nicht überprüft werden."</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Die Berechtigungsanfrage wird durch eine andere App verdeckt. Daher kann deine Antwort nicht geprüft werden."</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Zum Auswählen der gewünschten Funktion tippen:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Funktionen auswählen, die du mit der Schaltfläche \"Bedienungshilfen\" verwenden möchtest"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Funktionen für Verknüpfung mit Lautstärketaste auswählen"</string>
@@ -2359,4 +2359,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tastaturlayout festgelegt auf <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Zum Ändern tippen."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Physische Tastaturen konfiguriert"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Zum Ansehen der Tastaturen tippen"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Privat"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Klon"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Geschäftlich"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Geschäftlich 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Geschäftlich 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Gemeinsam genutzt"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b6b4da2..dc73c21 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -2359,4 +2359,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Η διάταξη πληκτρολογίου ορίστηκε σε <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Πατήστε για αλλαγή."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Τα φυσικά πληκτρολόγια διαμορφώθηκαν"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Πατήστε για να δείτε πληκτρολόγια"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Ιδιωτικό"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Κλώνος"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Εργασία"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Εργασία 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Εργασία 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Δοκιμή"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Κοινόχρηστο"</string>
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 94ae6cb..179bdb4 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tap to change."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Physical keyboards configured"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tap to view keyboards"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index ec41583..5fb0e5a 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -2359,4 +2359,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tap to change."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Physical keyboards configured"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tap to view keyboards"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Private"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Clone"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Work"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Work 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Work 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 2c15524..2a4f88e 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tap to change."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Physical keyboards configured"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tap to view keyboards"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index ff91080..0f08d2f 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tap to change."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Physical keyboards configured"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tap to view keyboards"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index b1dd1f1..0bdd2974 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -2359,4 +2359,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎Keyboard layout set to ‎‏‎‎‏‏‎<xliff:g id="LAYOUT_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="LAYOUT_2">%2$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="LAYOUT_3">%3$s</xliff:g>‎‏‎‎‏‏‏‎… Tap to change.‎‏‎‎‏‎"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎Physical keyboards configured‎‏‎‎‏‎"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎Tap to view keyboards‎‏‎‎‏‎"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎Private‎‏‎‎‏‎"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎Clone‎‏‎‎‏‎"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‎Work‎‏‎‎‏‎"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎Work 2‎‏‎‎‏‎"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎Work 3‎‏‎‎‏‎"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‏‎Test‎‏‎‎‏‎"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎Communal‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 39a479e..bef851d 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -2360,4 +2360,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Presiona para ver los teclados"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Privado"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Clonar"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Trabajo"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Trabajo 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Trabajo 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Probar"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Compartido"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 30ed624..29f0f8f 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1691,7 +1691,7 @@
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Quitar"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar sonidos fuertes durante mucho tiempo puede dañar los oídos."</string>
     <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"¿Seguir escuchando a un volumen alto?\n\nEl volumen de los auriculares ha estado alto durante más tiempo del recomendado, lo que puede dañar tu audición."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Sonido alto detectado\n\nEl volumen de los auriculares está más alto de lo recomendado, lo que puede dañar tu audición."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Volumen alto detectado\n\nEl volumen de los auriculares está más alto de lo recomendado, lo que puede dañar tu audición."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Utilizar acceso directo de accesibilidad?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Si el acceso directo está activado, pulsa los dos botones de volumen durante 3 segundos para iniciar una función de accesibilidad."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"¿Quieres activar el acceso directo a las funciones de accesibilidad?"</string>
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toca para cambiarlo."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toca para ver los teclados"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index c4ea351..4a42b00 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klaviatuuripaigutuseks on määratud <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> … puudutage muutmiseks."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Füüsilised klaviatuurid on seadistatud"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Puudutage klaviatuuride vaatamiseks"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 26362d5..3b76e88 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ezarri da <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> eta <xliff:g id="LAYOUT_3">%3$s</xliff:g> gisa teklatuaren diseinua… Diseinu hori aldatzeko, sakatu hau."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Konfiguratu dira teklatu fisikoak"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Sakatu hau teklatuak ikusteko"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index c96c580..71dbc43 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1711,7 +1711,7 @@
     <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"اجازه دادن"</string>
     <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"مجاز نبودن"</string>
     <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"حذف نصب"</string>
-    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"برنامه‌ای درخواست اجازه را می‌پوشاند و بنابراین نمی‌توان پاسخ شما را تأیید کرد."</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"پاسخ شما تأیید نشد زیرا یک برنامه درخواست اجازه را مسدود کرده است."</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"برای استفاده از ویژگی، روی آن ضربه بزنید:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"انتخاب ویژگی‌های موردنظر برای استفاده با دکمه دسترس‌پذیری"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"انتخاب ویژگی‌های موردنظر برای استفاده با میان‌بر کلید میزان صدا"</string>
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"جانمایی صفحه‌کلید چنین تنظیم شد: <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g>… برای تغییر ضربه بزنید"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"صفحه‌کلیدهای فیزیکی پیکربندی شدند"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"برای مشاهده صفحه‌کلیدها ضربه بزنید"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index c203786..c69bafe 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Näppäimistöasetteluksi valittu <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Muuta asetuksia napauttamalla."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fyysiset näppäimistöt määritetty"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Katso näppäimistöt napauttamalla"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index f06d20f..6c88f45 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Disposition du clavier définie à <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Touchez pour modifier."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Claviers physiques configurés"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Touchez pour afficher les claviers"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index b69db32..e0345dd 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -2360,4 +2360,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Disposition du clavier définie sur <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Appuyez pour la modifier."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Claviers physiques configurés"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Appuyez pour voir les claviers"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Privé"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Clone"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Professionnel"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Professionnel 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Professionnel 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Commun"</string>
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index f26dbfb..c1e2bbf 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"O deseño do teclado estableceuse en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toca para cambialo."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Configuráronse varios teclados físicos"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toca para ver os teclados"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index d64e33a..da75282 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"કીબોર્ડનું લેઆઉટ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> પર સેટ કરવામાં આવ્યું છે… બદલવા માટે ટૅપ કરો."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ભૌતિક કીબોર્ડની ગોઠવણી કરવામાં આવી છે"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"કીબોર્ડ જોવા માટે ટૅપ કરો"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 61db784..d448b51 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1951,7 +1951,7 @@
     <string name="language_selection_title" msgid="52674936078683285">"भाषा जोड़ें"</string>
     <string name="country_selection_title" msgid="5221495687299014379">"क्षेत्र प्राथमिकता"</string>
     <string name="search_language_hint" msgid="7004225294308793583">"भाषा का नाम लिखें"</string>
-    <string name="language_picker_section_suggested" msgid="6556199184638990447">"दिए गए सुझाव"</string>
+    <string name="language_picker_section_suggested" msgid="6556199184638990447">"सुझाई गई भाषाएं"</string>
     <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"सुझाए गए देश/इलाके"</string>
     <string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"सुझाई गई भाषाएं"</string>
     <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"सुझाए गए इलाके"</string>
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"कीबोर्ड का लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… पर सेट कर दिया गया है. इसे बदलने के लिए टैप करें."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"फ़िज़िकल कीबोर्ड कॉन्फ़िगर किए गए"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"कीबोर्ड देखने के लिए टैप करें"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 4b9b7bc..5ee1527 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Raspored tipkovnice postavljen je na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Dodirnite da biste ga promijenili."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizičke su tipkovnice konfigurirane"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Dodirnite da bi se prikazale tipkovnice"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 5827300..2c4c77e 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"A billentyűzetkiosztás a következőkre van beállítva: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… A módosításhoz koppintson."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizikai billentyűzetek beállítva"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Koppintson a billentyűzetek megtekintéséhez"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 9e313a6..482e075 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1710,10 +1710,8 @@
     <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>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Ապատեղադրել"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Հավելվածը թաքցնում է թույլտվության հայտը, ուստի ձեր պատասխանը հնարավոր չէ ստուգել։"</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Ընտրեք՝ որ գործառույթն օգտագործել"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Ընտրեք գործառույթները, որոնք կբացվեն «Հատուկ գործառույթներ» կոճակի միջոցով"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Ընտրեք գործառույթները, որոնք կբացվեն ձայնի կարգավորման կոճակի միջոցով"</string>
@@ -2361,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ստեղնաշարի համար կարգավորված են <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> դասավորությունները։ Հպեք փոխելու համար։"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Ֆիզիկական ստեղնաշարերը կարգավորված են"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Հպեք՝ ստեղնաշարերը դիտելու համար"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index b4044aa..f18d834 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1247,7 +1247,7 @@
     <string name="unsupported_display_size_show" msgid="980129850974919375">"Selalu tampilkan"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> dibuat untuk versi OS Android yang tidak kompatibel dan mungkin berperilaku tak terduga. Versi aplikasi yang diupdate mungkin tersedia."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Selalu tampilkan"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Periksa apakah ada update"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Periksa update"</string>
     <string name="smv_application" msgid="3775183542777792638">"Apl <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) telah melanggar kebijakan StrictMode yang diberlakukannya sendiri."</string>
     <string name="smv_process" msgid="1398801497130695446">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> telah melanggar kebijakan StrictMode yang diberlakukan secara otomatis."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Mengupdate ponsel…"</string>
@@ -1989,7 +1989,7 @@
     <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Setelan ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g>. Coba di tablet."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Setelan ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g>. Coba di ponsel."</string>
     <string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Aplikasi ini dibuat untuk versi lama Android. Aplikasi mungkin tidak berfungsi dengan baik dan tidak menyertakan perlindungan privasi dan keamanan terbaru. Periksa update, atau hubungi developer aplikasi."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Periksa apakah ada update"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Periksa update"</string>
     <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplikasi ini tidak kompatibel dengan versi terbaru Android. Periksa update atau hubungi developer aplikasi."</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Ada pesan baru"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"Buka aplikasi SMS untuk melihat"</string>
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tata letak keyboard disetel ke <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Ketuk untuk mengubah."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Keyboard fisik telah dikonfigurasi"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Ketuk untuk melihat keyboard"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 062b4bc..30d4231 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -2359,4 +2359,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Lyklaskipan er stillt á <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Ýttu til að breyta."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Vélbúnaðarlyklaborð eru stillt"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Ýttu til að sjá lyklaborð"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Lokað"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Afrit"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Vinna"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Vinna 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Vinna 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Prófun"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Sameiginlegt"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 2e024cb..076c5a3 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Layout tastiera impostato su <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tocca per cambiare l\'impostazione."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Tastiere fisiche configurate"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tocca per visualizzare le tastiere"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index e5e85c4..e8e3847 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -2360,4 +2360,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… אפשר להקיש כדי לשנות את ההגדרה הזו."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"הוגדרו מקלדות פיזיות"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"יש להקיש כדי להציג את המקלדות"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"פרטי"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"שכפול"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"פרופיל עבודה"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"פרופיל עבודה 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"פרופיל עבודה 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"בדיקה"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"שיתופי"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 6e86b57..8931518 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>などに設定されています。タップで変更できます。"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"物理キーボードの設定完了"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"タップするとキーボードを表示できます"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 34f56546..1ecdf74 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -2359,4 +2359,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"დაყენდა კლავიატურის განლაგება: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… შეეხეთ შესაცვლელად."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ფიზიკური კლავიატურები კონფიგურირებულია"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"შეეხეთ კლავიატურების სანახავად"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"პირადი"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"კლონი"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"სამსახური"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"სამსახური 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"სამსახური 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"სატესტო"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"საერთო"</string>
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 839f3f9..3e33115 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Пернетақта схемасы \"<xliff:g id="LAYOUT_1">%1$s</xliff:g>\", \"<xliff:g id="LAYOUT_2">%2$s</xliff:g>\", \"<xliff:g id="LAYOUT_3">%3$s</xliff:g>\" деп орнатылды… Өзгерту үшін түртіңіз."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физикалық пернетақталар конфигурацияланды"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Пернетақталарды көру үшін түртіңіз."</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 9a29150..0bcf992 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… សូមចុចដើម្បីប្ដូរ។"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"បានកំណត់រចនាសម្ព័ន្ធ​ក្ដារចុចរូបវន្ត"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ចុចដើម្បីមើលក្ដារចុច"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 9f1700d..a69601a 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಅನ್ನು <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ಗೆ ಸೆಟ್ ಮಾಡಲಾಗಿದೆ… ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 907e802..77d45c7 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>로 설정됩니다. 변경하려면 탭하세요."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"실제 키보드에 구성됨"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"키보드를 보려면 탭하세요."</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 5efcfc4b..ee7b407 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Баскычтопко төмөнкү калып коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Өзгөртүү үчүн басыңыз."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физикалык баскычтоптор конфигурацияланды"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Баскычтопторду көрүү үчүн басыңыз"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index d0f698d..d9698e3 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ຕັ້ງໂຄງຮ່າງແປ້ນພິມເປັນ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… ແຕະເພື່ອປ່ຽນແປງ."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ຕັ້ງຄ່າແປ້ນພິມແທ້ແລ້ວ"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ແຕະເພື່ອເບິ່ງແປ້ນພິມ"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 6b6bc50..2a2a088 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -2361,4 +2361,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Palieskite, kad pakeistumėte."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Sukonfigūruotos fizinės klaviatūros"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Palieskite, kad peržiūrėtumėte klaviatūras"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 931e681..8c7c206 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ir iestatīti šādi tastatūras izkārtojumi: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Lai to mainītu, pieskarieties."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fiziskās tastatūras ir konfigurētas"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Lai skatītu tastatūras, pieskarieties"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 420adfe..4d2f72e 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1710,10 +1710,8 @@
     <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>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Деинсталирај"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Апликација го прикрива барањето за дозвола, па вашиот одговор не може да се потврди."</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Допрете на функција за да почнете да ја користите:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Изберете ги функциите што ќе ги користите со копчето за пристапност"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Изберете ги функциите што ќе ги користите со кратенката за копчето за јачина на звук"</string>
@@ -2361,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Распоредот на тастатурата е поставен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Допрете за да промените."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физичките тастатури се конфигурирани"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Допрете за да ги видите тастатурите"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 466dab6..be40575 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"കീബോർഡ് ലേഔട്ട് ആയി ഇനിപ്പറയുന്നവ സജ്ജീകരിച്ചു: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"യഥാർത്ഥ കീബോർഡുകൾ കോൺഫിഗർ ചെയ്‌തു"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"കീബോർഡുകൾ കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 3cb9cb2..c215b88 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Гарын бүдүүвчийг <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> болгож тохируулсан… Өөрчлөхийн тулд товшино уу."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Биет гарыг тохируулсан"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Гарыг харахын тулд товшино уу"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index b20754b..03fcc17 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"कीबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> वर सेट करा… बदलण्यासाठी टॅप करा."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"वास्तविक कीबोर्ड कॉंफिगर केला"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"कीबोर्ड पाहण्यासाठी टॅप करा"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 6b1742c..84b79a8 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Reka letak papan kekunci ditetapkan kepada <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Ketik untuk menukar reka letak."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Papan kekunci fizikal dikonfigurasikan"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Ketik untuk melihat papan kekunci"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index edbe31f..01906b9 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1710,10 +1710,8 @@
     <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>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"ပရိုဂရမ်ကို ဖယ်ရှားရန်"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"အက်ပ်တစ်ခုသည် ခွင့်ပြုချက်တောင်းဆိုမှုကို ပိတ်နေသဖြင့် သင့်တုံ့ပြန်မှုကို စိစစ်၍မရပါ။"</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ဝန်ဆောင်မှုကို စတင်အသုံးပြုရန် တို့ပါ−"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"အများသုံးနိုင်မှု ခလုတ်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုများကို ရွေးပါ"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"အသံခလုတ် ဖြတ်လမ်းလင့်ခ်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုများကို ရွေးပါ"</string>
@@ -2361,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ကီးဘုတ်အပြင်အဆင်ကို <xliff:g id="LAYOUT_1">%1$s</xliff:g>၊ <xliff:g id="LAYOUT_2">%2$s</xliff:g>၊ <xliff:g id="LAYOUT_3">%3$s</xliff:g> သို့ သတ်မှတ်လိုက်သည်… ပြောင်းရန် တို့ပါ။"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ပကတိကီးဘုတ်များကို စီစဉ်သတ်မှတ်ထားသည်"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ကီးဘုတ်များကြည့်ရန် တို့ပါ"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 0732e67..d8e3b40 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tastaturoppsettet er satt til <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> … Trykk for å endre det."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"De fysiske tastaturene er konfigurert"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Trykk for å se tastaturene"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 7ac4c14..126f612 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"किबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> भाषामा सेट गरिएको छ… बदल्न ट्याप गर्नुहोस्।"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"भौतिक किबोर्डहरू कन्फिगर गरिएका छन्"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"किबोर्डहरू हेर्न ट्याप गर्नुहोस्"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 8f08689..bc18797 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Toetsenbordindeling ingesteld op <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tik om te wijzigen."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fysieke toetsenborden zijn ingesteld"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tik om toetsenborden te bekijken"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index e91e005..7f66887 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"କୀବୋର୍ଡ ଲେଆଉଟକୁ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>ରେ ସେଟ କରାଯାଇଛି… ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ଫିଜିକାଲ କୀବୋର୍ଡଗୁଡ଼ିକୁ କନଫିଗର କରାଯାଇଛି"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"କୀବୋର୍ଡଗୁଡ଼ିକୁ ଦେଖିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 29a0094..0396149 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> \'ਤੇ ਸੈੱਟ ਹੈ… ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡਾਂ ਦਾ ਸੰਰੂਪਣ ਕੀਤਾ ਗਿਆ"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ਕੀ-ਬੋਰਡਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 208810d..66d5570 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -2361,4 +2361,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ustawiono układ klawiatury <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Kliknij, aby to zmienić."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Skonfigurowano klawiatury fizyczne"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Kliknij, aby wyświetlić klawiatury"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index c509ed5..e32c738 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toque para mudar."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toque para conferir os teclados"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index daa2504..15e08ba 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -2360,4 +2360,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Esquema do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toque para o alterar."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toque para ver os teclados"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Privado"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Clone"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Trabalho"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Trabalho 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Trabalho 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Comum"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index c509ed5..e32c738 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toque para mudar."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toque para conferir os teclados"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 562fcc9..7b41180 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -2360,4 +2360,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tastatura este setată la <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Atinge pentru a schimba."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Tastaturile fizice au fost configurate"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Atinge pentru a vedea tastaturile"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Privat"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Clonează"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Serviciu"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Serviciu 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Serviciu 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Comun"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 84a4776..2f16db3 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -2361,4 +2361,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Настроены раскладки клавиатуры для яз.: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> и др. Нажмите, чтобы изменить."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физические клавиатуры настроены"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Нажмите, чтобы посмотреть подключенные клавиатуры."</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index c54e768..ac86d7b 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1710,10 +1710,8 @@
     <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>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"අස්ථාපනය කරන්න"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"යෙදුමක් අවසර ඉල්ලීම අඳුරු කරන බැවින්, ඔබේ ප්‍රතිචාරය සත්‍යාපනය කළ නොහැක."</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"එය භාවිත කිරීම ආරම්භ කිරීමට විශේෂාංගයක් තට්ටු කරන්න:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"ප්‍රවේශ්‍යතා බොත්තම සමග භාවිත කිරීමට විශේෂාංග තෝරා ගන්න"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"හඬ පරිමා යතුරු කෙටිමග සමග භාවිත කිරීමට විශේෂාංග තෝරා ගන්න"</string>
@@ -2361,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"යතුරු පුවරුව <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ලෙස සකසා ඇත… වෙනස් කිරීමට තට්ටු කරන්න."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"භෞතික යතුරු පුවරුව වින්‍යාස කෙරිණි"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"යතුරු පුවරු බැලීමට තට්ටු කරන්න"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f2153231..d1d7897 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -2361,4 +2361,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Rozloženie klávesnice je nastavené na jazyky <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> a <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Môžete to zmeniť klepnutím."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fyzické klávesnice sú nakonfigurované"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klávesnice si zobrazíte klepnutím"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e8ba9dd..19866f3 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -2361,4 +2361,11 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Razporeditev tipkovnice je nastavljena na »<xliff:g id="LAYOUT_1">%1$s</xliff:g>«, »<xliff:g id="LAYOUT_2">%2$s</xliff:g>«, »<xliff:g id="LAYOUT_3">%3$s</xliff:g>« … Za spremembo se dotaknite."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizične tipkovnice so konfigurirane"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Dotaknite se za ogled tipkovnic"</string>
+    <string name="profile_label_private" msgid="6463418670715290696">"Zasebno"</string>
+    <string name="profile_label_clone" msgid="769106052210954285">"Klon"</string>
+    <string name="profile_label_work" msgid="3495359133038584618">"Delo"</string>
+    <string name="profile_label_work_2" msgid="4691533661598632135">"Delo 2"</string>
+    <string name="profile_label_work_3" msgid="4834572253956798917">"Delo 3"</string>
+    <string name="profile_label_test" msgid="9168641926186071947">"Preizkus"</string>
+    <string name="profile_label_communal" msgid="8743921499944800427">"Skupno"</string>
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 1d28440..2cd76fd 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1710,10 +1710,8 @@
     <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Mund të monitorojë ndërveprimet me një aplikacion ose një sensor hardueri dhe të ndërveprojë me aplikacionet në emrin tënd."</string>
     <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Lejo"</string>
     <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuzo"</string>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Çinstalo"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Një aplikacion po fsheh kërkesën për leje, prandaj përgjigja jote nuk mund të verifikohet."</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Trokit te një veçori për të filluar ta përdorësh atë:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Zgjidh veçoritë që do të përdorësh me butonin e qasshmërisë"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Zgjidh veçoritë që do të përdorësh me shkurtoren e tastit të volumit"</string>
@@ -2361,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Struktura e tastierës u caktua në: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Trokit për ta ndryshuar."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Tastierat fizike u konfiguruan"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Trokit për të parë tastierat"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a6c994e..9e77bf6 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -2360,4 +2360,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Распоред тастатуре је подешен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Додирните да бисте променили."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физичке тастатуре су конфигурисане"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Додирните да бисте видели тастатуре"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 15b7029..ab5bfca 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tangentbordslayouten är inställd på <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> … Tryck om du vill ändra."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fysiska tangentbord har konfigurerats"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tryck för att visa tangentbord"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index aef89ee..61c0b17 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Muundo wa kibodi umewekwa kuwa <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Gusa ili ubadilishe."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Mipangilio ya kibodi halisi imewekwa"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Gusa ili uangalie kibodi"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index f81e935..edf6c2d 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"கீபோர்டு தளவமைப்பு <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… ஆகிய மொழிகளில் அமைக்கப்பட்டது, மாற்ற தட்டவும்."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"கீபோர்டுகள் உள்ளமைக்கப்பட்டன"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"கீபோர்டுகளைப் பார்க்க தட்டவும்"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 671aefb..d862e2f 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"కీబోర్డ్ లేఅవుట్ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>‌కు సెట్ చేయబడింది… మార్చడానికి ట్యాప్ చేయండి."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ఫిజికల్ కీబోర్డ్‌లు కాన్ఫిగర్ చేయబడ్డాయి"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"కీబోర్డ్‌లను చూడటానికి ట్యాప్ చేయండి"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 2d5ddf4..bda7e8a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ตั้งค่ารูปแบบแป้นพิมพ์เป็นภาษา<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… แตะเพื่อเปลี่ยน"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"กำหนดค่าแป้นพิมพ์จริงแล้ว"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"แตะเพื่อดูแป้นพิมพ์"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 47c4b5e..53201ea 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Naitakda ang layout ng keyboard sa <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… I-tap para baguhin."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Na-configure ang mga pisikal na keyboard"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"I-tap para tingnan ang mga keyboard"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 03536fe..ee1168f 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klavye düzeni <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> olarak ayarlandı… Değiştirmek için dokunun."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fiziksel klavyeler yapılandırıldı"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klavyeleri görüntülemek için dokunun"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 24cbc3f..b1adf52 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1712,10 +1712,8 @@
     <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>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Видалити"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Інший додаток перекриває запит на доступ, тому вашу відповідь не вдається підтвердити."</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Натисніть функцію, щоб почати використовувати її:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Виберіть функції для кнопки спеціальних можливостей"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Виберіть функції для комбінації з клавішами гучності"</string>
@@ -2363,4 +2361,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Вибрано такі розкладки клавіатури: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Натисніть, щоб змінити."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Фізичні клавіатури налаштовано"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Натисніть, щоб переглянути клавіатури"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 728b5ee..92fd266 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1710,10 +1710,8 @@
     <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>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"اَن انسٹال کریں"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"ایپ اجازت کی درخواست کو مبہم کر رہی ہے لہذا آپ کے جواب کی تصدیق نہیں کی جا سکتی۔"</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ایک خصوصیت کا استعمال شروع کرنے کیلئے اسے تھپتھپائیں:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"ایکسیسبیلٹی بٹن کے ساتھ استعمال کرنے کیلئے خصوصیات منتخب کریں"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"والیوم کلید کے شارٹ کٹ کے ساتھ استعمال کرنے کیلئے خصوصیات منتخب کریں"</string>
@@ -2361,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> پر سیٹ ہے… تبدیل کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"فزیکل کی بورڈز کنفیگر کئے گئے"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"کی بورڈز دیکھنے کے لیے تھپتھپائیں"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 1e1807e..79d9f9d 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1710,10 +1710,8 @@
     <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ilova yoki qurilma sensori bilan munosabatlaringizni kuzatishi hamda sizning nomingizdan ilovalar bilan ishlashi mumkin."</string>
     <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Ruxsat"</string>
     <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Rad etish"</string>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Oʻchirib tashlash"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Ilova ruxsat olish talabini berkitmoqda, shu sababdan javobingizni tasdiqlash imkonsiz."</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Kerakli funksiyani tanlang"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Qulayliklar tugmasi bilan foydalanish uchun funksiyalarni tanlang"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Tovush tugmasi bilan ishga tushiriladigan funksiyalarni tanlang"</string>
@@ -2361,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klaviatura terilmasi bunga sozlandi: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Oʻzgartirish uchun ustiga bosing."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Tashqi klaviaturalar sozlandi"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klaviaturalarni ochish uchun ustiga bosing"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 94ebd97..2ddf49f 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Đã thiết lập bố cục bàn phím thành <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Hãy nhấn để thay đổi."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Đã định cấu hình bàn phím vật lý"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Nhấn để xem bàn phím"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 108f507..f3b6a39 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"键盘布局已设为<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>…点按即可更改。"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"已配置物理键盘"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"点按即可查看键盘"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index a37f9a8..bf72080 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"鍵盤版面配置已設定為<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>…輕按即可變更。"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"已設定實體鍵盤"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"輕按即可查看鍵盤"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5dced74..1158cfd 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1710,10 +1710,8 @@
     <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>
-    <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) -->
-    <skip />
-    <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) -->
-    <skip />
+    <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"解除安裝"</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"應用程式遮擋了權限要求,因此系統無法驗證你的回覆。"</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"輕觸即可開始使用所需功能:"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"選擇要搭配無障礙工具按鈕使用的功能"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"選擇要搭配音量快速鍵使用的功能"</string>
@@ -2361,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"鍵盤配置已設為<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>…輕觸即可變更。"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"已設定實體鍵盤"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"輕觸即可查看鍵盤"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index aaa1787..db7c253 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -2359,4 +2359,18 @@
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Uhlaka lwekhibhodi lusethelwe ku-<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Thepha ukuze ushintshe."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Amakhibhodi aphathekayo amisiwe"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Thepha ukuze ubuke amakhibhodi"</string>
+    <!-- no translation found for profile_label_private (6463418670715290696) -->
+    <skip />
+    <!-- no translation found for profile_label_clone (769106052210954285) -->
+    <skip />
+    <!-- no translation found for profile_label_work (3495359133038584618) -->
+    <skip />
+    <!-- no translation found for profile_label_work_2 (4691533661598632135) -->
+    <skip />
+    <!-- no translation found for profile_label_work_3 (4834572253956798917) -->
+    <skip />
+    <!-- no translation found for profile_label_test (9168641926186071947) -->
+    <skip />
+    <!-- no translation found for profile_label_communal (8743921499944800427) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6cd6eb4..ba1f392 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1522,6 +1522,10 @@
     config_screenBrightnessSettingDefaultFloat instead -->
     <integer name="config_screenBrightnessSettingDefault">102</integer>
 
+    <!-- Maximum screen brightness setting when screen brightness capped in Wear Bedtime mode.
+    The value must be in the range [0, 255]. -->
+    <integer name="config_screenBrightnessCapForWearBedtimeMode">20</integer>
+
     <!-- Minimum screen brightness setting allowed by power manager.
          -2 is invalid so setting will resort to int value specified above.
          Set this to 0.0 to allow screen to go to minimal brightness.
@@ -2242,6 +2246,9 @@
     <!-- The default volume for the ring stream -->
     <integer name="config_audio_ring_vol_default">5</integer>
 
+    <!-- The default min volume for the alarm stream -->
+    <integer name="config_audio_alarm_min_vol">1</integer>
+
     <!-- 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>
@@ -4336,6 +4343,9 @@
     <!-- True if assistant app should be pinned via Pinner Service -->
     <bool name="config_pinnerAssistantApp">false</bool>
 
+    <!-- Bytes that the PinnerService will pin for WebView -->
+    <integer name="config_pinnerWebviewPinBytes">0</integer>
+
     <!-- Number of days preloaded file cache should be preserved on a device before it can be
          deleted -->
     <integer name="config_keepPreloadsMinDays">7</integer>
@@ -4986,6 +4996,11 @@
     <!-- Component name for the default module metadata provider on this device -->
     <string name="config_defaultModuleMetadataProvider" translatable="false">com.android.modulemetadata</string>
 
+    <!-- Packages that contain a security state.
+         {@link SecurityStateManager#getGlobalSecurityState} will read and report the state/version
+          of these packages. -->
+    <string-array name="config_securityStatePackages" translatable="false" />
+
     <!-- Package name for the default Health Connect app.
          OEMs can set this with their own health app package name to define a default app with high
          priority for the app to store the health data. If set the app always has priority of 1
@@ -6818,6 +6833,9 @@
      window that does not wrap content). -->
     <bool name="config_allowFloatingWindowsFillScreen">false</bool>
 
+    <!-- Whether to enable left-right split in portrait on this device -->
+    <bool name="config_leftRightSplitInPortrait">false</bool>
+
     <!-- Whether scroll haptic feedback is enabled for rotary encoder scrolls on
          {@link MotionEvent#AXIS_SCROLL} generated by {@link InputDevice#SOURCE_ROTARY_ENCODER}
          devices. -->
diff --git a/core/res/res/values/config_device_idle.xml b/core/res/res/values/config_device_idle.xml
index bc9ca3d..7a707c0 100644
--- a/core/res/res/values/config_device_idle.xml
+++ b/core/res/res/values/config_device_idle.xml
@@ -28,7 +28,7 @@
     <integer name="device_idle_flex_time_short_ms">60000</integer>
 
     <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT -->
-    <integer name="device_idle_light_after_inactive_to_ms">240000</integer>
+    <integer name="device_idle_light_after_inactive_to_ms">60000</integer>
 
     <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_TIMEOUT -->
     <integer name="device_idle_light_idle_to_ms">300000</integer>
@@ -43,7 +43,7 @@
     <item name="device_idle_light_idle_factor" format="float" type="integer">2.0</item>
 
     <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_INCREASE_LINEARLY -->
-    <bool name="device_idle_light_idle_increase_linearly">false</bool>
+    <bool name="device_idle_light_idle_increase_linearly">true</bool>
 
     <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS -->
     <integer name="device_idle_light_idle_linear_increase_factor_ms">300000</integer>
@@ -52,7 +52,7 @@
     <integer name="device_idle_light_idle_flex_linear_increase_factor_ms">60000</integer>
 
     <!-- Default for DeviceIdleController.Constants.LIGHT_MAX_IDLE_TIMEOUT -->
-    <integer name="device_idle_light_max_idle_to_ms">900000</integer>
+    <integer name="device_idle_light_max_idle_to_ms">1800000</integer>
 
     <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET -->
     <integer name="device_idle_light_idle_maintenance_min_budget_ms">60000</integer>
@@ -67,13 +67,13 @@
     <integer name="device_idle_min_deep_maintenance_time_ms">30000</integer>
 
     <!-- Default for DeviceIdleController.Constants.INACTIVE_TIMEOUT -->
-    <integer name="device_idle_inactive_to_ms">1800000</integer>
+    <integer name="device_idle_inactive_to_ms">60000</integer>
 
     <!-- Default for DeviceIdleController.Constants.SENSING_TIMEOUT -->
-    <integer name="device_idle_sensing_to_ms">240000</integer>
+    <integer name="device_idle_sensing_to_ms">30000</integer>
 
     <!-- Default for DeviceIdleController.Constants.LOCATING_TIMEOUT -->
-    <integer name="device_idle_locating_to_ms">30000</integer>
+    <integer name="device_idle_locating_to_ms">15000</integer>
 
     <!-- Default for DeviceIdleController.Constants.LOCATION_ACCURACY -->
     <item name="device_idle_location_accuracy" format="float" type="integer">20.0</item>
@@ -85,7 +85,7 @@
     <integer name="device_idle_motion_inactive_to_flex_ms">60000</integer>
 
     <!-- Default for DeviceIdleController.Constants.IDLE_AFTER_INACTIVE_TIMEOUT -->
-    <integer name="device_idle_idle_after_inactive_to_ms">1800000</integer>
+    <integer name="device_idle_idle_after_inactive_to_ms">60000</integer>
 
     <!-- Default for DeviceIdleController.Constants.IDLE_PENDING_TIMEOUT -->
     <integer name="device_idle_idle_pending_to_ms">300000</integer>
@@ -100,7 +100,7 @@
     <integer name="device_idle_quick_doze_delay_to_ms">60000</integer>
 
     <!-- Default for DeviceIdleController.Constants.IDLE_TIMEOUT -->
-    <integer name="device_idle_idle_to_ms">3600000</integer>
+    <integer name="device_idle_idle_to_ms">900000</integer>
 
     <!-- Default for DeviceIdleController.Constants.MAX_IDLE_TIMEOUT -->
     <integer name="device_idle_max_idle_to_ms">21600000</integer>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 38f1f67..7787c5d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -287,6 +287,7 @@
   <java-symbol type="integer" name="config_audio_notif_vol_steps" />
   <java-symbol type="integer" name="config_audio_ring_vol_default" />
   <java-symbol type="integer" name="config_audio_ring_vol_steps" />
+  <java-symbol type="integer" name="config_audio_alarm_min_vol" />
   <java-symbol type="bool" name="config_spatial_audio_head_tracking_enabled_default" />
   <java-symbol type="bool" name="config_avoidGfxAccel" />
   <java-symbol type="bool" name="config_bluetooth_address_validation" />
@@ -406,6 +407,7 @@
   <java-symbol type="bool" name="config_supportsMultiWindow" />
   <java-symbol type="bool" name="config_supportsSplitScreenMultiWindow" />
   <java-symbol type="bool" name="config_supportsMultiDisplay" />
+  <java-symbol type="bool" name="config_leftRightSplitInPortrait" />
   <java-symbol type="integer" name="config_supportsNonResizableMultiWindow" />
   <java-symbol type="integer" name="config_respectsActivityMinWidthHeightMultiWindow" />
   <java-symbol type="dimen" name="config_minPercentageMultiWindowSupportHeight" />
@@ -1274,6 +1276,7 @@
   <java-symbol type="array" name="policy_exempt_apps" />
   <java-symbol type="array" name="vendor_policy_exempt_apps" />
   <java-symbol type="array" name="cloneable_apps" />
+  <java-symbol type="array" name="config_securityStatePackages" />
 
   <java-symbol type="drawable" name="default_wallpaper" />
   <java-symbol type="drawable" name="default_lock_wallpaper" />
@@ -2078,6 +2081,7 @@
   <java-symbol type="integer" name="config_screenBrightnessSettingMinimum" />
   <java-symbol type="integer" name="config_screenBrightnessSettingMaximum" />
   <java-symbol type="integer" name="config_screenBrightnessSettingDefault" />
+  <java-symbol type="integer" name="config_screenBrightnessCapForWearBedtimeMode" />
   <java-symbol type="dimen" name="config_screenBrightnessSettingMinimumFloat" />
   <java-symbol type="dimen" name="config_screenBrightnessSettingMaximumFloat" />
   <java-symbol type="dimen" name="config_screenBrightnessSettingDefaultFloat" />
@@ -3385,6 +3389,7 @@
   <java-symbol type="bool" name="config_pinnerCameraApp" />
   <java-symbol type="bool" name="config_pinnerHomeApp" />
   <java-symbol type="bool" name="config_pinnerAssistantApp" />
+  <java-symbol type="integer" name="config_pinnerWebviewPinBytes" />
 
   <java-symbol type="string" name="config_doubleTouchGestureEnableFile" />
 
diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
index aaaa3c7..ac1f7d0 100644
--- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
+++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java
@@ -48,6 +48,11 @@
     private static final int UID_1 = 2000;
     private static final int UID_2 = 3000;
     private static final int UID_3 = 4000;
+    private static final int[] UID_USAGE_TIME_PROCESS_STATES = {
+            BatteryConsumer.PROCESS_STATE_FOREGROUND,
+            BatteryConsumer.PROCESS_STATE_BACKGROUND,
+            BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE
+    };
 
     @Test
     public void testGetStatsProto() {
@@ -195,6 +200,20 @@
         assertEquals("For uid " + uid,
                 uidConsumer.getTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND),
                 uidConsumerProto.timeInBackgroundMillis);
+        for (int processState : UID_USAGE_TIME_PROCESS_STATES) {
+            final long timeInStateMillis = uidConsumer.getTimeInProcessStateMs(processState);
+            if (timeInStateMillis <= 0) {
+                continue;
+            }
+            assertEquals("For uid " + uid + ", process state " + processState,
+                    timeInStateMillis,
+                    Arrays.stream(uidConsumerProto.timeInState)
+                            .filter(timeInState -> timeInState.processState == processState)
+                            .findFirst()
+                            .orElseThrow()
+                            .timeInStateMillis);
+        }
+
         if (expectNullBatteryConsumerData) {
             assertNull("For uid " + uid, uidConsumerProto.batteryConsumerData);
         } else {
@@ -250,8 +269,8 @@
         final UidBatteryConsumer.Builder uidBuilder = builder
                 .getOrCreateUidBatteryConsumerBuilder(UID_0)
                 .setPackageWithHighestDrain("myPackage0")
-                .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, 1000)
-                .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, 2000)
+                .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 1000)
+                .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND, 2000)
                 .setConsumedPower(
                         BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
                 .setConsumedPower(
@@ -285,7 +304,7 @@
 
         builder.getOrCreateUidBatteryConsumerBuilder(UID_1)
                 .setPackageWithHighestDrain("myPackage1")
-                .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 1234);
+                .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 1234);
 
         builder.getOrCreateUidBatteryConsumerBuilder(UID_2)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN,
@@ -331,8 +350,10 @@
         // significantly larger than 50 Kb
         for (int i = 0; i < 3000; i++) {
             builder.getOrCreateUidBatteryConsumerBuilder(i)
-                    .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 1 * 60 * 1000)
-                    .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 2 * 60 * 1000)
+                    .setTimeInProcessStateMs(
+                            BatteryConsumer.PROCESS_STATE_FOREGROUND, 1 * 60 * 1000)
+                    .setTimeInProcessStateMs(
+                            BatteryConsumer.PROCESS_STATE_BACKGROUND, 2 * 60 * 1000)
                     .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 30)
                     .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 40);
         }
@@ -340,16 +361,16 @@
         // Add a UID with much larger battery footprint
         final int largeConsumerUid = 3001;
         builder.getOrCreateUidBatteryConsumerBuilder(largeConsumerUid)
-                .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 10 * 60 * 1000)
-                .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 20 * 60 * 1000)
+                .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 10 * 60 * 1000)
+                .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND, 20 * 60 * 1000)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 400);
 
         // Add a UID with much larger usage duration
         final int highUsageUid = 3002;
         builder.getOrCreateUidBatteryConsumerBuilder(highUsageUid)
-                .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_FOREGROUND, 60 * 60 * 1000)
-                .setTimeInStateMs(android.os.UidBatteryConsumer.STATE_BACKGROUND, 120 * 60 * 1000)
+                .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 60 * 60 * 1000)
+                .setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND, 120 * 60 * 1000)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 3)
                 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 4);
 
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 445ddf5..37f592f 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -66,6 +66,7 @@
         "testables",
         "com.android.text.flags-aconfig-java",
         "flag-junit",
+        "ravenwood-junit",
     ],
 
     libs: [
@@ -163,3 +164,15 @@
         "framework-res",
     ],
 }
+
+android_ravenwood_test {
+    name: "FrameworksCoreTestsRavenwood",
+    static_libs: [
+        "androidx.annotation_annotation",
+        "androidx.test.rules",
+    ],
+    srcs: [
+        "src/android/os/FileUtilsTest.java",
+    ],
+    auto_gen_config: true,
+}
diff --git a/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java b/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java
index 5a202c5..9dce899 100644
--- a/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java
+++ b/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java
@@ -28,6 +28,7 @@
 import android.app.usage.UsageEvents.Event;
 import android.content.res.Configuration;
 import android.os.Parcel;
+import android.os.PersistableBundle;
 import android.test.suitebuilder.annotation.LargeTest;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -140,6 +141,12 @@
             case Event.LOCUS_ID_SET:
                 event.mLocusId = anyString();
                 break;
+            case Event.USER_INTERACTION:
+                PersistableBundle extras = new PersistableBundle();
+                extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, anyString());
+                extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, anyString());
+                event.mExtras = extras;
+                break;
         }
 
         event.mFlags = anyInt();
@@ -176,6 +183,14 @@
             case Event.LOCUS_ID_SET:
                 assertEquals(ue1.mLocusId, ue2.mLocusId);
                 break;
+            case Event.USER_INTERACTION:
+                final PersistableBundle extras1 = ue1.getExtras();
+                final PersistableBundle extras2 = ue2.getExtras();
+                assertEquals(extras1.getString(UsageStatsManager.EXTRA_EVENT_CATEGORY),
+                        extras2.getString(UsageStatsManager.EXTRA_EVENT_CATEGORY));
+                assertEquals(extras1.getString(UsageStatsManager.EXTRA_EVENT_ACTION),
+                        extras2.getString(UsageStatsManager.EXTRA_EVENT_ACTION));
+                break;
         }
 
         assertEquals(ue1.mFlags, ue2.mFlags);
diff --git a/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java b/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java
index 083e37a..fae7148 100644
--- a/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java
+++ b/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java
@@ -72,7 +72,7 @@
             "mShortcutId", "mShortcutIdToken", "mBucketAndReason", "mInstanceId",
             "mNotificationChannelId", "mNotificationChannelIdToken", "mTaskRootPackage",
             "mTaskRootPackageToken", "mTaskRootClass", "mTaskRootClassToken", "mLocusId",
-            "mLocusIdToken"};
+            "mLocusIdToken", "mExtras", "mUserInteractionExtrasToken"};
     // All fields in this list are defined in UsageEvents.Event but not persisted
     private static final String[] USAGEEVENTS_IGNORED_FIELDS = {"mAction", "mContentAnnotations",
             "mContentType", "DEVICE_EVENT_PACKAGE_NAME", "FLAG_IS_PACKAGE_INSTANT_APP",
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index 87c167c..4a9cb71 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -83,6 +83,12 @@
             }
 
             @Override
+            protected AssetManager createAssetManager(@NonNull final ResourcesKey key,
+                    ResourcesManager.ApkAssetsSupplier apkSupplier) {
+                return createAssetManager(key);
+            }
+
+            @Override
             protected DisplayMetrics getDisplayMetrics(int displayId, DisplayAdjustments daj) {
                 return mDisplayMetricsMap.get(displayId);
             }
@@ -100,7 +106,7 @@
                 null, APP_ONE_RES_DIR, null, null, null, null, null, null,
                 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null, null);
         assertNotNull(newResources);
-        assertSame(resources, newResources);
+        assertSame(resources.getImpl(), newResources.getImpl());
     }
 
     @SmallTest
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index a0d8183..60500d5 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -51,20 +51,17 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.content.Context;
 import android.os.FileUtils.MemoryPipe;
+import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.ravenwood.RavenwoodRule;
 import android.provider.DocumentsContract.Document;
 import android.util.DataUnit;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.google.android.collect.Sets;
-
-import libcore.io.Streams;
-
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -74,12 +71,19 @@
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Random;
 
 @RunWith(AndroidJUnit4.class)
 public class FileUtilsTest {
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule();
+
     private static final String TEST_DATA =
             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
@@ -90,17 +94,13 @@
 
     private final int[] DATA_SIZES = { 32, 32_000, 32_000_000 };
 
-    private Context getContext() {
-        return InstrumentationRegistry.getContext();
-    }
-
     @Before
     public void setUp() throws Exception {
-        mDir = getContext().getDir("testing", Context.MODE_PRIVATE);
+        mDir = Files.createTempDirectory("FileUtils").toFile();
         mTestFile = new File(mDir, "test.file");
         mCopyFile = new File(mDir, "copy.file");
 
-        mTarget = getContext().getFilesDir();
+        mTarget = mDir;
         FileUtils.deleteContents(mTarget);
     }
 
@@ -152,6 +152,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = MemoryPipe.class)
     public void testCopy_FileToPipe() throws Exception {
         for (int size : DATA_SIZES) {
             final File src = new File(mTarget, "src");
@@ -172,6 +173,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = MemoryPipe.class)
     public void testCopy_PipeToFile() throws Exception {
         for (int size : DATA_SIZES) {
             final File dest = new File(mTarget, "dest");
@@ -191,6 +193,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = MemoryPipe.class)
     public void testCopy_PipeToPipe() throws Exception {
         for (int size : DATA_SIZES) {
             byte[] expected = new byte[size];
@@ -208,6 +211,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = MemoryPipe.class)
     public void testCopy_ShortPipeToFile() throws Exception {
         byte[] source = new byte[33_000_000];
         new Random().nextBytes(source);
@@ -424,6 +428,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
     public void testBuildUniqueFile_normal() throws Exception {
         assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test"));
         assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
@@ -443,6 +448,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
     public void testBuildUniqueFile_unknown() throws Exception {
         assertNameEquals("test",
                 FileUtils.buildUniqueFile(mTarget, "application/octet-stream", "test"));
@@ -456,6 +462,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
     public void testBuildUniqueFile_dir() throws Exception {
         assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test"));
         new File(mTarget, "test").mkdir();
@@ -470,6 +477,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
     public void testBuildUniqueFile_increment() throws Exception {
         assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
         new File(mTarget, "test.jpg").createNewFile();
@@ -489,6 +497,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = android.webkit.MimeTypeMap.class)
     public void testBuildUniqueFile_mimeless() throws Exception {
         assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "test.jpg"));
         new File(mTarget, "test.jpg").createNewFile();
@@ -584,6 +593,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(reason = "Requires kernel support")
     public void testTranslateMode() throws Exception {
         assertTranslate("r", O_RDONLY, MODE_READ_ONLY);
 
@@ -603,6 +613,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(reason = "Requires kernel support")
     public void testMalformedTransate_int() throws Exception {
         try {
             // The non-standard Linux access mode 3 should throw
@@ -614,6 +625,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(reason = "Requires kernel support")
     public void testMalformedTransate_string() throws Exception {
         try {
             // The non-standard Linux access mode 3 should throw
@@ -625,6 +637,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(reason = "Requires kernel support")
     public void testTranslateMode_Invalid() throws Exception {
         try {
             translateModeStringToPosix("rwx");
@@ -639,6 +652,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(reason = "Requires kernel support")
     public void testTranslateMode_Access() throws Exception {
         assertEquals(O_RDONLY, translateModeAccessToPosix(F_OK));
         assertEquals(O_RDONLY, translateModeAccessToPosix(R_OK));
@@ -648,6 +662,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(reason = "Requires kernel support")
     public void testConvertToModernFd() throws Exception {
         final String nonce = String.valueOf(System.nanoTime());
 
@@ -720,13 +735,24 @@
     private byte[] readFile(File file) throws Exception {
         try (FileInputStream in = new FileInputStream(file);
                 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
-            Streams.copy(in, out);
+            copy(in, out);
             return out.toByteArray();
         }
     }
 
+    private static int copy(InputStream in, OutputStream out) throws IOException {
+        int total = 0;
+        byte[] buffer = new byte[8192];
+        int c;
+        while ((c = in.read(buffer)) != -1) {
+            total += c;
+            out.write(buffer, 0, c);
+        }
+        return total;
+    }
+
     private void assertDirContents(String... expected) {
-        final HashSet<String> expectedSet = Sets.newHashSet(expected);
+        final HashSet<String> expectedSet = new HashSet<>(Arrays.asList(expected));
         String[] actual = mDir.list();
         if (actual == null) actual = new String[0];
 
diff --git a/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java b/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java
index 0855268..1bdb006 100644
--- a/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java
+++ b/core/tests/coretests/src/android/service/notification/NotificationRankingUpdateTest.java
@@ -472,6 +472,9 @@
         NotificationRankingUpdate nru = generateUpdate(getContext());
         Parcel parcel = Parcel.obtain();
         nru.writeToParcel(parcel, 0);
+        if (Flags.rankingUpdateAshmem()) {
+            assertTrue(nru.isFdNotNullAndClosed());
+        }
         parcel.setDataPosition(0);
         NotificationRankingUpdate nru1 = NotificationRankingUpdate.CREATOR.createFromParcel(parcel);
         // The rankingUpdate file descriptor is only non-null in the new path.
diff --git a/core/tests/coretests/src/android/window/SystemPerformanceHinterTests.java b/core/tests/coretests/src/android/window/SystemPerformanceHinterTests.java
index 6229530..3147eac 100644
--- a/core/tests/coretests/src/android/window/SystemPerformanceHinterTests.java
+++ b/core/tests/coretests/src/android/window/SystemPerformanceHinterTests.java
@@ -21,7 +21,7 @@
 import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT;
 import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
 import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN;
-import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_SELF;
+import static android.view.SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_PROPAGATE;
 import static android.window.SystemPerformanceHinter.HINT_ADPF;
 import static android.window.SystemPerformanceHinter.HINT_ALL;
 import static android.window.SystemPerformanceHinter.HINT_SF_EARLY_WAKEUP;
@@ -170,7 +170,7 @@
         // Verify we call SF
         verify(mTransaction).setFrameRateSelectionStrategy(
                 eq(mDefaultDisplayRoot),
-                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+                eq(FRAME_RATE_SELECTION_STRATEGY_PROPAGATE));
         verify(mTransaction).setFrameRateCategory(
                 eq(mDefaultDisplayRoot),
                 eq(FRAME_RATE_CATEGORY_DEFAULT),
@@ -262,7 +262,7 @@
         // Verify we call SF and perf manager to clean up
         verify(mTransaction).setFrameRateSelectionStrategy(
                 eq(mDefaultDisplayRoot),
-                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+                eq(FRAME_RATE_SELECTION_STRATEGY_PROPAGATE));
         verify(mTransaction).setFrameRateCategory(
                 eq(mDefaultDisplayRoot),
                 eq(FRAME_RATE_CATEGORY_DEFAULT),
@@ -283,7 +283,7 @@
             // Verify we call SF and perf manager to clean up
             verify(mTransaction).setFrameRateSelectionStrategy(
                     eq(mDefaultDisplayRoot),
-                    eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+                    eq(FRAME_RATE_SELECTION_STRATEGY_PROPAGATE));
             verify(mTransaction).setFrameRateCategory(
                     eq(mDefaultDisplayRoot),
                     eq(FRAME_RATE_CATEGORY_DEFAULT),
@@ -334,7 +334,7 @@
         // Verify we call SF and perf manager to clean up
         verify(mTransaction).setFrameRateSelectionStrategy(
                 eq(mDefaultDisplayRoot),
-                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+                eq(FRAME_RATE_SELECTION_STRATEGY_PROPAGATE));
         verify(mTransaction).setFrameRateCategory(
                 eq(mDefaultDisplayRoot),
                 eq(FRAME_RATE_CATEGORY_DEFAULT),
@@ -385,7 +385,7 @@
         session1.close();
         verify(mTransaction).setFrameRateSelectionStrategy(
                 eq(mDefaultDisplayRoot),
-                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+                eq(FRAME_RATE_SELECTION_STRATEGY_PROPAGATE));
         verify(mTransaction).setFrameRateCategory(
                 eq(mDefaultDisplayRoot),
                 eq(FRAME_RATE_CATEGORY_DEFAULT),
@@ -410,7 +410,7 @@
                 anyInt());
         verify(mTransaction).setFrameRateSelectionStrategy(
                 eq(mSecondaryDisplayRoot),
-                eq(FRAME_RATE_SELECTION_STRATEGY_SELF));
+                eq(FRAME_RATE_SELECTION_STRATEGY_PROPAGATE));
         verify(mTransaction).setFrameRateCategory(
                 eq(mSecondaryDisplayRoot),
                 eq(FRAME_RATE_CATEGORY_DEFAULT),
diff --git a/core/tests/utiltests/Android.bp b/core/tests/utiltests/Android.bp
index 06340a2..967047e 100644
--- a/core/tests/utiltests/Android.bp
+++ b/core/tests/utiltests/Android.bp
@@ -57,8 +57,10 @@
     static_libs: [
         "androidx.annotation_annotation",
         "androidx.test.rules",
+        "mockito_ravenwood",
     ],
     srcs: [
+        "src/android/util/AtomicFileTest.java",
         "src/android/util/DataUnitTest.java",
         "src/android/util/EventLogTest.java",
         "src/android/util/IndentingPrintWriterTest.java",
diff --git a/core/tests/utiltests/src/android/util/AtomicFileTest.java b/core/tests/utiltests/src/android/util/AtomicFileTest.java
index 6f59714..742307b 100644
--- a/core/tests/utiltests/src/android/util/AtomicFileTest.java
+++ b/core/tests/utiltests/src/android/util/AtomicFileTest.java
@@ -23,16 +23,16 @@
 import static org.mockito.ArgumentMatchers.longThat;
 import static org.mockito.Mockito.spy;
 
-import android.app.Instrumentation;
-import android.content.Context;
 import android.os.SystemClock;
+import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -46,9 +46,13 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 
 @RunWith(Parameterized.class)
 public class AtomicFileTest {
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule();
+
     private static final String BASE_NAME = "base";
     private static final String NEW_NAME = BASE_NAME + ".new";
     private static final String LEGACY_BACKUP_NAME = BASE_NAME + ".bak";
@@ -80,14 +84,10 @@
     @Parameterized.Parameter(3)
     public byte[] mExpectedBytes;
 
-    private final Instrumentation mInstrumentation =
-            InstrumentationRegistry.getInstrumentation();
-    private final Context mContext = mInstrumentation.getContext();
-
-    private final File mDirectory = mContext.getFilesDir();
-    private final File mBaseFile = new File(mDirectory, BASE_NAME);
-    private final File mNewFile = new File(mDirectory, NEW_NAME);
-    private final File mLegacyBackupFile = new File(mDirectory, LEGACY_BACKUP_NAME);
+    private File mDirectory;
+    private File mBaseFile;
+    private File mNewFile;
+    private File mLegacyBackupFile;
 
     @Parameterized.Parameters(name = "{0}")
     public static Object[][] data() {
@@ -199,6 +199,13 @@
     }
 
     @Before
+    public void setUp() throws Exception {
+        mDirectory = Files.createTempDirectory("AtomicFile").toFile();
+        mBaseFile = new File(mDirectory, BASE_NAME);
+        mNewFile = new File(mDirectory, NEW_NAME);
+        mLegacyBackupFile = new File(mDirectory, LEGACY_BACKUP_NAME);
+    }
+
     @After
     public void deleteFiles() {
         mBaseFile.delete();
@@ -274,6 +281,7 @@
     }
 
     @Test
+    @IgnoreUnderRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class)
     public void testTimeLogging() throws Exception {
         var logger = spy(new SystemConfigFileCommitEventLogger("name"));
         var file = new AtomicFile(mBaseFile, logger);
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index f19acbe..2237ba1 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -529,6 +529,12 @@
       "group": "WM_DEBUG_TASKS",
       "at": "com\/android\/server\/wm\/ActivityStarter.java"
     },
+    "-1582845629": {
+      "message": "Starting animation on %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_DIMMER",
+      "at": "com\/android\/server\/wm\/DimmerAnimationHelper.java"
+    },
     "-1575977269": {
       "message": "Skipping %s: mismatch root %s",
       "level": "DEBUG",
@@ -925,6 +931,12 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
+    "-1243510456": {
+      "message": "Dim animation requested: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_DIMMER",
+      "at": "com\/android\/server\/wm\/DimmerAnimationHelper.java"
+    },
     "-1237827119": {
       "message": "Schedule remove starting %s startingWindow=%s animate=%b Callers=%s",
       "level": "VERBOSE",
@@ -991,12 +1003,6 @@
       "group": "WM_DEBUG_WINDOW_INSETS",
       "at": "com\/android\/server\/wm\/InsetsSourceProvider.java"
     },
-    "-1176488860": {
-      "message": "SURFACE isSecure=%b: %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
-    },
     "-1164930508": {
       "message": "Moving to RESUMED: %s (starting new instance) callers=%s",
       "level": "VERBOSE",
@@ -1177,6 +1183,12 @@
       "group": "WM_DEBUG_BACK_PREVIEW",
       "at": "com\/android\/server\/wm\/BackNavigationController.java"
     },
+    "-1028213464": {
+      "message": "%s skipping animation and directly setting alpha=%f, blur=%d",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_DIMMER",
+      "at": "com\/android\/server\/wm\/DimmerAnimationHelper.java"
+    },
     "-1022146708": {
       "message": "Skipping %s: mismatch activity type",
       "level": "DEBUG",
@@ -1801,12 +1813,6 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "-504637678": {
-      "message": "Starting animation on dim layer %s, requested by %s, alpha: %f -> %f, blur: %d -> %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_DIMMER",
-      "at": "com\/android\/server\/wm\/SmoothDimmer.java"
-    },
     "-503656156": {
       "message": "Update process config of %s to new config %s",
       "level": "VERBOSE",
@@ -3277,6 +3283,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "810599500": {
+      "message": "SURFACE isSecure=%b: %s",
+      "level": "INFO",
+      "group": "WM_SHOW_TRANSACTIONS",
+      "at": "com\/android\/server\/wm\/WindowState.java"
+    },
     "829434921": {
       "message": "Draw state now committed in %s",
       "level": "VERBOSE",
@@ -4027,12 +4039,6 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
-    "1620751818": {
-      "message": "Dim %s skipping animation and directly setting alpha=%f, blur=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_DIMMER",
-      "at": "com\/android\/server\/wm\/SmoothDimmer.java"
-    },
     "1621562070": {
       "message": "    startWCT=%s",
       "level": "VERBOSE",
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index 1048742..e7e1740 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -500,7 +500,7 @@
 
 key ESCAPE {
     base:                               none
-    alt, meta:                          fallback HOME
+    alt:                                fallback HOME
     ctrl:                               fallback MENU
 }
 
diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java
index 5e16bce..dd703f5 100644
--- a/keystore/java/android/security/KeyStore2.java
+++ b/keystore/java/android/security/KeyStore2.java
@@ -33,7 +33,6 @@
 import android.util.Log;
 
 import java.util.Calendar;
-import java.util.Objects;
 
 /**
  * @hide This should not be made public in its present form because it
@@ -139,13 +138,25 @@
         return new KeyStore2();
     }
 
+    /**
+     * Gets the {@link IKeystoreService} that should be started in early_hal in Android.
+     *
+     * @throws IllegalStateException if the KeystoreService is not available or has not
+     * been initialized when called. This is a state that should not happen and indicates
+     * and error somewhere in the stack or with the calling processes access permissions.
+     */
     @NonNull private synchronized IKeystoreService getService(boolean retryLookup) {
         if (mBinder == null || retryLookup) {
             mBinder = IKeystoreService.Stub.asInterface(ServiceManager
-                    .getService(KEYSTORE2_SERVICE_NAME));
-            Binder.allowBlocking(mBinder.asBinder());
+                .getService(KEYSTORE2_SERVICE_NAME));
         }
-        return Objects.requireNonNull(mBinder);
+        if (mBinder == null) {
+            throw new IllegalStateException(
+                    "Could not connect to Keystore service. Keystore may have crashed or not been"
+                            + " initialized");
+        }
+        Binder.allowBlocking(mBinder.asBinder());
+        return mBinder;
     }
 
     void delete(KeyDescriptor descriptor) throws KeyStoreException {
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 231fa48..4982f37 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -618,7 +618,7 @@
      * @see #isMgf1DigestsSpecified()
      */
     @NonNull
-    @FlaggedApi("MGF1_DIGEST_SETTER")
+    @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER)
     public @KeyProperties.DigestEnum Set<String> getMgf1Digests() {
         if (mMgf1Digests.isEmpty()) {
             throw new IllegalStateException("Mask generation function (MGF) not specified");
@@ -633,7 +633,7 @@
      * @see #getMgf1Digests()
      */
     @NonNull
-    @FlaggedApi("MGF1_DIGEST_SETTER")
+    @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER)
     public boolean isMgf1DigestsSpecified() {
         return !mMgf1Digests.isEmpty();
     }
@@ -1292,7 +1292,7 @@
          * <p>See {@link KeyProperties}.{@code DIGEST} constants.
          */
         @NonNull
-        @FlaggedApi("MGF1_DIGEST_SETTER")
+        @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER)
         public Builder setMgf1Digests(@NonNull @KeyProperties.DigestEnum String... mgf1Digests) {
             mMgf1Digests = Set.of(mgf1Digests);
             return this;
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index c1e3bab..7b6b2d1 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -401,7 +401,7 @@
      * @see #isMgf1DigestsSpecified()
      */
     @NonNull
-    @FlaggedApi("MGF1_DIGEST_SETTER")
+    @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER)
     public @KeyProperties.DigestEnum Set<String> getMgf1Digests() {
         if (mMgf1Digests.isEmpty()) {
             throw new IllegalStateException("Mask generation function (MGF) not specified");
@@ -416,7 +416,7 @@
      * @see #getMgf1Digests()
      */
     @NonNull
-    @FlaggedApi("MGF1_DIGEST_SETTER")
+    @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER)
     public boolean isMgf1DigestsSpecified() {
         return !mMgf1Digests.isEmpty();
     }
@@ -799,7 +799,7 @@
          * <p>See {@link KeyProperties}.{@code DIGEST} constants.
          */
         @NonNull
-        @FlaggedApi("MGF1_DIGEST_SETTER")
+        @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER)
         public Builder setMgf1Digests(@Nullable @KeyProperties.DigestEnum String... mgf1Digests) {
             mMgf1Digests = Set.of(mgf1Digests);
             return this;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index ed4b485..02efc2f 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -28,6 +28,7 @@
 import android.hardware.security.keymint.Tag;
 import android.os.Build;
 import android.os.StrictMode;
+import android.security.Flags;
 import android.security.KeyPairGeneratorSpec;
 import android.security.KeyStore2;
 import android.security.KeyStoreException;
@@ -853,6 +854,22 @@
                             KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mgf1Digest
                     ));
                 });
+
+                /* If the MGF1 Digest setter is not set, fall back to the previous behaviour:
+                 * Add, as MGF1 Digest function, all the primary digests.
+                 * Avoid adding the default MGF1 digest as it will have been included in the
+                 * mKeymasterMgf1Digests field.
+                 */
+                if (!Flags.mgf1DigestSetter()) {
+                    final int defaultMgf1Digest = KeyProperties.Digest.toKeymaster(
+                            DEFAULT_MGF1_DIGEST);
+                    ArrayUtils.forEach(mKeymasterDigests, (digest) -> {
+                        if (digest != defaultMgf1Digest) {
+                            params.add(KeyStore2ParameterUtils.makeEnum(
+                                    KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, digest));
+                        }
+                    });
+                }
             }
         });
         ArrayUtils.forEach(mKeymasterSignaturePaddings, (padding) -> {
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index ddbd93e..4f65884 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -25,6 +25,7 @@
 import android.hardware.security.keymint.KeyParameter;
 import android.hardware.security.keymint.SecurityLevel;
 import android.os.StrictMode;
+import android.security.Flags;
 import android.security.GateKeeper;
 import android.security.KeyStore2;
 import android.security.KeyStoreParameter;
@@ -537,11 +538,31 @@
                         /* Because of default MGF1 digest is SHA-1. It has to be added in Key
                          * characteristics. Otherwise, crypto operations will fail with Incompatible
                          * MGF1 digest.
+                         * If the MGF1 Digest setter flag isn't set, then the condition in the
+                         * if clause above must be false (cannot have MGF1 digests specified if the
+                         * flag was off). In that case, in addition to adding the default MGF1
+                         * digest, we have to add all the other digests as MGF1 Digests.
+                         *
                          */
                         importArgs.add(KeyStore2ParameterUtils.makeEnum(
                                 KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST,
                                 KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST)
                         ));
+                        if (!Flags.mgf1DigestSetter()) {
+                            final int defaultMgf1Digest = KeyProperties.Digest.toKeymaster(
+                                    DEFAULT_MGF1_DIGEST);
+                            for (String digest : spec.getDigests()) {
+                                int digestToAddAsMgf1Digest = KeyProperties.Digest.toKeymaster(
+                                        digest);
+                                // Do not add the default MGF1 digest as it has been added above.
+                                if (digestToAddAsMgf1Digest != defaultMgf1Digest) {
+                                    importArgs.add(KeyStore2ParameterUtils.makeEnum(
+                                            KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST,
+                                            digestToAddAsMgf1Digest
+                                    ));
+                                }
+                            }
+                        }
                     }
                 }
             }
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 50cfd94..4c2433f 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -443,7 +443,8 @@
         assertThat(taskContainer.getTaskFragmentContainers()).containsExactly(overlayContainer);
 
         taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(Configuration.EMPTY,
-                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+                null /* decorSurface */));
 
         mSplitController.updateOverlayContainer(mTransaction, overlayContainer);
 
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index 02031a6..8c274a2 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -1139,7 +1139,8 @@
     public void testOnTransactionReady_taskFragmentParentInfoChanged() {
         final TaskFragmentTransaction transaction = new TaskFragmentTransaction();
         final TaskFragmentParentInfo parentInfo = new TaskFragmentParentInfo(Configuration.EMPTY,
-                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */);
+                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+                null /* decorSurface */);
         transaction.addChange(new TaskFragmentTransaction.Change(
                 TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED)
                 .setTaskId(TASK_ID)
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
index e56c8ab..7b77235 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java
@@ -79,14 +79,16 @@
 
         configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
         taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(configuration,
-                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+                null /* decorSurface */));
 
         assertEquals(WINDOWING_MODE_MULTI_WINDOW,
                 taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
 
         configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
         taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(configuration,
-                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+                null /* decorSurface */));
 
         assertEquals(WINDOWING_MODE_FREEFORM,
                 taskContainer.getWindowingModeForSplitTaskFragment(splitBounds));
@@ -106,13 +108,15 @@
 
         configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
         taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(configuration,
-                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+                null /* decorSurface */));
 
         assertFalse(taskContainer.isInPictureInPicture());
 
         configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_PINNED);
         taskContainer.updateTaskFragmentParentInfo(new TaskFragmentParentInfo(configuration,
-                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */));
+                DEFAULT_DISPLAY, true /* visible */, false /* hasDirectActivity */,
+                null /* decorSurface */));
 
         assertTrue(taskContainer.isInPictureInPicture());
     }
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 4d2d960..4511f3b 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -50,3 +50,10 @@
     bug: "290220798"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "enable_left_right_split_in_portrait"
+    namespace: "multitasking"
+    description: "Enables left/right split in portrait"
+    bug: "291018646"
+}
diff --git a/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml b/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml
deleted file mode 100644
index d732b01..0000000
--- a/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml
+++ /dev/null
@@ -1,38 +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.
--->
-
-<com.android.wm.shell.legacysplitscreen.DividerView
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_height="match_parent"
-        android:layout_width="match_parent">
-
-    <View
-        style="@style/DockedDividerBackground"
-        android:id="@+id/docked_divider_background"
-        android:background="@color/split_divider_background"/>
-
-    <com.android.wm.shell.legacysplitscreen.MinimizedDockShadow
-        style="@style/DockedDividerMinimizedShadow"
-        android:id="@+id/minimized_dock_shadow"
-        android:alpha="0"/>
-
-    <com.android.wm.shell.common.split.DividerHandleView
-        style="@style/DockedDividerHandle"
-        android:id="@+id/docked_divider_handle"
-        android:contentDescription="@string/accessibility_divider"
-        android:background="@null"/>
-
-</com.android.wm.shell.legacysplitscreen.DividerView>
diff --git a/libs/WindowManager/Shell/res/layout/split_divider.xml b/libs/WindowManager/Shell/res/layout/split_divider.xml
index e3be700..db35c8c 100644
--- a/libs/WindowManager/Shell/res/layout/split_divider.xml
+++ b/libs/WindowManager/Shell/res/layout/split_divider.xml
@@ -24,17 +24,16 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
-        <View
-            style="@style/DockedDividerBackground"
-            android:id="@+id/docked_divider_background"/>
-
         <com.android.wm.shell.common.split.DividerHandleView
-            style="@style/DockedDividerHandle"
             android:id="@+id/docked_divider_handle"
+            android:layout_height="match_parent"
+            android:layout_width="match_parent"
+            android:layout_gravity="center"
             android:contentDescription="@string/accessibility_divider"
             android:background="@null"/>
 
         <com.android.wm.shell.common.split.DividerRoundedCorner
+            android:id="@+id/docked_divider_rounded_corner"
             android:layout_width="match_parent"
             android:layout_height="match_parent"/>
 
diff --git a/libs/WindowManager/Shell/res/values-land/dimens.xml b/libs/WindowManager/Shell/res/values-land/dimens.xml
index a95323f..1b96fa2 100644
--- a/libs/WindowManager/Shell/res/values-land/dimens.xml
+++ b/libs/WindowManager/Shell/res/values-land/dimens.xml
@@ -16,13 +16,6 @@
 */
 -->
 <resources>
-    <!-- Divider handle size for legacy split screen -->
-    <dimen name="docked_divider_handle_width">2dp</dimen>
-    <dimen name="docked_divider_handle_height">16dp</dimen>
-    <!-- Divider handle size for split screen -->
-    <dimen name="split_divider_handle_width">3dp</dimen>
-    <dimen name="split_divider_handle_height">72dp</dimen>
-
     <!-- Padding between status bar and bubbles when displayed in expanded state, smaller
      value in landscape since we have limited vertical space-->
     <dimen name="bubble_padding_top">4dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values-land/styles.xml b/libs/WindowManager/Shell/res/values-land/styles.xml
deleted file mode 100644
index e89f65b..0000000
--- a/libs/WindowManager/Shell/res/values-land/styles.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <style name="DockedDividerBackground">
-        <item name="android:layout_width">@dimen/split_divider_bar_width</item>
-        <item name="android:layout_height">match_parent</item>
-        <item name="android:layout_gravity">center_horizontal</item>
-        <item name="android:background">@color/split_divider_background</item>
-    </style>
-
-    <style name="DockedDividerHandle">
-        <item name="android:layout_gravity">center</item>
-        <item name="android:layout_width">48dp</item>
-        <item name="android:layout_height">96dp</item>
-    </style>
-
-    <style name="DockedDividerMinimizedShadow">
-        <item name="android:layout_width">8dp</item>
-        <item name="android:layout_height">match_parent</item>
-    </style>
-</resources>
-
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index f20d44d..8f9de61 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -96,6 +96,9 @@
     <dimen name="docked_divider_handle_width">16dp</dimen>
     <dimen name="docked_divider_handle_height">2dp</dimen>
     <!-- Divider handle size for split screen -->
+    <dimen name="split_divider_handle_region_width">96dp</dimen>
+    <dimen name="split_divider_handle_region_height">48dp</dimen>
+
     <dimen name="split_divider_handle_width">72dp</dimen>
     <dimen name="split_divider_handle_height">3dp</dimen>
 
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 468cfd5..08c2a02 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -60,20 +60,9 @@
 
     <style name="DockedDividerBackground">
         <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">@dimen/split_divider_bar_width</item>
-        <item name="android:layout_gravity">center_vertical</item>
-        <item name="android:background">@color/split_divider_background</item>
-    </style>
-
-    <style name="DockedDividerMinimizedShadow">
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">8dp</item>
-    </style>
-
-    <style name="DockedDividerHandle">
+        <item name="android:layout_height">match_parent</item>
         <item name="android:layout_gravity">center</item>
-        <item name="android:layout_width">96dp</item>
-        <item name="android:layout_height">48dp</item>
+        <item name="android:background">@color/split_divider_background</item>
     </style>
 
     <style name="TvPipEduText">
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index f5b877a..a3eb429 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -412,6 +412,23 @@
         setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
     }
 
+
+    /** Updates the width of the task view if it changed. */
+    void updateTaskViewContentWidth() {
+        if (mTaskView != null) {
+            int width = getContentWidth();
+            if (mTaskView.getWidth() != width) {
+                FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(width, MATCH_PARENT);
+                mTaskView.setLayoutParams(lp);
+            }
+        }
+    }
+
+    private int getContentWidth() {
+        boolean isStackOnLeft = mPositioner.isStackOnLeft(mStackView.getStackPosition());
+        return mPositioner.getTaskViewContentWidth(isStackOnLeft);
+    }
+
     /**
      * Initialize {@link BubbleController} and {@link BubbleStackView} here, this method must need
      * to be called after view inflate.
@@ -438,7 +455,12 @@
                     mController.getTaskViewTransitions(), mController.getSyncTransactionQueue());
             mTaskView = new TaskView(mContext, mTaskViewTaskController);
             mTaskView.setListener(mController.getMainExecutor(), mTaskViewListener);
-            mExpandedViewContainer.addView(mTaskView);
+
+            // set a fixed width so it is not recalculated as part of a rotation. the width will be
+            // updated manually after the rotation.
+            FrameLayout.LayoutParams lp =
+                    new FrameLayout.LayoutParams(getContentWidth(), MATCH_PARENT);
+            mExpandedViewContainer.addView(mTaskView, lp);
             bringChildToFront(mTaskView);
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 1efd9df..baa52a0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -375,6 +375,13 @@
         }
     }
 
+    /** Returns the width of the task view content. */
+    public int getTaskViewContentWidth(boolean onLeft) {
+        int[] paddings = getExpandedViewContainerPadding(onLeft, /* isOverflow = */ false);
+        int pointerOffset = showBubblesVertically() ? getPointerSize() : 0;
+        return mPositionRect.width() - paddings[0] - paddings[2] - pointerOffset;
+    }
+
     /** Gets the y position of the expanded view if it was top-aligned. */
     public float getExpandedViewYTopAligned() {
         final int top = getAvailableRect().top;
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 8f904c4..91a8ce7 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
@@ -537,8 +537,8 @@
                 return;
             }
 
-            final boolean clickedBubbleIsCurrentlyExpandedBubble =
-                    clickedBubble.getKey().equals(mExpandedBubble.getKey());
+            final boolean clickedBubbleIsCurrentlyExpandedBubble = mExpandedBubble != null
+                            && clickedBubble.getKey().equals(mExpandedBubble.getKey());
 
             if (isExpanded()) {
                 mExpandedAnimationController.onGestureFinished();
@@ -3288,6 +3288,7 @@
             mExpandedViewContainer.setTranslationY(mPositioner.getExpandedViewY(mExpandedBubble,
                     mPositioner.showBubblesVertically() ? p.y : p.x));
             mExpandedViewContainer.setTranslationX(0f);
+            mExpandedBubble.getExpandedView().updateTaskViewContentWidth();
             mExpandedBubble.getExpandedView().updateView(
                     mExpandedViewContainer.getLocationOnScreen());
             updatePointerPosition(false /* forIme */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java
index ec26800..999da24 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java
@@ -68,24 +68,33 @@
             };
 
     private final Paint mPaint = new Paint();
-    private final int mWidth;
-    private final int mHeight;
-    private final int mTouchingWidth;
-    private final int mTouchingHeight;
+    private int mWidth;
+    private int mHeight;
+    private int mTouchingWidth;
+    private int mTouchingHeight;
     private int mCurrentWidth;
     private int mCurrentHeight;
     private AnimatorSet mAnimator;
     private boolean mTouching;
     private boolean mHovering;
-    private final int mHoveringWidth;
-    private final int mHoveringHeight;
+    private int mHoveringWidth;
+    private int mHoveringHeight;
+    private boolean mIsLeftRightSplit;
 
     public DividerHandleView(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
         mPaint.setColor(getResources().getColor(R.color.docked_divider_handle, null));
         mPaint.setAntiAlias(true);
-        mWidth = getResources().getDimensionPixelSize(R.dimen.split_divider_handle_width);
-        mHeight = getResources().getDimensionPixelSize(R.dimen.split_divider_handle_height);
+        updateDimens();
+    }
+
+    private void updateDimens() {
+        mWidth = getResources().getDimensionPixelSize(mIsLeftRightSplit
+                ? R.dimen.split_divider_handle_height
+                : R.dimen.split_divider_handle_width);
+        mHeight = getResources().getDimensionPixelSize(mIsLeftRightSplit
+                ? R.dimen.split_divider_handle_width
+                : R.dimen.split_divider_handle_height);
         mCurrentWidth = mWidth;
         mCurrentHeight = mHeight;
         mTouchingWidth = mWidth > mHeight ? mWidth / 2 : mWidth;
@@ -94,6 +103,11 @@
         mHoveringHeight = mHeight > mWidth ? ((int) (mHeight * 1.5f)) : mHeight;
     }
 
+    void setIsLeftRightSplit(boolean isLeftRightSplit) {
+        mIsLeftRightSplit = isLeftRightSplit;
+        updateDimens();
+    }
+
     /** Sets touching state for this handle view. */
     public void setTouching(boolean touching, boolean animate) {
         if (touching == mTouching) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerRoundedCorner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerRoundedCorner.java
index 364bb65..834c15d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerRoundedCorner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerRoundedCorner.java
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.common.split;
 
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.view.RoundedCorner.POSITION_BOTTOM_LEFT;
 import static android.view.RoundedCorner.POSITION_BOTTOM_RIGHT;
 import static android.view.RoundedCorner.POSITION_TOP_LEFT;
@@ -47,6 +46,7 @@
     private InvertedRoundedCornerDrawInfo mTopRightCorner;
     private InvertedRoundedCornerDrawInfo mBottomLeftCorner;
     private InvertedRoundedCornerDrawInfo mBottomRightCorner;
+    private boolean mIsLeftRightSplit;
 
     public DividerRoundedCorner(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
@@ -98,8 +98,8 @@
         return false;
     }
 
-    private boolean isLandscape() {
-        return getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE;
+    void setIsLeftRightSplit(boolean isLeftRightSplit) {
+        mIsLeftRightSplit = isLeftRightSplit;
     }
 
     /**
@@ -134,7 +134,7 @@
         }
 
         private void calculateStartPos(Point outPos) {
-            if (isLandscape()) {
+            if (mIsLeftRightSplit) {
                 // Place left corner at the right side of the divider bar.
                 outPos.x = isLeftCorner()
                         ? getWidth() / 2 + mDividerWidth / 2
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index 0b0c693..0f0fbd9c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.common.split;
 
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
 import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
 import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
@@ -27,6 +26,8 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.provider.DeviceConfig;
@@ -65,12 +66,15 @@
     public static final long TOUCH_ANIMATION_DURATION = 150;
     public static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;
 
+    private final Paint mPaint = new Paint();
+    private final Rect mBackgroundRect = new Rect();
     private final int mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
 
     private SplitLayout mSplitLayout;
     private SplitWindowManager mSplitWindowManager;
     private SurfaceControlViewHost mViewHost;
     private DividerHandleView mHandle;
+    private DividerRoundedCorner mCorners;
     private View mBackground;
     private int mTouchElevation;
 
@@ -81,6 +85,8 @@
     private boolean mInteractive;
     private boolean mSetTouchRegion = true;
     private int mLastDraggingPosition;
+    private int mHandleRegionWidth;
+    private int mHandleRegionHeight;
 
     /**
      * Tracks divider bar visible bounds in screen-based coordination. Used to calculate with
@@ -123,7 +129,7 @@
         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
             super.onInitializeAccessibilityNodeInfo(host, info);
             final DividerSnapAlgorithm snapAlgorithm = mSplitLayout.mDividerSnapAlgorithm;
-            if (isLandscape()) {
+            if (mSplitLayout.isLeftRightSplit()) {
                 info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
                         mContext.getString(R.string.accessibility_action_divider_left_full)));
                 if (snapAlgorithm.isFirstSplitTargetAvailable()) {
@@ -215,6 +221,17 @@
         mViewHost = viewHost;
         layout.getDividerBounds(mDividerBounds);
         onInsetsChanged(insetsState, false /* animate */);
+
+        final boolean isLeftRightSplit = mSplitLayout.isLeftRightSplit();
+        mHandle.setIsLeftRightSplit(isLeftRightSplit);
+        mCorners.setIsLeftRightSplit(isLeftRightSplit);
+
+        mHandleRegionWidth = getResources().getDimensionPixelSize(isLeftRightSplit
+                ? R.dimen.split_divider_handle_region_height
+                : R.dimen.split_divider_handle_region_width);
+        mHandleRegionHeight = getResources().getDimensionPixelSize(isLeftRightSplit
+                ? R.dimen.split_divider_handle_region_width
+                : R.dimen.split_divider_handle_region_height);
     }
 
     void onInsetsChanged(InsetsState insetsState, boolean animate) {
@@ -255,30 +272,47 @@
         super.onFinishInflate();
         mDividerBar = findViewById(R.id.divider_bar);
         mHandle = findViewById(R.id.docked_divider_handle);
-        mBackground = findViewById(R.id.docked_divider_background);
+        mCorners = findViewById(R.id.docked_divider_rounded_corner);
         mTouchElevation = getResources().getDimensionPixelSize(
                 R.dimen.docked_stack_divider_lift_elevation);
         mDoubleTapDetector = new GestureDetector(getContext(), new DoubleTapListener());
         mInteractive = true;
         setOnTouchListener(this);
         mHandle.setAccessibilityDelegate(mHandleDelegate);
+        setWillNotDraw(false);
+        mPaint.setColor(getResources().getColor(R.color.split_divider_background, null));
+        mPaint.setAntiAlias(true);
+        mPaint.setStyle(Paint.Style.FILL);
     }
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
         if (mSetTouchRegion) {
-            mTempRect.set(mHandle.getLeft(), mHandle.getTop(), mHandle.getRight(),
-                    mHandle.getBottom());
+            int startX = (mDividerBounds.width() - mHandleRegionWidth) / 2;
+            int startY = (mDividerBounds.height() - mHandleRegionHeight) / 2;
+            mTempRect.set(startX, startY, startX + mHandleRegionWidth,
+                    startY + mHandleRegionHeight);
             mSplitWindowManager.setTouchRegion(mTempRect);
             mSetTouchRegion = false;
         }
+
+        if (changed) {
+            boolean isHorizontalSplit = mSplitLayout.isLeftRightSplit();
+            int dividerSize = getResources().getDimensionPixelSize(R.dimen.split_divider_bar_width);
+            left = isHorizontalSplit ? (getWidth() - dividerSize) / 2 : 0;
+            top = isHorizontalSplit ? 0 : (getHeight() - dividerSize) / 2;
+            right = isHorizontalSplit ? left + dividerSize : getWidth();
+            bottom = isHorizontalSplit ? getHeight() : top + dividerSize;
+            mBackgroundRect.set(left, top, right, bottom);
+        }
     }
 
     @Override
     public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
         return PointerIcon.getSystemIcon(getContext(),
-                isLandscape() ? TYPE_HORIZONTAL_DOUBLE_ARROW : TYPE_VERTICAL_DOUBLE_ARROW);
+                mSplitLayout.isLeftRightSplit() ? TYPE_HORIZONTAL_DOUBLE_ARROW
+                        : TYPE_VERTICAL_DOUBLE_ARROW);
     }
 
     @Override
@@ -295,8 +329,8 @@
         // moving divider bar and calculating dragging velocity.
         event.setLocation(event.getRawX(), event.getRawY());
         final int action = event.getAction() & MotionEvent.ACTION_MASK;
-        final boolean isLandscape = isLandscape();
-        final int touchPos = (int) (isLandscape ? event.getX() : event.getY());
+        final boolean isLeftRightSplit = mSplitLayout.isLeftRightSplit();
+        final int touchPos = (int) (isLeftRightSplit ? event.getX() : event.getY());
         switch (action) {
             case MotionEvent.ACTION_DOWN:
                 mVelocityTracker = VelocityTracker.obtain();
@@ -328,7 +362,7 @@
 
                 mVelocityTracker.addMovement(event);
                 mVelocityTracker.computeCurrentVelocity(1000 /* units */);
-                final float velocity = isLandscape
+                final float velocity = isLeftRightSplit
                         ? mVelocityTracker.getXVelocity()
                         : mVelocityTracker.getYVelocity();
                 final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
@@ -410,6 +444,11 @@
                 .start();
     }
 
+    @Override
+    protected void onDraw(@NonNull Canvas canvas) {
+        canvas.drawRect(mBackgroundRect, mPaint);
+    }
+
     @VisibleForTesting
     void releaseHovering() {
         mHandle.setHovering(false, true);
@@ -446,10 +485,6 @@
         mHandle.setVisibility(!mInteractive && hideHandle ? View.INVISIBLE : View.VISIBLE);
     }
 
-    private boolean isLandscape() {
-        return getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE;
-    }
-
     private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
         @Override
         public boolean onDoubleTap(MotionEvent e) {
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 63cdb4f..b699533 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
@@ -79,7 +79,7 @@
  * divide position changes.
  */
 public final class SplitLayout implements DisplayInsetsController.OnInsetsChangedListener {
-
+    private static final String TAG = "SplitLayout";
     public static final int PARALLAX_NONE = 0;
     public static final int PARALLAX_DISMISSING = 1;
     public static final int PARALLAX_ALIGN_CENTER = 2;
@@ -121,12 +121,15 @@
     private int mDividerPosition;
     private boolean mInitialized = false;
     private boolean mFreezeDividerWindow = false;
+    private boolean mIsLargeScreen = false;
     private int mOrientation;
     private int mRotation;
     private int mDensity;
     private int mUiMode;
 
     private final boolean mDimNonImeSide;
+    private final boolean mAllowLeftRightSplitInPortrait;
+    private boolean mIsLeftRightSplit;
     private ValueAnimator mDividerFlingAnimator;
 
     public SplitLayout(String windowName, Context context, Configuration configuration,
@@ -138,6 +141,7 @@
         mOrientation = configuration.orientation;
         mRotation = configuration.windowConfiguration.getRotation();
         mDensity = configuration.densityDpi;
+        mIsLargeScreen = configuration.smallestScreenWidthDp >= 600;
         mSplitLayoutHandler = splitLayoutHandler;
         mDisplayController = displayController;
         mDisplayImeController = displayImeController;
@@ -147,14 +151,17 @@
         mImePositionProcessor = new ImePositionProcessor(mContext.getDisplayId());
         mSurfaceEffectPolicy = new ResizingEffectPolicy(parallaxType);
 
+        final Resources res = mContext.getResources();
+        mDimNonImeSide = res.getBoolean(R.bool.config_dimNonImeAttachedSide);
+        mAllowLeftRightSplitInPortrait = SplitScreenUtils.allowLeftRightSplitInPortrait(res);
+        mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
+                configuration);
+
         updateDividerConfig(mContext);
 
         mRootBounds.set(configuration.windowConfiguration.getBounds());
         mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
         resetDividerPosition();
-
-        mDimNonImeSide = mContext.getResources().getBoolean(R.bool.config_dimNonImeAttachedSide);
-
         updateInvisibleRect();
     }
 
@@ -284,17 +291,17 @@
      * Returns the divider position as a fraction from 0 to 1.
      */
     public float getDividerPositionAsFraction() {
-        return Math.min(1f, Math.max(0f, isLandscape()
+        return Math.min(1f, Math.max(0f, mIsLeftRightSplit
                 ? (float) ((mBounds1.right + mBounds2.left) / 2f) / mBounds2.right
                 : (float) ((mBounds1.bottom + mBounds2.top) / 2f) / mBounds2.bottom));
     }
 
     private void updateInvisibleRect() {
         mInvisibleBounds.set(mRootBounds.left, mRootBounds.top,
-                isLandscape() ? mRootBounds.right / 2 : mRootBounds.right,
-                isLandscape() ? mRootBounds.bottom : mRootBounds.bottom / 2);
-        mInvisibleBounds.offset(isLandscape() ? mRootBounds.right : 0,
-                isLandscape() ? 0 : mRootBounds.bottom);
+                mIsLeftRightSplit ? mRootBounds.right / 2 : mRootBounds.right,
+                mIsLeftRightSplit ? mRootBounds.bottom : mRootBounds.bottom / 2);
+        mInvisibleBounds.offset(mIsLeftRightSplit ? mRootBounds.right : 0,
+                mIsLeftRightSplit ? 0 : mRootBounds.bottom);
     }
 
     /** Applies new configuration, returns {@code false} if there's no effect to the layout. */
@@ -309,6 +316,7 @@
         final int orientation = configuration.orientation;
         final int density = configuration.densityDpi;
         final int uiMode = configuration.uiMode;
+        final boolean wasLeftRightSplit = mIsLeftRightSplit;
 
         if (mOrientation == orientation
                 && mRotation == rotation
@@ -326,9 +334,12 @@
         mRotation = rotation;
         mDensity = density;
         mUiMode = uiMode;
+        mIsLargeScreen = configuration.smallestScreenWidthDp >= 600;
+        mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
+                configuration);
         mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
         updateDividerConfig(mContext);
-        initDividerPosition(mTempRect);
+        initDividerPosition(mTempRect, wasLeftRightSplit);
         updateInvisibleRect();
 
         return true;
@@ -347,18 +358,27 @@
         }
 
         // We only need new bounds here, other configuration should be update later.
+        final boolean wasLeftRightSplit = SplitScreenUtils.isLeftRightSplit(
+                mAllowLeftRightSplitInPortrait, mIsLargeScreen,
+                mRootBounds.width() >= mRootBounds.height());
         mTempRect.set(mRootBounds);
         mRootBounds.set(tmpRect);
+        mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
+                mIsLargeScreen, mRootBounds.width() >= mRootBounds.height());
         mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
-        initDividerPosition(mTempRect);
+        initDividerPosition(mTempRect, wasLeftRightSplit);
     }
 
-    private void initDividerPosition(Rect oldBounds) {
+    /**
+     * Updates the divider position to the position in the current orientation and bounds using the
+     * snap fraction calculated based on the previous orientation and bounds.
+     */
+    private void initDividerPosition(Rect oldBounds, boolean wasLeftRightSplit) {
         final float snapRatio = (float) mDividerPosition
-                / (float) (isLandscape(oldBounds) ? oldBounds.width() : oldBounds.height());
+                / (float) (wasLeftRightSplit ? oldBounds.width() : oldBounds.height());
         // Estimate position by previous ratio.
         final float length =
-                (float) (isLandscape() ? mRootBounds.width() : mRootBounds.height());
+                (float) (mIsLeftRightSplit ? mRootBounds.width() : mRootBounds.height());
         final int estimatePosition = (int) (length * snapRatio);
         // Init divider position by estimated position using current bounds snap algorithm.
         mDividerPosition = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(
@@ -376,8 +396,7 @@
         dividerBounds.set(mRootBounds);
         bounds1.set(mRootBounds);
         bounds2.set(mRootBounds);
-        final boolean isLandscape = isLandscape(mRootBounds);
-        if (isLandscape) {
+        if (mIsLeftRightSplit) {
             position += mRootBounds.left;
             dividerBounds.left = position - mDividerInsets;
             dividerBounds.right = dividerBounds.left + mDividerWindowWidth;
@@ -393,7 +412,7 @@
         DockedDividerUtils.sanitizeStackBounds(bounds1, true /** topLeft */);
         DockedDividerUtils.sanitizeStackBounds(bounds2, false /** topLeft */);
         if (setEffectBounds) {
-            mSurfaceEffectPolicy.applyDividerPosition(position, isLandscape);
+            mSurfaceEffectPolicy.applyDividerPosition(position, mIsLeftRightSplit);
         }
     }
 
@@ -563,13 +582,12 @@
     }
 
     private DividerSnapAlgorithm getSnapAlgorithm(Context context, Rect rootBounds) {
-        final boolean isLandscape = isLandscape(rootBounds);
         final Rect insets = getDisplayStableInsets(context);
 
         // Make split axis insets value same as the larger one to avoid bounds1 and bounds2
         // have difference for avoiding size-compat mode when switching unresizable apps in
         // landscape while they are letterboxed.
-        if (!isLandscape) {
+        if (!mIsLeftRightSplit) {
             final int largerInsets = Math.max(insets.top, insets.bottom);
             insets.set(insets.left, largerInsets, insets.right, largerInsets);
         }
@@ -579,9 +597,9 @@
                 rootBounds.width(),
                 rootBounds.height(),
                 mDividerSize,
-                !isLandscape,
+                !mIsLeftRightSplit,
                 insets,
-                isLandscape ? DOCKED_LEFT : DOCKED_TOP /* dockSide */);
+                mIsLeftRightSplit ? DOCKED_LEFT : DOCKED_TOP /* dockSide */);
     }
 
     /** Fling divider from current position to end or start position then exit */
@@ -643,13 +661,12 @@
     /** Switch both surface position with animation. */
     public void splitSwitching(SurfaceControl.Transaction t, SurfaceControl leash1,
             SurfaceControl leash2, Consumer<Rect> finishCallback) {
-        final boolean isLandscape = isLandscape();
         final Rect insets = getDisplayStableInsets(mContext);
-        insets.set(isLandscape ? insets.left : 0, isLandscape ? 0 : insets.top,
-                isLandscape ? insets.right : 0, isLandscape ? 0 : insets.bottom);
+        insets.set(mIsLeftRightSplit ? insets.left : 0, mIsLeftRightSplit ? 0 : insets.top,
+                mIsLeftRightSplit ? insets.right : 0, mIsLeftRightSplit ? 0 : insets.bottom);
 
         final int dividerPos = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(
-                isLandscape ? mBounds2.width() : mBounds2.height()).position;
+                mIsLeftRightSplit ? mBounds2.width() : mBounds2.height()).position;
         final Rect distBounds1 = new Rect();
         final Rect distBounds2 = new Rect();
         final Rect distDividerBounds = new Rect();
@@ -740,15 +757,12 @@
                         .toRect();
     }
 
-    private static boolean isLandscape(Rect bounds) {
-        return bounds.width() > bounds.height();
-    }
-
     /**
-     * Return if this layout is landscape.
+     * @return {@code true} if we should create a left-right split, {@code false} if we should
+     * create a top-bottom split.
      */
-    public boolean isLandscape() {
-        return isLandscape(mRootBounds);
+    public boolean isLeftRightSplit() {
+        return mIsLeftRightSplit;
     }
 
     /** Apply recorded surface layout to the {@link SurfaceControl.Transaction}. */
@@ -850,9 +864,13 @@
 
     /** Dumps the current split bounds recorded in this layout. */
     public void dump(@NonNull PrintWriter pw, String prefix) {
-        pw.println(prefix + "bounds1=" + mBounds1.toShortString());
-        pw.println(prefix + "dividerBounds=" + mDividerBounds.toShortString());
-        pw.println(prefix + "bounds2=" + mBounds2.toShortString());
+        final String innerPrefix = prefix + "\t";
+        pw.println(prefix + TAG + ":");
+        pw.println(innerPrefix + "mAllowLeftRightSplitInPortrait=" + mAllowLeftRightSplitInPortrait);
+        pw.println(innerPrefix + "mIsLeftRightSplit=" + mIsLeftRightSplit);
+        pw.println(innerPrefix + "bounds1=" + mBounds1.toShortString());
+        pw.println(innerPrefix + "dividerBounds=" + mDividerBounds.toShortString());
+        pw.println(innerPrefix + "bounds2=" + mBounds2.toShortString());
     }
 
     /** Handles layout change event. */
@@ -937,32 +955,32 @@
          * Applies a parallax to the task to hint dismissing progress.
          *
          * @param position    the split position to apply dismissing parallax effect
-         * @param isLandscape indicates whether it's splitting horizontally or vertically
+         * @param isLeftRightSplit indicates whether it's splitting horizontally or vertically
          */
-        void applyDividerPosition(int position, boolean isLandscape) {
+        void applyDividerPosition(int position, boolean isLeftRightSplit) {
             mDismissingSide = DOCKED_INVALID;
             mParallaxOffset.set(0, 0);
             mDismissingDimValue = 0;
 
             int totalDismissingDistance = 0;
             if (position < mDividerSnapAlgorithm.getFirstSplitTarget().position) {
-                mDismissingSide = isLandscape ? DOCKED_LEFT : DOCKED_TOP;
+                mDismissingSide = isLeftRightSplit ? DOCKED_LEFT : DOCKED_TOP;
                 totalDismissingDistance = mDividerSnapAlgorithm.getDismissStartTarget().position
                         - mDividerSnapAlgorithm.getFirstSplitTarget().position;
             } else if (position > mDividerSnapAlgorithm.getLastSplitTarget().position) {
-                mDismissingSide = isLandscape ? DOCKED_RIGHT : DOCKED_BOTTOM;
+                mDismissingSide = isLeftRightSplit ? DOCKED_RIGHT : DOCKED_BOTTOM;
                 totalDismissingDistance = mDividerSnapAlgorithm.getLastSplitTarget().position
                         - mDividerSnapAlgorithm.getDismissEndTarget().position;
             }
 
-            final boolean topLeftShrink = isLandscape
+            final boolean topLeftShrink = isLeftRightSplit
                     ? position < mWinBounds1.right : position < mWinBounds1.bottom;
             if (topLeftShrink) {
-                mShrinkSide = isLandscape ? DOCKED_LEFT : DOCKED_TOP;
+                mShrinkSide = isLeftRightSplit ? DOCKED_LEFT : DOCKED_TOP;
                 mContentBounds.set(mWinBounds1);
                 mSurfaceBounds.set(mBounds1);
             } else {
-                mShrinkSide = isLandscape ? DOCKED_RIGHT : DOCKED_BOTTOM;
+                mShrinkSide = isLeftRightSplit ? DOCKED_RIGHT : DOCKED_BOTTOM;
                 mContentBounds.set(mWinBounds2);
                 mSurfaceBounds.set(mBounds2);
             }
@@ -973,7 +991,7 @@
                 mDismissingDimValue = DIM_INTERPOLATOR.getInterpolation(fraction);
                 if (mParallaxType == PARALLAX_DISMISSING) {
                     fraction = calculateParallaxDismissingFraction(fraction, mDismissingSide);
-                    if (isLandscape) {
+                    if (isLeftRightSplit) {
                         mParallaxOffset.x = (int) (fraction * totalDismissingDistance);
                     } else {
                         mParallaxOffset.y = (int) (fraction * totalDismissingDistance);
@@ -982,7 +1000,7 @@
             }
 
             if (mParallaxType == PARALLAX_ALIGN_CENTER) {
-                if (isLandscape) {
+                if (isLeftRightSplit) {
                     mParallaxOffset.x =
                             (mSurfaceBounds.width() - mContentBounds.width()) / 2;
                 } else {
@@ -1129,7 +1147,7 @@
             // Calculate target bounds offset for IME
             mLastYOffset = mYOffsetForIme;
             final boolean needOffset = imeTargetPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
-                    && !isFloating && !isLandscape(mRootBounds) && mImeShown;
+                    && !isFloating && !mIsLeftRightSplit && mImeShown;
             mTargetYOffset = needOffset ? getTargetYOffset() : 0;
 
             if (mTargetYOffset != mLastYOffset) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
index d7ea1c0..0693543 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.common.split;
 
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+
 import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
 import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -25,9 +27,14 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.PendingIntent;
+import android.content.Context;
 import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.wm.shell.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
 
 /** Helper utility class for split screen components to use. */
@@ -94,4 +101,38 @@
     public static String splitFailureMessage(String caller, String reason) {
         return "(" + caller + ") Splitscreen aborted: " + reason;
     }
+
+    /**
+     * Returns whether left/right split is allowed in portrait.
+     */
+    public static boolean allowLeftRightSplitInPortrait(Resources res) {
+        return Flags.enableLeftRightSplitInPortrait() && res.getBoolean(
+                com.android.internal.R.bool.config_leftRightSplitInPortrait);
+    }
+
+    /**
+     * Returns whether left/right split is supported in the given configuration.
+     */
+    public static boolean isLeftRightSplit(boolean allowLeftRightSplitInPortrait,
+            Configuration config) {
+        // Compare the max bounds sizes as on near-square devices, the insets may result in a
+        // configuration in the other orientation
+        final boolean isLargeScreen = config.smallestScreenWidthDp >= 600;
+        final Rect maxBounds = config.windowConfiguration.getMaxBounds();
+        final boolean isLandscape = maxBounds.width() >= maxBounds.height();
+        return isLeftRightSplit(allowLeftRightSplitInPortrait, isLargeScreen, isLandscape);
+    }
+
+    /**
+     * Returns whether left/right split is supported in the given configuration state. This method
+     * is useful for cases where we need to calculate this given last saved state.
+     */
+    public static boolean isLeftRightSplit(boolean allowLeftRightSplitInPortrait,
+            boolean isLargeScreen, boolean isLandscape) {
+        if (allowLeftRightSplitInPortrait && isLargeScreen) {
+            return !isLandscape;
+        } else {
+            return isLandscape;
+        }
+    }
 }
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 0bf8ec3..fdfb6f3 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,6 +94,7 @@
     private ShellExecutor mMainExecutor;
     private ArrayList<DragAndDropListener> mListeners = new ArrayList<>();
 
+    // Map of displayId -> per-display info
     private final SparseArray<PerDisplay> mDisplayDropTargets = new SparseArray<>();
 
     /**
@@ -362,7 +363,7 @@
      */
     private boolean isReadyToHandleDrag() {
         for (int i = 0; i < mDisplayDropTargets.size(); i++) {
-            if (mDisplayDropTargets.valueAt(i).mHasDrawn) {
+            if (mDisplayDropTargets.valueAt(i).hasDrawn) {
                 return true;
             }
         }
@@ -398,8 +399,13 @@
      * Dumps information about this controller.
      */
     public void dump(@NonNull PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
         pw.println(prefix + TAG);
-        pw.println(prefix + " listeners=" + mListeners.size());
+        pw.println(innerPrefix + "listeners=" + mListeners.size());
+        pw.println(innerPrefix + "Per display:");
+        for (int i = 0; i < mDisplayDropTargets.size(); i++) {
+            mDisplayDropTargets.valueAt(i).dump(pw, innerPrefix);
+        }
     }
     
     /**
@@ -440,7 +446,7 @@
         final FrameLayout rootView;
         final DragLayout dragLayout;
         // Tracks whether the window has fully drawn since it was last made visible
-        boolean mHasDrawn;
+        boolean hasDrawn;
 
         boolean isHandlingDrag;
         // A count of the number of active drags in progress to ensure that we only hide the window
@@ -464,17 +470,29 @@
             rootView.setVisibility(visibility);
             if (visibility == View.VISIBLE) {
                 rootView.requestApplyInsets();
-                if (!mHasDrawn && rootView.getViewRootImpl() != null) {
+                if (!hasDrawn && rootView.getViewRootImpl() != null) {
                     rootView.getViewRootImpl().registerRtFrameCallback(this);
                 }
             } else {
-                mHasDrawn = false;
+                hasDrawn = false;
             }
         }
 
         @Override
         public void onFrameDraw(long frame) {
-            mHasDrawn = true;
+            hasDrawn = true;
+        }
+
+        /**
+         * Dumps information about this display's shell drop target.
+         */
+        public void dump(@NonNull PrintWriter pw, String prefix) {
+            final String innerPrefix = prefix + "  ";
+            pw.println(innerPrefix + "displayId=" + displayId);
+            pw.println(innerPrefix + "hasDrawn=" + hasDrawn);
+            pw.println(innerPrefix + "isHandlingDrag=" + isHandlingDrag);
+            pw.println(innerPrefix + "activeDragCount=" + activeDragCount);
+            dragLayout.dump(pw, innerPrefix);
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index e70768b..162ce19 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -138,7 +138,7 @@
         final Rect displayRegion = new Rect(l, t, l + iw, t + ih);
         final Rect fullscreenDrawRegion = new Rect(displayRegion);
         final Rect fullscreenHitRegion = new Rect(displayRegion);
-        final boolean inLandscape = mSession.displayLayout.isLandscape();
+        final boolean isLeftRightSplit = mSplitScreen != null && mSplitScreen.isLeftRightSplit();
         final boolean inSplitScreen = mSplitScreen != null && mSplitScreen.isSplitScreenVisible();
         final float dividerWidth = mContext.getResources().getDimensionPixelSize(
                 R.dimen.split_divider_bar_width);
@@ -155,7 +155,7 @@
             topOrLeftBounds.intersect(displayRegion);
             bottomOrRightBounds.intersect(displayRegion);
 
-            if (inLandscape) {
+            if (isLeftRightSplit) {
                 final Rect leftHitRegion = new Rect();
                 final Rect rightHitRegion = new Rect();
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index 205a455..445ba89 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -20,6 +20,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
 import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -47,14 +48,18 @@
 import android.view.WindowInsets.Type;
 import android.widget.LinearLayout;
 
+import androidx.annotation.NonNull;
+
 import com.android.internal.logging.InstanceId;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.Interpolators;
+import com.android.wm.shell.common.split.SplitScreenUtils;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 /**
@@ -74,6 +79,11 @@
     private final StatusBarManager mStatusBarManager;
     private final Configuration mLastConfiguration = new Configuration();
 
+    // Whether this device supports left/right split in portrait
+    private final boolean mAllowLeftRightSplitInPortrait;
+    // Whether the device is currently in left/right split mode
+    private boolean mIsLeftRightSplit;
+
     private DragAndDropPolicy.Target mCurrentTarget = null;
     private DropZoneView mDropZoneView1;
     private DropZoneView mDropZoneView2;
@@ -106,17 +116,18 @@
         setLayoutDirection(LAYOUT_DIRECTION_LTR);
         mDropZoneView1 = new DropZoneView(context);
         mDropZoneView2 = new DropZoneView(context);
-        addView(mDropZoneView1, new LinearLayout.LayoutParams(MATCH_PARENT,
-                MATCH_PARENT));
-        addView(mDropZoneView2, new LinearLayout.LayoutParams(MATCH_PARENT,
-                MATCH_PARENT));
+        addView(mDropZoneView1, new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+        addView(mDropZoneView2, new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
         ((LayoutParams) mDropZoneView1.getLayoutParams()).weight = 1;
         ((LayoutParams) mDropZoneView2.getLayoutParams()).weight = 1;
-        int orientation = getResources().getConfiguration().orientation;
-        setOrientation(orientation == Configuration.ORIENTATION_LANDSCAPE
-                ? LinearLayout.HORIZONTAL
-                : LinearLayout.VERTICAL);
-        updateContainerMargins(getResources().getConfiguration().orientation);
+        // We don't use the configuration orientation here to determine landscape because
+        // near-square devices may report the same orietation with insets taken into account
+        mAllowLeftRightSplitInPortrait = SplitScreenUtils.allowLeftRightSplitInPortrait(
+                context.getResources());
+        mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
+                getResources().getConfiguration());
+        setOrientation(mIsLeftRightSplit ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
+        updateContainerMargins(mIsLeftRightSplit);
     }
 
     @Override
@@ -124,11 +135,12 @@
         mInsets = insets.getInsets(Type.tappableElement() | Type.displayCutout());
         recomputeDropTargets();
 
-        final int orientation = getResources().getConfiguration().orientation;
-        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+        boolean isLeftRightSplit = mSplitScreenController != null
+                && mSplitScreenController.isLeftRightSplit();
+        if (isLeftRightSplit) {
             mDropZoneView1.setBottomInset(mInsets.bottom);
             mDropZoneView2.setBottomInset(mInsets.bottom);
-        } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+        } else {
             mDropZoneView1.setBottomInset(0);
             mDropZoneView2.setBottomInset(mInsets.bottom);
         }
@@ -136,14 +148,12 @@
     }
 
     public void onConfigChanged(Configuration newConfig) {
-        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE
-                && getOrientation() != HORIZONTAL) {
-            setOrientation(LinearLayout.HORIZONTAL);
-            updateContainerMargins(newConfig.orientation);
-        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT
-                && getOrientation() != VERTICAL) {
-            setOrientation(LinearLayout.VERTICAL);
-            updateContainerMargins(newConfig.orientation);
+        boolean isLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
+                newConfig);
+        if (isLeftRightSplit != mIsLeftRightSplit) {
+            mIsLeftRightSplit = isLeftRightSplit;
+            setOrientation(mIsLeftRightSplit ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
+            updateContainerMargins(mIsLeftRightSplit);
         }
 
         final int diff = newConfig.diff(mLastConfiguration);
@@ -162,14 +172,14 @@
         mDropZoneView2.setContainerMargin(0, 0, 0, 0);
     }
 
-    private void updateContainerMargins(int orientation) {
+    private void updateContainerMargins(boolean isLeftRightSplit) {
         final float halfMargin = mDisplayMargin / 2f;
-        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+        if (isLeftRightSplit) {
             mDropZoneView1.setContainerMargin(
                     mDisplayMargin, mDisplayMargin, halfMargin, mDisplayMargin);
             mDropZoneView2.setContainerMargin(
                     halfMargin, mDisplayMargin, mDisplayMargin, mDisplayMargin);
-        } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+        } else {
             mDropZoneView1.setContainerMargin(
                     mDisplayMargin, mDisplayMargin, mDisplayMargin, halfMargin);
             mDropZoneView2.setContainerMargin(
@@ -257,23 +267,21 @@
      * @param bounds2 bounds to apply to the second dropzone view, null if split in half.
      */
     private void updateDropZoneSizes(Rect bounds1, Rect bounds2) {
-        final int orientation = getResources().getConfiguration().orientation;
-        final boolean isPortrait = orientation == Configuration.ORIENTATION_PORTRAIT;
         final int halfDivider = mDividerSize / 2;
         final LinearLayout.LayoutParams dropZoneView1 =
                 (LayoutParams) mDropZoneView1.getLayoutParams();
         final LinearLayout.LayoutParams dropZoneView2 =
                 (LayoutParams) mDropZoneView2.getLayoutParams();
-        if (isPortrait) {
-            dropZoneView1.width = MATCH_PARENT;
-            dropZoneView2.width = MATCH_PARENT;
-            dropZoneView1.height = bounds1 != null ? bounds1.height() + halfDivider : MATCH_PARENT;
-            dropZoneView2.height = bounds2 != null ? bounds2.height() + halfDivider : MATCH_PARENT;
-        } else {
+        if (mIsLeftRightSplit) {
             dropZoneView1.width = bounds1 != null ? bounds1.width() + halfDivider : MATCH_PARENT;
             dropZoneView2.width = bounds2 != null ? bounds2.width() + halfDivider : MATCH_PARENT;
             dropZoneView1.height = MATCH_PARENT;
             dropZoneView2.height = MATCH_PARENT;
+        } else {
+            dropZoneView1.width = MATCH_PARENT;
+            dropZoneView2.width = MATCH_PARENT;
+            dropZoneView1.height = bounds1 != null ? bounds1.height() + halfDivider : MATCH_PARENT;
+            dropZoneView2.height = bounds2 != null ? bounds2.height() + halfDivider : MATCH_PARENT;
         }
         dropZoneView1.weight = bounds1 != null ? 0 : 1;
         dropZoneView2.weight = bounds2 != null ? 0 : 1;
@@ -371,7 +379,7 @@
         // Reset the state if we previously force-ignore the bottom margin
         mDropZoneView1.setForceIgnoreBottomMargin(false);
         mDropZoneView2.setForceIgnoreBottomMargin(false);
-        updateContainerMargins(getResources().getConfiguration().orientation);
+        updateContainerMargins(mIsLeftRightSplit);
         mCurrentTarget = null;
     }
 
@@ -481,4 +489,19 @@
         final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
         return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).toArgb();
     }
+
+    /**
+     * Dumps information about this drag layout.
+     */
+    public void dump(@NonNull PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + "DragLayout:");
+        pw.println(innerPrefix + "mIsLeftRightSplitInPortrait=" + mAllowLeftRightSplitInPortrait);
+        pw.println(innerPrefix + "mIsLeftRightSplit=" + mIsLeftRightSplit);
+        pw.println(innerPrefix + "mDisplayMargin=" + mDisplayMargin);
+        pw.println(innerPrefix + "mDividerSize=" + mDividerSize);
+        pw.println(innerPrefix + "mIsShowing=" + mIsShowing);
+        pw.println(innerPrefix + "mHasDropped=" + mHasDropped);
+        pw.println(innerPrefix + "mCurrentTarget=" + mCurrentTarget);
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
index 478b6a9..353d702 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
@@ -18,31 +18,17 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.ClipDescription.EXTRA_PENDING_INTENT;
-import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
-import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
-import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
-import static android.content.Intent.EXTRA_USER;
 
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
-import android.app.PendingIntent;
 import android.app.WindowConfiguration;
 import android.content.ClipData;
-import android.content.ClipDescription;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.net.Uri;
-import android.os.UserHandle;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
 
 import com.android.wm.shell.common.DisplayLayout;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
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 b4067d0..fdd3044 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
@@ -123,7 +123,7 @@
 
     private static final int EXTRA_CONTENT_OVERLAY_FADE_OUT_DELAY_MS =
             SystemProperties.getInt(
-                    "persist.wm.debug.extra_content_overlay_fade_out_delay_ms", 0);
+                    "persist.wm.debug.extra_content_overlay_fade_out_delay_ms", 450);
 
     private final Context mContext;
     private final SyncTransactionQueue mSyncTransactionQueue;
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 271a3b2..79c2076 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
@@ -590,7 +590,7 @@
                 cancel("transit_sleep");
                 return;
             }
-            if (mKeyguardLocked) {
+            if (mKeyguardLocked || (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0) {
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
                         "[%d] RecentsController.merge: keyguard is locked", mInstanceId);
                 // We will not accept new changes if we are swiping over the keyguard.
@@ -627,7 +627,8 @@
                         && mRecentsTask.equals(change.getContainer());
                 hasTaskChange = hasTaskChange || isRootTask;
                 final boolean isLeafTask = leafTaskFilter.test(change);
-                if (TransitionUtil.isOpeningType(change.getMode())) {
+                if (TransitionUtil.isOpeningType(change.getMode())
+                        || TransitionUtil.isOrderOnly(change)) {
                     if (isRecentsTask) {
                         recentsOpening = change;
                     } else if (isRootTask || isLeafTask) {
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 664d4491..37b24e5 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
@@ -366,6 +366,14 @@
         return mStageCoordinator.getStageOfTask(taskId);
     }
 
+    /**
+     * @return {@code true} if we should create a left-right split, {@code false} if we should
+     * create a top-bottom split.
+     */
+    public boolean isLeftRightSplit() {
+        return mStageCoordinator.isLeftRightSplit();
+    }
+
     /** Check split is foreground and task is under split or not by taskId. */
     public boolean isTaskInSplitScreenForeground(int taskId) {
         return isTaskInSplitScreen(taskId) && isSplitScreenVisible();
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 7a4834c..36e0eb4 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
@@ -1301,7 +1301,7 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Switch split position: %s", reason);
         mLogger.logSwap(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
                 getSideStagePosition(), mSideStage.getTopChildTaskUid(),
-                mSplitLayout.isLandscape());
+                mSplitLayout.isLeftRightSplit());
     }
 
     void setSideStagePosition(@SplitPosition int sideStagePosition,
@@ -1659,7 +1659,7 @@
             mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
                     getMainStagePosition(), mMainStage.getTopChildTaskUid(),
                     getSideStagePosition(), mSideStage.getTopChildTaskUid(),
-                    mSplitLayout.isLandscape());
+                    mSplitLayout.isLeftRightSplit());
         }
     }
 
@@ -1749,10 +1749,10 @@
         }
         if (stage == STAGE_TYPE_MAIN) {
             mLogger.logMainStageAppChange(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
-                    mSplitLayout.isLandscape());
+                    mSplitLayout.isLeftRightSplit());
         } else {
             mLogger.logSideStageAppChange(getSideStagePosition(), mSideStage.getTopChildTaskUid(),
-                    mSplitLayout.isLandscape());
+                    mSplitLayout.isLeftRightSplit());
         }
         if (present) {
             updateRecentTasksSplitPair();
@@ -2113,7 +2113,7 @@
                 mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
                         getMainStagePosition(), mMainStage.getTopChildTaskUid(),
                         getSideStagePosition(), mSideStage.getTopChildTaskUid(),
-                        mSplitLayout.isLandscape());
+                        mSplitLayout.isLeftRightSplit());
             }
         }
     }
@@ -2205,8 +2205,12 @@
         mLogger.logResize(mSplitLayout.getDividerPositionAsFraction());
     }
 
-    private boolean isLandscape() {
-        return mSplitLayout.isLandscape();
+    /**
+     * @return {@code true} if we should create a left-right split, {@code false} if we should
+     * create a top-bottom split.
+     */
+    boolean isLeftRightSplit() {
+        return mSplitLayout.isLeftRightSplit();
     }
 
     /**
@@ -3177,6 +3181,7 @@
         pw.println(innerPrefix + "mDividerVisible=" + mDividerVisible);
         pw.println(innerPrefix + "isSplitActive=" + isSplitActive());
         pw.println(innerPrefix + "isSplitVisible=" + isSplitScreenVisible());
+        pw.println(innerPrefix + "isLeftRightSplit=" + mSplitLayout.isLeftRightSplit());
         pw.println(innerPrefix + "MainStage");
         pw.println(childPrefix + "stagePosition=" + splitPositionToString(getMainStagePosition()));
         pw.println(childPrefix + "isActive=" + mMainStage.isActive());
@@ -3188,10 +3193,7 @@
         mSideStage.dump(pw, childPrefix);
         pw.println(innerPrefix + "SideStageListener");
         mSideStageListener.dump(pw, childPrefix);
-        if (mMainStage.isActive()) {
-            pw.println(innerPrefix + "SplitLayout");
-            mSplitLayout.dump(pw, childPrefix);
-        }
+        mSplitLayout.dump(pw, childPrefix);
         if (!mPausingTasks.isEmpty()) {
             pw.println(childPrefix + "mPausingTasks=" + mPausingTasks);
         }
@@ -3243,7 +3245,7 @@
         mLogger.logExit(exitReason,
                 SPLIT_POSITION_UNDEFINED, 0 /* mainStageUid */,
                 SPLIT_POSITION_UNDEFINED, 0 /* sideStageUid */,
-                mSplitLayout.isLandscape());
+                mSplitLayout.isLeftRightSplit());
     }
 
     /**
@@ -3256,7 +3258,7 @@
                 toMainStage ? mMainStage.getTopChildTaskUid() : 0 /* mainStageUid */,
                 !toMainStage ? getSideStagePosition() : SPLIT_POSITION_UNDEFINED,
                 !toMainStage ? mSideStage.getTopChildTaskUid() : 0 /* sideStageUid */,
-                mSplitLayout.isLandscape());
+                mSplitLayout.isLeftRightSplit());
     }
 
     class StageListenerImpl implements StageTaskListener.StageListenerCallbacks {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java
index ef8393c..35a1fa0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java
@@ -151,7 +151,14 @@
 
     @Override
     public void setResizeBgColor(SurfaceControl.Transaction t, int bgColor) {
-        runOnViewThread(() -> setResizeBackgroundColor(t, bgColor));
+        if (mHandler.getLooper().isCurrentThread()) {
+            // We can only use the transaction if it can updated synchronously, otherwise the tx
+            // will be applied immediately after but also used/updated on the view thread which
+            // will lead to a race and/or crash
+            runOnViewThread(() -> setResizeBackgroundColor(t, bgColor));
+        } else {
+            runOnViewThread(() -> setResizeBackgroundColor(bgColor));
+        }
     }
 
     /**
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 8cbcde3..53ec201 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
@@ -49,7 +49,6 @@
 import android.view.ViewConfiguration;
 import android.view.WindowManagerGlobal;
 
-import com.android.internal.view.BaseIWindow;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 
@@ -70,7 +69,9 @@
     private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;
 
     private final int mDisplayId;
-    private final BaseIWindow mFakeWindow;
+
+    private final IBinder mClientToken;
+
     private final IBinder mFocusGrantToken;
     private final SurfaceControl mDecorationSurface;
     private final InputChannel mInputChannel;
@@ -78,7 +79,7 @@
     private final DragPositioningCallback mCallback;
 
     private final SurfaceControl mInputSinkSurface;
-    private final BaseIWindow mFakeSinkWindow;
+    private final IBinder mSinkClientToken;
     private final InputChannel mSinkInputChannel;
     private final DisplayController mDisplayController;
 
@@ -116,17 +117,14 @@
         mTaskCornerRadius = taskCornerRadius;
         mDecorationSurface = decorationSurface;
         mDisplayController = displayController;
-        // Use a fake window as the backing surface is a container layer, and we don't want to
-        // create a buffer layer for it, so we can't use ViewRootImpl.
-        mFakeWindow = new BaseIWindow();
-        mFakeWindow.setSession(mWindowSession);
+        mClientToken = new Binder();
         mFocusGrantToken = new Binder();
         mInputChannel = new InputChannel();
         try {
             mWindowSession.grantInputChannel(
                     mDisplayId,
                     mDecorationSurface,
-                    mFakeWindow.asBinder(),
+                    mClientToken,
                     null /* hostInputToken */,
                     FLAG_NOT_FOCUSABLE,
                     PRIVATE_FLAG_TRUSTED_OVERLAY,
@@ -155,13 +153,13 @@
                 .setLayer(mInputSinkSurface, WindowDecoration.INPUT_SINK_Z_ORDER)
                 .show(mInputSinkSurface)
                 .apply();
-        mFakeSinkWindow = new BaseIWindow();
+        mSinkClientToken = new Binder();
         mSinkInputChannel = new InputChannel();
         try {
             mWindowSession.grantInputChannel(
                     mDisplayId,
                     mInputSinkSurface,
-                    mFakeSinkWindow.asBinder(),
+                    mSinkClientToken,
                     null /* hostInputToken */,
                     FLAG_NOT_FOCUSABLE,
                     0 /* privateFlags */,
@@ -324,14 +322,14 @@
         mInputEventReceiver.dispose();
         mInputChannel.dispose();
         try {
-            mWindowSession.remove(mFakeWindow.asBinder());
+            mWindowSession.remove(mClientToken);
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
 
         mSinkInputChannel.dispose();
         try {
-            mWindowSession.remove(mFakeSinkWindow.asBinder());
+            mWindowSession.remove(mSinkClientToken);
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp
index 366f7b1..4abaf5b 100644
--- a/libs/WindowManager/Shell/tests/flicker/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/Android.bp
@@ -52,7 +52,7 @@
 }
 
 java_defaults {
-    name: "WMShellFlickerTestsDefaultWithoutTemplate",
+    name: "WMShellFlickerTestsDefault",
     platform_apis: true,
     certificate: "platform",
     optimize: {
@@ -75,16 +75,9 @@
     ],
     data: [
         ":FlickerTestApp",
-        "trace_config/*",
     ],
 }
 
-java_defaults {
-    name: "WMShellFlickerTestsDefault",
-    defaults: ["WMShellFlickerTestsDefaultWithoutTemplate"],
-    test_config_template: "AndroidTestTemplate.xml",
-}
-
 java_library {
     name: "WMShellFlickerTestsBase",
     defaults: ["WMShellFlickerTestsDefault"],
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml
deleted file mode 100644
index b00d88e..0000000
--- a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2023 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
-    <option name="test-tag" value="FlickerTests"/>
-    <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
-    <option name="isolated-storage" value="false"/>
-
-    <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
-        <!-- keeps the screen on during tests -->
-        <option name="screen-always-on" value="on"/>
-        <!-- prevents the phone from restarting -->
-        <option name="force-skip-system-props" value="true"/>
-        <!-- set WM tracing verbose level to all -->
-        <option name="run-command" value="cmd window tracing level all"/>
-        <!-- set WM tracing to frame (avoid incomplete states) -->
-        <option name="run-command" value="cmd window tracing frame"/>
-        <!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests -->
-        <option name="run-command" value="pm disable com.google.android.internal.betterbug"/>
-        <!-- ensure lock screen mode is swipe -->
-        <option name="run-command" value="locksettings set-disabled false"/>
-        <!-- restart launcher to activate TAPL -->
-        <option name="run-command"
-                value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/>
-        <!-- Increase trace size: 20mb for WM and 80mb for SF -->
-        <option name="run-command" value="cmd window tracing size 20480"/>
-        <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/>
-        <!-- b/307664397 - Ensure camera has the correct permissions and doesn't show a dialog -->
-        <option name="run-command"
-                value="pm grant com.google.android.GoogleCamera android.permission.ACCESS_FINE_LOCATION"/>
-    </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-        <option name="test-user-token" value="%TEST_USER%"/>
-        <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
-        <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
-        <option name="run-command" value="settings put system show_touches 1"/>
-        <option name="run-command" value="settings put system pointer_location 1"/>
-        <option name="teardown-command"
-                value="settings delete secure show_ime_with_hard_keyboard"/>
-        <option name="teardown-command" value="settings delete system show_touches"/>
-        <option name="teardown-command" value="settings delete system pointer_location"/>
-        <option name="teardown-command"
-                value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
-    </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true"/>
-        <option name="test-file-name" value="{MODULE}.apk"/>
-        <option name="test-file-name" value="FlickerTestApp.apk"/>
-    </target_preparer>
-    <!-- Enable mocking GPS location by the test app -->
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-        <option name="run-command"
-                value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/>
-        <option name="teardown-command"
-                value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/>
-    </target_preparer>
-
-    <!-- Needed for pushing the trace config file -->
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="push-file"
-                key="trace_config.textproto"
-                value="/data/misc/perfetto-traces/trace_config.textproto"
-        />
-        <!--Install the content provider automatically when we push some file in sdcard folder.-->
-        <!--Needed to avoid the installation during the test suite.-->
-        <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
-        <option name="package" value="{PACKAGE}"/>
-        <option name="shell-timeout" value="6600s"/>
-        <option name="test-timeout" value="6000s"/>
-        <option name="hidden-api-checks" value="false"/>
-        <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
-        <!-- PerfettoListener related arguments -->
-        <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
-        <option name="instrumentation-arg"
-                key="perfetto_config_file"
-                value="trace_config.textproto"
-        />
-        <option name="instrumentation-arg" key="per_run" value="true"/>
-    </test>
-    <!-- Needed for pulling the collected trace config on to the host -->
-    <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
-        <option name="pull-pattern-keys" value="perfetto_file_path"/>
-        <option name="directory-keys"
-                value="/data/user/0/com.android.wm.shell.flicker/files"/>
-        <option name="directory-keys"
-                value="/data/user/0/com.android.wm.shell.flicker.bubbles/files"/>
-        <option name="directory-keys"
-                value="/data/user/0/com.android.wm.shell.flicker.pip/files"/>
-        <option name="directory-keys"
-                value="/data/user/0/com.android.wm.shell.flicker.splitscreen/files"/>
-        <option name="directory-keys"
-                value="/data/user/0/com.android.wm.shell.flicker.service/files"/>
-        <option name="collect-on-run-ended-only" value="true"/>
-        <option name="clean-up" value="true"/>
-    </metrics_collector>
-</configuration>
diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/Android.bp b/libs/WindowManager/Shell/tests/flicker/appcompat/Android.bp
index bae701f..e151ab2 100644
--- a/libs/WindowManager/Shell/tests/flicker/appcompat/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/Android.bp
@@ -36,6 +36,8 @@
     manifest: "AndroidManifest.xml",
     package_name: "com.android.wm.shell.flicker",
     instrumentation_target_package: "com.android.wm.shell.flicker",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: [":WMShellFlickerTestsAppCompat-src"],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/bubble/Android.bp b/libs/WindowManager/Shell/tests/flicker/bubble/Android.bp
index c4e9a84..f0b4f1f 100644
--- a/libs/WindowManager/Shell/tests/flicker/bubble/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/Android.bp
@@ -29,6 +29,8 @@
     manifest: "AndroidManifest.xml",
     package_name: "com.android.wm.shell.flicker.bubbles",
     instrumentation_target_package: "com.android.wm.shell.flicker.bubbles",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: ["src/**/*.kt"],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/Android.bp b/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
index 386983c..e61f762 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
@@ -62,11 +62,13 @@
     manifest: "AndroidManifest.xml",
     package_name: "com.android.wm.shell.flicker.pip",
     instrumentation_target_package: "com.android.wm.shell.flicker.pip",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: [
         ":WMShellFlickerTestsPip1-src",
         ":WMShellFlickerTestsPipCommon-src",
     ],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
 
 android_test {
@@ -75,11 +77,13 @@
     manifest: "AndroidManifest.xml",
     package_name: "com.android.wm.shell.flicker.pip",
     instrumentation_target_package: "com.android.wm.shell.flicker.pip",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: [
         ":WMShellFlickerTestsPip2-src",
         ":WMShellFlickerTestsPipCommon-src",
     ],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
 
 android_test {
@@ -88,6 +92,7 @@
     manifest: "AndroidManifest.xml",
     package_name: "com.android.wm.shell.flicker.pip",
     instrumentation_target_package: "com.android.wm.shell.flicker.pip",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: [
         ":WMShellFlickerTestsPip3-src",
         ":WMShellFlickerTestsPipCommon-src",
@@ -98,6 +103,7 @@
         ":WMShellFlickerTestsPipApps-src",
     ],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
 
 android_test {
@@ -106,19 +112,22 @@
     manifest: "AndroidManifest.xml",
     package_name: "com.android.wm.shell.flicker.pip.apps",
     instrumentation_target_package: "com.android.wm.shell.flicker.pip.apps",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: [
         ":WMShellFlickerTestsPipApps-src",
         ":WMShellFlickerTestsPipCommon-src",
     ],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
 
 android_test {
     name: "WMShellFlickerTestsPipAppsCSuite",
-    defaults: ["WMShellFlickerTestsDefaultWithoutTemplate"],
+    defaults: ["WMShellFlickerTestsDefault"],
     additional_manifests: ["AndroidManifest.xml"],
     package_name: "com.android.wm.shell.flicker.pip.apps",
     instrumentation_target_package: "com.android.wm.shell.flicker.pip.apps",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: [
         ":WMShellFlickerTestsPipApps-src",
         ":WMShellFlickerTestsPipCommon-src",
@@ -128,9 +137,11 @@
         "device-tests",
         "csuite",
     ],
+    data: ["trace_config/*"],
 }
 
 csuite_test {
     name: "csuite-1p3p-pip-flickers",
+    test_plan_include: "csuitePlan.xml",
     test_config_template: "csuiteDefaultTemplate.xml",
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml b/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
index 6429b00..f5a8655 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
+++ b/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
@@ -45,12 +45,15 @@
         <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
         <option name="run-command" value="settings put system show_touches 1"/>
         <option name="run-command" value="settings put system pointer_location 1"/>
+        <option name="run-command" value="settings put global package_verifier_user_consent -1"/>
         <option name="teardown-command"
                 value="settings delete secure show_ime_with_hard_keyboard"/>
         <option name="teardown-command" value="settings delete system show_touches"/>
         <option name="teardown-command" value="settings delete system pointer_location"/>
         <option name="teardown-command"
                 value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
+        <option name="teardown-command"
+                value="settings put global package_verifier_user_consent 1"/>
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true"/>
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/csuitePlan.xml b/libs/WindowManager/Shell/tests/flicker/pip/csuitePlan.xml
new file mode 100644
index 0000000..a2fc6b4
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/csuitePlan.xml
@@ -0,0 +1,3 @@
+<configuration description="Flicker tests C-Suite Crawler Test Plan">
+  <target_preparer class="com.android.csuite.core.AppCrawlTesterHostPreparer"/>
+</configuration>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/service/Android.bp b/libs/WindowManager/Shell/tests/flicker/service/Android.bp
index 9b8cd94..4f1a68a 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/service/Android.bp
@@ -52,8 +52,10 @@
     manifest: "AndroidManifest.xml",
     package_name: "com.android.wm.shell.flicker.service",
     instrumentation_target_package: "com.android.wm.shell.flicker.service",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: ["src/**/*.kt"],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
 
 android_test {
@@ -62,6 +64,8 @@
     manifest: "AndroidManifest.xml",
     package_name: "com.android.wm.shell.flicker.service",
     instrumentation_target_package: "com.android.wm.shell.flicker.service",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: [":WMShellFlickerServicePlatinumTests-src"],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
index 80ab24d..824e454 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
@@ -27,6 +28,7 @@
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -64,4 +66,8 @@
         primaryApp.exit(wmHelper)
         secondaryApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
index cc982d1..c52ada3b 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
@@ -29,6 +30,7 @@
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -75,4 +77,8 @@
         secondaryApp.exit(wmHelper)
         sendNotificationApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
index fa12bb8..8134fdd 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
@@ -29,6 +30,7 @@
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -82,4 +84,8 @@
         primaryApp.exit(wmHelper)
         secondaryApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
index 2592fd4..3417744 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
@@ -28,6 +29,7 @@
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -70,4 +72,8 @@
         primaryApp.exit(wmHelper)
         secondaryApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
index 983653b..f1a011c 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
@@ -27,6 +28,7 @@
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -70,4 +72,8 @@
         primaryApp.exit(wmHelper)
         secondaryApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
index 068171d..c9b1c91 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
@@ -20,6 +20,7 @@
 import android.graphics.Point
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.helpers.WindowUtils
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
@@ -29,6 +30,7 @@
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -149,4 +151,8 @@
         val LARGE_SCREEN_DP_THRESHOLD = 600
         return sizeDp.x >= LARGE_SCREEN_DP_THRESHOLD && sizeDp.y >= LARGE_SCREEN_DP_THRESHOLD
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
index 64b75c5..72f2db3 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
@@ -27,6 +28,7 @@
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -67,4 +69,8 @@
         primaryApp.exit(wmHelper)
         secondaryApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
index 1795010..511de4f 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
@@ -27,6 +28,7 @@
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -66,4 +68,8 @@
         primaryApp.exit(wmHelper)
         secondaryApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
index 7065846..558d2bf 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
@@ -27,6 +28,7 @@
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -68,4 +70,8 @@
         primaryApp.exit(wmHelper)
         secondaryApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
index 251cb50..ecd68295 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
@@ -27,6 +28,7 @@
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -69,4 +71,8 @@
         thirdApp.exit(wmHelper)
         fourthApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
index a9933bbe..f50d5c7 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
@@ -19,6 +19,7 @@
 import android.app.Instrumentation
 import android.tools.common.NavBar
 import android.tools.common.Rotation
+import android.tools.device.AndroidLoggerSetupRule
 import android.tools.device.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
@@ -27,6 +28,7 @@
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
@@ -66,4 +68,8 @@
         primaryApp.exit(wmHelper)
         secondaryApp.exit(wmHelper)
     }
+
+    companion object {
+        @ClassRule @JvmField val setupLoggerRule = AndroidLoggerSetupRule()
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp b/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
index 4629c53..f813b0d 100644
--- a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
@@ -54,11 +54,13 @@
     manifest: "AndroidManifest.xml",
     package_name: "com.android.wm.shell.flicker.splitscreen",
     instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
+    test_config_template: "AndroidTestTemplate.xml",
     srcs: [
         ":WMShellFlickerTestsSplitScreenBase-src",
         ":WMShellFlickerTestsSplitScreenGroup1-src",
     ],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
 
 android_test {
@@ -74,4 +76,5 @@
         ":WMShellFlickerTestsSplitScreenGroup1-src",
     ],
     static_libs: ["WMShellFlickerTestsBase"],
+    data: ["trace_config/*"],
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/trace_config/trace_config.textproto
deleted file mode 100644
index 406ada9..0000000
--- a/libs/WindowManager/Shell/tests/flicker/trace_config/trace_config.textproto
+++ /dev/null
@@ -1,75 +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.
-
-# proto-message: TraceConfig
-
-# Enable periodic flushing of the trace buffer into the output file.
-write_into_file: true
-
-# Writes the userspace buffer into the file every 1s.
-file_write_period_ms: 2500
-
-# See b/126487238 - we need to guarantee ordering of events.
-flush_period_ms: 30000
-
-# The trace buffers needs to be big enough to hold |file_write_period_ms| of
-# trace data. The trace buffer sizing depends on the number of trace categories
-# enabled and the device activity.
-
-# RSS events
-buffers: {
-  size_kb: 63488
-  fill_policy: RING_BUFFER
-}
-
-data_sources {
-  config {
-    name: "linux.process_stats"
-    target_buffer: 0
-    # polled per-process memory counters and process/thread names.
-    # If you don't want the polled counters, remove the "process_stats_config"
-    # section, but keep the data source itself as it still provides on-demand
-    # thread/process naming for ftrace data below.
-    process_stats_config {
-      scan_all_processes_on_start: true
-    }
-  }
-}
-
-data_sources: {
-  config {
-    name: "linux.ftrace"
-    ftrace_config {
-      ftrace_events: "ftrace/print"
-      ftrace_events: "task/task_newtask"
-      ftrace_events: "task/task_rename"
-      atrace_categories: "ss"
-      atrace_categories: "wm"
-      atrace_categories: "am"
-      atrace_categories: "aidl"
-      atrace_categories: "input"
-      atrace_categories: "binder_driver"
-      atrace_categories: "sched_process_exit"
-      atrace_apps: "com.android.server.wm.flicker.testapp"
-      atrace_apps: "com.android.systemui"
-      atrace_apps: "com.android.wm.shell.flicker"
-      atrace_apps: "com.android.wm.shell.flicker.other"
-      atrace_apps: "com.android.wm.shell.flicker.bubbles"
-      atrace_apps: "com.android.wm.shell.flicker.pip"
-      atrace_apps: "com.android.wm.shell.flicker.splitscreen"
-      atrace_apps: "com.google.android.apps.nexuslauncher"
-    }
-  }
-}
-
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestHandler.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestHandler.java
new file mode 100644
index 0000000..b91d6f9
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestHandler.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+
+/**
+ * Basic test handler that immediately executes anything that is posted on it.
+ */
+public class TestHandler extends Handler {
+    public TestHandler(Looper looper) {
+        super(looper);
+    }
+
+    @Override
+    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+        dispatchMessage(msg);
+        return true;
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
index 527dc01..1b347e0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
@@ -204,6 +204,7 @@
 
     @Test
     public void testDragAppOverFullscreenHome_expectOnlyFullscreenTarget() {
+        doReturn(true).when(mSplitScreenStarter).isLeftRightSplit();
         setRunningTask(mHomeTask);
         DragSession dragSession = new DragSession(mContext, mActivityTaskManager,
                 mLandscapeDisplayLayout, mActivityClipData);
@@ -219,6 +220,7 @@
 
     @Test
     public void testDragAppOverFullscreenApp_expectSplitScreenTargets() {
+        doReturn(true).when(mSplitScreenStarter).isLeftRightSplit();
         setRunningTask(mFullscreenAppTask);
         DragSession dragSession = new DragSession(mContext, mActivityTaskManager,
                 mLandscapeDisplayLayout, mActivityClipData);
@@ -239,6 +241,7 @@
 
     @Test
     public void testDragAppOverFullscreenAppPhone_expectVerticalSplitScreenTargets() {
+        doReturn(false).when(mSplitScreenStarter).isLeftRightSplit();
         setRunningTask(mFullscreenAppTask);
         DragSession dragSession = new DragSession(mContext, mActivityTaskManager,
                 mPortraitDisplayLayout, mActivityClipData);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenUtilsTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenUtilsTests.java
new file mode 100644
index 0000000..30847d3
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenUtilsTests.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.splitscreen;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.common.split.SplitScreenUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/** Tests for {@link com.android.wm.shell.common.split.SplitScreenUtils} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SplitScreenUtilsTests extends ShellTestCase {
+
+    @Test
+    public void testIsLeftRightSplit() {
+        Configuration portraitTablet = new Configuration();
+        portraitTablet.smallestScreenWidthDp = 720;
+        portraitTablet.windowConfiguration.setMaxBounds(new Rect(0, 0, 500, 1000));
+        Configuration landscapeTablet = new Configuration();
+        landscapeTablet.smallestScreenWidthDp = 720;
+        landscapeTablet.windowConfiguration.setMaxBounds(new Rect(0, 0, 1000, 500));
+        Configuration portraitPhone = new Configuration();
+        portraitPhone.smallestScreenWidthDp = 420;
+        portraitPhone.windowConfiguration.setMaxBounds(new Rect(0, 0, 500, 1000));
+        Configuration landscapePhone = new Configuration();
+        landscapePhone.smallestScreenWidthDp = 420;
+        landscapePhone.windowConfiguration.setMaxBounds(new Rect(0, 0, 1000, 500));
+
+        // Allow L/R split in portrait = false
+        assertTrue(SplitScreenUtils.isLeftRightSplit(false /* allowLeftRightSplitInPortrait */,
+                landscapeTablet));
+        assertTrue(SplitScreenUtils.isLeftRightSplit(false /* allowLeftRightSplitInPortrait */,
+                landscapePhone));
+        assertFalse(SplitScreenUtils.isLeftRightSplit(false /* allowLeftRightSplitInPortrait */,
+                portraitTablet));
+        assertFalse(SplitScreenUtils.isLeftRightSplit(false /* allowLeftRightSplitInPortrait */,
+                portraitPhone));
+
+        // Allow L/R split in portrait = true, only affects large screens
+        assertFalse(SplitScreenUtils.isLeftRightSplit(true /* allowLeftRightSplitInPortrait */,
+                landscapeTablet));
+        assertTrue(SplitScreenUtils.isLeftRightSplit(true /* allowLeftRightSplitInPortrait */,
+                landscapePhone));
+        assertTrue(SplitScreenUtils.isLeftRightSplit(true /* allowLeftRightSplitInPortrait */,
+                portraitTablet));
+        assertFalse(SplitScreenUtils.isLeftRightSplit(true /* allowLeftRightSplitInPortrait */,
+                portraitPhone));
+    }
+}
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 fff65f3..d819261 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
@@ -140,7 +140,7 @@
         when(mSplitLayout.getBounds1()).thenReturn(mBounds1);
         when(mSplitLayout.getBounds2()).thenReturn(mBounds2);
         when(mSplitLayout.getRootBounds()).thenReturn(mRootBounds);
-        when(mSplitLayout.isLandscape()).thenReturn(false);
+        when(mSplitLayout.isLeftRightSplit()).thenReturn(false);
         when(mSplitLayout.applyTaskChanges(any(), any(), any())).thenReturn(true);
         when(mSplitLayout.getDividerLeash()).thenReturn(mDividerLeash);
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java
index 4afb29e..d7c4610 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java
@@ -40,6 +40,7 @@
 import android.app.ActivityOptions;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.graphics.Color;
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -58,6 +59,7 @@
 
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestHandler;
 import com.android.wm.shell.common.HandlerExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.SyncTransactionQueue.TransactionRunnable;
@@ -92,8 +94,7 @@
     Transitions mTransitions;
     @Mock
     Looper mViewLooper;
-    @Mock
-    Handler mViewHandler;
+    TestHandler mViewHandler;
 
     SurfaceSession mSession;
     SurfaceControl mLeash;
@@ -112,7 +113,7 @@
 
         mContext = getContext();
         doReturn(true).when(mViewLooper).isCurrentThread();
-        doReturn(mViewLooper).when(mViewHandler).getLooper();
+        mViewHandler = spy(new TestHandler(mViewLooper));
 
         mTaskInfo = new ActivityManager.RunningTaskInfo();
         mTaskInfo.token = mToken;
@@ -668,4 +669,24 @@
         mTaskViewTaskController.onTaskInfoChanged(mTaskInfo);
         verify(mViewHandler).post(any());
     }
+
+    @Test
+    public void testSetResizeBgOnSameUiThread_expectUsesTransaction() {
+        SurfaceControl.Transaction tx = mock(SurfaceControl.Transaction.class);
+        mTaskView = spy(mTaskView);
+        mTaskView.setResizeBgColor(tx, Color.BLUE);
+        verify(mViewHandler, never()).post(any());
+        verify(mTaskView, never()).setResizeBackgroundColor(eq(Color.BLUE));
+        verify(mTaskView).setResizeBackgroundColor(eq(tx), eq(Color.BLUE));
+    }
+
+    @Test
+    public void testSetResizeBgOnDifferentUiThread_expectDoesNotUseTransaction() {
+        doReturn(false).when(mViewLooper).isCurrentThread();
+        SurfaceControl.Transaction tx = mock(SurfaceControl.Transaction.class);
+        mTaskView = spy(mTaskView);
+        mTaskView.setResizeBgColor(tx, Color.BLUE);
+        verify(mViewHandler).post(any());
+        verify(mTaskView).setResizeBackgroundColor(eq(Color.BLUE));
+    }
 }
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 12cb69d..d747489 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -105,7 +105,7 @@
                     ProfileType::None != Properties::getProfileType())) {
         SkCanvas* profileCanvas = backBuffer->getCanvas();
         SkAutoCanvasRestore saver(profileCanvas, true);
-        profileCanvas->concat(mVkSurface->getCurrentPreTransform());
+        profileCanvas->concat(preTransform);
         SkiaProfileRenderer profileRenderer(profileCanvas, frame.width(), frame.height());
         profiler->draw(profileRenderer);
     }
diff --git a/location/api/system-current.txt b/location/api/system-current.txt
index a1d6ab5..b1cf96d 100644
--- a/location/api/system-current.txt
+++ b/location/api/system-current.txt
@@ -113,13 +113,13 @@
   }
 
   public final class GnssMeasurementRequest implements android.os.Parcelable {
-    method @NonNull public android.os.WorkSource getWorkSource();
+    method @FlaggedApi(Flags.FLAG_GNSS_API_MEASUREMENT_REQUEST_WORK_SOURCE) @NonNull public android.os.WorkSource getWorkSource();
     method public boolean isCorrelationVectorOutputsEnabled();
   }
 
   public static final class GnssMeasurementRequest.Builder {
     method @NonNull public android.location.GnssMeasurementRequest.Builder setCorrelationVectorOutputsEnabled(boolean);
-    method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.location.GnssMeasurementRequest.Builder setWorkSource(@Nullable android.os.WorkSource);
+    method @FlaggedApi(Flags.FLAG_GNSS_API_MEASUREMENT_REQUEST_WORK_SOURCE) @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.location.GnssMeasurementRequest.Builder setWorkSource(@Nullable android.os.WorkSource);
   }
 
   public final class GnssReflectingPlane implements android.os.Parcelable {
diff --git a/location/java/android/location/GnssMeasurementRequest.java b/location/java/android/location/GnssMeasurementRequest.java
index 65af392..2f0835a 100644
--- a/location/java/android/location/GnssMeasurementRequest.java
+++ b/location/java/android/location/GnssMeasurementRequest.java
@@ -17,11 +17,13 @@
 package android.location;
 
 import android.Manifest;
+import android.annotation.FlaggedApi;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.location.flags.Flags;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.WorkSource;
@@ -121,6 +123,7 @@
      *
      * @hide
      */
+    @FlaggedApi(Flags.FLAG_GNSS_API_MEASUREMENT_REQUEST_WORK_SOURCE)
     @SystemApi
     public @NonNull WorkSource getWorkSource() {
         return mWorkSource;
@@ -298,6 +301,7 @@
          *
          * @hide
          */
+        @FlaggedApi(Flags.FLAG_GNSS_API_MEASUREMENT_REQUEST_WORK_SOURCE)
         @SystemApi
         @RequiresPermission(Manifest.permission.UPDATE_DEVICE_STATS)
         public @NonNull Builder setWorkSource(@Nullable WorkSource workSource) {
diff --git a/location/java/android/location/flags/gnss.aconfig b/location/java/android/location/flags/gnss.aconfig
index c471a27..b6055e8 100644
--- a/location/java/android/location/flags/gnss.aconfig
+++ b/location/java/android/location/flags/gnss.aconfig
@@ -5,4 +5,18 @@
     namespace: "location"
     description: "Flag for GNSS API for NavIC L1"
     bug: "302199306"
-}
\ No newline at end of file
+}
+
+flag {
+    name: "gnss_call_stop_before_set_position_mode"
+    namespace: "location"
+    description: "Flag for calling stop() before setPositionMode()"
+    bug: "306874828"
+}
+
+flag {
+    name: "gnss_api_measurement_request_work_source"
+    namespace: "location"
+    description: "Flag for GnssMeasurementRequest WorkSource API"
+    bug: "295235160"
+}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index d14775f..5c8758a 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -739,7 +739,7 @@
 
     oneway void stopLoudnessCodecUpdates(int piid);
 
-    oneway void addLoudnessCodecInfo(int piid, in LoudnessCodecInfo codecInfo);
+    oneway void addLoudnessCodecInfo(int piid, int mediaCodecHash, in LoudnessCodecInfo codecInfo);
 
     oneway void removeLoudnessCodecInfo(int piid, in LoudnessCodecInfo codecInfo);
 
diff --git a/media/java/android/media/LoudnessCodecConfigurator.java b/media/java/android/media/LoudnessCodecConfigurator.java
index 92f3372..de9d87c0 100644
--- a/media/java/android/media/LoudnessCodecConfigurator.java
+++ b/media/java/android/media/LoudnessCodecConfigurator.java
@@ -30,10 +30,10 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Executor;
@@ -47,9 +47,6 @@
  * parameter updates are defined by the CTA-2075 standard.
  * <p>A new object should be instantiated for each {@link AudioTrack} with the help
  * of {@link #create()} or {@link #create(Executor, OnLoudnessCodecUpdateListener)}.
- *
- * TODO: remove hide once API is final
- * @hide
  */
 @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
 public class LoudnessCodecConfigurator {
@@ -57,9 +54,6 @@
 
     /**
      * Listener used for receiving asynchronous loudness metadata updates.
-     *
-     * TODO: remove hide once API is final
-     * @hide
      */
     @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
     public interface OnLoudnessCodecUpdateListener {
@@ -76,9 +70,6 @@
          * @return a Bundle which contains the original computed codecValues
          * aggregated with user edits. The platform will configure the associated
          * MediaCodecs with the returned Bundle params.
-         *
-         * TODO: remove hide once API is final
-         * @hide
          */
         @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
         @NonNull
@@ -112,9 +103,6 @@
      * Otherwise, use {@link #create(Executor, OnLoudnessCodecUpdateListener)}.
      *
      * @return the {@link LoudnessCodecConfigurator} instance
-     *
-     * TODO: remove hide once API is final
-     * @hide
      */
     @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
     public static @NonNull LoudnessCodecConfigurator create() {
@@ -133,9 +121,6 @@
      * @param listener used for receiving updates
      *
      * @return the {@link LoudnessCodecConfigurator} instance
-     *
-     * TODO: remove hide once API is final
-     * @hide
      */
     @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
     public static @NonNull LoudnessCodecConfigurator create(
@@ -200,12 +185,9 @@
      *                   method will have the effect of clearing the existing set
      *                   {@link AudioTrack} and will stop receiving asynchronous
      *                   loudness updates
-     *
-     * TODO: remove hide once API is final
-     * @hide
      */
     @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
-    public void setAudioTrack(AudioTrack audioTrack) {
+    public void setAudioTrack(@Nullable AudioTrack audioTrack) {
         List<LoudnessCodecInfo> codecInfos;
         int piid = PLAYER_PIID_INVALID;
         int oldPiid = PLAYER_PIID_INVALID;
@@ -250,10 +232,11 @@
      * previously added.
      *
      * @param mediaCodec the codec to start receiving asynchronous loudness
-     *                   updates
-     *
-     * TODO: remove hide once API is final
-     * @hide
+     *                   updates. The codec has to be in a configured or started
+     *                   state in order to add it for loudness updates.
+     * @throws IllegalArgumentException if the {@code mediaCodec} was not configured,
+     *                                  does not contain loudness metadata or if it
+     *                                  was already added before
      */
     @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
     public void addMediaCodec(@NonNull MediaCodec mediaCodec) {
@@ -262,30 +245,31 @@
         int piid = PLAYER_PIID_INVALID;
         final LoudnessCodecInfo mcInfo = getCodecInfo(mc);
 
-        if (mcInfo != null) {
-            synchronized (mConfiguratorLock) {
-                final AtomicBoolean containsCodec = new AtomicBoolean(false);
-                Set<MediaCodec> newSet = mMediaCodecs.computeIfPresent(mcInfo, (info, codecSet) -> {
-                    containsCodec.set(!codecSet.add(mc));
-                    return codecSet;
-                });
-                if (newSet == null) {
-                    newSet = new HashSet<>();
-                    newSet.add(mc);
-                    mMediaCodecs.put(mcInfo, newSet);
-                }
-                if (containsCodec.get()) {
-                    Log.v(TAG, "Loudness configurator already added media codec " + mediaCodec);
-                    return;
-                }
-                if (mAudioTrack != null) {
-                    piid = mAudioTrack.getPlayerIId();
-                }
+        if (mcInfo == null) {
+            throw new IllegalArgumentException("Could not extract codec loudness information");
+        }
+        synchronized (mConfiguratorLock) {
+            final AtomicBoolean containsCodec = new AtomicBoolean(false);
+            Set<MediaCodec> newSet = mMediaCodecs.computeIfPresent(mcInfo, (info, codecSet) -> {
+                containsCodec.set(!codecSet.add(mc));
+                return codecSet;
+            });
+            if (newSet == null) {
+                newSet = new HashSet<>();
+                newSet.add(mc);
+                mMediaCodecs.put(mcInfo, newSet);
             }
+            if (containsCodec.get()) {
+                throw new IllegalArgumentException(
+                        "Loudness configurator already added " + mediaCodec);
+            }
+            if (mAudioTrack != null) {
+                piid = mAudioTrack.getPlayerIId();
+            }
+        }
 
-            if (piid != PLAYER_PIID_INVALID) {
-                mLcDispatcher.addLoudnessCodecInfo(piid, mcInfo);
-            }
+        if (piid != PLAYER_PIID_INVALID) {
+            mLcDispatcher.addLoudnessCodecInfo(piid, mediaCodec.hashCode(), mcInfo);
         }
     }
 
@@ -297,37 +281,44 @@
      * <p>No elements will be removed if the passed mediaCodec was not added before.
      *
      * @param mediaCodec the element to remove for receiving asynchronous updates
-     *
-     * TODO: remove hide once API is final
-     * @hide
+     * @throws IllegalArgumentException if the {@code mediaCodec} was not configured,
+     *                                  does not contain loudness metadata or if it
+     *                                  was not added before
      */
     @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
     public void removeMediaCodec(@NonNull MediaCodec mediaCodec) {
         int piid = PLAYER_PIID_INVALID;
         LoudnessCodecInfo mcInfo;
-        AtomicBoolean removed = new AtomicBoolean(false);
+        AtomicBoolean removedMc = new AtomicBoolean(false);
+        AtomicBoolean removeInfo = new AtomicBoolean(false);
 
         mcInfo = getCodecInfo(Objects.requireNonNull(mediaCodec,
                 "MediaCodec for removeMediaCodec cannot be null"));
 
-        if (mcInfo != null) {
-            synchronized (mConfiguratorLock) {
-                if (mAudioTrack != null) {
-                    piid = mAudioTrack.getPlayerIId();
+        if (mcInfo == null) {
+            throw new IllegalArgumentException("Could not extract codec loudness information");
+        }
+        synchronized (mConfiguratorLock) {
+            if (mAudioTrack != null) {
+                piid = mAudioTrack.getPlayerIId();
+            }
+            mMediaCodecs.computeIfPresent(mcInfo, (format, mcs) -> {
+                removedMc.set(mcs.remove(mediaCodec));
+                if (mcs.isEmpty()) {
+                    // remove the entry
+                    removeInfo.set(true);
+                    return null;
                 }
-                mMediaCodecs.computeIfPresent(mcInfo, (format, mcs) -> {
-                    removed.set(mcs.remove(mediaCodec));
-                    if (mcs.isEmpty()) {
-                        // remove the entry
-                        return null;
-                    }
-                    return mcs;
-                });
+                return mcs;
+            });
+            if (!removedMc.get()) {
+                throw new IllegalArgumentException(
+                        "Loudness configurator does not contain " + mediaCodec);
             }
+        }
 
-            if (piid != PLAYER_PIID_INVALID && removed.get()) {
-                mLcDispatcher.removeLoudnessCodecInfo(piid, mcInfo);
-            }
+        if (piid != PLAYER_PIID_INVALID && removeInfo.get()) {
+            mLcDispatcher.removeLoudnessCodecInfo(piid, mcInfo);
         }
     }
 
@@ -342,9 +333,6 @@
      *
      * @return the {@link Bundle} containing the current loudness parameters. Caller is
      * responsible to update the {@link MediaCodec}
-     *
-     * TODO: remove hide once API is final
-     * @hide
      */
     @FlaggedApi(FLAG_LOUDNESS_CONFIGURATOR_API)
     @NonNull
@@ -375,9 +363,9 @@
     }
 
     /** @hide */
-    /*package*/ List<MediaCodec> getRegisteredMediaCodecList() {
+    /*package*/ Map<LoudnessCodecInfo, Set<MediaCodec>> getRegisteredMediaCodecs() {
         synchronized (mConfiguratorLock) {
-            return mMediaCodecs.values().stream().flatMap(Collection::stream).toList();
+            return mMediaCodecs;
         }
     }
 
@@ -397,40 +385,43 @@
             return null;
         }
 
-        final MediaFormat inputFormat = mediaCodec.getInputFormat();
-        final String mimeType = inputFormat.getString(MediaFormat.KEY_MIME);
-        if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mimeType)) {
-            // check both KEY_AAC_PROFILE and KEY_PROFILE as some codecs may only recognize one of
-            // these two keys
-            int aacProfile = -1;
-            int profile = -1;
-            try {
-                aacProfile = inputFormat.getInteger(MediaFormat.KEY_AAC_PROFILE);
-            } catch (NullPointerException e) {
-                // does not contain KEY_AAC_PROFILE. do nothing
-            }
-            try {
-                profile = inputFormat.getInteger(MediaFormat.KEY_PROFILE);
-            } catch (NullPointerException e) {
-                // does not contain KEY_PROFILE. do nothing
-            }
-            if (aacProfile == MediaCodecInfo.CodecProfileLevel.AACObjectXHE
-                    || profile == MediaCodecInfo.CodecProfileLevel.AACObjectXHE) {
-                lci.metadataType = CODEC_METADATA_TYPE_MPEG_D;
+        try {
+            final MediaFormat inputFormat = mediaCodec.getInputFormat();
+            final String mimeType = inputFormat.getString(MediaFormat.KEY_MIME);
+            if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mimeType)) {
+                // check both KEY_AAC_PROFILE and KEY_PROFILE as some codecs may only recognize
+                // one of these two keys
+                int aacProfile = -1;
+                int profile = -1;
+                try {
+                    aacProfile = inputFormat.getInteger(MediaFormat.KEY_AAC_PROFILE);
+                } catch (NullPointerException e) {
+                    // does not contain KEY_AAC_PROFILE. do nothing
+                }
+                try {
+                    profile = inputFormat.getInteger(MediaFormat.KEY_PROFILE);
+                } catch (NullPointerException e) {
+                    // does not contain KEY_PROFILE. do nothing
+                }
+                if (aacProfile == MediaCodecInfo.CodecProfileLevel.AACObjectXHE
+                        || profile == MediaCodecInfo.CodecProfileLevel.AACObjectXHE) {
+                    lci.metadataType = CODEC_METADATA_TYPE_MPEG_D;
+                } else {
+                    lci.metadataType = CODEC_METADATA_TYPE_MPEG_4;
+                }
             } else {
-                lci.metadataType = CODEC_METADATA_TYPE_MPEG_4;
+                Log.w(TAG, "MediaCodec mime type not supported for loudness annotation");
+                return null;
             }
-        } else {
-            Log.w(TAG, "MediaCodec mime type not supported for loudness annotation");
+
+            final MediaFormat outputFormat = mediaCodec.getOutputFormat();
+            lci.isDownmixing = outputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
+                    < inputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "MediaCodec is not configured", e);
             return null;
         }
 
-        final MediaFormat outputFormat = mediaCodec.getOutputFormat();
-        lci.isDownmixing = outputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
-                < inputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
-
-        lci.mediaCodecHashCode = mediaCodec.hashCode();
-
         return lci;
     }
 }
diff --git a/media/java/android/media/LoudnessCodecDispatcher.java b/media/java/android/media/LoudnessCodecDispatcher.java
index be881b1..b546a81 100644
--- a/media/java/android/media/LoudnessCodecDispatcher.java
+++ b/media/java/android/media/LoudnessCodecDispatcher.java
@@ -27,12 +27,16 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
 
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.Executor;
 
 /**
@@ -52,6 +56,9 @@
         private final CallbackUtil.LazyListenerManager<OnLoudnessCodecUpdateListener>
                 mLoudnessListenerMgr = new CallbackUtil.LazyListenerManager<>();
 
+        private final Object mLock = new Object();
+
+        @GuardedBy("mLock")
         private final HashMap<OnLoudnessCodecUpdateListener, LoudnessCodecConfigurator>
                 mConfiguratorListener = new HashMap<>();
 
@@ -66,38 +73,56 @@
 
         @Override
         public void dispatchLoudnessCodecParameterChange(int piid, PersistableBundle params) {
-            mLoudnessListenerMgr.callListeners(listener ->
+            if (DEBUG) {
+                Log.d(TAG, "dispatchLoudnessCodecParameterChange for piid " + piid
+                        + " persistable bundle: " + params);
+            }
+            mLoudnessListenerMgr.callListeners(listener -> {
+                synchronized (mLock) {
                     mConfiguratorListener.computeIfPresent(listener, (l, lcConfig) -> {
                         // send the appropriate bundle for the user to update
                         if (lcConfig.getAssignedTrackPiid() == piid) {
-                            final List<MediaCodec> mediaCodecs =
-                                    lcConfig.getRegisteredMediaCodecList();
-                            for (MediaCodec mediaCodec : mediaCodecs) {
-                                final String infoKey = Integer.toString(mediaCodec.hashCode());
+                            final Map<LoudnessCodecInfo, Set<MediaCodec>> mediaCodecsMap =
+                                    lcConfig.getRegisteredMediaCodecs();
+                            for (LoudnessCodecInfo codecInfo : mediaCodecsMap.keySet()) {
+                                final String infoKey = Integer.toString(codecInfo.hashCode());
+                                Bundle bundle = null;
                                 if (params.containsKey(infoKey)) {
-                                    Bundle bundle = new Bundle(
-                                            params.getPersistableBundle(infoKey));
-                                    if (DEBUG) {
-                                        Log.d(TAG,
-                                                "Received for piid " + piid + " bundle: " + bundle);
+                                    bundle = new Bundle(params.getPersistableBundle(infoKey));
+                                }
+
+                                final Set<MediaCodec> mediaCodecs = mediaCodecsMap.get(codecInfo);
+                                for (MediaCodec mediaCodec : mediaCodecs) {
+                                    final String mediaCodecKey = Integer.toString(
+                                            mediaCodec.hashCode());
+                                    if (bundle == null && !params.containsKey(mediaCodecKey)) {
+                                        continue;
+                                    }
+                                    boolean canBreak = false;
+                                    if (bundle == null) {
+                                        // key was set by media codec hash to update single codec
+                                        bundle = new Bundle(
+                                                params.getPersistableBundle(mediaCodecKey));
+                                        canBreak = true;
                                     }
                                     bundle =
                                             LoudnessCodecUpdatesDispatcherStub.filterLoudnessParams(
-                                                    l.onLoudnessCodecUpdate(mediaCodec, bundle));
-                                    if (DEBUG) {
-                                        Log.d(TAG, "User changed for piid " + piid
-                                                + " to filtered bundle: " + bundle);
-                                    }
+                                                    l.onLoudnessCodecUpdate(mediaCodec,
+                                                            bundle));
 
                                     if (!bundle.isDefinitelyEmpty()) {
                                         mediaCodec.setParameters(bundle);
                                     }
+                                    if (canBreak) {
+                                        break;
+                                    }
                                 }
                             }
                         }
-
                         return lcConfig;
-                    }));
+                    });
+                }
+            });
         }
 
         private static Bundle filterLoudnessParams(Bundle bundle) {
@@ -130,21 +155,33 @@
             mLoudnessListenerMgr.addListener(
                     executor, listener, "addLoudnessCodecListener",
                     () -> dispatcher);
-            mConfiguratorListener.put(listener, configurator);
+            synchronized (mLock) {
+                mConfiguratorListener.put(listener, configurator);
+            }
         }
 
         void removeLoudnessCodecListener(@NonNull LoudnessCodecConfigurator configurator) {
             Objects.requireNonNull(configurator);
 
-            for (Entry<OnLoudnessCodecUpdateListener, LoudnessCodecConfigurator> e :
-                    mConfiguratorListener.entrySet()) {
-                if (e.getValue() == configurator) {
-                    final OnLoudnessCodecUpdateListener listener = e.getKey();
-                    mConfiguratorListener.remove(listener);
-                    mLoudnessListenerMgr.removeListener(listener, "removeLoudnessCodecListener");
-                    break;
+            OnLoudnessCodecUpdateListener listenerToRemove = null;
+            synchronized (mLock) {
+                Iterator<Entry<OnLoudnessCodecUpdateListener, LoudnessCodecConfigurator>> iterator =
+                        mConfiguratorListener.entrySet().iterator();
+                while (iterator.hasNext()) {
+                    Entry<OnLoudnessCodecUpdateListener, LoudnessCodecConfigurator> e =
+                            iterator.next();
+                    if (e.getValue() == configurator) {
+                        final OnLoudnessCodecUpdateListener listener = e.getKey();
+                        iterator.remove();
+                        listenerToRemove = listener;
+                        break;
+                    }
                 }
             }
+            if (listenerToRemove != null) {
+                mLoudnessListenerMgr.removeListener(listenerToRemove,
+                        "removeLoudnessCodecListener");
+            }
         }
     }
 
@@ -202,9 +239,10 @@
     }
 
     /** @hide */
-    public void addLoudnessCodecInfo(int piid, @NonNull LoudnessCodecInfo mcInfo) {
+    public void addLoudnessCodecInfo(int piid, int mediaCodecHash,
+            @NonNull LoudnessCodecInfo mcInfo) {
         try {
-            mAudioService.addLoudnessCodecInfo(piid, mcInfo);
+            mAudioService.addLoudnessCodecInfo(piid, mediaCodecHash, mcInfo);
         }  catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
diff --git a/media/java/android/media/LoudnessCodecInfo.aidl b/media/java/android/media/LoudnessCodecInfo.aidl
index fd69517..0ac5646 100644
--- a/media/java/android/media/LoudnessCodecInfo.aidl
+++ b/media/java/android/media/LoudnessCodecInfo.aidl
@@ -23,7 +23,7 @@
  *
  * {@hide}
  */
-@JavaDerive(equals = true)
+@JavaDerive(equals = true, toString = true)
 parcelable LoudnessCodecInfo {
     /** Supported codec metadata types for loudness updates. */
     @Backing(type="int")
@@ -37,7 +37,6 @@
         CODEC_METADATA_TYPE_DTS_UHD = 6
     }
 
-    int mediaCodecHashCode;
     CodecMetadataType metadataType;
     boolean isDownmixing;
 }
\ No newline at end of file
diff --git a/media/java/android/media/tv/ad/TvAdManager.java b/media/java/android/media/tv/ad/TvAdManager.java
index aa5a290..2b52c4b 100644
--- a/media/java/android/media/tv/ad/TvAdManager.java
+++ b/media/java/android/media/tv/ad/TvAdManager.java
@@ -16,6 +16,10 @@
 
 package android.media.tv.ad;
 
+import android.annotation.FlaggedApi;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.media.tv.flags.Flags;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
@@ -23,14 +27,17 @@
 /**
  * Central system API to the overall client-side TV AD architecture, which arbitrates interaction
  * between applications and AD services.
- * @hide
  */
+@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW)
+@SystemService(Context.TV_AD_SERVICE)
 public class TvAdManager {
+    // TODO: implement more methods and unhide APIs.
     private static final String TAG = "TvAdManager";
 
     private final ITvAdManager mService;
     private final int mUserId;
 
+    /** @hide */
     public TvAdManager(ITvAdManager service, int userId) {
         mService = service;
         mUserId = userId;
@@ -38,6 +45,7 @@
 
     /**
      * The Session provides the per-session functionality of AD service.
+     * @hide
      */
     public static final class Session {
         private final IBinder mToken;
diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig
index a73d1ff..018eaf6 100644
--- a/media/java/android/media/tv/flags/media_tv.aconfig
+++ b/media/java/android/media/tv/flags/media_tv.aconfig
@@ -5,4 +5,11 @@
     namespace: "media_tv"
     description: "Constants for standardizing broadcast visibility types."
     bug: "222402395"
+}
+
+flag {
+    name: "enable_ad_service_fw"
+    namespace: "media_tv"
+    description: "Enable the TV client-side AD framework."
+    bug: "303506816"
 }
\ No newline at end of file
diff --git a/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java b/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java
index 65a9799..c9e36b7 100644
--- a/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java
+++ b/media/tests/LoudnessCodecApiTest/src/com/android/loudnesscodecapitest/LoudnessCodecConfiguratorTest.java
@@ -208,7 +208,7 @@
         verify(mAudioService).startLoudnessCodecUpdates(eq(track.getPlayerIId()), anyList());
 
         mLcc.addMediaCodec(createAndConfigureMediaCodec());
-        verify(mAudioService).addLoudnessCodecInfo(eq(track.getPlayerIId()), any());
+        verify(mAudioService).addLoudnessCodecInfo(eq(track.getPlayerIId()), anyInt(), any());
     }
 
     @Test
diff --git a/packages/CredentialManager/Android.bp b/packages/CredentialManager/Android.bp
index fe26dc3..991fe41 100644
--- a/packages/CredentialManager/Android.bp
+++ b/packages/CredentialManager/Android.bp
@@ -16,10 +16,12 @@
 
     dex_preopt: {
         profile_guided: true,
+        //TODO: b/312357299 - Update baseline profile
         profile: "profile.txt.prof",
     },
 
     static_libs: [
+        "CredentialManagerShared",
         "PlatformComposeCore",
         "androidx.activity_activity-compose",
         "androidx.appcompat_appcompat",
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
index 42f1207..325d3f8 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt
@@ -16,6 +16,7 @@
 
 package com.android.credentialmanager
 
+import android.content.Context
 import android.content.Intent
 import android.content.pm.PackageManager
 import android.credentials.ui.RequestInfo
@@ -27,10 +28,10 @@
 import com.android.credentialmanager.model.Request
 
 fun Intent.parse(
-    packageManager: PackageManager,
+    context: Context,
 ): Request {
-    return parseCancelUiRequest(packageManager)
-        ?: parseRequestInfo()
+    return parseCancelUiRequest(context.packageManager)
+        ?: parseRequestInfo(context)
 }
 
 fun Intent.parseCancelUiRequest(packageManager: PackageManager): Request? =
@@ -51,11 +52,11 @@
         }
     }
 
-fun Intent.parseRequestInfo(): Request =
+fun Intent.parseRequestInfo(context: Context): Request =
     requestInfo.let{ info ->
         when (info?.type) {
             RequestInfo.TYPE_CREATE -> Request.Create(info.token)
-            RequestInfo.TYPE_GET -> toGet()
+            RequestInfo.TYPE_GET -> toGet(context)
             else -> {
                 throw IllegalStateException("Unrecognized request type: ${info?.type}")
             }
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt
index 83183b5..3ef65b0 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt
@@ -16,8 +16,8 @@
 
 package com.android.credentialmanager.client.impl
 
+import android.content.Context
 import android.content.Intent
-import android.content.pm.PackageManager
 import android.credentials.ui.BaseDialogResult
 import android.credentials.ui.UserSelectionDialogResult
 import android.os.Bundle
@@ -26,12 +26,13 @@
 import com.android.credentialmanager.model.Request
 import com.android.credentialmanager.parse
 import com.android.credentialmanager.client.CredentialManagerClient
+import dagger.hilt.android.qualifiers.ApplicationContext
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import javax.inject.Inject
 
 class CredentialManagerClientImpl @Inject constructor(
-        private val packageManager: PackageManager,
+    @ApplicationContext private val context: Context,
 ) : CredentialManagerClient {
 
     private val _requests = MutableStateFlow<Request?>(null)
@@ -40,7 +41,7 @@
 
     override fun updateRequest(intent: Intent) {
         val request = intent.parse(
-            packageManager = packageManager,
+            context = context,
         )
         Log.d(TAG, "Request parsed: $request, client instance: $this")
         if (request is Request.Cancel || request is Request.Close) {
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
new file mode 100644
index 0000000..f063074
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.ktx
+
+import android.app.slice.Slice
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageInfo
+import android.content.pm.PackageManager
+import android.credentials.Credential
+import android.credentials.flags.Flags
+import android.credentials.ui.AuthenticationEntry
+import android.credentials.ui.Entry
+import android.credentials.ui.GetCredentialProviderData
+import android.graphics.drawable.Drawable
+import android.text.TextUtils
+import android.util.Log
+import androidx.activity.result.IntentSenderRequest
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.provider.Action
+import androidx.credentials.provider.AuthenticationAction
+import androidx.credentials.provider.CredentialEntry
+import androidx.credentials.provider.CustomCredentialEntry
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.PublicKeyCredentialEntry
+import androidx.credentials.provider.RemoteEntry
+import com.android.credentialmanager.IS_AUTO_SELECTED_KEY
+import com.android.credentialmanager.model.get.ActionEntryInfo
+import com.android.credentialmanager.model.get.AuthenticationEntryInfo
+import com.android.credentialmanager.model.get.CredentialEntryInfo
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.get.ProviderInfo
+import com.android.credentialmanager.model.get.RemoteEntryInfo
+import com.android.credentialmanager.TAG
+
+fun CredentialEntryInfo.getIntentSenderRequest(
+    isAutoSelected: Boolean = false
+): IntentSenderRequest? {
+    val entryIntent = fillInIntent?.putExtra(IS_AUTO_SELECTED_KEY, isAutoSelected)
+
+    return pendingIntent?.let{
+        IntentSenderRequest
+            .Builder(pendingIntent = it)
+            .setFillInIntent(entryIntent)
+            .build()
+    }
+}
+
+// Returns the list (potentially empty) of enabled provider.
+fun List<GetCredentialProviderData>.toProviderList(
+    context: Context,
+): List<ProviderInfo> {
+    val providerList: MutableList<ProviderInfo> = mutableListOf()
+    this.forEach {
+        val providerLabelAndIcon = getServiceLabelAndIcon(
+            context.packageManager,
+            it.providerFlattenedComponentName
+        ) ?: return@forEach
+        val (providerLabel, providerIcon) = providerLabelAndIcon
+        providerList.add(
+            ProviderInfo(
+                id = it.providerFlattenedComponentName,
+                icon = providerIcon,
+                displayName = providerLabel,
+                credentialEntryList = getCredentialOptionInfoList(
+                    providerId = it.providerFlattenedComponentName,
+                    providerLabel = providerLabel,
+                    credentialEntries = it.credentialEntries,
+                    context = context
+                ),
+                authenticationEntryList = getAuthenticationEntryList(
+                    it.providerFlattenedComponentName,
+                    providerLabel,
+                    providerIcon,
+                    it.authenticationEntries),
+                remoteEntry = getRemoteEntry(
+                    it.providerFlattenedComponentName,
+                    it.remoteEntry
+                ),
+                actionEntryList = getActionEntryList(
+                    it.providerFlattenedComponentName, it.actionChips, providerIcon
+                ),
+            )
+        )
+    }
+    return providerList
+}
+
+/**
+ * Note: caller required handle empty list due to parsing error.
+ */
+private fun getCredentialOptionInfoList(
+    providerId: String,
+    providerLabel: String,
+    credentialEntries: List<Entry>,
+    context: Context,
+): List<CredentialEntryInfo> {
+    val result: MutableList<CredentialEntryInfo> = mutableListOf()
+    credentialEntries.forEach {
+        val credentialEntry = it.slice.credentialEntry
+        when (credentialEntry) {
+            is PasswordCredentialEntry -> {
+                result.add(
+                    CredentialEntryInfo(
+                    providerId = providerId,
+                    providerDisplayName = providerLabel,
+                    entryKey = it.key,
+                    entrySubkey = it.subkey,
+                    pendingIntent = credentialEntry.pendingIntent,
+                    fillInIntent = it.frameworkExtrasIntent,
+                    credentialType = CredentialType.PASSWORD,
+                    credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
+                    userName = credentialEntry.username.toString(),
+                    displayName = credentialEntry.displayName?.toString(),
+                    icon = credentialEntry.icon.loadDrawable(context),
+                    shouldTintIcon = credentialEntry.isDefaultIcon,
+                    lastUsedTimeMillis = credentialEntry.lastUsedTime,
+                    isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
+                            credentialEntry.autoSelectAllowedFromOption,
+                )
+                )
+            }
+            is PublicKeyCredentialEntry -> {
+                result.add(
+                    CredentialEntryInfo(
+                    providerId = providerId,
+                    providerDisplayName = providerLabel,
+                    entryKey = it.key,
+                    entrySubkey = it.subkey,
+                    pendingIntent = credentialEntry.pendingIntent,
+                    fillInIntent = it.frameworkExtrasIntent,
+                    credentialType = CredentialType.PASSKEY,
+                    credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
+                    userName = credentialEntry.username.toString(),
+                    displayName = credentialEntry.displayName?.toString(),
+                    icon = credentialEntry.icon.loadDrawable(context),
+                    shouldTintIcon = credentialEntry.isDefaultIcon,
+                    lastUsedTimeMillis = credentialEntry.lastUsedTime,
+                    isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
+                            credentialEntry.autoSelectAllowedFromOption,
+                )
+                )
+            }
+            is CustomCredentialEntry -> {
+                result.add(
+                    CredentialEntryInfo(
+                    providerId = providerId,
+                    providerDisplayName = providerLabel,
+                    entryKey = it.key,
+                    entrySubkey = it.subkey,
+                    pendingIntent = credentialEntry.pendingIntent,
+                    fillInIntent = it.frameworkExtrasIntent,
+                    credentialType = CredentialType.UNKNOWN,
+                    credentialTypeDisplayName =
+                    credentialEntry.typeDisplayName?.toString().orEmpty(),
+                    userName = credentialEntry.title.toString(),
+                    displayName = credentialEntry.subtitle?.toString(),
+                    icon = credentialEntry.icon.loadDrawable(context),
+                    shouldTintIcon = credentialEntry.isDefaultIcon,
+                    lastUsedTimeMillis = credentialEntry.lastUsedTime,
+                    isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
+                            credentialEntry.autoSelectAllowedFromOption,
+                )
+                )
+            }
+            else -> Log.d(
+                TAG,
+                "Encountered unrecognized credential entry ${it.slice.spec?.type}"
+            )
+        }
+    }
+    return result
+}
+val Slice.credentialEntry: CredentialEntry?
+    get() =
+        try {
+            when (spec?.type) {
+                Credential.TYPE_PASSWORD_CREDENTIAL -> PasswordCredentialEntry.fromSlice(this)!!
+                PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
+                    PublicKeyCredentialEntry.fromSlice(this)!!
+
+                else -> CustomCredentialEntry.fromSlice(this)!!
+            }
+        } catch (e: Exception) {
+            // Try CustomCredentialEntry.fromSlice one last time in case the cause was a failed
+            // password / passkey parsing attempt.
+            CustomCredentialEntry.fromSlice(this)
+        }
+
+
+/**
+ * Note: caller required handle empty list due to parsing error.
+ */
+private fun getAuthenticationEntryList(
+    providerId: String,
+    providerDisplayName: String,
+    providerIcon: Drawable,
+    authEntryList: List<AuthenticationEntry>,
+): List<AuthenticationEntryInfo> {
+    val result: MutableList<AuthenticationEntryInfo> = mutableListOf()
+    authEntryList.forEach { entry ->
+        val structuredAuthEntry =
+            AuthenticationAction.fromSlice(entry.slice) ?: return@forEach
+
+        val title: String =
+            structuredAuthEntry.title.toString().ifEmpty { providerDisplayName }
+
+        result.add(
+            AuthenticationEntryInfo(
+            providerId = providerId,
+            entryKey = entry.key,
+            entrySubkey = entry.subkey,
+            pendingIntent = structuredAuthEntry.pendingIntent,
+            fillInIntent = entry.frameworkExtrasIntent,
+            title = title,
+            providerDisplayName = providerDisplayName,
+            icon = providerIcon,
+            isUnlockedAndEmpty = entry.status != AuthenticationEntry.STATUS_LOCKED,
+            isLastUnlocked =
+            entry.status == AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT
+        )
+        )
+    }
+    return result
+}
+
+private fun getRemoteEntry(providerId: String, remoteEntry: Entry?): RemoteEntryInfo? {
+    if (remoteEntry == null) {
+        return null
+    }
+    val structuredRemoteEntry = RemoteEntry.fromSlice(remoteEntry.slice)
+        ?: return null
+    return RemoteEntryInfo(
+        providerId = providerId,
+        entryKey = remoteEntry.key,
+        entrySubkey = remoteEntry.subkey,
+        pendingIntent = structuredRemoteEntry.pendingIntent,
+        fillInIntent = remoteEntry.frameworkExtrasIntent,
+    )
+}
+
+/**
+ * Note: caller required handle empty list due to parsing error.
+ */
+private fun getActionEntryList(
+    providerId: String,
+    actionEntries: List<Entry>,
+    providerIcon: Drawable,
+): List<ActionEntryInfo> {
+    val result: MutableList<ActionEntryInfo> = mutableListOf()
+    actionEntries.forEach {
+        val actionEntryUi = Action.fromSlice(it.slice) ?: return@forEach
+        result.add(
+            ActionEntryInfo(
+            providerId = providerId,
+            entryKey = it.key,
+            entrySubkey = it.subkey,
+            pendingIntent = actionEntryUi.pendingIntent,
+            fillInIntent = it.frameworkExtrasIntent,
+            title = actionEntryUi.title.toString(),
+            icon = providerIcon,
+            subTitle = actionEntryUi.subtitle?.toString(),
+        )
+        )
+    }
+    return result
+}
+
+
+
+private fun getServiceLabelAndIcon(
+    pm: PackageManager,
+    providerFlattenedComponentName: String
+): Pair<String, Drawable>? {
+    var providerLabel: String? = null
+    var providerIcon: Drawable? = null
+    val component = ComponentName.unflattenFromString(providerFlattenedComponentName)
+    if (component == null) {
+        // Test data has only package name not component name.
+        // For test data usage only.
+        try {
+            val pkgInfo = if (Flags.instantAppsEnabled()) {
+                getPackageInfo(pm, providerFlattenedComponentName)
+            } else {
+                pm.getPackageInfo(
+                    providerFlattenedComponentName,
+                    PackageManager.PackageInfoFlags.of(0)
+                )
+            }
+            val applicationInfo = checkNotNull(pkgInfo.applicationInfo)
+            providerLabel =
+                applicationInfo.loadSafeLabel(
+                    pm, 0f,
+                    TextUtils.SAFE_STRING_FLAG_FIRST_LINE or TextUtils.SAFE_STRING_FLAG_TRIM
+                ).toString()
+            providerIcon = applicationInfo.loadIcon(pm)
+        } catch (e: Exception) {
+            Log.e(TAG, "Provider package info not found", e)
+        }
+    } else {
+        try {
+            val si = pm.getServiceInfo(component, PackageManager.ComponentInfoFlags.of(0))
+            providerLabel = si.loadSafeLabel(
+                pm, 0f,
+                TextUtils.SAFE_STRING_FLAG_FIRST_LINE or TextUtils.SAFE_STRING_FLAG_TRIM
+            ).toString()
+            providerIcon = si.loadIcon(pm)
+        } catch (e: PackageManager.NameNotFoundException) {
+            Log.e(TAG, "Provider service info not found", e)
+            // Added for mdoc use case where the provider may not need to register a service and
+            // instead only relies on the registration api.
+            try {
+                val pkgInfo = if (Flags.instantAppsEnabled()) {
+                    getPackageInfo(pm, providerFlattenedComponentName)
+                } else {
+                    pm.getPackageInfo(
+                        component.packageName,
+                        PackageManager.PackageInfoFlags.of(0)
+                    )
+                }
+                val applicationInfo = checkNotNull(pkgInfo.applicationInfo)
+                providerLabel =
+                    applicationInfo.loadSafeLabel(
+                        pm, 0f,
+                        TextUtils.SAFE_STRING_FLAG_FIRST_LINE or TextUtils.SAFE_STRING_FLAG_TRIM
+                    ).toString()
+                providerIcon = applicationInfo.loadIcon(pm)
+            } catch (e: Exception) {
+                Log.e(TAG, "Provider package info not found", e)
+            }
+        }
+    }
+    return if (providerLabel == null || providerIcon == null) {
+        Log.d(
+            TAG,
+            "Failed to load provider label/icon for provider $providerFlattenedComponentName"
+        )
+        null
+    } else {
+        Pair(providerLabel, providerIcon)
+    }
+}
+
+private fun getPackageInfo(
+    pm: PackageManager,
+    packageName: String
+): PackageInfo {
+    val packageManagerFlags = PackageManager.MATCH_INSTANT
+
+    return pm.getPackageInfo(
+        packageName,
+        PackageManager.PackageInfoFlags.of(
+            (packageManagerFlags).toLong())
+    )
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PasswordKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PasswordKtx.kt
deleted file mode 100644
index 3471070..0000000
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PasswordKtx.kt
+++ /dev/null
@@ -1,32 +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.0N
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.ktx
-
-import androidx.activity.result.IntentSenderRequest
-import com.android.credentialmanager.IS_AUTO_SELECTED_KEY
-import com.android.credentialmanager.model.Password
-
-fun Password.getIntentSenderRequest(
-    isAutoSelected: Boolean = false
-): IntentSenderRequest {
-    val entryIntent = entry.frameworkExtrasIntent
-    entryIntent?.putExtra(IS_AUTO_SELECTED_KEY, isAutoSelected)
-
-    return IntentSenderRequest.Builder(
-        pendingIntent = passwordCredentialEntry.pendingIntent
-    ).setFillInIntent(entryIntent).build()
-}
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt
index d4bca2a..f1f1f7c 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt
@@ -16,48 +16,18 @@
 
 package com.android.credentialmanager.mapper
 
+import android.content.Context
 import android.content.Intent
-import android.credentials.ui.Entry
-import androidx.credentials.provider.PasswordCredentialEntry
-import com.android.credentialmanager.factory.fromSlice
 import com.android.credentialmanager.ktx.getCredentialProviderDataList
 import com.android.credentialmanager.ktx.requestInfo
 import com.android.credentialmanager.ktx.resultReceiver
-import com.android.credentialmanager.model.Password
+import com.android.credentialmanager.ktx.toProviderList
 import com.android.credentialmanager.model.Request
-import com.google.common.collect.ImmutableList
-import com.google.common.collect.ImmutableMap
 
-fun Intent.toGet(): Request.Get {
-    val credentialEntries = mutableListOf<Pair<String, Entry>>()
-    for (providerData in getCredentialProviderDataList) {
-        for (credentialEntry in providerData.credentialEntries) {
-            credentialEntries.add(
-                Pair(providerData.providerFlattenedComponentName, credentialEntry)
-            )
-        }
-    }
-
-    val passwordEntries = mutableListOf<Password>()
-    for ((providerId, entry) in credentialEntries) {
-        val slice = fromSlice(entry.slice)
-        if (slice is PasswordCredentialEntry) {
-            passwordEntries.add(
-                Password(
-                    providerId = providerId,
-                    entry = entry,
-                    passwordCredentialEntry = slice
-                )
-            )
-        }
-    }
-
+fun Intent.toGet(context: Context): Request.Get {
     return Request.Get(
         token = requestInfo?.token,
-        resultReceiver = this.resultReceiver,
-        providers = ImmutableMap.copyOf(
-            getCredentialProviderDataList.associateBy { it.providerFlattenedComponentName }
-        ),
-        passwordEntries = ImmutableList.copyOf(passwordEntries)
+        resultReceiver = resultReceiver,
+        providerInfos = getCredentialProviderDataList.toProviderList(context)
     )
 }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/CredentialType.kt
similarity index 93%
rename from packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
rename to packages/CredentialManager/shared/src/com/android/credentialmanager/model/CredentialType.kt
index cc92f60..3f85192 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/CredentialType.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.common
+package com.android.credentialmanager.model
 
 enum class CredentialType {
     UNKNOWN, PASSKEY, PASSWORD,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/EntryInfo.kt
similarity index 92%
rename from packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
rename to packages/CredentialManager/shared/src/com/android/credentialmanager/model/EntryInfo.kt
index ee36989..6d59f11 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/EntryInfo.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.common
+package com.android.credentialmanager.model
 
 import android.app.PendingIntent
 import android.content.Intent
 
-open class BaseEntry (
+open class EntryInfo (
     val providerId: String,
     val entryKey: String,
     val entrySubkey: String,
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Password.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Password.kt
deleted file mode 100644
index 2fe4fd5..0000000
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Password.kt
+++ /dev/null
@@ -1,26 +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.0N
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.model
-
-import android.credentials.ui.Entry
-import androidx.credentials.provider.PasswordCredentialEntry
-
-data class Password(
-    val providerId: String,
-    val entry: Entry,
-    val passwordCredentialEntry: PasswordCredentialEntry,
-)
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
index 2289ed7..7636462 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt
@@ -16,11 +16,9 @@
 
 package com.android.credentialmanager.model
 
-import android.credentials.ui.ProviderData
 import android.os.IBinder
 import android.os.ResultReceiver
-import com.google.common.collect.ImmutableList
-import com.google.common.collect.ImmutableMap
+import com.android.credentialmanager.model.get.ProviderInfo
 
 /**
  * Represents the request made by the CredentialManager API.
@@ -51,8 +49,7 @@
     data class Get(
         override val token: IBinder?,
         val resultReceiver: ResultReceiver?,
-        val providers: ImmutableMap<String, ProviderData>,
-        val passwordEntries: ImmutableList<Password>,
+        val providerInfos: List<ProviderInfo>,
     ) : Request(token)
     /**
      * Request to start the create credentials flow.
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/CreateOptionInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/CreateOptionInfo.kt
new file mode 100644
index 0000000..d6189eb
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/CreateOptionInfo.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.creation
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import com.android.credentialmanager.model.EntryInfo
+import java.time.Instant
+
+class CreateOptionInfo(
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+    val userProviderDisplayName: String,
+    val profileIcon: Drawable?,
+    val passwordCount: Int?,
+    val passkeyCount: Int?,
+    val totalCredentialCount: Int?,
+    val lastUsedTime: Instant,
+    val footerDescription: String?,
+    val allowAutoSelect: Boolean,
+) : EntryInfo(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = true,
+)
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/RemoteInfo.kt
similarity index 61%
copy from packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
copy to packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/RemoteInfo.kt
index ee36989..7ee50d7 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/creation/RemoteInfo.kt
@@ -14,16 +14,23 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.common
+package com.android.credentialmanager.model.creation
 
 import android.app.PendingIntent
 import android.content.Intent
+import com.android.credentialmanager.model.EntryInfo
 
-open class BaseEntry (
-    val providerId: String,
-    val entryKey: String,
-    val entrySubkey: String,
-    val pendingIntent: PendingIntent?,
-    val fillInIntent: Intent?,
-    val shouldTerminateUiUponSuccessfulProviderResult: Boolean,
+class RemoteInfo(
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+) : EntryInfo(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = true,
 )
\ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ActionEntryInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ActionEntryInfo.kt
new file mode 100644
index 0000000..d9eee86
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ActionEntryInfo.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.get
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import com.android.credentialmanager.model.EntryInfo
+
+class ActionEntryInfo(
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+    val title: String,
+    val icon: Drawable,
+    val subTitle: String?,
+) : EntryInfo(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = true,
+)
\ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/AuthenticationEntryInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/AuthenticationEntryInfo.kt
new file mode 100644
index 0000000..01c394f
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/AuthenticationEntryInfo.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.credentialmanager.model.get
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import com.android.credentialmanager.model.EntryInfo
+
+class AuthenticationEntryInfo(
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+    val title: String,
+    val providerDisplayName: String,
+    val icon: Drawable,
+    // The entry had been unlocked and turned out to be empty. Used to determine whether to
+    // show "Tap to unlock" or "No sign-in info" for this entry.
+    val isUnlockedAndEmpty: Boolean,
+    // True if the entry was the last one unlocked. Used to show the no sign-in info snackbar.
+    val isLastUnlocked: Boolean,
+) : EntryInfo(
+    providerId,
+    entryKey, entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = false,
+)
\ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt
new file mode 100644
index 0000000..9725881
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.get
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.EntryInfo
+import java.time.Instant
+
+class CredentialEntryInfo(
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+    /** Type of this credential used for sorting. Not localized so must not be directly displayed. */
+    val credentialType: CredentialType,
+    /** Localized type value of this credential used for display purpose. */
+    val credentialTypeDisplayName: String,
+    val providerDisplayName: String,
+    val userName: String,
+    val displayName: String?,
+    val icon: Drawable?,
+    val shouldTintIcon: Boolean,
+    val lastUsedTimeMillis: Instant?,
+    val isAutoSelectable: Boolean,
+) : EntryInfo(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = true,
+)
\ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ProviderInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ProviderInfo.kt
new file mode 100644
index 0000000..6da4146
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/ProviderInfo.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager.model.get
+
+import android.graphics.drawable.Drawable
+
+data class ProviderInfo(
+    /**
+     * Unique id (component name) of this provider.
+     * Not for display purpose - [displayName] should be used for ui rendering.
+     */
+    val id: String,
+    val icon: Drawable,
+    val displayName: String,
+    val credentialEntryList: List<CredentialEntryInfo>,
+    val authenticationEntryList: List<AuthenticationEntryInfo>,
+    val remoteEntry: RemoteEntryInfo?,
+    val actionEntryList: List<ActionEntryInfo>,
+)
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/RemoteEntryInfo.kt
similarity index 61%
copy from packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
copy to packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/RemoteEntryInfo.kt
index ee36989..a68bf74 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/RemoteEntryInfo.kt
@@ -14,16 +14,23 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.common
+package com.android.credentialmanager.model.get
 
 import android.app.PendingIntent
 import android.content.Intent
+import com.android.credentialmanager.model.EntryInfo
 
-open class BaseEntry (
-    val providerId: String,
-    val entryKey: String,
-    val entrySubkey: String,
-    val pendingIntent: PendingIntent?,
-    val fillInIntent: Intent?,
-    val shouldTerminateUiUponSuccessfulProviderResult: Boolean,
+class RemoteEntryInfo(
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+) : EntryInfo(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = true,
 )
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index bce86c4..6c5a984 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -28,7 +28,7 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
 import androidx.lifecycle.ViewModel
-import com.android.credentialmanager.common.BaseEntry
+import com.android.credentialmanager.model.EntryInfo
 import com.android.credentialmanager.common.Constants
 import com.android.credentialmanager.common.DialogState
 import com.android.credentialmanager.common.ProviderActivityResult
@@ -47,7 +47,7 @@
 data class UiState(
     val createCredentialUiState: CreateCredentialUiState?,
     val getCredentialUiState: GetCredentialUiState?,
-    val selectedEntry: BaseEntry? = null,
+    val selectedEntry: EntryInfo? = null,
     val providerActivityState: ProviderActivityState = ProviderActivityState.NOT_APPLICABLE,
     val dialogState: DialogState = DialogState.ACTIVE,
     // True if the UI has one and only one auto selectable entry. Its provider activity will be
@@ -115,12 +115,13 @@
         launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
     ) {
         val entry = uiState.selectedEntry
-        if (entry != null && entry.pendingIntent != null) {
+        val pendingIntent = entry?.pendingIntent
+        if (pendingIntent != null) {
             Log.d(Constants.LOG_TAG, "Launching provider activity")
             uiState = uiState.copy(providerActivityState = ProviderActivityState.PENDING)
             val entryIntent = entry.fillInIntent
             entryIntent?.putExtra(Constants.IS_AUTO_SELECTED_KEY, uiState.isAutoSelectFlow)
-            val intentSenderRequest = IntentSenderRequest.Builder(entry.pendingIntent)
+            val intentSenderRequest = IntentSenderRequest.Builder(pendingIntent)
                 .setFillInIntent(entryIntent).build()
             try {
                 launcher.launch(intentSenderRequest)
@@ -201,7 +202,7 @@
     /**************************************************************************/
     /*****                      Get Flow Callbacks                        *****/
     /**************************************************************************/
-    fun getFlowOnEntrySelected(entry: BaseEntry) {
+    fun getFlowOnEntrySelected(entry: EntryInfo) {
         Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
             ", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
         uiState = if (entry.pendingIntent != null) {
@@ -363,7 +364,7 @@
         )
     }
 
-    fun createFlowOnEntrySelected(selectedEntry: BaseEntry) {
+    fun createFlowOnEntrySelected(selectedEntry: EntryInfo) {
         val providerId = selectedEntry.providerId
         val entryKey = selectedEntry.entryKey
         val entrySubkey = selectedEntry.entrySubkey
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index f0fa6c5..fc3970d 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -16,13 +16,10 @@
 
 package com.android.credentialmanager
 
-import android.app.slice.Slice
 import android.content.ComponentName
 import android.content.Context
 import android.content.pm.PackageInfo
 import android.content.pm.PackageManager
-import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
-import android.credentials.ui.AuthenticationEntry
 import android.credentials.ui.CreateCredentialProviderData
 import android.credentials.ui.DisabledProviderData
 import android.credentials.ui.Entry
@@ -32,36 +29,26 @@
 import android.text.TextUtils
 import android.util.Log
 import com.android.credentialmanager.common.Constants
-import com.android.credentialmanager.common.CredentialType
+import com.android.credentialmanager.model.CredentialType
 import com.android.credentialmanager.createflow.ActiveEntry
 import com.android.credentialmanager.createflow.CreateCredentialUiState
-import com.android.credentialmanager.createflow.CreateOptionInfo
+import com.android.credentialmanager.model.creation.CreateOptionInfo
 import com.android.credentialmanager.createflow.CreateScreenState
 import com.android.credentialmanager.createflow.DisabledProviderInfo
 import com.android.credentialmanager.createflow.EnabledProviderInfo
-import com.android.credentialmanager.createflow.RemoteInfo
+import com.android.credentialmanager.model.creation.RemoteInfo
 import com.android.credentialmanager.createflow.RequestDisplayInfo
-import com.android.credentialmanager.getflow.ActionEntryInfo
-import com.android.credentialmanager.getflow.AuthenticationEntryInfo
-import com.android.credentialmanager.getflow.CredentialEntryInfo
-import com.android.credentialmanager.getflow.ProviderInfo
-import com.android.credentialmanager.getflow.RemoteEntryInfo
-import com.android.credentialmanager.getflow.TopBrandingContent
+import com.android.credentialmanager.model.get.ProviderInfo
+import com.android.credentialmanager.ktx.toProviderList
 import androidx.credentials.CreateCredentialRequest
 import androidx.credentials.CreateCustomCredentialRequest
 import androidx.credentials.CreatePasswordRequest
 import androidx.credentials.CreatePublicKeyCredentialRequest
-import androidx.credentials.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
-import androidx.credentials.provider.Action
-import androidx.credentials.provider.AuthenticationAction
 import androidx.credentials.provider.CreateEntry
-import androidx.credentials.provider.CredentialEntry
-import androidx.credentials.provider.CustomCredentialEntry
-import androidx.credentials.provider.PasswordCredentialEntry
-import androidx.credentials.provider.PublicKeyCredentialEntry
 import androidx.credentials.provider.RemoteEntry
 import org.json.JSONObject
 import android.credentials.flags.Flags
+import com.android.credentialmanager.getflow.TopBrandingContent
 import java.time.Instant
 
 
@@ -179,43 +166,7 @@
         fun toProviderList(
             providerDataList: List<GetCredentialProviderData>,
             context: Context,
-        ): List<ProviderInfo> {
-            val providerList: MutableList<ProviderInfo> = mutableListOf()
-            providerDataList.forEach {
-                val providerLabelAndIcon = getServiceLabelAndIcon(
-                    context.packageManager,
-                    it.providerFlattenedComponentName
-                ) ?: return@forEach
-                val (providerLabel, providerIcon) = providerLabelAndIcon
-                providerList.add(
-                    ProviderInfo(
-                        id = it.providerFlattenedComponentName,
-                        icon = providerIcon,
-                        displayName = providerLabel,
-                        credentialEntryList = getCredentialOptionInfoList(
-                            providerId = it.providerFlattenedComponentName,
-                            providerLabel = providerLabel,
-                            credentialEntries = it.credentialEntries,
-                            context = context
-                        ),
-                        authenticationEntryList = getAuthenticationEntryList(
-                            it.providerFlattenedComponentName,
-                            providerLabel,
-                            providerIcon,
-                            it.authenticationEntries),
-                        remoteEntry = getRemoteEntry(
-                            it.providerFlattenedComponentName,
-                            it.remoteEntry
-                        ),
-                        actionEntryList = getActionEntryList(
-                            it.providerFlattenedComponentName, it.actionChips, providerIcon
-                        ),
-                    )
-                )
-            }
-            return providerList
-        }
-
+        ): List<ProviderInfo> = providerDataList.toProviderList(context)
         fun toRequestDisplayInfo(
             requestInfo: RequestInfo?,
             context: Context,
@@ -254,178 +205,6 @@
                 preferTopBrandingContent = preferTopBrandingContent,
             )
         }
-
-
-        /**
-         * Note: caller required handle empty list due to parsing error.
-         */
-        private fun getCredentialOptionInfoList(
-            providerId: String,
-            providerLabel: String,
-            credentialEntries: List<Entry>,
-            context: Context,
-        ): List<CredentialEntryInfo> {
-            val result: MutableList<CredentialEntryInfo> = mutableListOf()
-            credentialEntries.forEach {
-                val credentialEntry = parseCredentialEntryFromSlice(it.slice)
-                when (credentialEntry) {
-                    is PasswordCredentialEntry -> {
-                        result.add(CredentialEntryInfo(
-                            providerId = providerId,
-                            providerDisplayName = providerLabel,
-                            entryKey = it.key,
-                            entrySubkey = it.subkey,
-                            pendingIntent = credentialEntry.pendingIntent,
-                            fillInIntent = it.frameworkExtrasIntent,
-                            credentialType = CredentialType.PASSWORD,
-                            credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
-                            userName = credentialEntry.username.toString(),
-                            displayName = credentialEntry.displayName?.toString(),
-                            icon = credentialEntry.icon.loadDrawable(context),
-                            shouldTintIcon = credentialEntry.isDefaultIcon,
-                            lastUsedTimeMillis = credentialEntry.lastUsedTime,
-                            isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
-                                credentialEntry.autoSelectAllowedFromOption,
-                        ))
-                    }
-                    is PublicKeyCredentialEntry -> {
-                        result.add(CredentialEntryInfo(
-                            providerId = providerId,
-                            providerDisplayName = providerLabel,
-                            entryKey = it.key,
-                            entrySubkey = it.subkey,
-                            pendingIntent = credentialEntry.pendingIntent,
-                            fillInIntent = it.frameworkExtrasIntent,
-                            credentialType = CredentialType.PASSKEY,
-                            credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
-                            userName = credentialEntry.username.toString(),
-                            displayName = credentialEntry.displayName?.toString(),
-                            icon = credentialEntry.icon.loadDrawable(context),
-                            shouldTintIcon = credentialEntry.isDefaultIcon,
-                            lastUsedTimeMillis = credentialEntry.lastUsedTime,
-                            isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
-                                credentialEntry.autoSelectAllowedFromOption,
-                        ))
-                    }
-                    is CustomCredentialEntry -> {
-                        result.add(CredentialEntryInfo(
-                            providerId = providerId,
-                            providerDisplayName = providerLabel,
-                            entryKey = it.key,
-                            entrySubkey = it.subkey,
-                            pendingIntent = credentialEntry.pendingIntent,
-                            fillInIntent = it.frameworkExtrasIntent,
-                            credentialType = CredentialType.UNKNOWN,
-                            credentialTypeDisplayName =
-                            credentialEntry.typeDisplayName?.toString().orEmpty(),
-                            userName = credentialEntry.title.toString(),
-                            displayName = credentialEntry.subtitle?.toString(),
-                            icon = credentialEntry.icon.loadDrawable(context),
-                            shouldTintIcon = credentialEntry.isDefaultIcon,
-                            lastUsedTimeMillis = credentialEntry.lastUsedTime,
-                            isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
-                                credentialEntry.autoSelectAllowedFromOption,
-                        ))
-                    }
-                    else -> Log.d(
-                        Constants.LOG_TAG,
-                        "Encountered unrecognized credential entry ${it.slice.spec?.type}"
-                    )
-                }
-            }
-            return result
-        }
-
-        /**
-         * @hide
-         */
-        fun parseCredentialEntryFromSlice(slice: Slice): CredentialEntry? {
-            try {
-                when (slice.spec?.type) {
-                    TYPE_PASSWORD_CREDENTIAL -> return PasswordCredentialEntry.fromSlice(slice)!!
-                    TYPE_PUBLIC_KEY_CREDENTIAL -> return PublicKeyCredentialEntry.fromSlice(slice)!!
-                    else -> return CustomCredentialEntry.fromSlice(slice)!!
-                }
-            } catch (e: Exception) {
-                // Try CustomCredentialEntry.fromSlice one last time in case the cause was a failed
-                // password / passkey parsing attempt.
-                return CustomCredentialEntry.fromSlice(slice)
-            }
-        }
-
-        /**
-         * Note: caller required handle empty list due to parsing error.
-         */
-        private fun getAuthenticationEntryList(
-            providerId: String,
-            providerDisplayName: String,
-            providerIcon: Drawable,
-            authEntryList: List<AuthenticationEntry>,
-        ): List<AuthenticationEntryInfo> {
-            val result: MutableList<AuthenticationEntryInfo> = mutableListOf()
-            authEntryList.forEach { entry ->
-                val structuredAuthEntry =
-                    AuthenticationAction.fromSlice(entry.slice) ?: return@forEach
-
-                val title: String =
-                    structuredAuthEntry.title.toString().ifEmpty { providerDisplayName }
-
-                result.add(AuthenticationEntryInfo(
-                    providerId = providerId,
-                    entryKey = entry.key,
-                    entrySubkey = entry.subkey,
-                    pendingIntent = structuredAuthEntry.pendingIntent,
-                    fillInIntent = entry.frameworkExtrasIntent,
-                    title = title,
-                    providerDisplayName = providerDisplayName,
-                    icon = providerIcon,
-                    isUnlockedAndEmpty = entry.status != AuthenticationEntry.STATUS_LOCKED,
-                    isLastUnlocked =
-                    entry.status == AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT
-                ))
-            }
-            return result
-        }
-
-        private fun getRemoteEntry(providerId: String, remoteEntry: Entry?): RemoteEntryInfo? {
-            if (remoteEntry == null) {
-                return null
-            }
-            val structuredRemoteEntry = RemoteEntry.fromSlice(remoteEntry.slice)
-                ?: return null
-            return RemoteEntryInfo(
-                providerId = providerId,
-                entryKey = remoteEntry.key,
-                entrySubkey = remoteEntry.subkey,
-                pendingIntent = structuredRemoteEntry.pendingIntent,
-                fillInIntent = remoteEntry.frameworkExtrasIntent,
-            )
-        }
-
-        /**
-         * Note: caller required handle empty list due to parsing error.
-         */
-        private fun getActionEntryList(
-            providerId: String,
-            actionEntries: List<Entry>,
-            providerIcon: Drawable,
-        ): List<ActionEntryInfo> {
-            val result: MutableList<ActionEntryInfo> = mutableListOf()
-            actionEntries.forEach {
-                val actionEntryUi = Action.fromSlice(it.slice) ?: return@forEach
-                result.add(ActionEntryInfo(
-                    providerId = providerId,
-                    entryKey = it.key,
-                    entrySubkey = it.subkey,
-                    pendingIntent = actionEntryUi.pendingIntent,
-                    fillInIntent = it.frameworkExtrasIntent,
-                    title = actionEntryUi.title.toString(),
-                    icon = providerIcon,
-                    subTitle = actionEntryUi.subtitle?.toString(),
-                ))
-            }
-            return result
-        }
     }
 }
 
@@ -686,7 +465,8 @@
             val result: MutableList<CreateOptionInfo> = mutableListOf()
             creationEntries.forEach {
                 val createEntry = CreateEntry.fromSlice(it.slice) ?: return@forEach
-                result.add(CreateOptionInfo(
+                result.add(
+                    CreateOptionInfo(
                     providerId = providerId,
                     entryKey = it.key,
                     entrySubkey = it.subkey,
@@ -705,7 +485,8 @@
                         it.hasHint("androidx.credentials.provider.createEntry.SLICE_HINT_AUTO_" +
                             "SELECT_ALLOWED")
                     }?.text == "true",
-                ))
+                )
+                )
             }
             return result.sortedWith(
                 compareByDescending { it.lastUsedTime }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
index 281696d..20d2f09 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
@@ -48,10 +48,11 @@
 import androidx.credentials.provider.PasswordCredentialEntry
 import androidx.credentials.provider.PublicKeyCredentialEntry
 import com.android.credentialmanager.GetFlowUtils
-import com.android.credentialmanager.getflow.CredentialEntryInfo
+import com.android.credentialmanager.model.get.CredentialEntryInfo
 import com.android.credentialmanager.getflow.ProviderDisplayInfo
-import com.android.credentialmanager.getflow.ProviderInfo
+import com.android.credentialmanager.model.get.ProviderInfo
 import com.android.credentialmanager.getflow.toProviderDisplayInfo
+import com.android.credentialmanager.ktx.credentialEntry
 import org.json.JSONObject
 import java.util.concurrent.Executors
 
@@ -122,8 +123,7 @@
         val entryIconMap: MutableMap<String, Icon> = mutableMapOf()
         candidateProviderDataList.forEach { provider ->
             provider.credentialEntries.forEach { entry ->
-                val credentialEntry = GetFlowUtils.parseCredentialEntryFromSlice(entry.slice)
-                when (credentialEntry) {
+                when (val credentialEntry = entry.slice.credentialEntry) {
                     is PasswordCredentialEntry -> {
                         entryIconMap[entry.key + entry.subkey] = credentialEntry.icon
                     }
@@ -172,11 +172,11 @@
     }
 
     private fun processProvidersForAutofillId(
-            filLRequest: FillRequest,
-            autofillId: AutofillId,
-            providerList: List<ProviderInfo>,
-            entryIconMap: Map<String, Icon>,
-            fillResponseBuilder: FillResponse.Builder
+        filLRequest: FillRequest,
+        autofillId: AutofillId,
+        providerList: List<ProviderInfo>,
+        entryIconMap: Map<String, Icon>,
+        fillResponseBuilder: FillResponse.Builder
     ): Boolean {
         if (providerList.isEmpty()) {
             return false
@@ -200,7 +200,8 @@
         providerDisplayInfo.sortedUserNameToCredentialEntryList.forEach usernameLoop@ {
             val primaryEntry = it.sortedCredentialEntryList.first()
             val pendingIntent = primaryEntry.pendingIntent
-            if (pendingIntent == null || primaryEntry.fillInIntent == null) {
+            val fillInIntent = primaryEntry.fillInIntent
+            if (pendingIntent == null || fillInIntent == null) {
                 // FillInIntent will not be null because autofillId was retrieved from it.
                 Log.e(TAG, "PendingIntent was missing from the entry.")
                 return@usernameLoop
@@ -245,7 +246,7 @@
                                             presentationBuilder.build())
                                             .build())
                             .setAuthentication(pendingIntent.intentSender)
-                            .setAuthenticationExtras(primaryEntry.fillInIntent.extras)
+                            .setAuthenticationExtras(fillInIntent.extras)
                             .build())
             datasetAdded = true
         }
@@ -322,8 +323,8 @@
     }
 
     private fun copyProviderInfo(
-            providerInfo: ProviderInfo,
-            credentialList: List<CredentialEntryInfo>
+        providerInfo: ProviderInfo,
+        credentialList: List<CredentialEntryInfo>
     ): ProviderInfo {
         return ProviderInfo(
                 providerInfo.id,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index d45b6f6..14a9165 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -48,8 +48,8 @@
 import androidx.core.graphics.drawable.toBitmap
 import com.android.credentialmanager.CredentialSelectorViewModel
 import com.android.credentialmanager.R
-import com.android.credentialmanager.common.BaseEntry
-import com.android.credentialmanager.common.CredentialType
+import com.android.credentialmanager.model.EntryInfo
+import com.android.credentialmanager.model.CredentialType
 import com.android.credentialmanager.common.ProviderActivityState
 import com.android.credentialmanager.common.material.ModalBottomSheetDefaults
 import com.android.credentialmanager.common.ui.ActionButton
@@ -68,6 +68,8 @@
 import com.android.credentialmanager.common.ui.PasskeyBenefitRow
 import com.android.credentialmanager.common.ui.HeadlineText
 import com.android.credentialmanager.logging.CreateCredentialEvent
+import com.android.credentialmanager.model.creation.CreateOptionInfo
+import com.android.credentialmanager.model.creation.RemoteInfo
 import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
 import com.android.internal.logging.UiEventLogger.UiEventEnum
 
@@ -259,15 +261,15 @@
 
 @Composable
 fun MoreOptionsSelectionCard(
-        requestDisplayInfo: RequestDisplayInfo,
-        enabledProviderList: List<EnabledProviderInfo>,
-        disabledProviderList: List<DisabledProviderInfo>?,
-        sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
-        onBackCreationSelectionButtonSelected: () -> Unit,
-        onOptionSelected: (ActiveEntry) -> Unit,
-        onDisabledProvidersSelected: () -> Unit,
-        onRemoteEntrySelected: (BaseEntry) -> Unit,
-        onLog: @Composable (UiEventEnum) -> Unit,
+    requestDisplayInfo: RequestDisplayInfo,
+    enabledProviderList: List<EnabledProviderInfo>,
+    disabledProviderList: List<DisabledProviderInfo>?,
+    sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
+    onBackCreationSelectionButtonSelected: () -> Unit,
+    onOptionSelected: (ActiveEntry) -> Unit,
+    onDisabledProvidersSelected: () -> Unit,
+    onRemoteEntrySelected: (EntryInfo) -> Unit,
+    onLog: @Composable (UiEventEnum) -> Unit,
 ) {
     SheetContainerCard(topAppBar = {
         MoreOptionTopAppBar(
@@ -378,14 +380,14 @@
 
 @Composable
 fun CreationSelectionCard(
-        requestDisplayInfo: RequestDisplayInfo,
-        enabledProviderList: List<EnabledProviderInfo>,
-        providerInfo: EnabledProviderInfo,
-        createOptionInfo: CreateOptionInfo,
-        onOptionSelected: (BaseEntry) -> Unit,
-        onConfirm: () -> Unit,
-        onMoreOptionsSelected: () -> Unit,
-        onLog: @Composable (UiEventEnum) -> Unit,
+    requestDisplayInfo: RequestDisplayInfo,
+    enabledProviderList: List<EnabledProviderInfo>,
+    providerInfo: EnabledProviderInfo,
+    createOptionInfo: CreateOptionInfo,
+    onOptionSelected: (EntryInfo) -> Unit,
+    onConfirm: () -> Unit,
+    onMoreOptionsSelected: () -> Unit,
+    onLog: @Composable (UiEventEnum) -> Unit,
 ) {
     SheetContainerCard {
         item {
@@ -474,11 +476,11 @@
 
 @Composable
 fun ExternalOnlySelectionCard(
-        requestDisplayInfo: RequestDisplayInfo,
-        activeRemoteEntry: BaseEntry,
-        onOptionSelected: (BaseEntry) -> Unit,
-        onConfirm: () -> Unit,
-        onLog: @Composable (UiEventEnum) -> Unit,
+    requestDisplayInfo: RequestDisplayInfo,
+    activeRemoteEntry: EntryInfo,
+    onOptionSelected: (EntryInfo) -> Unit,
+    onConfirm: () -> Unit,
+    onLog: @Composable (UiEventEnum) -> Unit,
 ) {
     SheetContainerCard {
         item { HeadlineIcon(imageVector = Icons.Outlined.QrCodeScanner) }
@@ -575,17 +577,14 @@
 @Composable
 fun PrimaryCreateOptionRow(
     requestDisplayInfo: RequestDisplayInfo,
-    entryInfo: BaseEntry,
-    onOptionSelected: (BaseEntry) -> Unit
+    entryInfo: EntryInfo,
+    onOptionSelected: (EntryInfo) -> Unit
 ) {
     Entry(
         onClick = { onOptionSelected(entryInfo) },
-        iconImageBitmap =
-        if (entryInfo is CreateOptionInfo && entryInfo.profileIcon != null) {
-            entryInfo.profileIcon.toBitmap().asImageBitmap()
-        } else {
-            requestDisplayInfo.typeIcon.toBitmap().asImageBitmap()
-        },
+        iconImageBitmap = ((entryInfo as? CreateOptionInfo)?.profileIcon
+            ?: requestDisplayInfo.typeIcon)
+            .toBitmap().asImageBitmap(),
         shouldApplyIconImageBitmapTint = !(entryInfo is CreateOptionInfo &&
             entryInfo.profileIcon != null),
         entryHeadlineText = requestDisplayInfo.title,
@@ -627,32 +626,33 @@
         entryThirdLineText =
         if (requestDisplayInfo.type == CredentialType.PASSKEY ||
             requestDisplayInfo.type == CredentialType.PASSWORD) {
-            if (createOptionInfo.passwordCount != null &&
-                createOptionInfo.passkeyCount != null
-            ) {
+            val passwordCount = createOptionInfo.passwordCount
+            val passkeyCount = createOptionInfo.passkeyCount
+            if (passwordCount != null && passkeyCount != null) {
                 stringResource(
                     R.string.more_options_usage_passwords_passkeys,
-                    createOptionInfo.passwordCount,
-                    createOptionInfo.passkeyCount
+                    passwordCount,
+                    passkeyCount
                 )
-            } else if (createOptionInfo.passwordCount != null) {
+            } else if (passwordCount != null) {
                 stringResource(
                     R.string.more_options_usage_passwords,
-                    createOptionInfo.passwordCount
+                    passwordCount
                 )
-            } else if (createOptionInfo.passkeyCount != null) {
+            } else if (passkeyCount != null) {
                 stringResource(
                     R.string.more_options_usage_passkeys,
-                    createOptionInfo.passkeyCount
+                    passkeyCount
                 )
             } else {
                 null
             }
         } else {
-            if (createOptionInfo.totalCredentialCount != null) {
+            val totalCredentialCount = createOptionInfo.totalCredentialCount
+            if (totalCredentialCount != null) {
                 stringResource(
                     R.string.more_options_usage_credentials,
-                    createOptionInfo.totalCredentialCount
+                    totalCredentialCount
                 )
             } else {
                 null
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
index e9e8c2e..8b0ba87 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
@@ -16,22 +16,21 @@
 
 package com.android.credentialmanager.createflow
 
-import android.app.PendingIntent
-import android.content.Intent
 import android.graphics.drawable.Drawable
-import com.android.credentialmanager.common.BaseEntry
-import com.android.credentialmanager.common.CredentialType
-import java.time.Instant
+import com.android.credentialmanager.model.EntryInfo
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.creation.CreateOptionInfo
+import com.android.credentialmanager.model.creation.RemoteInfo
 
 data class CreateCredentialUiState(
-  val enabledProviders: List<EnabledProviderInfo>,
-  val disabledProviders: List<DisabledProviderInfo>? = null,
-  val currentScreenState: CreateScreenState,
-  val requestDisplayInfo: RequestDisplayInfo,
-  val sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
-  val activeEntry: ActiveEntry? = null,
-  val remoteEntry: RemoteInfo? = null,
-  val foundCandidateFromUserDefaultProvider: Boolean,
+    val enabledProviders: List<EnabledProviderInfo>,
+    val disabledProviders: List<DisabledProviderInfo>? = null,
+    val currentScreenState: CreateScreenState,
+    val requestDisplayInfo: RequestDisplayInfo,
+    val sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
+    val activeEntry: ActiveEntry? = null,
+    val remoteEntry: RemoteInfo? = null,
+    val foundCandidateFromUserDefaultProvider: Boolean,
 )
 
 internal fun isFlowAutoSelectable(
@@ -75,44 +74,6 @@
   displayName: String,
 ) : ProviderInfo(icon, id, displayName)
 
-class CreateOptionInfo(
-    providerId: String,
-    entryKey: String,
-    entrySubkey: String,
-    pendingIntent: PendingIntent?,
-    fillInIntent: Intent?,
-    val userProviderDisplayName: String,
-    val profileIcon: Drawable?,
-    val passwordCount: Int?,
-    val passkeyCount: Int?,
-    val totalCredentialCount: Int?,
-    val lastUsedTime: Instant,
-    val footerDescription: String?,
-    val allowAutoSelect: Boolean,
-) : BaseEntry(
-    providerId,
-    entryKey,
-    entrySubkey,
-    pendingIntent,
-    fillInIntent,
-    shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
-class RemoteInfo(
-  providerId: String,
-  entryKey: String,
-  entrySubkey: String,
-  pendingIntent: PendingIntent?,
-  fillInIntent: Intent?,
-) : BaseEntry(
-    providerId,
-    entryKey,
-    entrySubkey,
-    pendingIntent,
-    fillInIntent,
-    shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
 data class RequestDisplayInfo(
   val title: String,
   val subtitle: String?,
@@ -131,8 +92,8 @@
  * user selects a different entry on the more option page.
  */
 data class ActiveEntry (
-  val activeProvider: EnabledProviderInfo,
-  val activeEntryInfo: BaseEntry,
+    val activeProvider: EnabledProviderInfo,
+    val activeEntryInfo: EntryInfo,
 )
 
 /** The name of the current screen. */
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index 72d030b..4ed84b9 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -48,8 +48,9 @@
 import androidx.core.graphics.drawable.toBitmap
 import com.android.credentialmanager.CredentialSelectorViewModel
 import com.android.credentialmanager.R
-import com.android.credentialmanager.common.BaseEntry
-import com.android.credentialmanager.common.CredentialType
+import com.android.credentialmanager.model.EntryInfo
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.get.ProviderInfo
 import com.android.credentialmanager.common.ProviderActivityState
 import com.android.credentialmanager.common.material.ModalBottomSheetDefaults
 import com.android.credentialmanager.common.ui.ActionButton
@@ -68,6 +69,10 @@
 import com.android.credentialmanager.common.ui.LargeLabelTextOnSurfaceVariant
 import com.android.credentialmanager.common.ui.Snackbar
 import com.android.credentialmanager.logging.GetCredentialEvent
+import com.android.credentialmanager.model.get.ActionEntryInfo
+import com.android.credentialmanager.model.get.AuthenticationEntryInfo
+import com.android.credentialmanager.model.get.CredentialEntryInfo
+import com.android.credentialmanager.model.get.RemoteEntryInfo
 import com.android.credentialmanager.userAndDisplayNameForPasskey
 import com.android.internal.logging.UiEventLogger.UiEventEnum
 
@@ -175,8 +180,8 @@
     requestDisplayInfo: RequestDisplayInfo,
     providerDisplayInfo: ProviderDisplayInfo,
     providerInfoList: List<ProviderInfo>,
-    activeEntry: BaseEntry?,
-    onEntrySelected: (BaseEntry) -> Unit,
+    activeEntry: EntryInfo?,
+    onEntrySelected: (EntryInfo) -> Unit,
     onConfirm: () -> Unit,
     onMoreOptionSelected: () -> Unit,
     onLog: @Composable (UiEventEnum) -> Unit,
@@ -358,7 +363,7 @@
 fun AllSignInOptionCard(
     providerInfoList: List<ProviderInfo>,
     providerDisplayInfo: ProviderDisplayInfo,
-    onEntrySelected: (BaseEntry) -> Unit,
+    onEntrySelected: (EntryInfo) -> Unit,
     onBackButtonClicked: () -> Unit,
     onCancel: () -> Unit,
     onLog: @Composable (UiEventEnum) -> Unit,
@@ -436,7 +441,7 @@
 @Composable
 fun ActionChips(
     providerInfoList: List<ProviderInfo>,
-    onEntrySelected: (BaseEntry) -> Unit,
+    onEntrySelected: (EntryInfo) -> Unit,
     isFirstSection: Boolean,
 ) {
     val actionChips = providerInfoList.flatMap { it.actionEntryList }
@@ -460,7 +465,7 @@
 @Composable
 fun RemoteEntryCard(
     remoteEntry: RemoteEntryInfo,
-    onEntrySelected: (BaseEntry) -> Unit,
+    onEntrySelected: (EntryInfo) -> Unit,
     isFirstSection: Boolean,
 ) {
     CredentialListSectionHeader(
@@ -486,7 +491,7 @@
 @Composable
 fun LockedCredentials(
     authenticationEntryList: List<AuthenticationEntryInfo>,
-    onEntrySelected: (BaseEntry) -> Unit,
+    onEntrySelected: (EntryInfo) -> Unit,
     isFirstSection: Boolean,
 ) {
     CredentialListSectionHeader(
@@ -508,7 +513,7 @@
 @Composable
 fun PerUserNameCredentials(
     perUserNameCredentialEntryList: PerUserNameCredentialEntryList,
-    onEntrySelected: (BaseEntry) -> Unit,
+    onEntrySelected: (EntryInfo) -> Unit,
     isFirstSection: Boolean,
 ) {
     CredentialListSectionHeader(
@@ -532,7 +537,7 @@
 @Composable
 fun CredentialEntryRow(
     credentialEntryInfo: CredentialEntryInfo,
-    onEntrySelected: (BaseEntry) -> Unit,
+    onEntrySelected: (EntryInfo) -> Unit,
     enforceOneLine: Boolean = false,
     onTextLayout: (TextLayoutResult) -> Unit = {},
 ) {
@@ -571,7 +576,7 @@
 @Composable
 fun AuthenticationEntryRow(
     authenticationEntryInfo: AuthenticationEntryInfo,
-    onEntrySelected: (BaseEntry) -> Unit,
+    onEntrySelected: (EntryInfo) -> Unit,
     enforceOneLine: Boolean = false,
 ) {
     Entry(
@@ -596,7 +601,7 @@
 @Composable
 fun ActionEntryRow(
     actionEntryInfo: ActionEntryInfo,
-    onEntrySelected: (BaseEntry) -> Unit,
+    onEntrySelected: (EntryInfo) -> Unit,
 ) {
     ActionEntry(
         iconImageBitmap = actionEntryInfo.icon.toBitmap().asImageBitmap(),
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index 447a9d2..46bebc4 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -16,21 +16,21 @@
 
 package com.android.credentialmanager.getflow
 
-import android.app.PendingIntent
-import android.content.Intent
 import android.graphics.drawable.Drawable
-import com.android.credentialmanager.common.BaseEntry
-import com.android.credentialmanager.common.CredentialType
+import com.android.credentialmanager.model.get.ProviderInfo
+import com.android.credentialmanager.model.EntryInfo
+import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.get.AuthenticationEntryInfo
+import com.android.credentialmanager.model.get.CredentialEntryInfo
+import com.android.credentialmanager.model.get.RemoteEntryInfo
 import com.android.internal.util.Preconditions
 
-import java.time.Instant
-
 data class GetCredentialUiState(
     val providerInfoList: List<ProviderInfo>,
     val requestDisplayInfo: RequestDisplayInfo,
     val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerInfoList),
     val currentScreenState: GetScreenState = toGetScreenState(providerDisplayInfo),
-    val activeEntry: BaseEntry? = toActiveEntry(providerDisplayInfo),
+    val activeEntry: EntryInfo? = toActiveEntry(providerDisplayInfo),
     val isNoAccount: Boolean = false,
 )
 
@@ -58,20 +58,6 @@
     return null
 }
 
-data class ProviderInfo(
-    /**
-     * Unique id (component name) of this provider.
-     * Not for display purpose - [displayName] should be used for ui rendering.
-     */
-    val id: String,
-    val icon: Drawable,
-    val displayName: String,
-    val credentialEntryList: List<CredentialEntryInfo>,
-    val authenticationEntryList: List<AuthenticationEntryInfo>,
-    val remoteEntry: RemoteEntryInfo?,
-    val actionEntryList: List<ActionEntryInfo>,
-)
-
 /** Display-centric data structure derived from the [ProviderInfo]. This abstraction is not grouping
  *  by the provider id but instead focuses on structures convenient for display purposes. */
 data class ProviderDisplayInfo(
@@ -84,87 +70,6 @@
     val remoteEntry: RemoteEntryInfo?
 )
 
-class CredentialEntryInfo(
-    providerId: String,
-    entryKey: String,
-    entrySubkey: String,
-    pendingIntent: PendingIntent?,
-    fillInIntent: Intent?,
-    /** Type of this credential used for sorting. Not localized so must not be directly displayed. */
-    val credentialType: CredentialType,
-    /** Localized type value of this credential used for display purpose. */
-    val credentialTypeDisplayName: String,
-    val providerDisplayName: String,
-    val userName: String,
-    val displayName: String?,
-    val icon: Drawable?,
-    val shouldTintIcon: Boolean,
-    val lastUsedTimeMillis: Instant?,
-    val isAutoSelectable: Boolean,
-) : BaseEntry(
-    providerId,
-    entryKey,
-    entrySubkey,
-    pendingIntent,
-    fillInIntent,
-    shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
-class AuthenticationEntryInfo(
-    providerId: String,
-    entryKey: String,
-    entrySubkey: String,
-    pendingIntent: PendingIntent?,
-    fillInIntent: Intent?,
-    val title: String,
-    val providerDisplayName: String,
-    val icon: Drawable,
-    // The entry had been unlocked and turned out to be empty. Used to determine whether to
-    // show "Tap to unlock" or "No sign-in info" for this entry.
-    val isUnlockedAndEmpty: Boolean,
-    // True if the entry was the last one unlocked. Used to show the no sign-in info snackbar.
-    val isLastUnlocked: Boolean,
-) : BaseEntry(
-    providerId,
-    entryKey, entrySubkey,
-    pendingIntent,
-    fillInIntent,
-    shouldTerminateUiUponSuccessfulProviderResult = false,
-)
-
-class RemoteEntryInfo(
-    providerId: String,
-    entryKey: String,
-    entrySubkey: String,
-    pendingIntent: PendingIntent?,
-    fillInIntent: Intent?,
-) : BaseEntry(
-    providerId,
-    entryKey,
-    entrySubkey,
-    pendingIntent,
-    fillInIntent,
-    shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
-class ActionEntryInfo(
-    providerId: String,
-    entryKey: String,
-    entrySubkey: String,
-    pendingIntent: PendingIntent?,
-    fillInIntent: Intent?,
-    val title: String,
-    val icon: Drawable,
-    val subTitle: String?,
-) : BaseEntry(
-    providerId,
-    entryKey,
-    entrySubkey,
-    pendingIntent,
-    fillInIntent,
-    shouldTerminateUiUponSuccessfulProviderResult = true,
-)
-
 data class RequestDisplayInfo(
     val appName: String,
     val preferImmediatelyAvailableCredentials: Boolean,
@@ -218,8 +123,8 @@
     val remoteEntryList = mutableListOf<RemoteEntryInfo>()
     providerInfoList.forEach { providerInfo ->
         authenticationEntryList.addAll(providerInfo.authenticationEntryList)
-        if (providerInfo.remoteEntry != null) {
-            remoteEntryList.add(providerInfo.remoteEntry)
+        providerInfo.remoteEntry?.let {
+            remoteEntryList.add(it)
         }
         // There can only be at most one remote entry
         Preconditions.checkState(remoteEntryList.size <= 1)
@@ -260,11 +165,11 @@
 
 private fun toActiveEntry(
     providerDisplayInfo: ProviderDisplayInfo,
-): BaseEntry? {
+): EntryInfo? {
     val sortedUserNameToCredentialEntryList =
         providerDisplayInfo.sortedUserNameToCredentialEntryList
     val authenticationEntryList = providerDisplayInfo.authenticationEntryList
-    var activeEntry: BaseEntry? = null
+    var activeEntry: EntryInfo? = null
     if (sortedUserNameToCredentialEntryList
             .size == 1 && authenticationEntryList.isEmpty()
     ) {
@@ -302,17 +207,18 @@
                 return 1
             }
         }
-
+        val p0LastUsedTimeMillis = p0.lastUsedTimeMillis
+        val p1LastUsedTimeMillis = p1.lastUsedTimeMillis
         // Then order by last used timestamp
-        if (p0.lastUsedTimeMillis != null && p1.lastUsedTimeMillis != null) {
-            if (p0.lastUsedTimeMillis < p1.lastUsedTimeMillis) {
+        if (p0LastUsedTimeMillis != null && p1LastUsedTimeMillis != null) {
+            if (p0LastUsedTimeMillis < p1LastUsedTimeMillis) {
                 return 1
-            } else if (p0.lastUsedTimeMillis > p1.lastUsedTimeMillis) {
+            } else if (p0LastUsedTimeMillis > p1LastUsedTimeMillis) {
                 return -1
             }
-        } else if (p0.lastUsedTimeMillis != null) {
+        } else if (p0LastUsedTimeMillis != null) {
             return -1
-        } else if (p1.lastUsedTimeMillis != null) {
+        } else if (p1LastUsedTimeMillis != null) {
             return 1
         }
         return 0
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt
index 6ededf3..d8a6019 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt
@@ -1,29 +1,20 @@
 package com.android.credentialmanager.di
 
-import android.content.Context
-import android.content.pm.PackageManager
 import com.android.credentialmanager.client.CredentialManagerClient
 import com.android.credentialmanager.client.impl.CredentialManagerClientImpl
+import dagger.Binds
 import dagger.Module
-import dagger.Provides
 import dagger.hilt.InstallIn
-import dagger.hilt.android.qualifiers.ApplicationContext
 import dagger.hilt.components.SingletonComponent
 import javax.inject.Singleton
 
 @Module
 @InstallIn(SingletonComponent::class)
-internal object AppModule {
-    @Provides
+abstract class AppModule {
+    @Binds
     @Singleton
-    @JvmStatic
-    fun providePackageManager(@ApplicationContext context: Context): PackageManager =
-        context.packageManager
-
-    @Provides
-    @Singleton
-    @JvmStatic
-    fun provideCredentialManagerClient(packageManager: PackageManager): CredentialManagerClient =
-        CredentialManagerClientImpl(packageManager)
+    abstract fun provideCredentialManagerClient(
+        client: CredentialManagerClientImpl
+    ): CredentialManagerClient
 }
 
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
index f2f878e..14b992a 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
@@ -23,8 +23,8 @@
     // TODO: b/301206470 returning a hard coded state for MVP
     if (true) return CredentialSelectorUiState.Get.SingleProviderSinglePassword
 
-    return if (providers.size == 1) {
-        if (passwordEntries.size == 1) {
+    return if (providerInfos.size == 1) {
+        if (providerInfos.first().credentialEntryList.size == 1) {
             CredentialSelectorUiState.Get.SingleProviderSinglePassword
         } else {
             TODO() // b/301206470 - Implement other get flows
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
index c28df3e8..b64f581 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
@@ -76,7 +76,9 @@
             }
 
             SideEffect {
-                launcher.launch(state.intentSenderRequest)
+                state.intentSenderRequest?.let {
+                    launcher.launch(it)
+                }
             }
         }
 
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt
index fb72c54..26bee1f 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt
@@ -26,9 +26,9 @@
 import androidx.lifecycle.viewModelScope
 import com.android.credentialmanager.TAG
 import com.android.credentialmanager.ktx.getIntentSenderRequest
-import com.android.credentialmanager.model.Password
 import com.android.credentialmanager.model.Request
 import com.android.credentialmanager.client.CredentialManagerClient
+import com.android.credentialmanager.model.get.CredentialEntryInfo
 import com.android.credentialmanager.ui.model.PasswordUiModel
 import dagger.hilt.android.lifecycle.HiltViewModel
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -44,7 +44,7 @@
     private var initializeCalled = false
 
     private lateinit var requestGet: Request.Get
-    private lateinit var password: Password
+    private lateinit var entryInfo: CredentialEntryInfo
 
     private val _uiState =
         MutableStateFlow<SinglePasswordScreenUiState>(SinglePasswordScreenUiState.Idle)
@@ -63,14 +63,15 @@
                 _uiState.value = SinglePasswordScreenUiState.Error
             } else {
                 requestGet = request
-                if (requestGet.passwordEntries.isEmpty()) {
+
+                if (requestGet.providerInfos.all { it.credentialEntryList.isEmpty() }) {
                     Log.d(TAG, "Empty passwordEntries")
                     _uiState.value = SinglePasswordScreenUiState.Error
                 } else {
-                    password = requestGet.passwordEntries.first()
+                    entryInfo = requestGet.providerInfos.first().credentialEntryList.first()
                     _uiState.value = SinglePasswordScreenUiState.Loaded(
                         PasswordUiModel(
-                            email = password.passwordCredentialEntry.username.toString(),
+                            email = entryInfo.userName,
                         )
                     )
                 }
@@ -84,7 +85,7 @@
 
     fun onOKClick() {
         _uiState.value = SinglePasswordScreenUiState.PasswordSelected(
-            intentSenderRequest = password.getIntentSenderRequest()
+            intentSenderRequest = entryInfo.getIntentSenderRequest()
         )
     }
 
@@ -94,9 +95,9 @@
     ) {
         val userSelectionDialogResult = UserSelectionDialogResult(
             requestGet.token,
-            password.providerId,
-            password.entry.key,
-            password.entry.subkey,
+            entryInfo.providerId,
+            entryInfo.entryKey,
+            entryInfo.entrySubkey,
             if (resultCode != null) ProviderPendingIntentResponse(resultCode, resultData) else null
         )
         credentialManagerClient.sendResult(userSelectionDialogResult)
@@ -108,7 +109,7 @@
     data object Idle : SinglePasswordScreenUiState()
     data class Loaded(val passwordUiModel: PasswordUiModel) : SinglePasswordScreenUiState()
     data class PasswordSelected(
-        val intentSenderRequest: IntentSenderRequest
+        val intentSenderRequest: IntentSenderRequest?
     ) : SinglePasswordScreenUiState()
 
     data object Cancel : SinglePasswordScreenUiState()
diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp
index 38bd7d5..6213b34 100644
--- a/packages/PackageInstaller/Android.bp
+++ b/packages/PackageInstaller/Android.bp
@@ -49,6 +49,7 @@
         "androidx.fragment_fragment",
         "androidx.lifecycle_lifecycle-livedata",
         "androidx.lifecycle_lifecycle-extensions",
+        "android.content.pm.flags-aconfig-java",
     ],
 
     lint: {
@@ -75,6 +76,7 @@
         "androidx.fragment_fragment",
         "androidx.lifecycle_lifecycle-livedata",
         "androidx.lifecycle_lifecycle-extensions",
+        "android.content.pm.flags-aconfig-java",
     ],
     aaptflags: ["--product tablet"],
 
@@ -103,6 +105,7 @@
         "androidx.fragment_fragment",
         "androidx.lifecycle_lifecycle-livedata",
         "androidx.lifecycle_lifecycle-extensions",
+        "android.content.pm.flags-aconfig-java",
     ],
     aaptflags: ["--product tv"],
 
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index ef218fd..2e4fd9b 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -206,7 +206,19 @@
                   android:noHistory="true"
                   android:exported="true">
             <intent-filter android:priority="1">
-                <action android:name="android.intent.action.UNARCHIVE_DIALOG" />
+                <action android:name="com.android.intent.action.UNARCHIVE_DIALOG" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".UnarchiveErrorActivity"
+                  android:configChanges="orientation|keyboardHidden|screenSize"
+                  android:theme="@style/Theme.AlertDialogActivity.NoActionBar"
+                  android:excludeFromRecents="true"
+                  android:noHistory="true"
+                  android:exported="true">
+            <intent-filter android:priority="1">
+                <action android:name="com.android.intent.action.UNARCHIVE_ERROR_DIALOG" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
diff --git a/packages/PackageInstaller/TEST_MAPPING b/packages/PackageInstaller/TEST_MAPPING
index cef9014..76d7ab1 100644
--- a/packages/PackageInstaller/TEST_MAPPING
+++ b/packages/PackageInstaller/TEST_MAPPING
@@ -22,6 +22,9 @@
     },
     {
       "name": "PackageInstallerTests"
+    },
+    {
+      "name": "CtsIntentSignatureTestCases"
     }
   ]
 }
diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml
index 38a781a..a3496ca 100644
--- a/packages/PackageInstaller/res/values-af/strings.xml
+++ b/packages/PackageInstaller/res/values-af/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Kennisgewing dat program geïnstalleer is"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Suksesvol geïnstalleer"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” is suksesvol geïnstalleer"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Stel <xliff:g id="APPNAME">%1$s</xliff:g> terug vanaf <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Hierdie app sal in die agtergrond begin aflaai"</string>
+    <string name="restore" msgid="8460854736328970444">"Stel terug"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml
index 7b664bc..9d0fd53 100644
--- a/packages/PackageInstaller/res/values-am/strings.xml
+++ b/packages/PackageInstaller/res/values-am/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"የመተግበሪያ ተጭኗል ማሳወቂያ"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"በተሳካ ሁኔታ ተጭኗል"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"«<xliff:g id="APPNAME">%1$s</xliff:g>» በተሳካ ሁኔታ ተጭኗል"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"ከ <xliff:g id="INSTALLERNAME">%1$s</xliff:g> ወደነበረበት <xliff:g id="APPNAME">%1$s</xliff:g> መልስ?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"ይህ መተግበሪያ በዳራ ማውረድ ይጀምራል።"</string>
+    <string name="restore" msgid="8460854736328970444">"ወደነበረበት መልስ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index 9a4d7ea..f4c9581 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"إشعار \"تم تثبيت التطبيق\""</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"تم التثبيت بنجاح."</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"تم تثبيت \"<xliff:g id="APPNAME">%1$s</xliff:g>\" بنجاح."</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"هل تريد استعادة التطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" من \"<xliff:g id="INSTALLERNAME">%1$s</xliff:g>\"؟"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"سيبدأ تنزيل هذا التطبيق في الخلفية."</string>
+    <string name="restore" msgid="8460854736328970444">"استعادة"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml
index 65f6641..4d264c6 100644
--- a/packages/PackageInstaller/res/values-as/strings.xml
+++ b/packages/PackageInstaller/res/values-as/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"এপ্ ইনষ্টল কৰাৰ জাননী"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"সফলতাৰে ইনষ্টল কৰা হ’ল"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” সফলতাৰে ইনষ্টল কৰা হ’ল"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g>ৰ পৰা <xliff:g id="APPNAME">%1$s</xliff:g> পুনঃস্থাপন কৰিবনে?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"এই এপ্‌টোৱে নেপথ্যত ডাউনল’ড কৰিবলৈ আৰম্ভ কৰিব"</string>
+    <string name="restore" msgid="8460854736328970444">"পুনঃস্থাপন কৰক"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml
index cf3ea84..0807ef7 100644
--- a/packages/PackageInstaller/res/values-az/strings.xml
+++ b/packages/PackageInstaller/res/values-az/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Tətbiq quraşdırma bildirişi"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Quraşdırıldı"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" quraşdırıldı"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> <xliff:g id="INSTALLERNAME">%1$s</xliff:g> ünvanından bərpa edilsin?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Bu tətbiq arxa fonda endirilməyə başlayacaq"</string>
+    <string name="restore" msgid="8460854736328970444">"Bərpa edin"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
index 77fe3ba..6b9cd04 100644
--- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
+++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Obaveštenje o instaliranju aplikacije"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Instalirana je"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Aplikacija „<xliff:g id="APPNAME">%1$s</xliff:g>“ je instalirana"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Želite da vratite <xliff:g id="APPNAME">%1$s</xliff:g> iz <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Aplikacija će započeti preuzimanje u pozadini."</string>
+    <string name="restore" msgid="8460854736328970444">"Vrati"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml
index b10a9e0..9e6e6fd 100644
--- a/packages/PackageInstaller/res/values-be/strings.xml
+++ b/packages/PackageInstaller/res/values-be/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Апавяшчэнне пра завяршэнне ўсталявання"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Усталявана"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Усталявана праграма \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Аднавіць праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\" адсюль: <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Праграма пачне спампоўвацца ў фонавым рэжыме"</string>
+    <string name="restore" msgid="8460854736328970444">"Аднавіць"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml
index 8d4739c..1c91874 100644
--- a/packages/PackageInstaller/res/values-bg/strings.xml
+++ b/packages/PackageInstaller/res/values-bg/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Известие, че приложението е инсталирано"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Инсталирането бе успешно"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Приложението <xliff:g id="APPNAME">%1$s</xliff:g> бе инсталирано успешно"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Да се възстанови ли <xliff:g id="APPNAME">%1$s</xliff:g> от <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Това приложение ще започне да се изтегля на заден план"</string>
+    <string name="restore" msgid="8460854736328970444">"Възстановяване"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml
index d3c8ad7..5a78f37 100644
--- a/packages/PackageInstaller/res/values-bn/strings.xml
+++ b/packages/PackageInstaller/res/values-bn/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"\'অ্যাপ ইনস্টল করা হয়েছে\' বিজ্ঞপ্তি"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"ইনস্টল করা হয়েছে"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" ইনস্টল করা হয়েছে"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> থেকে <xliff:g id="APPNAME">%1$s</xliff:g> ফিরিয়ে আনবেন?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"এই অ্যাপটি ব্যাকগ্রাউন্ডে ডাউনলোড হওয়া শুরু হবে"</string>
+    <string name="restore" msgid="8460854736328970444">"ফিরিয়ে আনুন"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml
index f93263f0..aed2d22 100644
--- a/packages/PackageInstaller/res/values-bs/strings.xml
+++ b/packages/PackageInstaller/res/values-bs/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Obavještenje o instaliranoj aplikaciji"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Uspješno instalirano"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Aplikacija \"<xliff:g id="APPNAME">%1$s</xliff:g>\" je uspješno instalirana"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Vratiti aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g> s usluge <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Preuzimanje aplikacije će započeti u pozadini"</string>
+    <string name="restore" msgid="8460854736328970444">"Vrati"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml
index 7a60d46..85e5110 100644
--- a/packages/PackageInstaller/res/values-ca/strings.xml
+++ b/packages/PackageInstaller/res/values-ca/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notificació d\'aplicació instal·lada"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"S\'ha instal·lat correctament"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"S\'ha instal·lat <xliff:g id="APPNAME">%1$s</xliff:g> correctament"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Vols restaurar <xliff:g id="APPNAME">%1$s</xliff:g> des de <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Aquesta aplicació començarà a baixar-se en segon pla"</string>
+    <string name="restore" msgid="8460854736328970444">"Restaura"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml
index 0874214..fc85bca 100644
--- a/packages/PackageInstaller/res/values-cs/strings.xml
+++ b/packages/PackageInstaller/res/values-cs/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Oznámení o nainstalované aplikaci"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Úspěšně nainstalováno"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Aplikace <xliff:g id="APPNAME">%1$s</xliff:g> byla úspěšně nainstalována"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Obnovit aplikaci <xliff:g id="APPNAME">%1$s</xliff:g> z aplikace <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Aplikace se začne stahovat na pozadí"</string>
+    <string name="restore" msgid="8460854736328970444">"Obnovit"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml
index 85032c9..aa6fe8f 100644
--- a/packages/PackageInstaller/res/values-da/strings.xml
+++ b/packages/PackageInstaller/res/values-da/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notifikation om appinstallation"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Appen er installeret"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" er installeret"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Vil du gendanne <xliff:g id="APPNAME">%1$s</xliff:g> fra <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Download af denne app startes i baggrunden"</string>
+    <string name="restore" msgid="8460854736328970444">"Gendan"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml
index b638040b..dc23696 100644
--- a/packages/PackageInstaller/res/values-de/strings.xml
+++ b/packages/PackageInstaller/res/values-de/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Installationsbenachrichtigung für App"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Erfolgreich installiert"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" wurde erfolgreich installiert"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> von <xliff:g id="INSTALLERNAME">%1$s</xliff:g> wiederherstellen?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Diese App beginnt im Hintergrund mit dem Herunterladen"</string>
+    <string name="restore" msgid="8460854736328970444">"Wiederherstellen"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml
index 96b582b..ea4eeb6 100644
--- a/packages/PackageInstaller/res/values-el/strings.xml
+++ b/packages/PackageInstaller/res/values-el/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Ειδοποίηση εγκατάστασης εφαρμογής"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Εγκαταστάθηκε επιτυχώς"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Η εφαρμογή \"<xliff:g id="APPNAME">%1$s</xliff:g>\" εγκαταστάθηκε επιτυχώς"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Επαναφορά <xliff:g id="APPNAME">%1$s</xliff:g> από <xliff:g id="INSTALLERNAME">%1$s</xliff:g>;"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Η λήψη της εφαρμογής θα ξεκινήσει στο παρασκήνιο"</string>
+    <string name="restore" msgid="8460854736328970444">"Επαναφορά"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml
index 08b8bf1a..0187172 100644
--- a/packages/PackageInstaller/res/values-en-rAU/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"App installed notification"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Successfully installed"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Successfully installed \'<xliff:g id="APPNAME">%1$s</xliff:g>\'"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restore <xliff:g id="APPNAME">%1$s</xliff:g> from <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"This app will start downloading in the background"</string>
+    <string name="restore" msgid="8460854736328970444">"Restore"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rCA/strings.xml b/packages/PackageInstaller/res/values-en-rCA/strings.xml
index da4a8a0..9b31f27 100644
--- a/packages/PackageInstaller/res/values-en-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rCA/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"App installed notification"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Successfully installed"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Successfully installed “<xliff:g id="APPNAME">%1$s</xliff:g>”"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restore <xliff:g id="APPNAME">%1$s</xliff:g> from <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"This app will begin to download in the background"</string>
+    <string name="restore" msgid="8460854736328970444">"Restore"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml
index 08b8bf1a..0187172 100644
--- a/packages/PackageInstaller/res/values-en-rGB/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"App installed notification"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Successfully installed"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Successfully installed \'<xliff:g id="APPNAME">%1$s</xliff:g>\'"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restore <xliff:g id="APPNAME">%1$s</xliff:g> from <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"This app will start downloading in the background"</string>
+    <string name="restore" msgid="8460854736328970444">"Restore"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml
index 08b8bf1a..0187172 100644
--- a/packages/PackageInstaller/res/values-en-rIN/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"App installed notification"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Successfully installed"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Successfully installed \'<xliff:g id="APPNAME">%1$s</xliff:g>\'"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restore <xliff:g id="APPNAME">%1$s</xliff:g> from <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"This app will start downloading in the background"</string>
+    <string name="restore" msgid="8460854736328970444">"Restore"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rXC/strings.xml b/packages/PackageInstaller/res/values-en-rXC/strings.xml
index 0749a27..67ffce5 100644
--- a/packages/PackageInstaller/res/values-en-rXC/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rXC/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎App installed notification‎‏‎‎‏‎"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎Successfully installed‎‏‎‎‏‎"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎Successfully installed “‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎”‎‏‎‎‏‎"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‏‏‎‏‎Restore ‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ from ‎‏‎‎‏‏‎<xliff:g id="INSTALLERNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎This app will begin to download in the background‎‏‎‎‏‎"</string>
+    <string name="restore" msgid="8460854736328970444">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎Restore‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml
index 3330e5f..2a8559a 100644
--- a/packages/PackageInstaller/res/values-es-rUS/strings.xml
+++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notificación de app instalada"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Se instaló correctamente"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Se instaló correctamente \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"¿Quieres restablecer <xliff:g id="APPNAME">%1$s</xliff:g> desde <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Esta app comenzará la descarga en segundo plano"</string>
+    <string name="restore" msgid="8460854736328970444">"Restablecer"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml
index c351f15..5e1022b 100644
--- a/packages/PackageInstaller/res/values-es/strings.xml
+++ b/packages/PackageInstaller/res/values-es/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notificación de aplicación instalada"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Se ha instalado correctamente"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"<xliff:g id="APPNAME">%1$s</xliff:g> se ha instalado correctamente"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"¿Restaurar <xliff:g id="APPNAME">%1$s</xliff:g> de <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Esta aplicación comenzará a descargarse en segundo plano"</string>
+    <string name="restore" msgid="8460854736328970444">"Restaurar"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml
index 5ecfbf4..2bd2c04 100644
--- a/packages/PackageInstaller/res/values-et/strings.xml
+++ b/packages/PackageInstaller/res/values-et/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Rakenduse installimise märguanne"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Installimine õnnestus"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Rakenduse „<xliff:g id="APPNAME">%1$s</xliff:g>” installimine õnnestus"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Kas taastada rakendus <xliff:g id="APPNAME">%1$s</xliff:g> rakenduse <xliff:g id="INSTALLERNAME">%1$s</xliff:g> kaudu?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Selle rakenduse allalaadimine algab taustal"</string>
+    <string name="restore" msgid="8460854736328970444">"Taasta"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index ec720ac..574d4ab 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Aplikazioa instalatu izanaren jakinarazpena"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Instalatu da"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Instalatu da \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> aplikaziotik leheneratu nahi duzu <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Atzeko planoan deskargatuko da aplikazioa"</string>
+    <string name="restore" msgid="8460854736328970444">"Leheneratu"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml
index 7a8b579..1869cb6 100644
--- a/packages/PackageInstaller/res/values-fa/strings.xml
+++ b/packages/PackageInstaller/res/values-fa/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"اعلان نصب برنامه"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"نصب موفقیت‌آمیز بود"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"<xliff:g id="APPNAME">%1$s</xliff:g> باموفقیت نصب شد"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> از <xliff:g id="INSTALLERNAME">%1$s</xliff:g> بازیابی شود؟"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"این برنامه در پس‌زمینه شروع به بارگیری می‌کند"</string>
+    <string name="restore" msgid="8460854736328970444">"بازیابی"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml
index a9b6984..8f960ea 100644
--- a/packages/PackageInstaller/res/values-fi/strings.xml
+++ b/packages/PackageInstaller/res/values-fi/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Sovellus asennettu ‑ilmoitus"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Asennus onnistui"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"<xliff:g id="APPNAME">%1$s</xliff:g>: asennus onnistui"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Palautetaanko <xliff:g id="APPNAME">%1$s</xliff:g> sovelluksella <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Sovelluksen lataus aloitetaan taustalla"</string>
+    <string name="restore" msgid="8460854736328970444">"Palauta"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
index 0ef53b9..647a7b5 100644
--- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notification d\'application installée"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Installation réussie"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Installation de « <xliff:g id="APPNAME">%1$s</xliff:g> » réussie"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restaurer <xliff:g id="APPNAME">%1$s</xliff:g> à partir de <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Le téléchargement de cette application commencera en arrière-plan"</string>
+    <string name="restore" msgid="8460854736328970444">"Restaurer"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml
index 5065a22..3cf043b 100644
--- a/packages/PackageInstaller/res/values-fr/strings.xml
+++ b/packages/PackageInstaller/res/values-fr/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notification d\'application installée"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"L\'application a été installée"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"L\'application <xliff:g id="APPNAME">%1$s</xliff:g> a bien été installée"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restaurer <xliff:g id="APPNAME">%1$s</xliff:g> depuis <xliff:g id="INSTALLERNAME">%1$s</xliff:g> ?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Cette application commencera à se télécharger en arrière-plan"</string>
+    <string name="restore" msgid="8460854736328970444">"Restaurer"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml
index 694218d..eeb1f95 100644
--- a/packages/PackageInstaller/res/values-gl/strings.xml
+++ b/packages/PackageInstaller/res/values-gl/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notificación da aplicación instalada"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Instalouse correctamente"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Instalouse correctamente a aplicación <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Queres restaurar <xliff:g id="APPNAME">%1$s</xliff:g> desde <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Esta aplicación comezará a descargarse en segundo plano"</string>
+    <string name="restore" msgid="8460854736328970444">"Restaurar"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-gu/strings.xml b/packages/PackageInstaller/res/values-gu/strings.xml
index 8f5976c..e1f1887 100644
--- a/packages/PackageInstaller/res/values-gu/strings.xml
+++ b/packages/PackageInstaller/res/values-gu/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ઍપ ઇન્સ્ટૉલ થવાનું નોટિફિકેશન"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"સફળતાપૂર્વક ઇન્સ્ટૉલ કરેલ"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” સફળતાપૂર્વક ઇન્સ્ટૉલ કરેલ"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g>માંથી <xliff:g id="APPNAME">%1$s</xliff:g> રિસ્ટોર કરીએ?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"બૅકગ્રાઉન્ડમાં આ ઍપ ડાઉનલોડ થવાનું શરૂ થશે"</string>
+    <string name="restore" msgid="8460854736328970444">"રિસ્ટોર કરો"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml
index ddb16dd..642bbd9 100644
--- a/packages/PackageInstaller/res/values-hi/strings.xml
+++ b/packages/PackageInstaller/res/values-hi/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ऐप्लिकेशन इंस्टॉल होने की सूचना"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"पूरी तरह से इंस्टॉल हो गया है"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” पूरी तरह से इंस्टॉल हो गया है"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> को <xliff:g id="INSTALLERNAME">%1$s</xliff:g> से वापस लाएं?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"यह ऐप्लिकेशन, बैकग्राउंड में डाउनलोड होना शुरू हो जाएगा"</string>
+    <string name="restore" msgid="8460854736328970444">"वापस लाएं"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml
index c758f4f..69ce3f1 100644
--- a/packages/PackageInstaller/res/values-hr/strings.xml
+++ b/packages/PackageInstaller/res/values-hr/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Obavijest o instaliranoj aplikaciji"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Uspješno instalirano"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Aplikacija \"<xliff:g id="APPNAME">%1$s</xliff:g>\" uspješno je instalirana"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Želite li vratiti aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g> putem aplikacije <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Ova aplikacija počet će se preuzimati u pozadini"</string>
+    <string name="restore" msgid="8460854736328970444">"Vrati"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml
index 4fd866d..ea8cfc7 100644
--- a/packages/PackageInstaller/res/values-hu/strings.xml
+++ b/packages/PackageInstaller/res/values-hu/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Alkalmazás telepítve értesítés"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Sikeresen telepítve"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> alkalmazás sikeresen telepítve"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Visszaállítja a(z) <xliff:g id="APPNAME">%1$s</xliff:g> appot innen: <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"A háttérben megkezdődik az app letöltése"</string>
+    <string name="restore" msgid="8460854736328970444">"Visszaállítás"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml
index e5e7cec..a447371 100644
--- a/packages/PackageInstaller/res/values-hy/strings.xml
+++ b/packages/PackageInstaller/res/values-hy/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Ծանուցում հավելվածի տեղադրման մասին"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Տեղադրվեց"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը տեղադրվեց"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Վերականգնե՞լ <xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը <xliff:g id="INSTALLERNAME">%1$s</xliff:g>-ից"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Այս հավելվածը կներբեռնվի ֆոնային ռեժիմում"</string>
+    <string name="restore" msgid="8460854736328970444">"Վերականգնել"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml
index a52b63c..9e24424 100644
--- a/packages/PackageInstaller/res/values-in/strings.xml
+++ b/packages/PackageInstaller/res/values-in/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notifikasi penginstalan aplikasi"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Berhasil diinstal"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Berhasil menginstal “<xliff:g id="APPNAME">%1$s</xliff:g>”"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Pulihkan <xliff:g id="APPNAME">%1$s</xliff:g> dari <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Aplikasi ini akan mulai didownload di latar belakang"</string>
+    <string name="restore" msgid="8460854736328970444">"Pulihkan"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml
index b125da1..c24f284 100644
--- a/packages/PackageInstaller/res/values-is/strings.xml
+++ b/packages/PackageInstaller/res/values-is/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Tilkynning um uppsett forrit"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Uppsetning tókst"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ sett upp"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Endurheimta <xliff:g id="APPNAME">%1$s</xliff:g> úr <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Forritið verður sótt í bakgrunni"</string>
+    <string name="restore" msgid="8460854736328970444">"Endurheimta"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml
index 9ee0882..604d88a 100644
--- a/packages/PackageInstaller/res/values-it/strings.xml
+++ b/packages/PackageInstaller/res/values-it/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notifica relativa alle app installate"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Installata"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"App \"<xliff:g id="APPNAME">%1$s</xliff:g>\" installata"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Ripristinare <xliff:g id="APPNAME">%1$s</xliff:g> da <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Il download di quest\'app inizierà in background"</string>
+    <string name="restore" msgid="8460854736328970444">"Ripristina"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml
index 6684ec0..0e37b2e 100644
--- a/packages/PackageInstaller/res/values-iw/strings.xml
+++ b/packages/PackageInstaller/res/values-iw/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"התראה על התקנת האפליקציה"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"הותקנה בהצלחה"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"האפליקציה \"<xliff:g id="APPNAME">%1$s</xliff:g>\" הותקנה"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"לשחזר את <xliff:g id="APPNAME">%1$s</xliff:g> מ-<xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"תהליך ההורדה של האפליקציה יתחיל ברקע"</string>
+    <string name="restore" msgid="8460854736328970444">"שחזור"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml
index 600b6b7..58e46a6 100644
--- a/packages/PackageInstaller/res/values-ja/strings.xml
+++ b/packages/PackageInstaller/res/values-ja/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"アプリのインストールに関する通知"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"インストールしました"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"「<xliff:g id="APPNAME">%1$s</xliff:g>」をインストールしました"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> から <xliff:g id="APPNAME">%1$s</xliff:g> を復元しますか?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"このアプリのダウンロードをバックグラウンドで開始します"</string>
+    <string name="restore" msgid="8460854736328970444">"復元する"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ka/strings.xml b/packages/PackageInstaller/res/values-ka/strings.xml
index c8bf93b..bbd63d1 100644
--- a/packages/PackageInstaller/res/values-ka/strings.xml
+++ b/packages/PackageInstaller/res/values-ka/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"შეტყობინება აპის ინსტალაციის შესახებ"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"წარმატებით დაინსტალირდა"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ წარმატებით დაინსტალირდა"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"აღვადგინოთ <xliff:g id="APPNAME">%1$s</xliff:g> <xliff:g id="INSTALLERNAME">%1$s</xliff:g>-დან?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"ამ აპის ჩამოტვირთვა ფონურ რეჟიმში დაიწყება"</string>
+    <string name="restore" msgid="8460854736328970444">"აღდგენა"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml
index 1ccac10..02843b8 100644
--- a/packages/PackageInstaller/res/values-kk/strings.xml
+++ b/packages/PackageInstaller/res/values-kk/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Қолданба орнатылғаны туралы хабарландыру"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Орнатылды"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" орнатылды"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасын <xliff:g id="INSTALLERNAME">%1$s</xliff:g> арқылы қалпына келтіру керек пе?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Бұл қолданба фондық режимде жүктеп алына бастайды."</string>
+    <string name="restore" msgid="8460854736328970444">"Қалпына келтіру"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml
index 3e3ef99..bb84976 100644
--- a/packages/PackageInstaller/res/values-km/strings.xml
+++ b/packages/PackageInstaller/res/values-km/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ការជូនដំណឹង​អំពីកម្មវិធីដែល​បានដំឡើង"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"បាន​ដំឡើង​ដោយ​ជោគជ័យ​ហើយ"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"បាន​ដំឡើង \"<xliff:g id="APPNAME">%1$s</xliff:g>\" ដោយ​ជោគជ័យ​ហើយ"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"ស្ដារ <xliff:g id="APPNAME">%1$s</xliff:g> ពី <xliff:g id="INSTALLERNAME">%1$s</xliff:g> ឬ?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"កម្មវិធីនេះនឹងចាប់ផ្ដើមទាញយកនៅផ្ទៃខាងក្រោយ"</string>
+    <string name="restore" msgid="8460854736328970444">"ស្ដារ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml
index 9cfe389..476b45d 100644
--- a/packages/PackageInstaller/res/values-kn/strings.xml
+++ b/packages/PackageInstaller/res/values-kn/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ಆ್ಯಪ್ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿರುವ ಕುರಿತು ನೋಟಿಫಿಕೇಶನ್"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"ಯಶಸ್ವಿಯಾಗಿ ಇನ್‌ಸ್ಟಾಲ್ ಆಗಿದೆ"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" ಆ್ಯಪ್ ಅನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿದೆ"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> ನಿಂದ <xliff:g id="APPNAME">%1$s</xliff:g> ಅನ್ನು ಮರುಸ್ಥಾಪಿಸಬೇಕೆ?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಡೌನ್‌ಲೋಡ್ ಆಗಲು ಈ ಆ್ಯಪ್ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ"</string>
+    <string name="restore" msgid="8460854736328970444">"ಮರುಸ್ಥಾಪಿಸಿ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml
index 271ec90..7ae19ac 100644
--- a/packages/PackageInstaller/res/values-ko/strings.xml
+++ b/packages/PackageInstaller/res/values-ko/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"앱 설치 완료 알림"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"설치 완료"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\'<xliff:g id="APPNAME">%1$s</xliff:g>\' 설치 완료"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g>에서 <xliff:g id="APPNAME">%1$s</xliff:g> 앱을 복원하시겠습니까?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"백그라운드에서 앱이 다운로드되기 시작합니다"</string>
+    <string name="restore" msgid="8460854736328970444">"복원"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml
index 5e9948d..faf3df2 100644
--- a/packages/PackageInstaller/res/values-ky/strings.xml
+++ b/packages/PackageInstaller/res/values-ky/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Колдонмолорду орноткучтун билдирмелери"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Ийгиликтүү орнотулду"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" орнотулду"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> <xliff:g id="INSTALLERNAME">%1$s</xliff:g> платформасынан калыбына келтирилсинби?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Бул колдонмо фондо жүктөлүп алына баштайт"</string>
+    <string name="restore" msgid="8460854736328970444">"Калыбына келтирүү"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml
index d12bb4b..e9b3e8e 100644
--- a/packages/PackageInstaller/res/values-lo/strings.xml
+++ b/packages/PackageInstaller/res/values-lo/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ການແຈ້ງເຕືອນແອັບທີ່ຕິດຕັ້ງແລ້ວ"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"ຕິດຕັ້ງສຳເລັດແລ້ວ"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"ຕິດຕັ້ງ \"<xliff:g id="APPNAME">%1$s</xliff:g>\" ສຳເລັດແລ້ວ"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"ກູ້ຄືນ <xliff:g id="APPNAME">%1$s</xliff:g> ຈາກ <xliff:g id="INSTALLERNAME">%1$s</xliff:g> ບໍ?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"ແອັບນີ້ຈະເລີ່ມດາວໂຫຼດໃນພື້ນຫຼັງ"</string>
+    <string name="restore" msgid="8460854736328970444">"ກູ້ຄືນ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml
index 91ae9d1..654dee0 100644
--- a/packages/PackageInstaller/res/values-lt/strings.xml
+++ b/packages/PackageInstaller/res/values-lt/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Pranešimas apie įdiegtą programą"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Sėkmingai įdiegta"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ sėkmingai įdiegta"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Atkurti „<xliff:g id="APPNAME">%1$s</xliff:g>“ iš „<xliff:g id="INSTALLERNAME">%1$s</xliff:g>“?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Šios programos atsisiuntimas bus pradėtas fone"</string>
+    <string name="restore" msgid="8460854736328970444">"Atkurti"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml
index c6f9eb4..2d319fc 100644
--- a/packages/PackageInstaller/res/values-lv/strings.xml
+++ b/packages/PackageInstaller/res/values-lv/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Paziņojums par instalētu lietotni"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Sekmīgi instalēta"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Lietotne “<xliff:g id="APPNAME">%1$s</xliff:g>” sekmīgi instalēta"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Vai atjaunot lietotni <xliff:g id="APPNAME">%1$s</xliff:g> no <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Fonā tiks sākta šīs lietotnes lejupielāde."</string>
+    <string name="restore" msgid="8460854736328970444">"Atjaunot"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml
index bc5cb90..e02c3c5 100644
--- a/packages/PackageInstaller/res/values-mk/strings.xml
+++ b/packages/PackageInstaller/res/values-mk/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Известување за инсталирана апликација"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Успешно инсталирана"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"<xliff:g id="APPNAME">%1$s</xliff:g> е успешно инсталирана"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Да се врати <xliff:g id="APPNAME">%1$s</xliff:g> од <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Апликацијава ќе почне да се презема во заднина"</string>
+    <string name="restore" msgid="8460854736328970444">"Враќање"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ml/strings.xml b/packages/PackageInstaller/res/values-ml/strings.xml
index a64f87f..2e5dcfb 100644
--- a/packages/PackageInstaller/res/values-ml/strings.xml
+++ b/packages/PackageInstaller/res/values-ml/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌ത അറിയിപ്പ്"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"ഇൻസ്‌റ്റാൾ ചെയ്‌തു"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" ഇൻസ്‌റ്റാൾ ചെയ്‌തു"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> എന്നതിൽ നിന്ന് <xliff:g id="APPNAME">%1$s</xliff:g> പുനഃസ്ഥാപിക്കണോ?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"പശ്ചാത്തലത്തിൽ ഈ ആപ്പ് ഡൗൺലോഡ് ചെയ്ത് തുടങ്ങും"</string>
+    <string name="restore" msgid="8460854736328970444">"പുനഃസ്ഥാപിക്കുക"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml
index a9365b6..5deda94 100644
--- a/packages/PackageInstaller/res/values-mn/strings.xml
+++ b/packages/PackageInstaller/res/values-mn/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Апп суулгасны мэдэгдэл"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Амжилттай суулгасан"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>”-г амжилттай суулгасан"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g>-г <xliff:g id="INSTALLERNAME">%1$s</xliff:g>-с сэргээх үү?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Энэ аппыг дэвсгэрт татаж эхэлнэ"</string>
+    <string name="restore" msgid="8460854736328970444">"Сэргээх"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml
index d6f04b4..53ca403 100644
--- a/packages/PackageInstaller/res/values-mr/strings.xml
+++ b/packages/PackageInstaller/res/values-mr/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"अ‍ॅप इंस्टॉल सूचना"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"यशस्वीरित्या इंस्टॉल केले"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" यशस्वीरित्या इंस्टॉल झाले"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> मधून <xliff:g id="APPNAME">%1$s</xliff:g> रिस्टोअर करायचे आहे का?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"हे ॲप बॅकग्राउंडमध्ये डाउनलोड होण्यास सुरुवात होईल"</string>
+    <string name="restore" msgid="8460854736328970444">"रिस्टोअर करा"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ms/strings.xml b/packages/PackageInstaller/res/values-ms/strings.xml
index 80f4be3..4b0b560 100644
--- a/packages/PackageInstaller/res/values-ms/strings.xml
+++ b/packages/PackageInstaller/res/values-ms/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Pemberitahuan apl dipasang"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Berjaya dipasang"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Berjaya memasang \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Pulihkan <xliff:g id="APPNAME">%1$s</xliff:g> daripada <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Apl ini akan mula dimuat turun dalam latar"</string>
+    <string name="restore" msgid="8460854736328970444">"Pulihkan"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-my/strings.xml b/packages/PackageInstaller/res/values-my/strings.xml
index 77a45899..302c2c3 100644
--- a/packages/PackageInstaller/res/values-my/strings.xml
+++ b/packages/PackageInstaller/res/values-my/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"အက်ပ်ထည့်သွင်းခြင်း အကြောင်းကြားချက်"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"ထည့်သွင်းပြီးပြီ"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" ကို ထည့်သွင်းပြီးပြီ"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> မှ <xliff:g id="APPNAME">%1$s</xliff:g> ကို ပြန်ယူမလား။"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"ဤအက်ပ်ကို နောက်ခံတွင် စတင်ဒေါင်းလုဒ်လုပ်ပါမည်"</string>
+    <string name="restore" msgid="8460854736328970444">"ပြန်ယူရန်"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml
index 89d9762..65c0cb8 100644
--- a/packages/PackageInstaller/res/values-nb/strings.xml
+++ b/packages/PackageInstaller/res/values-nb/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Varsel om at appen er installert"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Installert"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"«<xliff:g id="APPNAME">%1$s</xliff:g>» er installert"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Vil du gjenopprette <xliff:g id="APPNAME">%1$s</xliff:g> fra <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Denne appen begynner å laste ned i bakgrunnen"</string>
+    <string name="restore" msgid="8460854736328970444">"Gjenopprett"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
index 23a689f..b72218c 100644
--- a/packages/PackageInstaller/res/values-ne/strings.xml
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"एपको स्थापना गरिएको सूचना"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"सफलतापूर्वक स्थापना गरियो"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” सफलतापूर्वक स्थापना गरियो"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> बाट <xliff:g id="APPNAME">%1$s</xliff:g> रिस्टोर गर्ने हो?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"यो एप ब्याकग्राउन्डमा डाउनलोड हुन थाल्ने छ"</string>
+    <string name="restore" msgid="8460854736328970444">"रिस्टोर गर्नुहोस्"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
index 731dc48..a1eb708 100644
--- a/packages/PackageInstaller/res/values-nl/strings.xml
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Melding dat app is geïnstalleerd"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Installatie voltooid"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\'<xliff:g id="APPNAME">%1$s</xliff:g>\' is geïnstalleerd"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> herstellen via <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Deze app wordt gedownload op de achtergrond"</string>
+    <string name="restore" msgid="8460854736328970444">"Herstellen"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
index 331852e1..a1c685c 100644
--- a/packages/PackageInstaller/res/values-or/strings.xml
+++ b/packages/PackageInstaller/res/values-or/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ଆପ୍ ଇନ୍‌ଷ୍ଟଲ୍‌ କରାଯାଇଥିବା ବିଜ୍ଞପ୍ତି"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"ସଫଳତାପୂର୍ବକ ଇନ୍‌ଷ୍ଟଲ୍‌ କରାଗଲା"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” ସଫଳତାପୂର୍ବକ ଇନ୍‌ଷ୍ଚଲ୍ କରାଗଲା"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g>ରୁ <xliff:g id="APPNAME">%1$s</xliff:g>କୁ ରିଷ୍ଟୋର କରିବେ?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"ଏହି ଆପ ପୃଷ୍ଠପଟରେ ଡାଉନଲୋଡ ହେବା ଆରମ୍ଭ କରିବ"</string>
+    <string name="restore" msgid="8460854736328970444">"ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml
index 5bc4624..1c7fb862 100644
--- a/packages/PackageInstaller/res/values-pa/strings.xml
+++ b/packages/PackageInstaller/res/values-pa/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ਐਪ ਸਥਾਪਨਾ ਦੀ ਸੂਚਨਾ"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"ਸਫਲਤਾਪੂਰਵਕ ਸਥਾਪਤ ਕੀਤੀ ਗਈ"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" ਨੂੰ ਸਫਲਤਾਪੂਰਵਕ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"ਕੀ <xliff:g id="APPNAME">%1$s</xliff:g> ਨੂੰ <xliff:g id="INSTALLERNAME">%1$s</xliff:g> ਤੋਂ ਮੁੜ-ਬਹਾਲ ਕਰਨਾ ਹੈ?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"ਇਹ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡਾਊਨਲੋਡ ਹੋਣੀ ਸ਼ੁਰੂ ਹੋ ਜਾਵੇਗੀ"</string>
+    <string name="restore" msgid="8460854736328970444">"ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml
index 4aa96f7..8fa11ed 100644
--- a/packages/PackageInstaller/res/values-pl/strings.xml
+++ b/packages/PackageInstaller/res/values-pl/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Powiadomienie o zainstalowaniu aplikacji"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Zainstalowano"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Zainstalowano aplikację „<xliff:g id="APPNAME">%1$s</xliff:g>”"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Przywrócić aplikację <xliff:g id="APPNAME">%1$s</xliff:g> z aplikacji <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Ta aplikacja zacznie pobieranie w tle"</string>
+    <string name="restore" msgid="8460854736328970444">"Przywróć"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
index d8713db..71ecb2b3 100644
--- a/packages/PackageInstaller/res/values-pt-rBR/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notificação de app instalado"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Instalação concluída"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” instalado"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restaurar <xliff:g id="APPNAME">%1$s</xliff:g> usando o app <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"O download desse app será feito em segundo plano"</string>
+    <string name="restore" msgid="8460854736328970444">"Restaurar"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
index fb2240e..1d5c1a2 100644
--- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notificação de app instalada"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"App instalada com êxito"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Aplicação \"<xliff:g id="APPNAME">%1$s</xliff:g>\" instalada com êxito"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restaurar <xliff:g id="APPNAME">%1$s</xliff:g> a partir da <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Esta app vai começar a ser transferida em segundo plano"</string>
+    <string name="restore" msgid="8460854736328970444">"Restaurar"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml
index d8713db..71ecb2b3 100644
--- a/packages/PackageInstaller/res/values-pt/strings.xml
+++ b/packages/PackageInstaller/res/values-pt/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notificação de app instalado"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Instalação concluída"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” instalado"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restaurar <xliff:g id="APPNAME">%1$s</xliff:g> usando o app <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"O download desse app será feito em segundo plano"</string>
+    <string name="restore" msgid="8460854736328970444">"Restaurar"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml
index fab0c33..810f544 100644
--- a/packages/PackageInstaller/res/values-ro/strings.xml
+++ b/packages/PackageInstaller/res/values-ro/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notificare de aplicație instalată"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Aplicația a fost instalată"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"„<xliff:g id="APPNAME">%1$s</xliff:g>” a fost instalată"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Restabilești <xliff:g id="APPNAME">%1$s</xliff:g> din <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Descărcarea aplicației va începe în fundal"</string>
+    <string name="restore" msgid="8460854736328970444">"Restabilește"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml
index 094a19a..e368f12 100644
--- a/packages/PackageInstaller/res/values-ru/strings.xml
+++ b/packages/PackageInstaller/res/values-ru/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Уведомление об установке приложения"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Установлено"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" установлено"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Восстановить приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" из <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Приложение начнет скачиваться в фоновом режиме."</string>
+    <string name="restore" msgid="8460854736328970444">"Восстановить"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml
index afc2195..cea50a6 100644
--- a/packages/PackageInstaller/res/values-si/strings.xml
+++ b/packages/PackageInstaller/res/values-si/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"යෙදුම් ස්ථාපනය කළ දැනුම්දීම"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"සාර්ථකව ස්ථාපනය කරන ලදී"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" සාර්ථකව ස්ථාපනය කරන ලදි"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> වෙතින් <xliff:g id="APPNAME">%1$s</xliff:g> ප්‍රතිසාධනය කරන්න ද?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"මෙම යෙදුම පසුබිමේ බාගැනීම ආරම්භ කරනු ඇත"</string>
+    <string name="restore" msgid="8460854736328970444">"ප්‍රතිසාධනය කරන්න"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml
index 7a1e70c..34117c3 100644
--- a/packages/PackageInstaller/res/values-sk/strings.xml
+++ b/packages/PackageInstaller/res/values-sk/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Upozornenie na inštaláciu aplikácie"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Úspešne nainštalovaná"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Aplikácia <xliff:g id="APPNAME">%1$s</xliff:g> bola nainštalovaná"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Chcete obnoviť <xliff:g id="APPNAME">%1$s</xliff:g> z inštalátora <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Táto aplikácia sa začne sťahovať na pozadí"</string>
+    <string name="restore" msgid="8460854736328970444">"Obnoviť"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml
index 91bcbda..a303759 100644
--- a/packages/PackageInstaller/res/values-sl/strings.xml
+++ b/packages/PackageInstaller/res/values-sl/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Obvestilo o namestitvi aplikacije"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Uspešno nameščeno"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Uspešno nameščeno: »<xliff:g id="APPNAME">%1$s</xliff:g>«"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Želite obnoviti aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g> iz aplikacije <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Aplikacija bo začela prenos v ozadju"</string>
+    <string name="restore" msgid="8460854736328970444">"Obnovi"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml
index 566054ed..7f68c8b 100644
--- a/packages/PackageInstaller/res/values-sq/strings.xml
+++ b/packages/PackageInstaller/res/values-sq/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Njoftimi për aplikacionin e instaluar"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"U instalua me sukses"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” u instalua me sukses"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Të restaurohet <xliff:g id="APPNAME">%1$s</xliff:g> nga <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Ky aplikacion do të fillojë të shkarkohet në sfond"</string>
+    <string name="restore" msgid="8460854736328970444">"Restauro"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml
index 9e17716..196e784 100644
--- a/packages/PackageInstaller/res/values-sr/strings.xml
+++ b/packages/PackageInstaller/res/values-sr/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Обавештење о инсталирању апликације"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Инсталирана је"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Апликација „<xliff:g id="APPNAME">%1$s</xliff:g>“ је инсталирана"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Желите да вратите <xliff:g id="APPNAME">%1$s</xliff:g> из <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Апликација ће започети преузимање у позадини."</string>
+    <string name="restore" msgid="8460854736328970444">"Врати"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml
index 79e5738..0ce696e 100644
--- a/packages/PackageInstaller/res/values-sv/strings.xml
+++ b/packages/PackageInstaller/res/values-sv/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Avisering om installerad app"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Appen har installerats"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"<xliff:g id="APPNAME">%1$s</xliff:g> har installerats"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Vill du återställa <xliff:g id="APPNAME">%1$s</xliff:g> från <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Appen börjar ladda ned i bakgrunden"</string>
+    <string name="restore" msgid="8460854736328970444">"Återställ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml
index f69d612..0a34d81 100644
--- a/packages/PackageInstaller/res/values-sw/strings.xml
+++ b/packages/PackageInstaller/res/values-sw/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Arifa ya kusakinishwa kwa programu"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Imesakinishwa"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"<xliff:g id="APPNAME">%1$s</xliff:g> imesakinishwa"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Je, ungependa kurejesha <xliff:g id="APPNAME">%1$s</xliff:g> kutoka kwenye <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Itaanza kupakua programu hii chinichini"</string>
+    <string name="restore" msgid="8460854736328970444">"Rejesha"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml
index f2d5463..322ce5c 100644
--- a/packages/PackageInstaller/res/values-ta/strings.xml
+++ b/packages/PackageInstaller/res/values-ta/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ஆப்ஸ் நிறுவப்பட்டது குறித்த அறிவிப்பு"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"வெற்றிகரமாக நிறுவப்பட்டது"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" வெற்றிகரமாக நிறுவப்பட்டது"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g>ல் இருந்து <xliff:g id="APPNAME">%1$s</xliff:g> ஐ மீட்டெடுக்கவா?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"இந்த ஆப்ஸ் பின்னணியில் பதிவிறக்கத் தொடங்கும்"</string>
+    <string name="restore" msgid="8460854736328970444">"மீட்டெடு"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml
index 1013e3d..9abc87e 100644
--- a/packages/PackageInstaller/res/values-te/strings.xml
+++ b/packages/PackageInstaller/res/values-te/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"యాప్ ఇన్‌స్టాల్ చేయబడిందనే నోటిఫికేషన్"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"విజయవంతంగా ఇన్‌స్టాల్ చేయబడింది"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” విజయవంతంగా ఇన్‌స్టాల్ చేయబడింది"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> నుండి <xliff:g id="APPNAME">%1$s</xliff:g>‌ను రీస్టోర్ చేయాలా?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"ఈ యాప్ బ్యాక్‌గ్రౌండ్‌లో డౌన్‌లోడ్ అవ్వడం ప్రారంభమవుతుంది"</string>
+    <string name="restore" msgid="8460854736328970444">"రీస్టోర్ చేయండి"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml
index 35a7611..b1faa1c 100644
--- a/packages/PackageInstaller/res/values-th/strings.xml
+++ b/packages/PackageInstaller/res/values-th/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"การแจ้งเตือนว่าติดตั้งแอปแล้ว"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"ติดตั้งเรียบร้อยแล้ว"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"ติดตั้ง “<xliff:g id="APPNAME">%1$s</xliff:g>” สำเร็จแล้ว"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"กู้คืน <xliff:g id="APPNAME">%1$s</xliff:g> จาก <xliff:g id="INSTALLERNAME">%1$s</xliff:g> ใช่ไหม"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"แอปนี้จะเริ่มดาวน์โหลดในเบื้องหลัง"</string>
+    <string name="restore" msgid="8460854736328970444">"กู้คืน"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml
index 78a1b2b..8e6e2517 100644
--- a/packages/PackageInstaller/res/values-tl/strings.xml
+++ b/packages/PackageInstaller/res/values-tl/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notification na na-install ang app"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Matagumpay na na-install"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Matagumpay na na-install ang “<xliff:g id="APPNAME">%1$s</xliff:g>”"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"I-restore ang <xliff:g id="APPNAME">%1$s</xliff:g> mula sa <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Magsisimulang mag-download ang app na ito sa background"</string>
+    <string name="restore" msgid="8460854736328970444">"I-restore"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml
index a34765c..dc84030 100644
--- a/packages/PackageInstaller/res/values-tr/strings.xml
+++ b/packages/PackageInstaller/res/values-tr/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Uygulama yükleme bildirimi"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Başarıyla yüklendi"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" başarıyla yüklendi"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulaması <xliff:g id="INSTALLERNAME">%1$s</xliff:g> üzerinden geri yüklensin mi?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Bu uygulama arka planda indirilmeye başlanacak"</string>
+    <string name="restore" msgid="8460854736328970444">"Geri yükle"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml
index 76f3372..3d7083f 100644
--- a/packages/PackageInstaller/res/values-uk/strings.xml
+++ b/packages/PackageInstaller/res/values-uk/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Сповіщення: додаток установлено"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Установлено"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Додаток <xliff:g id="APPNAME">%1$s</xliff:g> установлено"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Відновити додаток <xliff:g id="APPNAME">%1$s</xliff:g> з <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Цей додаток почне завантажуватись у фоновому режимі"</string>
+    <string name="restore" msgid="8460854736328970444">"Відновити"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml
index e621d71..08a8315 100644
--- a/packages/PackageInstaller/res/values-ur/strings.xml
+++ b/packages/PackageInstaller/res/values-ur/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"ایپ انسٹال ہونے کی اطلاع"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"کامیابی کے ساتھ انسٹال ہو گئی"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" کامیابی کے ساتھ انسٹال ہو گئی"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> کو <xliff:g id="INSTALLERNAME">%1$s</xliff:g> سے بحال کریں"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"یہ ایپ پس منظر میں ڈاؤن لوڈ ہونا شروع ہو جائے گی"</string>
+    <string name="restore" msgid="8460854736328970444">"بحال کریں"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-uz/strings.xml b/packages/PackageInstaller/res/values-uz/strings.xml
index 7597fb2..894e867 100644
--- a/packages/PackageInstaller/res/values-uz/strings.xml
+++ b/packages/PackageInstaller/res/values-uz/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Ilova oʻrnatilgani haqida bildirishnoma"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"O‘rnatildi"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” o‘rnatildi"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"<xliff:g id="APPNAME">%1$s</xliff:g> ilovasi <xliff:g id="INSTALLERNAME">%1$s</xliff:g> orqali tiklansinmi?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Bu ilova orqa fonda yuklab olinishi boshlanadi"</string>
+    <string name="restore" msgid="8460854736328970444">"Tiklash"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml
index 53b2a78..14959da 100644
--- a/packages/PackageInstaller/res/values-vi/strings.xml
+++ b/packages/PackageInstaller/res/values-vi/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Thông báo đã cài đặt ứng dụng"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Đã cài đặt thành công"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Đã cài đặt thành công “<xliff:g id="APPNAME">%1$s</xliff:g>”"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Khôi phục <xliff:g id="APPNAME">%1$s</xliff:g> từ <xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Ứng dụng này sẽ bắt đầu tải xuống ở chế độ nền"</string>
+    <string name="restore" msgid="8460854736328970444">"Khôi phục"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-zh-rCN/strings.xml b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
index eb6d0f2..ae12559 100644
--- a/packages/PackageInstaller/res/values-zh-rCN/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"“应用已安装”通知"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"已成功安装"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>”安装成功"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"要从 <xliff:g id="INSTALLERNAME">%1$s</xliff:g> 中恢复 <xliff:g id="APPNAME">%1$s</xliff:g> 吗?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"系统将开始在后台下载此应用"</string>
+    <string name="restore" msgid="8460854736328970444">"恢复"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
index 883a6b1..5a79817 100644
--- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"「應用程式已安裝」通知"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"已成功安裝"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"「<xliff:g id="APPNAME">%1$s</xliff:g>」已成功安裝"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"要從「<xliff:g id="INSTALLERNAME">%1$s</xliff:g>」還原「<xliff:g id="APPNAME">%1$s</xliff:g>」嗎?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"此應用程式將開始在背景下載"</string>
+    <string name="restore" msgid="8460854736328970444">"還原"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-zh-rTW/strings.xml b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
index 0d9e266..873392b 100644
--- a/packages/PackageInstaller/res/values-zh-rTW/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"「應用程式已安裝」通知"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"安裝成功"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"已成功安裝「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"要從「<xliff:g id="INSTALLERNAME">%1$s</xliff:g>」還原「<xliff:g id="APPNAME">%1$s</xliff:g>」嗎?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"系統將開始在背景下載這個應用程式"</string>
+    <string name="restore" msgid="8460854736328970444">"還原"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml
index 98c75e8..8ff1e38 100644
--- a/packages/PackageInstaller/res/values-zu/strings.xml
+++ b/packages/PackageInstaller/res/values-zu/strings.xml
@@ -103,4 +103,7 @@
     <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Isaziso sokufakwa kohlelo lokusebenza"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Ifakwe ngempumelelo"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Kufakwe ngempumelelo i-\"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
+    <string name="unarchive_application_title" msgid="7958278328280721421">"Buyisela i-<xliff:g id="APPNAME">%1$s</xliff:g> ukusuka ku-<xliff:g id="INSTALLERNAME">%1$s</xliff:g>?"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Le app izoqala ukudawuniloda ingemuva"</string>
+    <string name="restore" msgid="8460854736328970444">"Buyisela"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values/strings.xml b/packages/PackageInstaller/res/values/strings.xml
index 0a2e880..e5036b0 100644
--- a/packages/PackageInstaller/res/values/strings.xml
+++ b/packages/PackageInstaller/res/values/strings.xml
@@ -267,4 +267,86 @@
     <!-- The action to restore (i.e. re-install, re-download) an app after parts of the app have been previously moved
          into the cloud for temporary storage. [CHAR LIMIT=15] -->
     <string name="restore">Restore</string>
+
+    <!-- Dialog title shown when the user is trying to restore an app but the associated download
+         cannot happen immediately because the device is offline (has no internet connection.
+         [CHAR LIMIT=50] -->
+    <string name="unarchive_error_offline_title">You\'re offline</string>
+
+    <!-- Dialog body test shown when the user is trying to restore an app but the associated download
+         cannot happen immediately because the device is offline (has no internet connection.
+         [CHAR LIMIT=none] -->
+    <string name="unarchive_error_offline_body">
+        This app will automatically restore when you\'re connected to the internet
+    </string>
+
+    <!-- Dialog title shown when the user is trying to restore an app but a generic error happened.
+         [CHAR LIMIT=50] -->
+    <string name="unarchive_error_generic_title">Something went wrong</string>
+
+    <!-- Dialog body shown when the user is trying to restore an app but a generic error happened.
+         [CHAR LIMIT=none] -->
+    <string name="unarchive_error_generic_body">
+        There was a problem trying to restore this app
+    </string>
+
+    <!-- Dialog title shown when the user is trying to restore an app but the device is out of
+         storage. [CHAR LIMIT=50] -->
+    <string name="unarchive_error_storage_title">Not enough storage</string>
+
+    <!-- Dialog body shown when the user is trying to restore an app but the device is out of
+         storage. [CHAR LIMIT=none] -->
+    <string name="unarchive_error_storage_body">
+        To restore this app, you can free up space on this device. Storage
+        required: <xliff:g id="bytes" example="100 MB">%1$s</xliff:g>
+    </string>
+
+    <!-- Dialog title shown when the user is trying to restore an app but the installer needs to
+         perform an additional action. [CHAR LIMIT=50] -->
+    <string name="unarchive_action_required_title">Action required</string>
+
+    <!-- Dialog body shown when the user is trying to restore an app but the installer needs to
+         perform an additional action. [CHAR LIMIT=none] -->
+    <string name="unarchive_action_required_body">
+        Follow the next steps to restore this app
+    </string>
+    <!-- Dialog title shown when the user is trying to restore an app but the installer responsible
+         for the action is in a disabled state. [CHAR LIMIT=50] -->
+    <string name="unarchive_error_installer_disabled_title">
+        <xliff:g id="installername" example="App Store">%1$s</xliff:g> is disabled
+    </string>
+
+    <!-- Dialog body shown when the user is trying to restore an app but the installer responsible
+         for the action is in a disabled state. [CHAR LIMIT=none] -->
+    <string name="unarchive_error_installer_disabled_body">
+        To restore this app, enable the
+        <xliff:g id="installername" example="App Store">%1$s</xliff:g> in Settings
+    </string>
+
+    <!-- Dialog title shown when the user is trying to restore an app but the installer responsible
+     for the action is uninstalled. [CHAR LIMIT=50] -->
+    <string name="unarchive_error_installer_uninstalled_title">
+        <xliff:g id="installername" example="App Store">%1$s</xliff:g> is uninstalled
+    </string>
+
+    <!-- Dialog body shown when the user is trying to restore an app but the installer responsible
+         for the action is uninstalled. [CHAR LIMIT=none] -->
+    <string name="unarchive_error_installer_uninstalled_body">
+        To restore this app, you\'ll need to install
+        <xliff:g id="installername" example="App Store">%1$s</xliff:g>
+    </string>
+
+    <!-- Dialog action to continue with the next action. [CHAR LIMIT=30] -->
+    <string name="unarchive_action_required_continue">Continue</string>
+
+    <!-- Dialog action to clear device storage, as in deleting some apps or photos to free up bytes
+         [CHAR LIMIT=30] -->
+    <string name="unarchive_clear_storage_button">Clear storage</string>
+
+    <!-- Dialog action to open the Settings app. [CHAR LIMIT=30] -->
+    <string name="unarchive_settings_button">Settings</string>
+
+    <!-- Dialog action to close a dialog. [CHAR LIMIT=30] -->
+    <string name="close">Close</string>
+
 </resources>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
index 19d74b3..7b17cbd 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
@@ -16,8 +16,6 @@
 
 package com.android.packageinstaller;
 
-import static android.content.Intent.CATEGORY_LAUNCHER;
-
 import static com.android.packageinstaller.PackageInstallerActivity.EXTRA_STAGED_SESSION_ID;
 
 import android.app.Activity;
@@ -47,9 +45,6 @@
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         setResult(resultCode, data);
         finish();
-        if (data != null && data.hasCategory(CATEGORY_LAUNCHER)) {
-            startActivity(data);
-        }
     }
 
     @Override
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index daedb1a..8d8254a 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -298,7 +298,14 @@
                         broadcastIntent,
                         PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
 
-                session.commit(pendingIntent.getIntentSender());
+                try {
+                    session.commit(pendingIntent.getIntentSender());
+                } catch (Exception e) {
+                    Log.e(LOG_TAG, "Cannot install package: ", e);
+                    launchFailure(PackageInstaller.STATUS_FAILURE,
+                        PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
+                    return;
+                }
                 mCancelButton.setEnabled(false);
                 setFinishOnTouchOutside(false);
             } else {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index e2107eb..4187058 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -16,12 +16,14 @@
 
 package com.android.packageinstaller;
 
+import static android.content.pm.Flags.usePiaV2;
 import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
 
 import android.Manifest;
 import android.app.Activity;
 import android.app.DialogFragment;
 import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -57,14 +59,21 @@
 
     private final boolean mLocalLOGV = false;
 
-    // TODO (sumedhsen): Replace with an Android Feature Flag once implemented
-    private static final boolean USE_PIA_V2 = false;
-
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        if (USE_PIA_V2) {
+        mPackageManager = getPackageManager();
+        if (usePiaV2()) {
+            Log.i(TAG, "Using Pia V2");
+
+            mPackageManager.setComponentEnabledSetting(new ComponentName(this,
+                    com.android.packageinstaller.InstallEventReceiver.class),
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
+            mPackageManager.setComponentEnabledSetting(new ComponentName(this,
+                    com.android.packageinstaller.v2.model.InstallEventReceiver.class),
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
+
             Intent piaV2 = new Intent(getIntent());
             piaV2.putExtra(InstallLaunch.EXTRA_CALLING_PKG_NAME, getCallingPackage());
             piaV2.putExtra(InstallLaunch.EXTRA_CALLING_PKG_UID, getLaunchedFromUid());
@@ -74,7 +83,6 @@
             finish();
             return;
         }
-        mPackageManager = getPackageManager();
         mUserManager = getSystemService(UserManager.class);
 
         Intent intent = getIntent();
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
index 9af88c3b..215ead3 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -120,7 +121,12 @@
         Button launchButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
         if (enabled) {
             launchButton.setOnClickListener(view -> {
-                setResult(Activity.RESULT_OK, mLaunchIntent);
+                try {
+                    startActivity(mLaunchIntent.addFlags(
+                        Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP));
+                } catch (ActivityNotFoundException | SecurityException e) {
+                    Log.e(LOG_TAG, "Could not start activity", e);
+                }
                 finish();
             });
         } else {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveErrorActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveErrorActivity.java
new file mode 100644
index 0000000..78d2f88
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveErrorActivity.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.app.Activity;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.content.pm.PackageInstaller;
+import android.os.Bundle;
+
+import java.util.Objects;
+
+public class UnarchiveErrorActivity extends Activity {
+
+    static final String EXTRA_REQUIRED_BYTES =
+            "com.android.content.pm.extra.UNARCHIVE_EXTRA_REQUIRED_BYTES";
+    static final String EXTRA_INSTALLER_PACKAGE_NAME =
+            "com.android.content.pm.extra.UNARCHIVE_INSTALLER_PACKAGE_NAME";
+    static final String EXTRA_INSTALLER_TITLE =
+            "com.android.content.pm.extra.UNARCHIVE_INSTALLER_TITLE";
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(null);
+
+        Bundle extras = getIntent().getExtras();
+        int unarchivalStatus = extras.getInt(PackageInstaller.EXTRA_UNARCHIVE_STATUS);
+        long requiredBytes = extras.getLong(EXTRA_REQUIRED_BYTES);
+        PendingIntent intent = extras.getParcelable(Intent.EXTRA_INTENT, PendingIntent.class);
+        String installerPackageName = extras.getString(EXTRA_INSTALLER_PACKAGE_NAME);
+        // We cannot derive this from the package name because the installer might not be installed
+        // anymore.
+        String installerAppTitle = extras.getString(EXTRA_INSTALLER_TITLE);
+
+        if (unarchivalStatus == PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED) {
+            Objects.requireNonNull(intent);
+        }
+
+        FragmentTransaction ft = getFragmentManager().beginTransaction();
+        Fragment prev = getFragmentManager().findFragmentByTag("dialog");
+        if (prev != null) {
+            ft.remove(prev);
+        }
+
+        Bundle args = new Bundle();
+        args.putInt(PackageInstaller.EXTRA_UNARCHIVE_STATUS, unarchivalStatus);
+        args.putLong(EXTRA_REQUIRED_BYTES, requiredBytes);
+        if (intent != null) {
+            args.putParcelable(Intent.EXTRA_INTENT, intent);
+        }
+        if (installerPackageName != null) {
+            args.putString(EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName);
+        }
+        if (installerAppTitle != null) {
+            args.putString(EXTRA_INSTALLER_TITLE, installerAppTitle);
+        }
+
+        DialogFragment fragment = new UnarchiveErrorFragment();
+        fragment.setArguments(args);
+        fragment.show(ft, "dialog");
+    }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveErrorFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveErrorFragment.java
new file mode 100644
index 0000000..d33433f
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveErrorFragment.java
@@ -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.packageinstaller;
+
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.PendingIntent;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageInstaller;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.text.format.Formatter;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+public class UnarchiveErrorFragment extends DialogFragment implements
+        DialogInterface.OnClickListener {
+
+    private static final String TAG = "UnarchiveErrorFragment";
+
+    private int mStatus;
+
+    @Nullable
+    private PendingIntent mExtraIntent;
+
+    @Nullable
+    private String mInstallerPackageName;
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Bundle args = getArguments();
+        mStatus = args.getInt(PackageInstaller.EXTRA_UNARCHIVE_STATUS, -1);
+        mExtraIntent = args.getParcelable(Intent.EXTRA_INTENT, PendingIntent.class);
+        long requiredBytes = args.getLong(UnarchiveErrorActivity.EXTRA_REQUIRED_BYTES);
+        mInstallerPackageName = args.getString(
+                UnarchiveErrorActivity.EXTRA_INSTALLER_PACKAGE_NAME);
+        String installerAppTitle = args.getString(UnarchiveErrorActivity.EXTRA_INSTALLER_TITLE);
+
+        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
+
+        dialogBuilder.setTitle(getDialogTitle(mStatus, installerAppTitle));
+        dialogBuilder.setMessage(getBodyText(mStatus, installerAppTitle, requiredBytes));
+
+        addButtons(dialogBuilder, mStatus);
+
+        return dialogBuilder.create();
+    }
+
+    private void addButtons(AlertDialog.Builder dialogBuilder, int status) {
+        switch (status) {
+            case PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED:
+                dialogBuilder.setPositiveButton(R.string.unarchive_action_required_continue, this);
+                dialogBuilder.setNegativeButton(R.string.close, this);
+                break;
+            case PackageInstaller.UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE:
+                dialogBuilder.setPositiveButton(R.string.unarchive_clear_storage_button, this);
+                dialogBuilder.setNegativeButton(R.string.close, this);
+                break;
+            case PackageInstaller.UNARCHIVAL_ERROR_INSTALLER_DISABLED:
+                dialogBuilder.setPositiveButton(R.string.external_sources_settings, this);
+                dialogBuilder.setNegativeButton(R.string.close, this);
+                break;
+            case PackageInstaller.UNARCHIVAL_ERROR_NO_CONNECTIVITY:
+            case PackageInstaller.UNARCHIVAL_ERROR_INSTALLER_UNINSTALLED:
+            case PackageInstaller.UNARCHIVAL_GENERIC_ERROR:
+                dialogBuilder.setPositiveButton(android.R.string.ok, this);
+                break;
+            default:
+                // This should never happen through normal API usage.
+                throw new IllegalArgumentException("Invalid unarchive status " + status);
+        }
+    }
+
+    private String getBodyText(int status, String installerAppTitle, long requiredBytes) {
+        switch (status) {
+            case PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED:
+                return getString(R.string.unarchive_action_required_body);
+            case PackageInstaller.UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE:
+                return String.format(getString(R.string.unarchive_error_storage_body),
+                        Formatter.formatShortFileSize(getActivity(), requiredBytes));
+            case PackageInstaller.UNARCHIVAL_ERROR_NO_CONNECTIVITY:
+                return getString(R.string.unarchive_error_offline_body);
+            case PackageInstaller.UNARCHIVAL_ERROR_INSTALLER_DISABLED:
+                return String.format(getString(R.string.unarchive_error_installer_disabled_body),
+                        installerAppTitle);
+            case PackageInstaller.UNARCHIVAL_ERROR_INSTALLER_UNINSTALLED:
+                return String.format(
+                        getString(R.string.unarchive_error_installer_uninstalled_body),
+                        installerAppTitle);
+            case PackageInstaller.UNARCHIVAL_GENERIC_ERROR:
+                return getString(R.string.unarchive_error_generic_body);
+            default:
+                // This should never happen through normal API usage.
+                throw new IllegalArgumentException("Invalid unarchive status " + status);
+        }
+    }
+
+    private String getDialogTitle(int status, String installerAppTitle) {
+        switch (status) {
+            case PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED:
+                return getString(R.string.unarchive_action_required_title);
+            case PackageInstaller.UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE:
+                return getString(R.string.unarchive_error_storage_title);
+            case PackageInstaller.UNARCHIVAL_ERROR_NO_CONNECTIVITY:
+                return getString(R.string.unarchive_error_offline_title);
+            case PackageInstaller.UNARCHIVAL_ERROR_INSTALLER_DISABLED:
+                return String.format(getString(R.string.unarchive_error_installer_disabled_title),
+                        installerAppTitle);
+            case PackageInstaller.UNARCHIVAL_ERROR_INSTALLER_UNINSTALLED:
+                return String.format(
+                        getString(R.string.unarchive_error_installer_uninstalled_title),
+                        installerAppTitle);
+            case PackageInstaller.UNARCHIVAL_GENERIC_ERROR:
+                return getString(R.string.unarchive_error_generic_title);
+            default:
+                // This should never happen through normal API usage.
+                throw new IllegalArgumentException("Invalid unarchive status " + status);
+        }
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        if (which != Dialog.BUTTON_POSITIVE) {
+            return;
+        }
+
+        try {
+            onClickInternal();
+        } catch (IntentSender.SendIntentException e) {
+            Log.e(TAG, "Failed to start intent after onClick.", e);
+        }
+    }
+
+    private void onClickInternal() throws IntentSender.SendIntentException {
+        Activity activity = getActivity();
+        if (activity == null) {
+            // This probably shouldn't happen in practice.
+            Log.i(TAG, "Lost reference to activity, cannot act onClick.");
+            return;
+        }
+
+        switch (mStatus) {
+            case PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED:
+                activity.startIntentSender(mExtraIntent.getIntentSender(), /* fillInIntent= */
+                        null, /* flagsMask= */ 0, FLAG_ACTIVITY_NEW_TASK, /* extraFlags= */ 0);
+                break;
+            case PackageInstaller.UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE:
+                if (mExtraIntent != null) {
+                    activity.startIntentSender(mExtraIntent.getIntentSender(), /* fillInIntent= */
+                            null, /* flagsMask= */ 0, FLAG_ACTIVITY_NEW_TASK, /* extraFlags= */ 0);
+                } else {
+                    Intent intent = new Intent("android.intent.action.MANAGE_PACKAGE_STORAGE");
+                    startActivity(intent);
+                }
+                break;
+            case PackageInstaller.UNARCHIVAL_ERROR_INSTALLER_DISABLED:
+                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+                Uri uri = Uri.fromParts("package", mInstallerPackageName, null);
+                intent.setData(uri);
+                startActivity(intent);
+                break;
+            default:
+                // Do nothing. The rest of the dialogs are purely informational.
+        }
+    }
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        super.onDismiss(dialog);
+        if (isAdded()) {
+            getActivity().finish();
+        }
+    }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
index 34062a4..ba627e9 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
@@ -17,8 +17,8 @@
 package com.android.packageinstaller;
 
 import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.content.pm.Flags.usePiaV2;
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
-
 import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
 
 import android.Manifest;
@@ -81,9 +81,6 @@
     private String mPackageName;
     private DialogInfo mDialogInfo;
 
-    // TODO (sumedhsen): Replace with an Android Feature Flag once implemented
-    private static final boolean USE_PIA_V2 = false;
-
     @Override
     public void onCreate(Bundle icicle) {
         getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
@@ -92,7 +89,18 @@
         // be stale, if e.g. the app was uninstalled while the activity was destroyed.
         super.onCreate(null);
 
-        if (USE_PIA_V2 && !isTv()) {
+        if (usePiaV2() && !isTv()) {
+            Log.i(TAG, "Using Pia V2");
+
+            PackageManager pm = getPackageManager();
+            pm.setComponentEnabledSetting(
+                new ComponentName(this, com.android.packageinstaller.UninstallEventReceiver.class),
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
+            pm.setComponentEnabledSetting(
+                new ComponentName(this,
+                    com.android.packageinstaller.v2.model.UninstallEventReceiver.class),
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
+
             boolean returnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false);
             Intent piaV2 = new Intent(getIntent());
             piaV2.putExtra(UninstallLaunch.EXTRA_CALLING_PKG_UID, getLaunchedFromUid());
diff --git a/packages/SettingsLib/MainSwitchPreference/Android.bp b/packages/SettingsLib/MainSwitchPreference/Android.bp
index 4871ef3..010a6ce 100644
--- a/packages/SettingsLib/MainSwitchPreference/Android.bp
+++ b/packages/SettingsLib/MainSwitchPreference/Android.bp
@@ -17,7 +17,6 @@
     static_libs: [
         "androidx.preference_preference",
         "SettingsLibSettingsTheme",
-        "SettingsLibUtils",
     ],
 
     sdk_version: "system_current",
diff --git a/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml b/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml
index 4b3acbf..e70114f 100644
--- a/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml
+++ b/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml
@@ -17,5 +17,5 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.settingslib.widget.mainswitch">
-
+    <uses-sdk android:minSdkVersion="21" />
 </manifest>
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
index 2b5fcd8..e6f61a8 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -18,6 +18,8 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
@@ -30,7 +32,6 @@
 
 import androidx.annotation.ColorInt;
 
-import com.android.settingslib.utils.BuildCompatUtils;
 import com.android.settingslib.widget.mainswitch.R;
 
 import java.util.ArrayList;
@@ -72,11 +73,18 @@
 
         LayoutInflater.from(context).inflate(R.layout.settingslib_main_switch_bar, this);
 
-        if (!BuildCompatUtils.isAtLeastS()) {
-            final TypedArray a = context.obtainStyledAttributes(
-                    new int[]{android.R.attr.colorAccent});
-            mBackgroundActivatedColor = a.getColor(0, 0);
-            mBackgroundColor = context.getColor(androidx.appcompat.R.color.material_grey_600);
+        if (Build.VERSION.SDK_INT < VERSION_CODES.S) {
+            TypedArray a;
+            if (Build.VERSION.SDK_INT >= VERSION_CODES.M) {
+                a = context.obtainStyledAttributes(
+                        new int[]{android.R.attr.colorAccent});
+                mBackgroundActivatedColor = a.getColor(0, 0);
+                mBackgroundColor = context.getColor(androidx.appcompat.R.color.material_grey_600);
+            } else {
+                a = context.obtainStyledAttributes(new int[]{android.R.attr.colorPrimary});
+                mBackgroundActivatedColor = a.getColor(0, 0);
+                mBackgroundColor = a.getColor(0, 0);
+            }
             a.recycle();
         }
 
@@ -148,7 +156,7 @@
      * Set icon space reserved for title
      */
     public void setIconSpaceReserved(boolean iconSpaceReserved) {
-        if (mTextView != null && !BuildCompatUtils.isAtLeastS()) {
+        if (mTextView != null && (Build.VERSION.SDK_INT < VERSION_CODES.S)) {
             LayoutParams params = (LayoutParams) mTextView.getLayoutParams();
             int iconSpace = getContext().getResources().getDimensionPixelSize(
                     R.dimen.settingslib_switchbar_subsettings_margin_start);
@@ -207,7 +215,7 @@
         mTextView.setEnabled(enabled);
         mSwitch.setEnabled(enabled);
 
-        if (BuildCompatUtils.isAtLeastS()) {
+        if (Build.VERSION.SDK_INT >= VERSION_CODES.S) {
             mFrameView.setEnabled(enabled);
             mFrameView.setActivated(isChecked());
         }
@@ -222,7 +230,7 @@
     }
 
     private void setBackground(boolean isChecked) {
-        if (!BuildCompatUtils.isAtLeastS()) {
+        if (Build.VERSION.SDK_INT < VERSION_CODES.S) {
             setBackgroundColor(isChecked ? mBackgroundActivatedColor : mBackgroundColor);
         } else {
             mFrameView.setActivated(isChecked);
diff --git a/packages/SettingsLib/Spa/build.gradle.kts b/packages/SettingsLib/Spa/build.gradle.kts
index 80b944f..60bf48c 100644
--- a/packages/SettingsLib/Spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/build.gradle.kts
@@ -25,11 +25,11 @@
     alias(libs.plugins.kotlin.android) apply false
 }
 
-val androidTop : String = File(rootDir, "../../../../..").canonicalPath
+val androidTop: String = File(rootDir, "../../../../..").canonicalPath
 
 allprojects {
     extra["androidTop"] = androidTop
-    extra["jetpackComposeVersion"] = "1.6.0-alpha08"
+    extra["jetpackComposeVersion"] = "1.6.0-beta01"
 }
 
 subprojects {
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/card/CardPageProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/card/CardPageProvider.kt
index 8386bc1..f216abb 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/card/CardPageProvider.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/card/CardPageProvider.kt
@@ -17,24 +17,32 @@
 package com.android.settingslib.spa.gallery.card
 
 import android.os.Bundle
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.Error
 import androidx.compose.material.icons.outlined.PowerOff
 import androidx.compose.material.icons.outlined.Shield
 import androidx.compose.material.icons.outlined.WarningAmber
+import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
+import com.android.settingslib.spa.framework.theme.SettingsDimension
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.gallery.R
 import com.android.settingslib.spa.widget.card.CardButton
 import com.android.settingslib.spa.widget.card.CardModel
 import com.android.settingslib.spa.widget.card.SettingsCard
 import com.android.settingslib.spa.widget.card.SettingsCollapsibleCard
+import com.android.settingslib.spa.widget.card.SettingsCardContent
 import com.android.settingslib.spa.widget.preference.Preference
 import com.android.settingslib.spa.widget.preference.PreferenceModel
 import com.android.settingslib.spa.widget.scaffold.RegularScaffold
@@ -50,6 +58,7 @@
             SettingsCardWithIcon()
             SettingsCardWithoutIcon()
             SampleSettingsCollapsibleCard()
+            SampleSettingsCardContent()
         }
     }
 
@@ -108,6 +117,32 @@
         )
     }
 
+    @Composable
+    fun SampleSettingsCardContent() {
+        SettingsCard {
+            SettingsCardContent {
+                Box(
+                    Modifier
+                        .fillMaxWidth()
+                        .clickable { }
+                        .padding(SettingsDimension.dialogItemPadding),
+                ) {
+                    Text(text = "Abc")
+                }
+            }
+            SettingsCardContent {
+                Box(
+                    Modifier
+                        .fillMaxWidth()
+                        .clickable { }
+                        .padding(SettingsDimension.dialogItemPadding),
+                ) {
+                    Text(text = "123")
+                }
+            }
+        }
+    }
+
     fun buildInjectEntry(): SettingsEntryBuilder {
         return SettingsEntryBuilder.createInject(owner = createSettingsPage())
             .setUiLayoutFn {
diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts
index 4335173..acd90f3 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/spa/build.gradle.kts
@@ -57,13 +57,13 @@
     api("androidx.slice:slice-builders:1.1.0-alpha02")
     api("androidx.slice:slice-core:1.1.0-alpha02")
     api("androidx.slice:slice-view:1.1.0-alpha02")
-    api("androidx.compose.material3:material3:1.2.0-alpha10")
+    api("androidx.compose.material3:material3:1.2.0-alpha11")
     api("androidx.compose.material:material-icons-extended:$jetpackComposeVersion")
     api("androidx.compose.runtime:runtime-livedata:$jetpackComposeVersion")
     api("androidx.compose.ui:ui-tooling-preview:$jetpackComposeVersion")
     api("androidx.lifecycle:lifecycle-livedata-ktx")
     api("androidx.lifecycle:lifecycle-runtime-compose")
-    api("androidx.navigation:navigation-compose:2.7.5")
+    api("androidx.navigation:navigation-compose:2.7.4")
     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:$jetpackComposeVersion")
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsShape.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsShape.kt
index 8c862d4..f7c5414 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsShape.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsShape.kt
@@ -20,6 +20,8 @@
 import androidx.compose.ui.unit.dp
 
 object SettingsShape {
+    val CornerExtraSmall = RoundedCornerShape(4.dp)
+
     val CornerMedium = RoundedCornerShape(12.dp)
 
     val CornerExtraLarge = RoundedCornerShape(28.dp)
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt
index 26372b6..c395558 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTheme.kt
@@ -17,9 +17,7 @@
 package com.android.settingslib.spa.framework.theme
 
 import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.material.ripple.LocalRippleTheme
-import androidx.compose.material.ripple.RippleAlpha
-import androidx.compose.material.ripple.RippleTheme
+import androidx.compose.material3.LocalContentColor
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
@@ -39,7 +37,7 @@
     MaterialTheme(colorScheme = colorScheme, typography = rememberSettingsTypography()) {
         CompositionLocalProvider(
             LocalColorScheme provides settingsColorScheme(isDarkTheme),
-            LocalRippleTheme provides SettingsRippleTheme,
+            LocalContentColor provides MaterialTheme.colorScheme.onSurface,
         ) {
             content()
         }
@@ -52,19 +50,3 @@
         @ReadOnlyComposable
         get() = LocalColorScheme.current
 }
-
-private object SettingsRippleTheme : RippleTheme {
-    @Composable
-    override fun defaultColor() = MaterialTheme.colorScheme.onSurface
-
-    @Composable
-    override fun rippleAlpha() = RippleAlpha
-}
-
-/** Alpha levels for all content. */
-private val RippleAlpha = RippleAlpha(
-    pressedAlpha = 0.48f,
-    focusedAlpha = 0.48f,
-    draggedAlpha = 0.32f,
-    hoveredAlpha = 0.16f,
-)
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCard.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCard.kt
index 10e2686..4379278 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCard.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCard.kt
@@ -36,10 +36,13 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.dp
 import com.android.settingslib.spa.debug.UiModePreviews
 import com.android.settingslib.spa.framework.theme.SettingsDimension
 import com.android.settingslib.spa.framework.theme.SettingsShape.CornerExtraLarge
+import com.android.settingslib.spa.framework.theme.SettingsShape.CornerExtraSmall
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.widget.ui.SettingsBody
 import com.android.settingslib.spa.widget.ui.SettingsTitle
@@ -49,7 +52,7 @@
     Card(
         shape = CornerExtraLarge,
         colors = CardDefaults.cardColors(
-            containerColor = SettingsTheme.colorScheme.surface,
+            containerColor = Color.Transparent,
         ),
         modifier = Modifier
             .fillMaxWidth()
@@ -62,6 +65,20 @@
 }
 
 @Composable
+fun SettingsCardContent(content: @Composable ColumnScope.() -> Unit) {
+    Card(
+        shape = CornerExtraSmall,
+        colors = CardDefaults.cardColors(
+            containerColor = SettingsTheme.colorScheme.surface,
+        ),
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(vertical = 1.dp),
+        content = content,
+    )
+}
+
+@Composable
 fun SettingsCard(model: CardModel) {
     SettingsCard {
         SettingsCardImpl(model)
@@ -70,14 +87,16 @@
 
 @Composable
 internal fun SettingsCardImpl(model: CardModel) {
-    Column(
-        modifier = Modifier.padding(SettingsDimension.itemPaddingStart),
-        verticalArrangement = Arrangement.spacedBy(SettingsDimension.itemPaddingAround)
-    ) {
-        CardIcon(model.imageVector)
-        SettingsTitle(model.title)
-        SettingsBody(model.text)
-        Buttons(model.buttons)
+    SettingsCardContent {
+        Column(
+            modifier = Modifier.padding(SettingsDimension.itemPaddingStart),
+            verticalArrangement = Arrangement.spacedBy(SettingsDimension.itemPaddingAround)
+        ) {
+            CardIcon(model.imageVector)
+            SettingsTitle(model.title)
+            SettingsBody(model.text)
+            Buttons(model.buttons)
+        }
     }
 }
 
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCollapsibleCard.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCollapsibleCard.kt
index 7d10645..bf192a1 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCollapsibleCard.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/card/SettingsCollapsibleCard.kt
@@ -30,7 +30,6 @@
 import androidx.compose.material.icons.outlined.Error
 import androidx.compose.material.icons.outlined.PowerOff
 import androidx.compose.material.icons.outlined.Shield
-import androidx.compose.material3.HorizontalDivider
 import androidx.compose.material3.Icon
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Surface
@@ -54,18 +53,16 @@
 fun SettingsCollapsibleCard(
     title: String,
     imageVector: ImageVector,
-    models: List<CardModel>
+    models: List<CardModel>,
 ) {
     var expanded by rememberSaveable { mutableStateOf(false) }
     SettingsCard {
-        Header(title, imageVector, models.size, expanded) { expanded = it }
+        SettingsCardContent {
+            Header(title, imageVector, models.size, expanded) { expanded = it }
+        }
         AnimatedVisibility(expanded) {
             Column {
                 for (model in models) {
-                    HorizontalDivider(
-                        thickness = SettingsDimension.paddingSmall,
-                        color = MaterialTheme.colorScheme.surface,
-                    )
                     SettingsCardImpl(model)
                 }
             }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/chart/BarChart.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/chart/BarChart.kt
index 7ca15d9..e761a33 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/chart/BarChart.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/chart/BarChart.kt
@@ -86,6 +86,10 @@
      */
     val yAxisLabelCount: Int
         get() = 3
+
+    /** If set to true, touch gestures are enabled on the [BarChart]. */
+    val enableBarchartTouch: Boolean
+        get() = true
 }
 
 data class BarChartData(
@@ -127,6 +131,7 @@
                             legend.isEnabled = false
                             extraBottomOffset = 4f
                             setScaleEnabled(false)
+                            setTouchEnabled(barChartModel.enableBarchartTouch)
 
                             xAxis.apply {
                                 position = XAxis.XAxisPosition.BOTTOM
diff --git a/packages/SettingsLib/res/layout-v33/restricted_switch_preference.xml b/packages/SettingsLib/res/layout-v33/restricted_switch_preference.xml
index 31e9696..bee9e20 100644
--- a/packages/SettingsLib/res/layout-v33/restricted_switch_preference.xml
+++ b/packages/SettingsLib/res/layout-v33/restricted_switch_preference.xml
@@ -53,7 +53,7 @@
             android:id="@android:id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:maxLines="2"
+            android:maxLines="10"
             android:hyphenationFrequency="normalFast"
             android:lineBreakWordStyle="phrase"
             android:textAppearance="?android:attr/textAppearanceListItem"
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index d282520..3a25838 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Gekoppel deur ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Gekoppel deur eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV-verstek"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-uitset"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Interne luidsprekers"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kan nie koppel nie. Skakel toestel af en weer aan"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedrade oudiotoestel"</string>
     <string name="help_label" msgid="3528360748637781274">"Hulp en terugvoer"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index f047648..c2be887 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI ኢኤአርሲ"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"በኤአርሲ በኩል ተገናኝቷል"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"በኢኤአርሲ በኩል ተገናኝቷል"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"የቲቪ ነባሪ"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"የHDMI ውጽዓት"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"ውስጣዊ ድምፅ ማውጫዎች"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"የቲቪ ነባሪ"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"የHDMI ውጤት"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"ውስጣዊ ድምፅ ማውጫዎች"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"መገናኘት ላይ ችግር። መሳሪያውን ያጥፉት እና እንደገና ያብሩት"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ባለገመድ የኦዲዮ መሣሪያ"</string>
     <string name="help_label" msgid="3528360748637781274">"እገዛ እና ግብረመልስ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 7fa5c03..6dd70fa 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"‏متّصل من خلال ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"‏متّصل من خلال eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"الجهاز التلقائي لإخراج صوت التلفزيون"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"‏إخراج الصوت من خلال HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"مكبّرات الصوت الداخلية"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"حدثت مشكلة أثناء الاتصال. يُرجى إيقاف الجهاز ثم إعادة تشغيله."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"جهاز سماعي سلكي"</string>
     <string name="help_label" msgid="3528360748637781274">"المساعدة والملاحظات"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index a2d6955..c8eeee3 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARCৰ জৰিয়তে সংযুক্ত"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARCৰ জৰিয়তে সংযুক্ত"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"টিভি ডিফ’ল্ট"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI আউটপুট"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"অভ্যন্তৰীণ স্পীকাৰ"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"সংযোগ হোৱাত সমস্যা হৈছে। ডিভাইচটো অফ কৰি পুনৰ অন কৰক"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"তাঁৰযুক্ত অডিঅ’ ডিভাইচ"</string>
     <string name="help_label" msgid="3528360748637781274">"সহায় আৰু মতামত"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 99af557..34f506e 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Chrome-da Tətbiqin İşləmə Müddəti vasitəsilə qoşulub"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC vasitəsilə qoşulub"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV Defoltu"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI Çıxışı"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Daxili Dinamiklər"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Qoşulmaqla bağlı problem. Cihazı deaktiv edin, sonra yenidən aktiv edin"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio cihaz"</string>
     <string name="help_label" msgid="3528360748637781274">"Yardım və rəy"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index cca8315..ee75df2 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Povezano preko ARC-a"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Povezano preko eARC-a"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Podrazumevana vrednost za TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI izlaz"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Unutrašnji zvučnici"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem pri povezivanju. Isključite uređaj, pa ga ponovo uključite"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index de703e9..c17d7236 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Падключана праз ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Падключана праз eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Стандартны (тэлевізар)"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Выхад HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Унутраныя дынамікі"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Праблема з падключэннем. Выключыце і зноў уключыце прыладу"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Правадная аўдыяпрылада"</string>
     <string name="help_label" msgid="3528360748637781274">"Даведка і водгукі"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index fd173c1..222e758 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Свързано посредством ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Свързано посредством eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Стандартна настройка за телевизора"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI изход"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Вградени високоговорители"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"При свързването възникна проблем. Изключете устройството и го включете отново"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Аудиоустройство с кабел"</string>
     <string name="help_label" msgid="3528360748637781274">"Помощ и отзиви"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 2290c09..a7c95df 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC-এর মাধ্যমে কানেক্ট করা হয়েছে"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC-এর মাধ্যমে কানেক্ট করা হয়েছে"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"টিভির ডিফল্ট অডিও আউটপুট"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI আউটপুট"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"ইন্টার্নাল স্পিকার"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"কানেক্ট করতে সমস্যা হচ্ছে। ডিভাইস বন্ধ করে আবার চালু করুন"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ওয়্যার অডিও ডিভাইস"</string>
     <string name="help_label" msgid="3528360748637781274">"সহায়তা ও মতামত"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 7057619..31ea4d4 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Povezano je putem ARC-a"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Povezano je putem eARC-a"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV je zadan"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI izlaz"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Interni zvučnici"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Došlo je do problema prilikom povezivanja. Isključite, pa ponovo uključite uređaj"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 00c31dc..1bb02c2 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connectat mitjançant ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connectat mitjançant eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Valor predeterminat per al televisor"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Sortida HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Altaveus interns"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Hi ha hagut un problema amb la connexió. Apaga el dispositiu i torna\'l a encendre."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositiu d\'àudio amb cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda i suggeriments"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 47ed7e9..53b7c70 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Připojeno přes ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Připojeno přes eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Výchozí nastavení televize"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Výstup HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Interní reproduktory"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Výchozí nastavení televize"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Výstup HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interní reproduktory"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problém s připojením. Vypněte zařízení a znovu jej zapněte"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kabelové audiozařízení"</string>
     <string name="help_label" msgid="3528360748637781274">"Nápověda a zpětná vazba"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 6e12771..7ab6669 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Forbundet via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Forbundet via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Fjernsyn som standard"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-udgang"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Interne højttalere"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Der kunne ikke oprettes forbindelse. Sluk og tænd enheden"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhed med ledning"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjælp og feedback"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 4a7f786..7936478 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Per ARC verbunden"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Per eARC verbunden"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Standardeinstellung: Fernseher"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-Ausgang"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Interne Lautsprecher"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Standardeinstellung: Fernseher"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-Ausgang"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Interne Lautsprecher"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Verbindung kann nicht hergestellt werden. Schalte das Gerät aus &amp; und wieder ein."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Netzbetriebenes Audiogerät"</string>
     <string name="help_label" msgid="3528360748637781274">"Hilfe und Feedback"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 532e380..65f1f77 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Συνδέθηκε μέσω ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Συνδέθηκε μέσω eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Προεπιλογή τηλεόρασης"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Έξοδος HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Εσωτερικά ηχεία"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Προεπιλογή τηλεόρασης"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Έξοδος HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Εσωτερικά ηχεία"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Πρόβλημα κατά τη σύνδεση. Απενεργοποιήστε τη συσκευή και ενεργοποιήστε την ξανά"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ενσύρματη συσκευή ήχου"</string>
     <string name="help_label" msgid="3528360748637781274">"Βοήθεια και σχόλια"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 27f2fc5..29038bc 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connected via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connected via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV default"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI Output"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Internal speakers"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index b59f765..1c51ea5 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connected via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connected via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV Default"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI Output"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Internal Speakers"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"TV default"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI output"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Internal speakers"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off &amp; back on"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 27f2fc5..29038bc 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connected via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connected via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV default"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI Output"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Internal speakers"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 27f2fc5..29038bc 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connected via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connected via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV default"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI Output"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Internal speakers"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 15946f4..2ff386c 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎HDMI eARC‎‏‎‎‏‎"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎Connected via ARC‎‏‎‎‏‎"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎Connected via eARC‎‏‎‎‏‎"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎TV Default‎‏‎‎‏‎"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎HDMI Output‎‏‎‎‏‎"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‎Internal Speakers‎‏‎‎‏‎"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎TV default‎‏‎‎‏‎"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‎HDMI output‎‏‎‎‏‎"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎Internal speakers‎‏‎‎‏‎"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‎Problem connecting. Turn device off &amp; back on‎‏‎‎‏‎"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎Wired audio device‎‏‎‎‏‎"</string>
     <string name="help_label" msgid="3528360748637781274">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎Help &amp; feedback‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index a76cf86..780a45d 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Se estableció conexión con un cable ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Se estableció conexión con un cable eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Configuración predeterminada de la TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Salida de HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Bocinas internas"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Configuración predeterminada de la TV"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Salida de HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Bocinas internas"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Error al establecer la conexión. Apaga el dispositivo y vuelve a encenderlo."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 90476b6..82cd2bf 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectado mediante ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectado mediante eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Predeterminado de la televisión"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Salida HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Altavoces internos"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"No se ha podido conectar; reinicia el dispositivo"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index e5c8242..35ae73e 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Ühendatud ARC-i kaudu"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Ühendatud eARC-i kaudu"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Teleri vaikeseade"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-väljund"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Sisemised kõlarid"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem ühendamisel. Lülitage seade välja ja uuesti sisse"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Juhtmega heliseade"</string>
     <string name="help_label" msgid="3528360748637781274">"Abi ja tagasiside"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 65a88d3..7ebad68 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC bidez konektatuta"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC bidez konektatuta"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Telebistaren audio-irteera lehenetsia"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI irteera"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Barneko bozgorailuak"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Arazo bat izan da konektatzean. Itzali gailua eta pitz ezazu berriro."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio-gailu kableduna"</string>
     <string name="help_label" msgid="3528360748637781274">"Laguntza eta iritziak"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index b01bcbc..51fd626 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"‏متصل ازطریق ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"‏متصل ازطریق eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"پیش‌فرض تلویزیون"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"‏خروجی HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"بلندگوهای داخلی"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"مشکل در اتصال. دستگاه را خاموش و دوباره روشن کنید"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"دستگاه صوتی سیمی"</string>
     <string name="help_label" msgid="3528360748637781274">"راهنما و بازخورد"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 58e87a6..f8c9054 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Yhdistetty ARC:n kautta"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Yhdistetty eARC:n kautta"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV:n oletusasetus"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-toisto"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Sisäiset kaiuttimet"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Yhteysvirhe. Sammuta laite ja käynnistä se uudelleen."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Langallinen äänilaite"</string>
     <string name="help_label" msgid="3528360748637781274">"Ohje ja palaute"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index c889d3d..2a7266d 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connecté par ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connecté par eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Sortie audio par défaut de la télévision"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Sortie HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Haut-parleurs internes"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteingez et rallumez l\'appareil"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio à câble"</string>
     <string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 8a9bedf..e30a4ab 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connecté via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connecté via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Sortie audio par défaut de la TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Sortie HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Haut-parleurs internes"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Sortie par défaut de la TV"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Sortie HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Haut-parleurs internes"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez l\'appareil, puis rallumez-le"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio filaire"</string>
     <string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 3258db0..7b79386 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectado mediante ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectado mediante eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Saída predeterminada da televisión"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Saída HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Altofalantes internos"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Produciuse un problema coa conexión. Apaga e acende o dispositivo."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Axuda e comentarios"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 0dd9bfe..ec534da 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC મારફતે કનેક્ટેડ"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC મારફતે કનેક્ટેડ"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ટીવીમાંથી ડિફૉલ્ટ ઑડિયો આઉટપુટ"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI આઉટપુટ"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"આંતરિક સ્પીકર"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"કનેક્ટ કરવામાં સમસ્યા આવી રહી છે. ડિવાઇસને બંધ કરીને ફરી ચાલુ કરો"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"વાયરવાળો ઑડિયો ડિવાઇસ"</string>
     <string name="help_label" msgid="3528360748637781274">"સહાય અને પ્રતિસાદ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index ea5c5ba..092c729 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"एचडीएमआई eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC से कनेक्ट किए गए डिवाइस"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC से कनेक्ट किए गए डिवाइस"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"टीवी का डिफ़ॉल्ट ऑडियो आउटपुट"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"एचडीएमआई आउटपुट"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"इंटरनल स्पीकर"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्ट करने में समस्या हो रही है. डिवाइस को बंद करके चालू करें"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर वाला ऑडियो डिवाइस"</string>
     <string name="help_label" msgid="3528360748637781274">"सहायता और सुझाव"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 346b602..eaebfc9 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Povezano putem ARC-a"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Povezano putem eARC-a"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Zadano za TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI izlaz"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Unutarnji zvučnici"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem s povezivanjem. Isključite i ponovo uključite uređaj"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audiouređaj"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 186b42b..d287ce3 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Csatlakoztatva ARC-n keresztül"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Csatlakoztatva eARC-n keresztül"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Alapértelmezett tévé"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-kimenet"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Belső hangszóró"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sikertelen csatlakozás. Kapcsolja ki az eszközt, majd kapcsolja be újra."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Vezetékes audioeszköz"</string>
     <string name="help_label" msgid="3528360748637781274">"Súgó és visszajelzés"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index ff42a37..4d27099 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Միացված է ARC-ի միջոցով"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Միացված է eARC-ի միջոցով"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Հեռուստացույցի կանխադրված կարգավորումներ"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI ելք"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Ներքին բարձրախոսներ"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Կապի խնդիր կա: Սարքն անջատեք և նորից միացրեք:"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Լարով աուդիո սարք"</string>
     <string name="help_label" msgid="3528360748637781274">"Օգնություն և հետադարձ կապ"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 7159d87..ce770af 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Terhubung melalui ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Terhubung melalui eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV sebagai Default"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Output HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Speaker Internal"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ada masalah saat menghubungkan. Nonaktifkan perangkat &amp; aktifkan kembali"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Perangkat audio berkabel"</string>
     <string name="help_label" msgid="3528360748637781274">"Bantuan &amp; masukan"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 53f9045..09587ee 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Tengt með ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Tengt með eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Sjálfgefið í sjónvarpi"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-úttak"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Innri hátalarar"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Sjálfgefið í sjónvarpi"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"HDMI-úttak"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Innri hátalarar"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Vandamál í tengingu. Slökktu og kveiktu á tækinu"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Snúrutengt hljómtæki"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjálp og ábendingar"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index f83594df..fd68d14 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"eARC HDMI"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Connessione tramite ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Connessione tramite eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Valore predefinito: TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Uscita HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Speaker interni"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema di connessione. Spegni e riaccendi il dispositivo"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo audio cablato"</string>
     <string name="help_label" msgid="3528360748637781274">"Guida e feedback"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 755e8ce..fbd715a 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"‏חיבור דרך ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"‏חיבור דרך eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ברירת המחדל של הטלוויזיה"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"‏פלט HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"רמקולים פנימיים"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"ברירת המחדל של הטלוויזיה"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"‏פלט HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"רמקולים פנימיים"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"יש בעיה בחיבור. עליך לכבות את המכשיר ולהפעיל אותו מחדש"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"התקן אודיו חוטי"</string>
     <string name="help_label" msgid="3528360748637781274">"עזרה ומשוב"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index d9f76fd..58d4f0e 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC 経由で接続済み"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC 経由で接続済み"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"テレビのデフォルト"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI 出力"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"内蔵スピーカー"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"接続エラーです。デバイスを OFF にしてから ON に戻してください"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線オーディオ デバイス"</string>
     <string name="help_label" msgid="3528360748637781274">"ヘルプとフィードバック"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index fb58973..eb89b19 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"დაკავშირებულია ARC-ის მეშვეობით"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"დაკავშირებულია eARC-ის მეშვეობით"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ნაგულისხმევი ტელევიზორი"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"გამომავალი HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"შიდა დინამიკები"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"ტელევიზორის ნაგულისხმევი"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"გამომავალი HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"შიდა დინამიკები"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"დაკავშირებისას წარმოიქმნა პრობლემა. გამორთეთ და კვლავ ჩართეთ მოწყობილობა"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"სადენიანი აუდიო მოწყობილობა"</string>
     <string name="help_label" msgid="3528360748637781274">"დახმარება და გამოხმაურება"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index c991133..0d31dde 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC арқылы жалғанған."</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC арқылы жалғанған."</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Әдепкі теледидар"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI шығыс құрылғысы"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Ішкі динамиктер"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Байланыс орнату қатесі шығуып жатыр. Құрылғыны өшіріп, қайта қосыңыз."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Сымды аудио құрылғысы"</string>
     <string name="help_label" msgid="3528360748637781274">"Анықтама және пікір"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 7ad4e53..8ee7987 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"បានភ្ជាប់តាមរយៈ ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"បានភ្ជាប់តាមរយៈ eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"លំនាំដើម​ទូរទស្សន៍"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"ធាតុចេញ HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"ឧបករណ៍បំពងសំឡេងខាងក្នុង"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"មាន​បញ្ហា​ក្នុងការ​ភ្ជាប់។ បិទ រួច​បើក​ឧបករណ៍​វិញ"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ឧបករណ៍​សំឡេងប្រើខ្សែ"</string>
     <string name="help_label" msgid="3528360748637781274">"ជំនួយ និងមតិកែលម្អ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 8f5c042..73f7a20 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ಮೂಲಕ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ಮೂಲಕ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ಟಿವಿ ಡೀಫಾಲ್ಟ್"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI ಔಟ್‌‌ಪುಟ್"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"ಆಂತರಿಕ ಸ್ಪೀಕರ್‌ಗಳು"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ಕನೆಕ್ಟ್ ಮಾಡುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ ಸಾಧನವನ್ನು ಆಫ್ ಮಾಡಿ ಹಾಗೂ ನಂತರ ಪುನಃ ಆನ್ ಮಾಡಿ"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ವೈರ್ ಹೊಂದಿರುವ ಆಡಿಯೋ ಸಾಧನ"</string>
     <string name="help_label" msgid="3528360748637781274">"ಸಹಾಯ ಮತ್ತು ಪ್ರತಿಕ್ರಿಯೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index b2564a0..418e47e 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC를 통해 연결됨"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC를 통해 연결됨"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV 기본값"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI 출력"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"내부 스피커"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"연결 중에 문제가 발생했습니다. 기기를 껐다가 다시 켜 보세요."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"유선 오디오 기기"</string>
     <string name="help_label" msgid="3528360748637781274">"고객센터"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 18f792c..182e912 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC аркылуу туташты"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC аркылуу туташты"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV\'нин демейки параметрлери"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI Аудио түзмөгү"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Ички динамиктер"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Туташууда маселе келип чыкты. Түзмөктү өчүрүп, кайра күйгүзүп көрүңүз"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Зымдуу аудио түзмөк"</string>
     <string name="help_label" msgid="3528360748637781274">"Жардам/Пикир билдирүү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index c75326e..5f8ba5f 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ເຊື່ອມຕໍ່ຜ່ານ ARC ແລ້ວ"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"ເຊື່ອມຕໍ່ຜ່ານ eARC ແລ້ວ"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ຄ່າເລີ່ມຕົ້ນສຳລັບໂທລະທັດ"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"ເອົ້າພຸດ HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"ລຳໂພງຂອງເຄື່ອງ"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ເກີດບັນຫາໃນການເຊື່ອມຕໍ່. ປິດອຸປະກອນແລ້ວເປີດກັບຄືນມາໃໝ່"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ອຸປະກອນສຽງແບບມີສາຍ"</string>
     <string name="help_label" msgid="3528360748637781274">"ຊ່ວຍເຫຼືອ ແລະ ຕິຊົມ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 37a3576..5294f4a 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI „eARC“"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Prisijungta per ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Prisijungta per „eARC“"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV numatytasis"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI išvesti"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Vidiniai garsiakalbiai"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Prisijungiant kilo problema. Išjunkite įrenginį ir vėl jį įjunkite"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Laidinis garso įrenginys"</string>
     <string name="help_label" msgid="3528360748637781274">"Pagalba ir atsiliepimai"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 6cd9c57..7ea01e7 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -266,9 +266,9 @@
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"Uzlādes laikā ekrāns nekad nepārslēgsies miega režīmā"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Iespējot Bluetooth HCI analizētāja žurnālu"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Tvert Bluetooth paketes. (Pārslēgt Bluetooth pēc šī iestatījuma mainīšanas.)"</string>
-    <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM atbloķēšana"</string>
+    <string name="oem_unlock_enable" msgid="5334869171871566731">"OAR atbloķēšana"</string>
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Atļaut palaišanas ielādētāja atbloķēšanu"</string>
-    <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Vai atļaut OEM atbloķēšanu?"</string>
+    <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Vai atļaut OAR atbloķēšanu?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"BRĪDINĀJUMS. Kamēr šis iestatījums būs ieslēgts, ierīces aizsardzības funkcijas nedarbosies."</string>
     <string name="mock_location_app" msgid="6269380172542248304">"Atlasīt imitētas atrašanās vietas lietotni"</string>
     <string name="mock_location_app_not_set" msgid="6972032787262831155">"Nav iestatīta imitētas atrašanās vietas lietotne"</string>
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Savienojums izveidots, izmantojot ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Savienojums izveidots, izmantojot eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Noklusējuma iestatījums televizorā"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI izvade"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Iekšējie skaļruņi"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Radās problēma ar savienojuma izveidi. Izslēdziet un atkal ieslēdziet ierīci."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Vadu audioierīce"</string>
     <string name="help_label" msgid="3528360748637781274">"Palīdzība un atsauksmes"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 75dbbf1..d38f42c 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Поврзано преку ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Поврзано преку eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Стандардни поставки за телевизор"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Излез за HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Внатрешни звучници"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем со поврзување. Исклучете го уредот и повторно вклучете го"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичен аудиоуред"</string>
     <string name="help_label" msgid="3528360748637781274">"Помош и повратни информации"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 2cb4da1..8b6150d 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC വഴി കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC വഴി കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ടിവി ഡിഫോൾട്ട്"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI ഔട്ട്പുട്ട്"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"ആന്തരിക സ്‌പീക്കറുകൾ"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"കണക്‌റ്റ് ചെയ്യുന്നതിൽ പ്രശ്‌നമുണ്ടായി. ഉപകരണം ഓഫാക്കി വീണ്ടും ഓണാക്കുക"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"വയർ മുഖേന ബന്ധിപ്പിച്ച ഓഡിയോ ഉപകരണം"</string>
     <string name="help_label" msgid="3528360748637781274">"സഹായവും ഫീഡ്‌ബാക്കും"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 0a99650..e7c83a8 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC-р холбогдсон"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC-р холбогдсон"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ТВ-ийн өгөгдмөл"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI гаралт"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Дотоод чанга яригч"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Холбогдоход асуудал гарлаа. Төхөөрөмжийг унтраагаад дахин асаана уу"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Утастай аудио төхөөрөмж"</string>
     <string name="help_label" msgid="3528360748637781274">"Тусламж, санал хүсэлт"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index dca07e2..381d0b8 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC द्वारे कनेक्ट केलेली"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC द्वारे कनेक्ट केलेली"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"टीव्ही डीफॉल्ट"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI आउटपुट"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"अंतर्गत स्पीकर"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्‍ट करण्‍यात समस्‍या आली. डिव्हाइस बंद करा आणि नंतर सुरू करा"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर असलेले ऑडिओ डिव्हाइस"</string>
     <string name="help_label" msgid="3528360748637781274">"मदत आणि फीडबॅक"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index ad29abc..3e7d901 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Disambungkan melalui ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Disambungkan melalui eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Tetapan Lalai TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Output HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Pembesar Suara Dalaman"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Masalah penyambungan. Matikan &amp; hidupkan kembali peranti"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Peranti audio berwayar"</string>
     <string name="help_label" msgid="3528360748637781274">"Bantuan &amp; maklum balas"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index d538dc8..68ae549 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV မူရင်း"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI အထွက်"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"စက်ရှိ စပီကာများ"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ချိတ်ဆက်ရာတွင် ပြဿနာရှိပါသည်။ စက်ကိုပိတ်ပြီး ပြန်ဖွင့်ပါ"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ကြိုးတပ် အသံစက်ပစ္စည်း"</string>
     <string name="help_label" msgid="3528360748637781274">"အကူအညီနှင့် အကြံပြုချက်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index ae46b68..a11bfff 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Tilkoblet via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Tilkoblet via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV-ens standardinnstilling"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-utdata"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Interne høyttalere"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Tilkoblingsproblemer. Slå enheten av og på igjen"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhet med kabel"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjelp og tilbakemelding"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index f73cd0b..b833c14 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC मार्फत कनेक्ट गरिएका"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC मार्फत कनेक्ट गरिएका"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"टिभीको डिफल्ट अडियो आउटपुट"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI आउटपुट"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"आन्तरिक स्पिकरहरू"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"जोड्ने क्रममा समस्या भयो। यन्त्रलाई निष्क्रिय पारेर फेरि अन गर्नुहोस्"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"तारयुक्त अडियो यन्त्र"</string>
     <string name="help_label" msgid="3528360748637781274">"मद्दत र प्रतिक्रिया"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 2a47d7e..f9215e5 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Verbonden via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Verbonden via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Tv-standaard"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-uitvoer"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Interne speakers"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem bij verbinding maken. Zet het apparaat uit en weer aan."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedraad audioapparaat"</string>
     <string name="help_label" msgid="3528360748637781274">"Hulp en feedback"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 185870a..c4ed005 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ମାଧ୍ୟମରେ କନେକ୍ଟ କରାଯାଇଛି"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ମାଧ୍ୟମରେ କନେକ୍ଟ କରାଯାଇଛି"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ଟିଭିର ଡିଫଲ୍ଟ ଅଡିଓ ଆଉଟପୁଟ"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI ଆଉଟପୁଟ"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"ଇଣ୍ଟର୍ନଲ ସ୍ପିକର"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ସଂଯୋଗ କରିବାରେ ସମସ୍ୟା ହେଉଛି। ଡିଭାଇସ୍ ବନ୍ଦ କରି ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ତାରଯୁକ୍ତ ଅଡିଓ ଡିଭାଇସ୍"</string>
     <string name="help_label" msgid="3528360748637781274">"ସାହାଯ୍ୟ ଓ ମତାମତ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 4a72574..b7a67fd 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤੇ ਗਏ ਡੀਵਾਈਸ"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤੇ ਗਏ ਡੀਵਾਈਸ"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ਟੀਵੀ ਦਾ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਆਊਟਪੁੱਟ"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI ਆਊਟਪੁੱਟ"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"ਅੰਦਰੂਨੀ ਸਪੀਕਰ"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ਕਨੈਕਟ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ ਆਈ। ਡੀਵਾਈਸ ਨੂੰ ਬੰਦ ਕਰਕੇ ਵਾਪਸ ਚਾਲੂ ਕਰੋ"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ਤਾਰ ਵਾਲਾ ਆਡੀਓ ਡੀਵਾਈਸ"</string>
     <string name="help_label" msgid="3528360748637781274">"ਮਦਦ ਅਤੇ ਵਿਚਾਰ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 61ae709..3ef8fd7e 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Połączono przez ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Połączono przez eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Wyjście domyślne telewizora"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Wyjście HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Głośniki wewnętrzne"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem z połączeniem. Wyłącz i ponownie włącz urządzenie"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Przewodowe urządzenie audio"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoc i opinie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 20c0460..b76b37b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectado via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectado via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Padrão da TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Saída HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Alto-falantes internos"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fio"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 8c8482f..1a81f2d 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Ligado através de ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Ligado através de eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Predefinição da TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Saída HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Altifalantes internos"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Predefinição da TV"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Saída HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Altifalantes internos"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema ao ligar. Desligue e volte a ligar o dispositivo."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fios"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda e comentários"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 20c0460..b76b37b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectado via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectado via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Padrão da TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Saída HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Alto-falantes internos"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fio"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 4b4c075..5956d63 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectat prin ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectat prin eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Prestabilită pentru televizor"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Ieșire HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Difuzoare interne"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Prestabilit pentru televizor"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Ieșire HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Difuzoare interne"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problemă la conectare. Oprește și repornește dispozitivul."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispozitiv audio cu fir"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajutor și feedback"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 53f2729..862e3d4 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Подключено через ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Подключено через eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Стандартный выход на телевизоре"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Выход HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Внутренние динамики"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ошибка подключения. Выключите и снова включите устройство."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Проводное аудиоустройство"</string>
     <string name="help_label" msgid="3528360748637781274">"Справка/отзыв"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index d7dd1d09..795abec 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC හරහා සම්බන්ධ කර ඇත"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC හරහා සම්බන්ධ කර ඇත"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"රූපවාහිනී පෙරනිමිය"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI ප්‍රතිදානය"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"අභ්‍යන්තර ස්පීකර්"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"සම්බන්ධ කිරීමේ ගැටලුවකි උපාංගය ක්‍රියාවිරහිත කර &amp; ආපසු ක්‍රියාත්මක කරන්න"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"රැහැන්ගත කළ ඕඩියෝ උපාංගය"</string>
     <string name="help_label" msgid="3528360748637781274">"උදවු &amp; ප්‍රතිපෝෂණ"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 4b83ba0..00c0bc1 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Pripojené prostredníctvom rozhrania ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Pripojené prostredníctvom rozhrania eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Predvolené nastavenie televízora"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Výstup HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Vnútorné reproduktory"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Pri pripájaní sa vyskytol problém. Zariadenie vypnite a znova zapnite."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio zariadenie s káblom"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomocník a spätná väzba"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index c70716d..ddf0f71 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Povezano prek zvočnega kanala ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Povezano prek zvočnega kanala eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Privzeti izhod televizorja"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Izhod HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Notranji zvočniki"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Privzeti izhod televizorja"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Izhod HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Notranji zvočniki"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Težava pri povezovanju. Napravo izklopite in znova vklopite."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žična zvočna naprava"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoč in povratne informacije"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index a02ca5a..f204017 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Lidhur përmes ARC-së"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Lidhur përmes eARC-së"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Parazgjedhja e televizorit"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Dalja HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Altoparlantët e brendshëm"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem me lidhjen. Fike dhe ndize përsëri pajisjen"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Pajisja audio me tel"</string>
     <string name="help_label" msgid="3528360748637781274">"Ndihma dhe komentet"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index bc0114f..b83986a 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Повезано преко ARC-а"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Повезано преко eARC-а"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Подразумевана вредност за ТВ"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI излаз"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Унутрашњи звучници"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем при повезивању. Искључите уређај, па га поново укључите"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичани аудио уређај"</string>
     <string name="help_label" msgid="3528360748637781274">"Помоћ и повратне информације"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 51e00b7..58e3705 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Ansluten via ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Ansluten via eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Standardinställning för tv:n"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI-utgång"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Interna högtalare"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Det gick inte att ansluta. Stäng av enheten och slå på den igen"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ljudenhet med kabelanslutning"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjälp och feedback"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 6bacc32..5870cde 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -567,9 +567,9 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Imeunganishwa kupitia ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Imeunganishwa kupitia eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Mipangilio Chaguomsingi ya Televisheni"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Kutoa Sauti Kupitia HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Spika za Ndani"</string>
+    <string name="tv_media_transfer_default" msgid="5403053145185843843">"Mipangilio Chaguomsingi ya TV"</string>
+    <string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Kutoa sauti kupitia HDMI"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Spika za ndani"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kuna tatizo la kuunganisha kwenye Intaneti. Zima kisha uwashe kifaa"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kifaa cha sauti kinachotumia waya"</string>
     <string name="help_label" msgid="3528360748637781274">"Usaidizi na maoni"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 07bdaf2..2a2536b 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC மூலம் இணைக்கப்பட்டுள்ளவை"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC மூலம் இணைக்கப்பட்டுள்ளவை"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"டிவி இயல்புநிலை"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI அவுட்புட்"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"உட்புற ஸ்பீக்கர்கள்"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"இணைப்பதில் சிக்கல். சாதனத்தை ஆஃப் செய்து மீண்டும் ஆன் செய்யவும்"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"வயருடன்கூடிய ஆடியோ சாதனம்"</string>
     <string name="help_label" msgid="3528360748637781274">"உதவியும் கருத்தும்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 81739b3..303d310 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ద్వారా కనెక్ట్ చేయబడింది"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ద్వారా కనెక్ట్ చేయబడింది"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"టీవీ ఆటోమేటిక్ సెట్టింగ్"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI అవుట్‌పుట్"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"అంతర్గత స్పీకర్‌లు"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"కనెక్ట్ చేయడంలో సమస్య ఉంది. పరికరాన్ని ఆఫ్ చేసి, ఆపై తిరిగి ఆన్ చేయండి"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"వైర్ గల ఆడియో పరికరం"</string>
     <string name="help_label" msgid="3528360748637781274">"సహాయం &amp; ఫీడ్‌బ్యాక్"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 001af01..0ac8cb8 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"เชื่อมต่อผ่าน ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"เชื่อมต่อผ่าน eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"ค่าเริ่มต้นของทีวี"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"เอาต์พุต HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"ลำโพงของเครื่อง"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"เกิดปัญหาในการเชื่อมต่อ ปิดอุปกรณ์แล้วเปิดใหม่อีกครั้ง"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"อุปกรณ์เสียงแบบมีสาย"</string>
     <string name="help_label" msgid="3528360748637781274">"ความช่วยเหลือและความคิดเห็น"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 9ccc801..4f92e1d 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Nakakonekta sa pamamagitan ng ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Nakakonekta sa pamamagitan ng eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Naka-default sa TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI Output"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Mga Internal na Speaker"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Nagkaproblema sa pagkonekta. I-off at pagkatapos ay i-on ang device"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired na audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Tulong at feedback"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index a49f3ab..795bb30 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC ile bağlandı"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC ile bağlandı"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"TV Varsayılanı"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI Çıkışı"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Dahili Hoparlörler"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Bağlanırken sorun oluştu. Cihazı kapatıp tekrar açın"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kablolu ses cihazı"</string>
     <string name="help_label" msgid="3528360748637781274">"Yardım ve geri bildirim"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index eba7926..beb2c91 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Підключено через ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Підключено через eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Стандартні налаштування телевізора"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Вихід HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Внутрішні динаміки"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Не вдається підключитися. Перезавантажте пристрій."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Дротовий аудіопристрій"</string>
     <string name="help_label" msgid="3528360748637781274">"Довідка й відгуки"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index ce5ed31..13718d9 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"‏ARC کے ذریعے منسلک ہے"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"‏eARC کے ذریعے منسلک ہے"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"‏TV ڈیفالٹ"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"‏HDMI آؤٹ پٹ"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"اندرونی اسپیکرز"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"منسلک کرنے میں مسئلہ پیش آ گیا۔ آلہ کو آف اور بیک آن کریں"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"وائرڈ آڈیو آلہ"</string>
     <string name="help_label" msgid="3528360748637781274">"مدد اور تاثرات"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 5d23a93..7559a3d 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC orqali ulangan"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC orqali ulangan"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Televizorda birlamchi"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI chiqishi"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Ichki karnaylar"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ulanishda muammo yuz berdi. Qurilmani oʻchiring va yoqing"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio qurilma"</string>
     <string name="help_label" msgid="3528360748637781274">"Yordam/fikr-mulohaza"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index e96c49f..ccdc0bc 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Đã kết nối qua ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Đã kết nối qua eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"Chế độ mặc định của TV"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Đầu ra HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Loa trong"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sự cố kết nối. Hãy tắt thiết bị rồi bật lại"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Thiết bị âm thanh có dây"</string>
     <string name="help_label" msgid="3528360748637781274">"Trợ giúp và phản hồi"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 2174e12..6b3e061 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"已通过 ARC 连接"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"已通过 eARC 连接"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"电视默认设置"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI 输出"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"内置扬声器"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"连接时遇到问题。请关闭并重新开启设备"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有线音频设备"</string>
     <string name="help_label" msgid="3528360748637781274">"帮助和反馈"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index dc490ee..3517109 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"已透過 ARC 連接"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"已透過 eARC 連接"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"電視預設的音訊輸出裝置"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI 輸出"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"內置喇叭"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"無法連接,請關閉裝置然後重新開機"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線音響裝置"</string>
     <string name="help_label" msgid="3528360748637781274">"說明與意見反映"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 5049011..eeed9f3 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"透過 ARC 連線"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"透過 eARC 連線"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"電視預設的音訊輸出裝置"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"HDMI 輸出裝置"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"內建喇叭"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"無法連線,請關閉裝置後再重新開啟"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線音訊裝置"</string>
     <string name="help_label" msgid="3528360748637781274">"說明與意見回饋"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 7c82c19..e94b929 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -567,9 +567,12 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"I-HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Ixhunywe nge-ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Ixhunywe nge-eARC"</string>
-    <string name="tv_media_transfer_default" msgid="38102257053315304">"I-TV Ezenzakalelayo"</string>
-    <string name="tv_media_transfer_hdmi" msgid="2229000864416329818">"Okukhishwayo kwe-HDMI"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="2433193551482972117">"Izipikha Zangaphakathi"</string>
+    <!-- no translation found for tv_media_transfer_default (5403053145185843843) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_hdmi (692569220956829921) -->
+    <skip />
+    <!-- no translation found for tv_media_transfer_internal_speakers (8181494402866565865) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Inkinga yokuxhumeka. Vala idivayisi futhi uphinde uyivule"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Idivayisi yomsindo enentambo"</string>
     <string name="help_label" msgid="3528360748637781274">"Usizo nempendulo"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/PrimarySwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/PrimarySwitchPreference.java
index 0a2d9fc..e41126f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/PrimarySwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/PrimarySwitchPreference.java
@@ -140,12 +140,6 @@
         }
     }
 
-    @Override
-    public void setEnabled(boolean enabled) {
-        super.setEnabled(enabled);
-        setSwitchEnabled(enabled);
-    }
-
     @VisibleForTesting(otherwise = VisibleForTesting.NONE)
     public boolean isSwitchEnabled() {
         return mEnableSwitch;
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 8b0f19d..29ea25e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -22,7 +22,6 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.UserHandle;
 import android.text.TextUtils;
@@ -237,15 +236,13 @@
     }
 
     private void updateDisabledState() {
-        boolean isEnabled = !(mDisabledByAdmin || mDisabledByAppOps);
         if (!(mPreference instanceof RestrictedTopLevelPreference)) {
-            mPreference.setEnabled(isEnabled);
+            mPreference.setEnabled(!(mDisabledByAdmin || mDisabledByAppOps));
         }
 
-        Drawable icon = mPreference.getIcon();
-        if (!isEnabled && icon != null) {
-            Utils.convertToGrayscale(icon);
-            mPreference.setIcon(icon);
+        if (mPreference instanceof PrimarySwitchPreference) {
+            ((PrimarySwitchPreference) mPreference)
+                    .setSwitchEnabled(!(mDisabledByAdmin || mDisabledByAppOps));
         }
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index f03263b..107d5f8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -728,14 +728,4 @@
         return false;
     }
 
-    /**
-     *  Convert a drawable to grayscale drawable
-     */
-    public static void convertToGrayscale(@NonNull Drawable drawable) {
-        ColorMatrix matrix = new ColorMatrix();
-        matrix.setSaturation(0.0f);
-
-        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
-        drawable.setColorFilter(filter);
-    }
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 8412cba..5c09b16 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -251,6 +251,8 @@
         Settings.Secure.STYLUS_HANDWRITING_ENABLED,
         Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
         Settings.Secure.CREDENTIAL_SERVICE,
-        Settings.Secure.CREDENTIAL_SERVICE_PRIMARY
+        Settings.Secure.CREDENTIAL_SERVICE_PRIMARY,
+        Settings.Secure.EVEN_DIMMER_ACTIVATED,
+        Settings.Secure.EVEN_DIMMER_MIN_NITS
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 9197554..b0169a1 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -110,6 +110,9 @@
         VALIDATORS.put(Secure.FONT_WEIGHT_ADJUSTMENT, ANY_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.REDUCE_BRIGHT_COLORS_LEVEL, PERCENTAGE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.REDUCE_BRIGHT_COLORS_PERSIST_ACROSS_REBOOTS, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.EVEN_DIMMER_ACTIVATED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.EVEN_DIMMER_MIN_NITS,
+                new InclusiveFloatRangeValidator(0.0f, Float.MAX_VALUE));
         VALIDATORS.put(Secure.TTS_DEFAULT_RATE, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.TTS_DEFAULT_PITCH, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.TTS_DEFAULT_SYNTH, PACKAGE_NAME_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index a509ba3..a978889 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2135,6 +2135,15 @@
                 Settings.Secure.ENHANCED_VOICE_PRIVACY_ENABLED,
                 SecureSettingsProto.ENHANCED_VOICE_PRIVACY_ENABLED);
 
+        final long evenDimmerToken = p.start(SecureSettingsProto.EVEN_DIMMER);
+        dumpSetting(s, p,
+                Settings.Secure.EVEN_DIMMER_ACTIVATED,
+                SecureSettingsProto.EvenDimmer.EVEN_DIMMER_ACTIVATED);
+        dumpSetting(s, p,
+                Settings.Secure.EVEN_DIMMER_MIN_NITS,
+                SecureSettingsProto.EvenDimmer.EVEN_DIMMER_MIN_NITS);
+        p.end(evenDimmerToken);
+
         final long gestureToken = p.start(SecureSettingsProto.GESTURE);
         dumpSetting(s, p,
                 Settings.Secure.AWARE_ENABLED,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index efed8c3..85e8769 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -235,6 +235,7 @@
                     Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR,
                     Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH,
                     Settings.Global.DEVICE_DEMO_MODE,
+                    Settings.Global.DEVICE_IDLE_CONSTANTS,
                     Settings.Global.DISABLE_WINDOW_BLURS,
                     Settings.Global.BATTERY_SAVER_CONSTANTS,
                     Settings.Global.BATTERY_TIP_CONSTANTS,
diff --git a/packages/SoundPicker/res/values-ro/strings.xml b/packages/SoundPicker/res/values-ro/strings.xml
index 58b5aeb..01a2a1a 100644
--- a/packages/SoundPicker/res/values-ro/strings.xml
+++ b/packages/SoundPicker/res/values-ro/strings.xml
@@ -19,7 +19,7 @@
     <string name="ringtone_default" msgid="798836092118824500">"Ton de apel prestabilit"</string>
     <string name="notification_sound_default" msgid="8133121186242636840">"Sunet de notificare prestabilit"</string>
     <string name="alarm_sound_default" msgid="4787646764557462649">"Sunet de alarmă prestabilit"</string>
-    <string name="add_ringtone_text" msgid="6642389991738337529">"Adaugă un ton de sonerie"</string>
+    <string name="add_ringtone_text" msgid="6642389991738337529">"Adaugă un ton de apel"</string>
     <string name="add_alarm_text" msgid="3545497316166999225">"Adaugă o alarmă"</string>
     <string name="add_notification_text" msgid="4431129543300614788">"Adaugă o notificare"</string>
     <string name="delete_ringtone_text" msgid="201443984070732499">"Șterge"</string>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index d78038e..7cf562f 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -242,184 +242,10 @@
 }
 
 filegroup {
-    name: "SystemUI-test-fakes",
-    srcs: [
-        /* Status bar fakes */
-        "tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt",
-        "tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt",
-        "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt",
-        "tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt",
-
-        /* QS fakes */
-        "tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt",
-    ],
-    path: "tests/src",
-}
-
-filegroup {
-    name: "SystemUI-tests-robolectric-pilots",
-    srcs: [
-        /* Keyguard converted tests */
-        // data
-        "tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt",
-        "tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.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/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt",
-        "tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt",
-        "tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
-        "tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.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",
-        // ui
-        "tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt",
-        "tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt",
-        "tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt",
-        "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt",
-        "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt",
-        "tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt",
-        "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/dock/DockManagerFake.java",
-        "tests/src/com/android/systemui/dump/LogBufferHelper.kt",
-        "tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java",
-
-        /* Biometric converted tests */
-        "tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt",
-        "tests/src/com/android/systemui/biometrics/AuthControllerTest.java",
-        "tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java",
-        "tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt",
-        "tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt",
-        "tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt",
-        "tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java",
-        "tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java",
-        "tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java",
-        "tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java",
-        "tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java",
-        "tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt",
-        "tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt",
-        "tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt",
-
-        /* Status bar wifi converted tests */
-        "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt",
-        "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt",
-        "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt",
-        "tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt",
-        "tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt",
-        "tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt",
-        "tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt",
-
-        /* Bouncer UI tests */
-        "tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt",
-        "tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt",
-        "tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java",
-        "tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt",
-        "tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java",
-        "tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt",
-        "tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java",
-        "tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt",
-        "tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt",
-
-        /* Communal tests */
-        "tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt",
-        "tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt",
-        "tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt",
-
-        /* Dream tests */
-        "tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java",
-        "tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java",
-        "tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java",
-        "tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java",
-        "tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java",
-        "tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java",
-        "tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java",
-        "tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt",
-        "tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt",
-        "tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java",
-        "tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java",
-        "tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java",
-        "tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java",
-        "tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java",
-        "tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java",
-
-        /* Smartspace tests */
-        "tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt",
-        "tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt",
-        "tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt",
-        "tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt",
-
-        /* Quick Settings new pipeline converted tests */
-        "tests/src/com/android/systemui/qs/pipeline/data/**/*Test.kt",
-        "tests/src/com/android/systemui/qs/pipeline/domain/**/*Test.kt",
-        "tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt",
-        "tests/src/com/android/systemui/qs/tiles/base/**/*.kt",
-        "tests/src/com/android/systemui/qs/tiles/viewmodel/**/*.kt",
-        "tests/src/com/android/systemui/qs/tiles/impl/**/*.kt",
-
-        /* Authentication */
-        "tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt",
-        "tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt",
-
-        /* Device entry */
-        "tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt",
-        "tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt",
-
-        /* Bouncer scene */
-        "tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt",
-        "tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt",
-        "tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt",
-        "tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt",
-        "tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt",
-        "tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt",
-        "tests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt",
-
-        /* Lockscreen scene */
-        "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt",
-
-        /* Shade scene */
-        "tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt",
-        "tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt",
-
-        /* Quick Settings scene */
-        "tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt",
-
-        /* Flexiglass / Scene framework tests */
-        "tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt",
-        "tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt",
-        "tests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt",
-        "tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt",
-        "tests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt",
-        "tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt",
-        "tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt",
-
-    ],
-    path: "tests/src",
-}
-
-filegroup {
     name: "SystemUI-tests-multivalent",
     srcs: [
         "multivalentTests/src/**/*.kt",
+        "multivalentTests/src/**/*.java",
     ],
     path: "multivalentTests/src",
 }
@@ -597,8 +423,6 @@
         "tests/robolectric/src/**/*.kt",
         "tests/robolectric/src/**/*.java",
         ":SystemUI-tests-utils",
-        ":SystemUI-test-fakes",
-        ":SystemUI-tests-robolectric-pilots",
         ":SystemUI-tests-multivalent",
     ],
     static_libs: [
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 0a71cda..f1029a3 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -512,15 +512,6 @@
             </intent-filter>
         </activity-alias>
 
-        <activity
-            android:name="com.android.wm.shell.legacysplitscreen.ForcedResizableInfoActivity"
-            android:theme="@style/ForcedResizableTheme"
-            android:excludeFromRecents="true"
-            android:stateNotNeeded="true"
-            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
-            android:exported="false">
-        </activity>
-
         <!-- Springboard for launching the share and edit activity. This needs to be in the main
              system ui process since we need to notify the status bar to dismiss the keyguard -->
         <receiver android:name=".screenshot.ActionProxyReceiver"
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index 0480b9d..0c89a5d 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -126,24 +126,6 @@
           "exclude-annotation": "android.platform.test.annotations.Postsubmit"
         }
       ]
-    },
-    {
-      // TODO(b/251476085): Consider merging with SystemUIGoogleScreenshotTests (in U+)
-      "name": "SystemUIGoogleBiometricsScreenshotTests",
-      "options": [
-        {
-          "exclude-annotation": "org.junit.Ignore"
-        },
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        },
-        {
-          "exclude-annotation": "android.platform.test.annotations.FlakyTest"
-        },
-        {
-          "exclude-annotation": "android.platform.test.annotations.Postsubmit"
-        }
-      ]
     }
   ],
   
@@ -170,18 +152,6 @@
           "include-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
-    },
-    {
-      // TODO(b/251476085): Consider merging with SystemUIGoogleScreenshotTests (in U+)
-      "name": "SystemUIGoogleBiometricsScreenshotTests",
-      "options": [
-        {
-          "exclude-annotation": "org.junit.Ignore"
-        },
-        {
-          "include-annotation": "androidx.test.filters.FlakyTest"
-        }
-      ]
     }
   ]
 }
diff --git a/packages/SystemUI/aconfig/OWNERS b/packages/SystemUI/aconfig/OWNERS
index e1a7a0f..902ba90 100644
--- a/packages/SystemUI/aconfig/OWNERS
+++ b/packages/SystemUI/aconfig/OWNERS
@@ -1 +1,2 @@
 per-file accessibility.aconfig = file:/core/java/android/view/accessibility/OWNERS
+per-file biometrics_framework.aconfig = file:/services/core/java/com/android/server/biometrics/OWNERS
diff --git a/packages/SystemUI/aconfig/biometrics_framework.aconfig b/packages/SystemUI/aconfig/biometrics_framework.aconfig
new file mode 100644
index 0000000..5fd3b48
--- /dev/null
+++ b/packages/SystemUI/aconfig/biometrics_framework.aconfig
@@ -0,0 +1,10 @@
+package: "com.android.systemui"
+
+# NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
+
+flag {
+    name: "bp_talkback"
+    namespace: "biometrics_framework"
+    description: "Adds talkback directional guidance when using UDFPS with biometric prompt"
+    bug: "310044658"
+}
\ No newline at end of file
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index a9dc145..77c4aa6 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -68,6 +68,16 @@
 }
 
 flag {
+    name: "notification_background_tint_optimization"
+    namespace: "systemui"
+    description: "Re-enable the codepath that removed tinting of notifications when the"
+        " standard background color is desired.  This was the behavior before we discovered"
+        " a resources threading issue, which we worked around by tinting the notification"
+        " backgrounds and footer buttons."
+    bug: "294347738"
+}
+
+flag {
     name: "scene_container"
     namespace: "systemui"
     description: "Enables the scene container framework go/flexiglass."
@@ -114,6 +124,13 @@
 }
 
 flag {
+    name: "unfold_animation_background_progress"
+    namespace: "systemui"
+    description: "Moves unfold animation progress calculation to a background thread"
+    bug: "277879146"
+}
+
+flag {
     name: "qs_new_pipeline"
     namespace: "systemui"
     description: "Use the new pipeline for Quick Settings. Should have no behavior changes."
@@ -157,3 +174,17 @@
    bug: "296122467"
 }
 
+flag {
+   name: "rest_to_unlock"
+   namespace: "systemui"
+   description: "Require prolonged touch for fingerprint authentication"
+   bug: "303672286"
+}
+
+flag {
+   name: "record_issue_qs_tile"
+   namespace: "systemui"
+   description: "Replace Record Trace QS Tile with expanded Record Issue QS Tile"
+   bug: "305049544"
+}
+
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
index 0b13383..eb06889 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
@@ -16,12 +16,10 @@
 
 package com.android.systemui.bouncer.ui.composable
 
+import android.view.ViewTreeObserver
 import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.ExperimentalLayoutApi
 import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.WindowInsets
 import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.imeAnimationTarget
 import androidx.compose.foundation.text.KeyboardActions
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.material3.LocalTextStyle
@@ -30,46 +28,56 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.State
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.produceState
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalView
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.KeyboardType
 import androidx.compose.ui.text.input.PasswordVisualTransformation
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
+import androidx.core.view.WindowInsetsCompat
 import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
 
 /** UI for the input part of a password-requiring version of the bouncer. */
-@OptIn(ExperimentalLayoutApi::class)
 @Composable
 internal fun PasswordBouncer(
     viewModel: PasswordBouncerViewModel,
     modifier: Modifier = Modifier,
 ) {
     val focusRequester = remember { FocusRequester() }
+    val isTextFieldFocusRequested by viewModel.isTextFieldFocusRequested.collectAsState()
+    LaunchedEffect(isTextFieldFocusRequested) {
+        if (isTextFieldFocusRequested) {
+            focusRequester.requestFocus()
+        }
+    }
+    val (isTextFieldFocused, onTextFieldFocusChanged) = remember { mutableStateOf(false) }
+    LaunchedEffect(isTextFieldFocused) {
+        viewModel.onTextFieldFocusChanged(isFocused = isTextFieldFocused)
+    }
+
     val password: String by viewModel.password.collectAsState()
     val isInputEnabled: Boolean by viewModel.isInputEnabled.collectAsState()
     val animateFailure: Boolean by viewModel.animateFailure.collectAsState()
 
-    val density = LocalDensity.current
-    val isImeVisible by rememberUpdatedState(WindowInsets.imeAnimationTarget.getBottom(density) > 0)
+    val isImeVisible by isSoftwareKeyboardVisible()
     LaunchedEffect(isImeVisible) { viewModel.onImeVisibilityChanged(isImeVisible) }
 
     DisposableEffect(Unit) {
         viewModel.onShown()
-
-        // When the UI comes up, request focus on the TextField to bring up the software keyboard.
-        focusRequester.requestFocus()
-
         onDispose { viewModel.onHidden() }
     }
 
@@ -104,16 +112,39 @@
                     onDone = { viewModel.onAuthenticateKeyPressed() },
                 ),
             modifier =
-                Modifier.focusRequester(focusRequester).drawBehind {
-                    drawLine(
-                        color = color,
-                        start = Offset(x = 0f, y = size.height - lineWidthPx),
-                        end = Offset(size.width, y = size.height - lineWidthPx),
-                        strokeWidth = lineWidthPx,
-                    )
-                },
+                Modifier.focusRequester(focusRequester)
+                    .onFocusChanged { onTextFieldFocusChanged(it.isFocused) }
+                    .drawBehind {
+                        drawLine(
+                            color = color,
+                            start = Offset(x = 0f, y = size.height - lineWidthPx),
+                            end = Offset(size.width, y = size.height - lineWidthPx),
+                            strokeWidth = lineWidthPx,
+                        )
+                    },
         )
 
         Spacer(Modifier.height(100.dp))
     }
 }
+
+/** Returns a [State] with `true` when the IME/keyboard is visible and `false` when it's not. */
+@Composable
+fun isSoftwareKeyboardVisible(): State<Boolean> {
+    val view = LocalView.current
+    val viewTreeObserver = view.viewTreeObserver
+
+    return produceState(
+        initialValue = false,
+        key1 = viewTreeObserver,
+    ) {
+        val listener =
+            ViewTreeObserver.OnGlobalLayoutListener {
+                value = view.rootWindowInsets?.isVisible(WindowInsetsCompat.Type.ime()) ?: false
+            }
+
+        viewTreeObserver.addOnGlobalLayoutListener(listener)
+
+        awaitDispose { viewTreeObserver.removeOnGlobalLayoutListener(listener) }
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
new file mode 100644
index 0000000..735c433
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.ui.composable
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.viewinterop.AndroidView
+import com.android.compose.animation.scene.ElementKey
+import com.android.compose.animation.scene.SceneScope
+import com.android.systemui.media.controls.ui.MediaCarouselController
+import com.android.systemui.media.controls.ui.MediaHost
+import com.android.systemui.util.animation.MeasurementInput
+
+private object MediaCarousel {
+    object Elements {
+        internal val Content = ElementKey("MediaCarouselContent")
+    }
+}
+
+@Composable
+fun SceneScope.MediaCarousel(
+    mediaHost: MediaHost,
+    modifier: Modifier = Modifier,
+    layoutWidth: Int,
+    layoutHeight: Int,
+    carouselController: MediaCarouselController,
+) {
+    // Notify controller to size the carousel for the current space
+    mediaHost.measurementInput = MeasurementInput(layoutWidth, layoutHeight)
+    carouselController.setSceneContainerSize(layoutWidth, layoutHeight)
+
+    AndroidView(
+        modifier = modifier.element(MediaCarousel.Elements.Content),
+        factory = { _ -> carouselController.mediaFrame },
+    )
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index 2df151b..fcb1619 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -23,23 +23,34 @@
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.layout
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.unit.dp
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.SceneScope
 import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.media.controls.ui.MediaCarouselController
+import com.android.systemui.media.controls.ui.MediaHost
+import com.android.systemui.media.controls.ui.composable.MediaCarousel
+import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
 import com.android.systemui.notifications.ui.composable.NotificationStack
 import com.android.systemui.qs.ui.adapter.QSSceneAdapter
 import com.android.systemui.qs.ui.composable.QuickSettings
+import com.android.systemui.res.R
 import com.android.systemui.scene.shared.model.Direction
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
@@ -49,7 +60,9 @@
 import com.android.systemui.statusbar.phone.StatusBarIconController
 import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager
 import com.android.systemui.statusbar.phone.StatusBarLocation
+import com.android.systemui.util.animation.MeasurementInput
 import javax.inject.Inject
+import javax.inject.Named
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
@@ -59,6 +72,7 @@
 object Shade {
     object Elements {
         val QuickSettings = ElementKey("ShadeQuickSettings")
+        val MediaCarousel = ElementKey("ShadeMediaCarousel")
         val Scrim = ElementKey("ShadeScrim")
         val ScrimBackground = ElementKey("ShadeScrimBackground")
     }
@@ -87,6 +101,8 @@
     private val tintedIconManagerFactory: TintedIconManager.Factory,
     private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
     private val statusBarIconController: StatusBarIconController,
+    private val mediaCarouselController: MediaCarouselController,
+    @Named(QUICK_QS_PANEL) private val mediaHost: MediaHost,
 ) : ComposableScene {
     override val key = SceneKey.Shade
 
@@ -108,6 +124,8 @@
             createTintedIconManager = tintedIconManagerFactory::create,
             createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
             statusBarIconController = statusBarIconController,
+            mediaCarouselController = mediaCarouselController,
+            mediaHost = mediaHost,
             modifier = modifier,
         )
 
@@ -127,8 +145,12 @@
     createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
     createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
     statusBarIconController: StatusBarIconController,
+    mediaCarouselController: MediaCarouselController,
+    mediaHost: MediaHost,
     modifier: Modifier = Modifier,
 ) {
+    val layoutWidth = remember { mutableStateOf(0) }
+
     Box(modifier.element(Shade.Elements.Scrim)) {
         Spacer(
             modifier =
@@ -159,6 +181,34 @@
                 viewModel.qsSceneAdapter,
                 QSSceneAdapter.State.QQS
             )
+
+            if (viewModel.isMediaVisible()) {
+                val mediaHeight = dimensionResource(R.dimen.qs_media_session_height_expanded)
+                MediaCarousel(
+                    modifier =
+                        Modifier.height(mediaHeight).fillMaxWidth().layout { measurable, constraints
+                            ->
+                            val placeable = measurable.measure(constraints)
+
+                            // Notify controller to size the carousel for the current space
+                            mediaHost.measurementInput =
+                                MeasurementInput(placeable.width, placeable.height)
+                            mediaCarouselController.setSceneContainerSize(
+                                placeable.width,
+                                placeable.height
+                            )
+
+                            layout(placeable.width, placeable.height) {
+                                placeable.placeRelative(0, 0)
+                            }
+                        },
+                    mediaHost = mediaHost,
+                    layoutWidth = layoutWidth.value,
+                    layoutHeight = with(LocalDensity.current) { mediaHeight.toPx() }.toInt(),
+                    carouselController = mediaCarouselController,
+                )
+            }
+
             Spacer(modifier = Modifier.height(16.dp))
             NotificationStack(
                 viewModel = viewModel.notifications,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
new file mode 100644
index 0000000..90d36e7
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics
+
+import android.graphics.Rect
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_BP
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_OTHER
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
+import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_ENROLLING
+import android.hardware.biometrics.BiometricOverlayConstants.ShowReason
+import android.hardware.fingerprint.IUdfpsOverlayControllerCallback
+import android.testing.TestableLooper.RunWithLooper
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.Surface
+import android.view.Surface.Rotation
+import android.view.View
+import android.view.WindowManager
+import android.view.accessibility.AccessibilityManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
+import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel
+import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
+import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.LockscreenShadeTransitionController
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.systemui.statusbar.phone.SystemUIDialogManager
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import com.android.systemui.util.settings.SecureSettings
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
+
+private const val REQUEST_ID = 2L
+
+// Dimensions for the current display resolution.
+private const val DISPLAY_WIDTH = 1080
+private const val DISPLAY_HEIGHT = 1920
+private const val SENSOR_WIDTH = 30
+private const val SENSOR_HEIGHT = 60
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@RunWithLooper(setAsMainLooper = true)
+class UdfpsControllerOverlayTest : SysuiTestCase() {
+
+    @JvmField @Rule var rule = MockitoJUnit.rule()
+
+    @Mock private lateinit var inflater: LayoutInflater
+    @Mock private lateinit var windowManager: WindowManager
+    @Mock private lateinit var accessibilityManager: AccessibilityManager
+    @Mock private lateinit var statusBarStateController: StatusBarStateController
+    @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var dialogManager: SystemUIDialogManager
+    @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var transitionController: LockscreenShadeTransitionController
+    @Mock private lateinit var configurationController: ConfigurationController
+    @Mock private lateinit var keyguardStateController: KeyguardStateController
+    @Mock
+    private lateinit var unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController
+    @Mock private lateinit var udfpsDisplayMode: UdfpsDisplayModeProvider
+    @Mock private lateinit var secureSettings: SecureSettings
+    @Mock private lateinit var controllerCallback: IUdfpsOverlayControllerCallback
+    @Mock private lateinit var udfpsController: UdfpsController
+    @Mock private lateinit var udfpsView: UdfpsView
+    @Mock private lateinit var mUdfpsKeyguardViewLegacy: UdfpsKeyguardViewLegacy
+    @Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
+    @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
+    @Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
+    @Mock private lateinit var mSelectedUserInteractor: SelectedUserInteractor
+    @Mock
+    private lateinit var deviceEntryUdfpsTouchOverlayViewModel:
+        DeviceEntryUdfpsTouchOverlayViewModel
+    @Mock private lateinit var defaultUdfpsTouchOverlayViewModel: DefaultUdfpsTouchOverlayViewModel
+    @Mock
+    private lateinit var udfpsKeyguardAccessibilityDelegate: UdfpsKeyguardAccessibilityDelegate
+    @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
+    @Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
+
+    private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true }
+    private var overlayParams: UdfpsOverlayParams = UdfpsOverlayParams()
+    private lateinit var controllerOverlay: UdfpsControllerOverlay
+
+    @Before
+    fun setup() {
+        whenever(inflater.inflate(R.layout.udfps_view, null, false)).thenReturn(udfpsView)
+        whenever(inflater.inflate(R.layout.udfps_bp_view, null))
+            .thenReturn(mock(UdfpsBpView::class.java))
+        whenever(inflater.inflate(R.layout.udfps_keyguard_view_legacy, null))
+            .thenReturn(mUdfpsKeyguardViewLegacy)
+        whenever(inflater.inflate(R.layout.udfps_fpm_empty_view, null))
+            .thenReturn(mock(UdfpsFpmEmptyView::class.java))
+    }
+
+    private fun withReason(
+        @ShowReason reason: Int,
+        isDebuggable: Boolean = false,
+        enableDeviceEntryUdfpsRefactor: Boolean = false,
+        block: () -> Unit,
+    ) {
+        if (enableDeviceEntryUdfpsRefactor) {
+            mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
+        } else {
+            mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
+        }
+        controllerOverlay =
+            UdfpsControllerOverlay(
+                context,
+                inflater,
+                windowManager,
+                accessibilityManager,
+                statusBarStateController,
+                statusBarKeyguardViewManager,
+                keyguardUpdateMonitor,
+                dialogManager,
+                dumpManager,
+                transitionController,
+                configurationController,
+                keyguardStateController,
+                unlockedScreenOffAnimationController,
+                udfpsDisplayMode,
+                REQUEST_ID,
+                reason,
+                controllerCallback,
+                onTouch,
+                activityLaunchAnimator,
+                primaryBouncerInteractor,
+                alternateBouncerInteractor,
+                isDebuggable,
+                udfpsKeyguardAccessibilityDelegate,
+                keyguardTransitionInteractor,
+                mSelectedUserInteractor,
+                { deviceEntryUdfpsTouchOverlayViewModel },
+                { defaultUdfpsTouchOverlayViewModel },
+            )
+        block()
+    }
+
+    @Test fun showUdfpsOverlay_bp() = withReason(REASON_AUTH_BP) { showUdfpsOverlay() }
+
+    @Test
+    fun showUdfpsOverlay_keyguard() =
+        withReason(REASON_AUTH_KEYGUARD) {
+            showUdfpsOverlay()
+            verify(mUdfpsKeyguardViewLegacy).updateSensorLocation(eq(overlayParams.sensorBounds))
+        }
+
+    @Test fun showUdfpsOverlay_other() = withReason(REASON_AUTH_OTHER) { showUdfpsOverlay() }
+
+    private fun withRotation(@Rotation rotation: Int, block: () -> Unit) {
+        // Sensor that's in the top left corner of the display in natural orientation.
+        val sensorBounds = Rect(0, 0, SENSOR_WIDTH, SENSOR_HEIGHT)
+        val overlayBounds = Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT)
+        overlayParams =
+            UdfpsOverlayParams(
+                sensorBounds,
+                overlayBounds,
+                DISPLAY_WIDTH,
+                DISPLAY_HEIGHT,
+                scaleFactor = 1f,
+                rotation
+            )
+        block()
+    }
+
+    @Test
+    fun showUdfpsOverlay_withRotation0() =
+        withRotation(Surface.ROTATION_0) {
+            withReason(REASON_AUTH_BP) {
+                controllerOverlay.show(udfpsController, overlayParams)
+                verify(windowManager)
+                    .addView(eq(controllerOverlay.getTouchOverlay()), layoutParamsCaptor.capture())
+
+                // ROTATION_0 is the native orientation. Sensor should stay in the top left corner.
+                val lp = layoutParamsCaptor.value
+                assertThat(lp.x).isEqualTo(0)
+                assertThat(lp.y).isEqualTo(0)
+                assertThat(lp.width).isEqualTo(DISPLAY_WIDTH)
+                assertThat(lp.height).isEqualTo(DISPLAY_HEIGHT)
+            }
+        }
+
+    @Test
+    fun showUdfpsOverlay_withRotation180() =
+        withRotation(Surface.ROTATION_180) {
+            withReason(REASON_AUTH_BP) {
+                controllerOverlay.show(udfpsController, overlayParams)
+                verify(windowManager)
+                    .addView(eq(controllerOverlay.getTouchOverlay()), layoutParamsCaptor.capture())
+
+                // ROTATION_180 is not supported. Sensor should stay in the top left corner.
+                val lp = layoutParamsCaptor.value
+                assertThat(lp.x).isEqualTo(0)
+                assertThat(lp.y).isEqualTo(0)
+                assertThat(lp.width).isEqualTo(DISPLAY_WIDTH)
+                assertThat(lp.height).isEqualTo(DISPLAY_HEIGHT)
+            }
+        }
+
+    @Test
+    fun showUdfpsOverlay_withRotation90() =
+        withRotation(Surface.ROTATION_90) {
+            withReason(REASON_AUTH_BP) {
+                controllerOverlay.show(udfpsController, overlayParams)
+                verify(windowManager)
+                    .addView(eq(controllerOverlay.getTouchOverlay()), layoutParamsCaptor.capture())
+
+                // Sensor should be in the bottom left corner in ROTATION_90.
+                val lp = layoutParamsCaptor.value
+                assertThat(lp.x).isEqualTo(0)
+                assertThat(lp.y).isEqualTo(0)
+                assertThat(lp.width).isEqualTo(DISPLAY_HEIGHT)
+                assertThat(lp.height).isEqualTo(DISPLAY_WIDTH)
+            }
+        }
+
+    @Test
+    fun showUdfpsOverlay_withRotation270() =
+        withRotation(Surface.ROTATION_270) {
+            withReason(REASON_AUTH_BP) {
+                controllerOverlay.show(udfpsController, overlayParams)
+                verify(windowManager)
+                    .addView(eq(controllerOverlay.getTouchOverlay()), layoutParamsCaptor.capture())
+
+                // Sensor should be in the top right corner in ROTATION_270.
+                val lp = layoutParamsCaptor.value
+                assertThat(lp.x).isEqualTo(0)
+                assertThat(lp.y).isEqualTo(0)
+                assertThat(lp.width).isEqualTo(DISPLAY_HEIGHT)
+                assertThat(lp.height).isEqualTo(DISPLAY_WIDTH)
+            }
+        }
+
+    private fun showUdfpsOverlay() {
+        val didShow = controllerOverlay.show(udfpsController, overlayParams)
+
+        verify(windowManager).addView(eq(controllerOverlay.getTouchOverlay()), any())
+        verify(udfpsView).setUdfpsDisplayModeProvider(eq(udfpsDisplayMode))
+        verify(udfpsView).animationViewController = any()
+        verify(udfpsView).addView(any())
+
+        assertThat(didShow).isTrue()
+        assertThat(controllerOverlay.isShowing).isTrue()
+        assertThat(controllerOverlay.isHiding).isFalse()
+        assertThat(controllerOverlay.getTouchOverlay()).isNotNull()
+    }
+
+    @Test fun hideUdfpsOverlay_bp() = withReason(REASON_AUTH_BP) { hideUdfpsOverlay() }
+
+    @Test fun hideUdfpsOverlay_keyguard() = withReason(REASON_AUTH_KEYGUARD) { hideUdfpsOverlay() }
+
+    @Test fun hideUdfpsOverlay_settings() = withReason(REASON_AUTH_SETTINGS) { hideUdfpsOverlay() }
+
+    @Test fun hideUdfpsOverlay_other() = withReason(REASON_AUTH_OTHER) { hideUdfpsOverlay() }
+
+    private fun hideUdfpsOverlay() {
+        val didShow = controllerOverlay.show(udfpsController, overlayParams)
+        val view = controllerOverlay.getTouchOverlay()
+        val didHide = controllerOverlay.hide()
+
+        verify(windowManager).removeView(eq(view))
+
+        assertThat(didShow).isTrue()
+        assertThat(didHide).isTrue()
+        assertThat(controllerOverlay.getTouchOverlay()).isNull()
+        assertThat(controllerOverlay.animationViewController).isNull()
+        assertThat(controllerOverlay.isShowing).isFalse()
+        assertThat(controllerOverlay.isHiding).isTrue()
+    }
+
+    @Test
+    fun canNotHide() = withReason(REASON_AUTH_BP) { assertThat(controllerOverlay.hide()).isFalse() }
+
+    @Test
+    fun canNotReshow() =
+        withReason(REASON_AUTH_BP) {
+            assertThat(controllerOverlay.show(udfpsController, overlayParams)).isTrue()
+            assertThat(controllerOverlay.show(udfpsController, overlayParams)).isFalse()
+        }
+
+    @Test
+    fun cancels() =
+        withReason(REASON_AUTH_BP) {
+            controllerOverlay.cancel()
+            verify(controllerCallback).onUserCanceled()
+        }
+
+    @Test
+    fun unconfigureDisplayOnHide() =
+        withReason(REASON_AUTH_BP) {
+            whenever(udfpsView.isDisplayConfigured).thenReturn(true)
+
+            controllerOverlay.show(udfpsController, overlayParams)
+            controllerOverlay.hide()
+            verify(udfpsView).unconfigureDisplay()
+        }
+
+    @Test
+    fun matchesRequestIds() =
+        withReason(REASON_AUTH_BP) {
+            assertThat(controllerOverlay.matchesRequestId(REQUEST_ID)).isTrue()
+            assertThat(controllerOverlay.matchesRequestId(REQUEST_ID + 1)).isFalse()
+        }
+
+    @Test
+    fun smallOverlayOnEnrollmentWithA11y() =
+        withRotation(Surface.ROTATION_0) {
+            withReason(REASON_ENROLL_ENROLLING) {
+                // When a11y enabled during enrollment
+                whenever(accessibilityManager.isTouchExplorationEnabled).thenReturn(true)
+
+                controllerOverlay.show(udfpsController, overlayParams)
+                verify(windowManager)
+                    .addView(eq(controllerOverlay.getTouchOverlay()), layoutParamsCaptor.capture())
+
+                // Layout params should use sensor bounds
+                val lp = layoutParamsCaptor.value
+                assertThat(lp.width).isEqualTo(overlayParams.sensorBounds.width())
+                assertThat(lp.height).isEqualTo(overlayParams.sensorBounds.height())
+            }
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index e2cab29..97ee526 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -81,6 +81,8 @@
 import com.android.systemui.biometrics.udfps.NormalizedTouchData;
 import com.android.systemui.biometrics.udfps.SinglePointerTouchProcessor;
 import com.android.systemui.biometrics.udfps.TouchProcessorResult;
+import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel;
+import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.dump.DumpManager;
@@ -106,6 +108,8 @@
 import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.util.time.SystemClock;
 
+import dagger.Lazy;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -241,6 +245,10 @@
     private FpsUnlockTracker mFpsUnlockTracker;
     @Mock
     private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
+    @Mock
+    private Lazy<DeviceEntryUdfpsTouchOverlayViewModel> mDeviceEntryUdfpsTouchOverlayViewModel;
+    @Mock
+    private Lazy<DefaultUdfpsTouchOverlayViewModel> mDefaultUdfpsTouchOverlayViewModel;
 
     @Before
     public void setUp() {
@@ -334,7 +342,10 @@
                 mUdfpsKeyguardViewModels,
                 mSelectedUserInteractor,
                 mFpsUnlockTracker,
-                mKeyguardTransitionInteractor
+                mKeyguardTransitionInteractor,
+                mDeviceEntryUdfpsTouchOverlayViewModel,
+                mDefaultUdfpsTouchOverlayViewModel
+
         );
         verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
         mOverlayController = mOverlayCaptor.getValue();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
index 2ea803c..ac16c13 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
@@ -94,6 +95,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR);
         when(mView.getContext()).thenReturn(mResourceContext);
         when(mResourceContext.getString(anyInt())).thenReturn("test string");
         when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
index f0d26b6..0870122 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
@@ -37,6 +37,7 @@
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
@@ -166,6 +167,7 @@
     }
 
     @Test
+    @Ignore("b/287599719")
     fun canShowAlternateBouncerForFingerprint_rearFps() {
         mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
         initializeUnderTest()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 1e80732..83fb17f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -319,10 +319,10 @@
     @Test
     fun imeHiddenEvent_isTriggered() =
         testScope.runTest {
-            val imeHiddenEvent by collectLastValue(underTest.onImeHidden)
+            val imeHiddenEvent by collectLastValue(underTest.onImeHiddenByUser)
             runCurrent()
 
-            underTest.onImeHidden()
+            underTest.onImeHiddenByUser()
             runCurrent()
 
             assertThat(imeHiddenEvent).isNotNull()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
similarity index 82%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
index 63c992b..45c186d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
@@ -23,8 +23,6 @@
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.scene.SceneTestUtils
-import com.android.systemui.scene.shared.model.SceneKey
-import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runTest
@@ -76,18 +74,4 @@
             underTest.onAuthenticateButtonClicked()
             assertThat(animateFailure).isFalse()
         }
-
-    @Test
-    fun onImeVisibilityChanged() =
-        testScope.runTest {
-            sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "")
-            sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "")
-            val onImeHidden by collectLastValue(bouncerInteractor.onImeHidden)
-
-            underTest.onImeVisibilityChanged(true)
-            assertThat(onImeHidden).isNull()
-
-            underTest.onImeVisibilityChanged(false)
-            assertThat(onImeHidden).isNotNull()
-        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
similarity index 65%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index 9b1e958..937c703 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -20,7 +20,9 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
 import com.android.systemui.res.R
 import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
@@ -43,7 +45,11 @@
 
     private val utils = SceneTestUtils(this)
     private val testScope = utils.testScope
-    private val authenticationInteractor = utils.authenticationInteractor()
+    private val authenticationRepository = utils.authenticationRepository
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = authenticationRepository,
+        )
     private val sceneInteractor = utils.sceneInteractor()
     private val bouncerInteractor =
         utils.bouncerInteractor(
@@ -207,6 +213,101 @@
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
         }
 
+    @Test
+    fun onImeVisibilityChanged_false_doesNothing() =
+        testScope.runTest {
+            val events by collectValues(bouncerInteractor.onImeHiddenByUser)
+            assertThat(events).isEmpty()
+
+            underTest.onImeVisibilityChanged(isVisible = false)
+            assertThat(events).isEmpty()
+        }
+
+    @Test
+    fun onImeVisibilityChanged_falseAfterTrue_emitsOnImeHiddenByUserEvent() =
+        testScope.runTest {
+            val events by collectValues(bouncerInteractor.onImeHiddenByUser)
+            assertThat(events).isEmpty()
+
+            underTest.onImeVisibilityChanged(isVisible = true)
+            assertThat(events).isEmpty()
+
+            underTest.onImeVisibilityChanged(isVisible = false)
+            assertThat(events).hasSize(1)
+
+            underTest.onImeVisibilityChanged(isVisible = true)
+            assertThat(events).hasSize(1)
+
+            underTest.onImeVisibilityChanged(isVisible = false)
+            assertThat(events).hasSize(2)
+        }
+
+    @Test
+    fun onImeVisibilityChanged_falseAfterTrue_whileThrottling_doesNothing() =
+        testScope.runTest {
+            val events by collectValues(bouncerInteractor.onImeHiddenByUser)
+            assertThat(events).isEmpty()
+            underTest.onImeVisibilityChanged(isVisible = true)
+            setThrottling(true)
+
+            underTest.onImeVisibilityChanged(isVisible = false)
+
+            assertThat(events).isEmpty()
+        }
+
+    @Test
+    fun isTextFieldFocusRequested_initiallyTrue() =
+        testScope.runTest {
+            val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+            assertThat(isTextFieldFocusRequested).isTrue()
+        }
+
+    @Test
+    fun isTextFieldFocusRequested_focusGained_becomesFalse() =
+        testScope.runTest {
+            val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+
+            underTest.onTextFieldFocusChanged(isFocused = true)
+
+            assertThat(isTextFieldFocusRequested).isFalse()
+        }
+
+    @Test
+    fun isTextFieldFocusRequested_focusLost_becomesTrue() =
+        testScope.runTest {
+            val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+            underTest.onTextFieldFocusChanged(isFocused = true)
+
+            underTest.onTextFieldFocusChanged(isFocused = false)
+
+            assertThat(isTextFieldFocusRequested).isTrue()
+        }
+
+    @Test
+    fun isTextFieldFocusRequested_focusLostWhileThrottling_staysFalse() =
+        testScope.runTest {
+            val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+            underTest.onTextFieldFocusChanged(isFocused = true)
+            setThrottling(true)
+
+            underTest.onTextFieldFocusChanged(isFocused = false)
+
+            assertThat(isTextFieldFocusRequested).isFalse()
+        }
+
+    @Test
+    fun isTextFieldFocusRequested_throttlingCountdownEnds_becomesTrue() =
+        testScope.runTest {
+            val isTextFieldFocusRequested by collectLastValue(underTest.isTextFieldFocusRequested)
+            underTest.onTextFieldFocusChanged(isFocused = true)
+            setThrottling(true)
+            underTest.onTextFieldFocusChanged(isFocused = false)
+
+            setThrottling(false)
+
+            assertThat(isTextFieldFocusRequested).isTrue()
+        }
+
     private fun TestScope.switchToScene(toScene: SceneKey) {
         val currentScene by collectLastValue(sceneInteractor.desiredScene)
         val bouncerShown = currentScene?.key != SceneKey.Bouncer && toScene == SceneKey.Bouncer
@@ -226,6 +327,35 @@
         switchToScene(SceneKey.Bouncer)
     }
 
+    private suspend fun TestScope.setThrottling(
+        isThrottling: Boolean,
+        failedAttemptCount: Int = 5,
+    ) {
+        if (isThrottling) {
+            repeat(failedAttemptCount) {
+                authenticationRepository.reportAuthenticationAttempt(false)
+            }
+            val remainingTimeMs = 30_000
+            authenticationRepository.setThrottleDuration(remainingTimeMs)
+            authenticationRepository.setThrottling(
+                AuthenticationThrottlingModel(
+                    failedAttemptCount = failedAttemptCount,
+                    remainingMs = remainingTimeMs,
+                )
+            )
+        } else {
+            authenticationRepository.reportAuthenticationAttempt(true)
+            authenticationRepository.setThrottling(
+                AuthenticationThrottlingModel(
+                    failedAttemptCount = failedAttemptCount,
+                    remainingMs = 0,
+                )
+            )
+        }
+
+        runCurrent()
+    }
+
     companion object {
         private const val ENTER_YOUR_PASSWORD = "Enter your password"
         private const val WRONG_PASSWORD = "Wrong password"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinInputViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
similarity index 97%
rename from packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index 0004f52..910097e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
 import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository
 import com.android.systemui.keyguard.data.repository.FakeTrustRepository
@@ -56,6 +57,13 @@
         )
 
     @Test
+    fun canSwipeToEnter_startsNull() =
+        testScope.runTest {
+            val values by collectValues(underTest.canSwipeToEnter)
+            assertThat(values[0]).isNull()
+        }
+
+    @Test
     fun isUnlocked_whenAuthMethodIsNoneAndLockscreenDisabled_isTrue() =
         testScope.runTest {
             utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dock/DockManagerFake.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dock/DockManagerFake.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dump/LogBufferHelper.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/dump/LogBufferHelper.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
similarity index 75%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
index 02db0d7..a613ad8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
@@ -29,17 +29,16 @@
 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.coroutines.collectLastValue
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.wallet.controller.QuickAccessWalletController
 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.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestDispatcher
+import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -48,7 +47,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
@@ -56,26 +54,32 @@
     @Mock private lateinit var walletController: QuickAccessWalletController
     @Mock private lateinit var activityStarter: ActivityStarter
 
+    private lateinit var testDispatcher: TestDispatcher
+    private lateinit var testScope: TestScope
+
     private lateinit var underTest: QuickAccessWalletKeyguardQuickAffordanceConfig
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
+        testDispatcher = StandardTestDispatcher()
+        testScope = TestScope(testDispatcher)
+
         underTest =
             QuickAccessWalletKeyguardQuickAffordanceConfig(
                 context,
+                testDispatcher,
                 walletController,
                 activityStarter,
             )
     }
 
     @Test
-    fun affordance_keyguardShowing_hasWalletCard_visibleModel() = runBlockingTest {
+    fun affordance_keyguardShowing_hasWalletCard_visibleModel() = testScope.runTest {
         setUpState()
-        var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
 
-        val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+        val latest by collectLastValue(underTest.lockScreenState)
 
         val visibleModel = latest as KeyguardQuickAffordanceConfig.LockScreenState.Visible
         assertThat(visibleModel.icon)
@@ -88,77 +92,61 @@
                         ),
                 )
             )
-        job.cancel()
     }
 
     @Test
-    fun affordance_keyguardShowing_hasNonPaymentCard_modelIsNone() =
-        runTest(UnconfinedTestDispatcher()) {
+    fun affordance_keyguardShowing_hasNonPaymentCard_modelIsNone() = testScope.runTest {
             setUpState(cardType = WalletCard.CARD_TYPE_NON_PAYMENT)
-            var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
 
-            val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+            val latest by collectLastValue(underTest.lockScreenState)
 
             assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
-            job.cancel()
         }
 
     @Test
-    fun affordance_keyguardShowing_hasPaymentCard_visibleModel() =
-        runTest(UnconfinedTestDispatcher()) {
-            setUpState(cardType = WalletCard.CARD_TYPE_PAYMENT)
-            var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+    fun affordance_keyguardShowing_hasPaymentCard_visibleModel() = testScope.runTest {
+        setUpState(cardType = WalletCard.CARD_TYPE_PAYMENT)
 
-            val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+        val latest by collectLastValue(underTest.lockScreenState)
 
-            val visibleModel = latest as KeyguardQuickAffordanceConfig.LockScreenState.Visible
-            assertThat(visibleModel.icon)
-                .isEqualTo(
-                    Icon.Loaded(
-                        drawable = ICON,
-                        contentDescription =
-                            ContentDescription.Resource(
-                                res = R.string.accessibility_wallet_button,
-                            ),
-                    )
+        val visibleModel = latest as KeyguardQuickAffordanceConfig.LockScreenState.Visible
+        assertThat(visibleModel.icon)
+            .isEqualTo(
+                Icon.Loaded(
+                    drawable = ICON,
+                    contentDescription =
+                        ContentDescription.Resource(
+                            res = R.string.accessibility_wallet_button,
+                        ),
                 )
-            job.cancel()
-        }
+            )
+    }
 
     @Test
-    fun affordance_walletFeatureNotEnabled_modelIsNone() = runBlockingTest {
+    fun affordance_walletFeatureNotEnabled_modelIsNone() = testScope.runTest {
         setUpState(isWalletFeatureAvailable = false)
-        var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
 
-        val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+        val latest by collectLastValue(underTest.lockScreenState)
 
         assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
-
-        job.cancel()
     }
 
     @Test
-    fun affordance_queryNotSuccessful_modelIsNone() = runBlockingTest {
+    fun affordance_queryNotSuccessful_modelIsNone() = testScope.runTest {
         setUpState(isWalletQuerySuccessful = false)
-        var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
 
-        val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+        val latest by collectLastValue(underTest.lockScreenState)
 
         assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
-
-        job.cancel()
     }
 
     @Test
-    fun affordance_noSelectedCard_modelIsNone() = runBlockingTest {
+    fun affordance_noSelectedCard_modelIsNone() = testScope.runTest {
         setUpState(hasSelectedCard = false)
-        var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
 
-        val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+        val latest by collectLastValue(underTest.lockScreenState)
 
         assertThat(latest).isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
-
-        job.cancel()
     }
 
     @Test
@@ -179,7 +167,7 @@
     }
 
     @Test
-    fun getPickerScreenState_default() = runTest {
+    fun getPickerScreenState_default() = testScope.runTest {
         setUpState()
 
         assertThat(underTest.getPickerScreenState())
@@ -187,7 +175,7 @@
     }
 
     @Test
-    fun getPickerScreenState_unavailable() = runTest {
+    fun getPickerScreenState_unavailable() = testScope.runTest {
         setUpState(
             isWalletServiceAvailable = false,
         )
@@ -197,7 +185,7 @@
     }
 
     @Test
-    fun getPickerScreenState_disabledWhenTheFeatureIsNotEnabled() = runTest {
+    fun getPickerScreenState_disabledWhenTheFeatureIsNotEnabled() = testScope.runTest {
         setUpState(
             isWalletFeatureAvailable = false,
         )
@@ -207,7 +195,7 @@
     }
 
     @Test
-    fun getPickerScreenState_disabledWhenThereIsNoCard() = runTest {
+    fun getPickerScreenState_disabledWhenThereIsNoCard() = testScope.runTest {
         setUpState(
             hasSelectedCard = false,
         )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileDataInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplate/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
new file mode 100644
index 0000000..cf076c5
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.custom.data.repository
+
+import android.content.ComponentName
+import android.graphics.drawable.Icon
+import android.os.UserHandle
+import android.service.quicksettings.Tile
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.qs.external.FakeCustomTileStatePersister
+import com.android.systemui.qs.external.TileServiceKey
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat
+import com.android.systemui.qs.tiles.impl.custom.commons.copy
+import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalCoroutinesApi::class)
+class CustomTileRepositoryTest : SysuiTestCase() {
+
+    private val testScope = TestScope()
+
+    private val persister = FakeCustomTileStatePersister()
+
+    private val underTest: CustomTileRepository =
+        CustomTileRepositoryImpl(
+            TileSpec.create(TEST_COMPONENT),
+            persister,
+            testScope.testScheduler,
+        )
+
+    @Test
+    fun persistableTileIsRestoredForUser() =
+        testScope.runTest {
+            persister.persistState(TEST_TILE_KEY_1, TEST_TILE_1)
+            persister.persistState(TEST_TILE_KEY_2, TEST_TILE_2)
+
+            underTest.restoreForTheUserIfNeeded(TEST_USER_1, true)
+            runCurrent()
+
+            assertThat(underTest.getTile(TEST_USER_1)).isEqualTo(TEST_TILE_1)
+            assertThat(underTest.getTiles(TEST_USER_1).first()).isEqualTo(TEST_TILE_1)
+        }
+
+    @Test
+    fun notPersistableTileIsNotRestored() =
+        testScope.runTest {
+            persister.persistState(TEST_TILE_KEY_1, TEST_TILE_1)
+            val tiles = collectValues(underTest.getTiles(TEST_USER_1))
+
+            underTest.restoreForTheUserIfNeeded(TEST_USER_1, false)
+            runCurrent()
+
+            assertThat(tiles()).isEmpty()
+        }
+
+    @Test
+    fun emptyPersistedStateIsHandled() =
+        testScope.runTest {
+            val tiles = collectValues(underTest.getTiles(TEST_USER_1))
+
+            underTest.restoreForTheUserIfNeeded(TEST_USER_1, true)
+            runCurrent()
+
+            assertThat(tiles()).isEmpty()
+        }
+
+    @Test
+    fun updatingWithPersistableTilePersists() =
+        testScope.runTest {
+            underTest.updateWithTile(TEST_USER_1, TEST_TILE_1, true)
+            runCurrent()
+
+            assertThat(persister.readState(TEST_TILE_KEY_1)).isEqualTo(TEST_TILE_1)
+        }
+
+    @Test
+    fun updatingWithNotPersistableTileDoesntPersist() =
+        testScope.runTest {
+            underTest.updateWithTile(TEST_USER_1, TEST_TILE_1, false)
+            runCurrent()
+
+            assertThat(persister.readState(TEST_TILE_KEY_1)).isNull()
+        }
+
+    @Test
+    fun updateWithTileEmits() =
+        testScope.runTest {
+            underTest.updateWithTile(TEST_USER_1, TEST_TILE_1, true)
+            runCurrent()
+
+            assertThat(underTest.getTiles(TEST_USER_1).first()).isEqualTo(TEST_TILE_1)
+            assertThat(underTest.getTile(TEST_USER_1)).isEqualTo(TEST_TILE_1)
+        }
+
+    @Test
+    fun updatingPeristableWithDefaultsPersists() =
+        testScope.runTest {
+            underTest.updateWithDefaults(TEST_USER_1, TEST_DEFAULTS_1, true)
+            runCurrent()
+
+            assertThat(persister.readState(TEST_TILE_KEY_1)).isEqualTo(TEST_TILE_1)
+        }
+
+    @Test
+    fun updatingNotPersistableWithDefaultsDoesntPersist() =
+        testScope.runTest {
+            underTest.updateWithDefaults(TEST_USER_1, TEST_DEFAULTS_1, false)
+            runCurrent()
+
+            assertThat(persister.readState(TEST_TILE_KEY_1)).isNull()
+        }
+
+    @Test
+    fun updatingPeristableWithErrorDefaultsDoesntPersist() =
+        testScope.runTest {
+            underTest.updateWithDefaults(TEST_USER_1, CustomTileDefaults.Error, true)
+            runCurrent()
+
+            assertThat(persister.readState(TEST_TILE_KEY_1)).isNull()
+        }
+
+    @Test
+    fun updateWithDefaultsEmits() =
+        testScope.runTest {
+            underTest.updateWithDefaults(TEST_USER_1, TEST_DEFAULTS_1, true)
+            runCurrent()
+
+            assertThat(underTest.getTiles(TEST_USER_1).first()).isEqualTo(TEST_TILE_1)
+            assertThat(underTest.getTile(TEST_USER_1)).isEqualTo(TEST_TILE_1)
+        }
+
+    @Test
+    fun getTileForAnotherUserReturnsNull() =
+        testScope.runTest {
+            underTest.updateWithTile(TEST_USER_1, TEST_TILE_1, true)
+            runCurrent()
+
+            assertThat(underTest.getTile(TEST_USER_2)).isNull()
+        }
+
+    @Test
+    fun getTilesForAnotherUserEmpty() =
+        testScope.runTest {
+            val tiles = collectValues(underTest.getTiles(TEST_USER_2))
+
+            underTest.updateWithTile(TEST_USER_1, TEST_TILE_1, true)
+            runCurrent()
+
+            assertThat(tiles()).isEmpty()
+        }
+
+    @Test
+    fun updatingWithTileForTheSameUserAddsData() =
+        testScope.runTest {
+            underTest.updateWithTile(TEST_USER_1, TEST_TILE_1, true)
+            runCurrent()
+
+            underTest.updateWithTile(TEST_USER_1, Tile().apply { subtitle = "test_subtitle" }, true)
+            runCurrent()
+
+            val expectedTile = TEST_TILE_1.copy().apply { subtitle = "test_subtitle" }
+            assertThat(underTest.getTile(TEST_USER_1)).isEqualTo(expectedTile)
+            assertThat(underTest.getTiles(TEST_USER_1).first()).isEqualTo(expectedTile)
+        }
+
+    @Test
+    fun updatingWithTileForAnotherUserOverridesTile() =
+        testScope.runTest {
+            underTest.updateWithTile(TEST_USER_1, TEST_TILE_1, true)
+            runCurrent()
+
+            val tiles = collectValues(underTest.getTiles(TEST_USER_2))
+            underTest.updateWithTile(TEST_USER_2, TEST_TILE_2, true)
+            runCurrent()
+
+            assertThat(underTest.getTile(TEST_USER_2)).isEqualTo(TEST_TILE_2)
+            assertThat(tiles()).hasSize(1)
+            assertThat(tiles().last()).isEqualTo(TEST_TILE_2)
+        }
+
+    @Test
+    fun updatingWithDefaultsForTheSameUserAddsData() =
+        testScope.runTest {
+            underTest.updateWithTile(TEST_USER_1, Tile().apply { subtitle = "test_subtitle" }, true)
+            runCurrent()
+
+            underTest.updateWithDefaults(TEST_USER_1, TEST_DEFAULTS_1, true)
+            runCurrent()
+
+            val expectedTile = TEST_TILE_1.copy().apply { subtitle = "test_subtitle" }
+            assertThat(underTest.getTile(TEST_USER_1)).isEqualTo(expectedTile)
+            assertThat(underTest.getTiles(TEST_USER_1).first()).isEqualTo(expectedTile)
+        }
+
+    @Test
+    fun updatingWithDefaultsForAnotherUserOverridesTile() =
+        testScope.runTest {
+            underTest.updateWithDefaults(TEST_USER_1, TEST_DEFAULTS_1, true)
+            runCurrent()
+
+            val tiles = collectValues(underTest.getTiles(TEST_USER_2))
+            underTest.updateWithDefaults(TEST_USER_2, TEST_DEFAULTS_2, true)
+            runCurrent()
+
+            assertThat(underTest.getTile(TEST_USER_2)).isEqualTo(TEST_TILE_2)
+            assertThat(tiles()).hasSize(1)
+            assertThat(tiles().last()).isEqualTo(TEST_TILE_2)
+        }
+
+    private companion object {
+
+        val TEST_COMPONENT = ComponentName("test.pkg", "test.cls")
+
+        val TEST_USER_1 = UserHandle.of(1)!!
+        val TEST_TILE_1 =
+            Tile().apply {
+                label = "test_tile_1"
+                icon = Icon.createWithContentUri("file://test_1")
+            }
+        val TEST_TILE_KEY_1 = TileServiceKey(TEST_COMPONENT, TEST_USER_1.identifier)
+        val TEST_DEFAULTS_1 = CustomTileDefaults.Result(TEST_TILE_1.icon, TEST_TILE_1.label)
+
+        val TEST_USER_2 = UserHandle.of(2)!!
+        val TEST_TILE_2 =
+            Tile().apply {
+                label = "test_tile_2"
+                icon = Icon.createWithContentUri("file://test_2")
+            }
+        val TEST_TILE_KEY_2 = TileServiceKey(TEST_COMPONENT, TEST_USER_2.identifier)
+        val TEST_DEFAULTS_2 = CustomTileDefaults.Result(TEST_TILE_2.icon, TEST_TILE_2.label)
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
new file mode 100644
index 0000000..eebb145
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.custom.domain.interactor
+
+import android.content.ComponentName
+import android.graphics.drawable.Icon
+import android.os.UserHandle
+import android.service.quicksettings.Tile
+import android.text.format.DateUtils
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.qs.external.FakeCustomTileStatePersister
+import com.android.systemui.qs.external.TileServiceKey
+import com.android.systemui.qs.external.TileServiceManager
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat
+import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTileDefaultsRepository
+import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTileRepository
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalCoroutinesApi::class)
+class CustomTileInteractorTest : SysuiTestCase() {
+
+    @Mock private lateinit var tileServiceManager: TileServiceManager
+
+    private val testScope = TestScope()
+
+    private val defaultsRepository = FakeCustomTileDefaultsRepository()
+    private val customTileStatePersister = FakeCustomTileStatePersister()
+    private val customTileRepository =
+        FakeCustomTileRepository(
+            TEST_TILE_SPEC,
+            customTileStatePersister,
+            testScope.testScheduler,
+        )
+
+    private lateinit var underTest: CustomTileInteractor
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        underTest =
+            CustomTileInteractor(
+                TEST_USER,
+                defaultsRepository,
+                customTileRepository,
+                tileServiceManager,
+                testScope.backgroundScope,
+                testScope.testScheduler,
+            )
+    }
+
+    @Test
+    fun activeTileIsAvailableAfterRestored() =
+        testScope.runTest {
+            whenever(tileServiceManager.isActiveTile).thenReturn(true)
+            customTileStatePersister.persistState(
+                TileServiceKey(TEST_COMPONENT, TEST_USER.identifier),
+                TEST_TILE,
+            )
+
+            underTest.init()
+
+            assertThat(underTest.tile).isEqualTo(TEST_TILE)
+            assertThat(underTest.tiles.first()).isEqualTo(TEST_TILE)
+        }
+
+    @Test
+    fun notActiveTileIsAvailableAfterUpdated() =
+        testScope.runTest {
+            whenever(tileServiceManager.isActiveTile).thenReturn(false)
+            customTileStatePersister.persistState(
+                TileServiceKey(TEST_COMPONENT, TEST_USER.identifier),
+                TEST_TILE,
+            )
+            val tiles = collectValues(underTest.tiles)
+            val initJob = launch { underTest.init() }
+
+            underTest.updateTile(TEST_TILE)
+            runCurrent()
+            initJob.join()
+
+            assertThat(tiles()).hasSize(1)
+            assertThat(tiles().last()).isEqualTo(TEST_TILE)
+        }
+
+    @Test
+    fun notActiveTileIsAvailableAfterDefaultsUpdated() =
+        testScope.runTest {
+            whenever(tileServiceManager.isActiveTile).thenReturn(false)
+            customTileStatePersister.persistState(
+                TileServiceKey(TEST_COMPONENT, TEST_USER.identifier),
+                TEST_TILE,
+            )
+            val tiles = collectValues(underTest.tiles)
+            val initJob = launch { underTest.init() }
+
+            defaultsRepository.putDefaults(TEST_USER, TEST_COMPONENT, TEST_DEFAULTS)
+            defaultsRepository.requestNewDefaults(TEST_USER, TEST_COMPONENT)
+            runCurrent()
+            initJob.join()
+
+            assertThat(tiles()).hasSize(1)
+            assertThat(tiles().last()).isEqualTo(TEST_TILE)
+        }
+
+    @Test(expected = IllegalStateException::class)
+    fun getTileBeforeInitThrows() = testScope.runTest { underTest.tile }
+
+    @Test
+    fun initSuspendsForActiveTileNotRestoredAndNotUpdated() =
+        testScope.runTest {
+            whenever(tileServiceManager.isActiveTile).thenReturn(true)
+            val tiles = collectValues(underTest.tiles)
+
+            val initJob = backgroundScope.launch { underTest.init() }
+            advanceTimeBy(1 * DateUtils.DAY_IN_MILLIS)
+
+            // Is still suspended
+            assertThat(initJob.isActive).isTrue()
+            assertThat(tiles()).isEmpty()
+        }
+
+    @Test
+    fun initSuspendedForNotActiveTileWithoutUpdates() =
+        testScope.runTest {
+            whenever(tileServiceManager.isActiveTile).thenReturn(false)
+            customTileStatePersister.persistState(
+                TileServiceKey(TEST_COMPONENT, TEST_USER.identifier),
+                TEST_TILE,
+            )
+            val tiles = collectValues(underTest.tiles)
+
+            val initJob = backgroundScope.launch { underTest.init() }
+            advanceTimeBy(1 * DateUtils.DAY_IN_MILLIS)
+
+            // Is still suspended
+            assertThat(initJob.isActive).isTrue()
+            assertThat(tiles()).isEmpty()
+        }
+
+    private companion object {
+
+        val TEST_COMPONENT = ComponentName("test.pkg", "test.cls")
+        val TEST_TILE_SPEC = TileSpec.create(TEST_COMPONENT)
+        val TEST_USER = UserHandle.of(1)!!
+        val TEST_TILE =
+            Tile().apply {
+                label = "test_tile_1"
+                icon = Icon.createWithContentUri("file://test_1")
+            }
+        val TEST_DEFAULTS = CustomTileDefaults.Result(TEST_TILE.icon, TEST_TILE.label)
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt
index fab290d..7b2ac90 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.qs.tiles.impl.flashlight.domain
 
-import android.graphics.drawable.Drawable
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -26,7 +25,6 @@
 import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
 import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
-import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertEquals
 import org.junit.Test
@@ -37,7 +35,7 @@
 class FlashlightMapperTest : SysuiTestCase() {
     private val kosmos = Kosmos()
     private val qsTileConfig = kosmos.qsFlashlightTileConfig
-    private val mapper by lazy { FlashlightMapper(context) }
+    private val mapper by lazy { FlashlightMapper(context.orCreateTestableResources.resources) }
 
     @Test
     fun mapsDisabledDataToInactiveState() {
@@ -58,12 +56,7 @@
 
     @Test
     fun mapsEnabledDataToOnIconState() {
-        val fakeDrawable = mock<Drawable>()
-        context.orCreateTestableResources.addOverride(
-            R.drawable.qs_flashlight_icon_on,
-            fakeDrawable
-        )
-        val expectedIcon = Icon.Loaded(fakeDrawable, null)
+        val expectedIcon = Icon.Resource(R.drawable.qs_flashlight_icon_on, null)
 
         val tileState: QSTileState = mapper.map(qsTileConfig, FlashlightTileModel(true))
 
@@ -73,12 +66,7 @@
 
     @Test
     fun mapsDisabledDataToOffIconState() {
-        val fakeDrawable = mock<Drawable>()
-        context.orCreateTestableResources.addOverride(
-            R.drawable.qs_flashlight_icon_off,
-            fakeDrawable
-        )
-        val expectedIcon = Icon.Loaded(fakeDrawable, null)
+        val expectedIcon = Icon.Resource(R.drawable.qs_flashlight_icon_off, null)
 
         val tileState: QSTileState = mapper.map(qsTileConfig, FlashlightTileModel(false))
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt
index 820c056..8791877 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.qs.tiles.impl.location.domain
 
-import android.graphics.drawable.Drawable
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -26,7 +25,6 @@
 import com.android.systemui.qs.tiles.impl.location.qsLocationTileConfig
 import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
-import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth
 import junit.framework.Assert
 import org.junit.Test
@@ -37,7 +35,8 @@
 class LocationTileMapperTest : SysuiTestCase() {
     private val kosmos = Kosmos()
     private val qsTileConfig = kosmos.qsLocationTileConfig
-    private val mapper by lazy { LocationTileMapper(context) }
+
+    private val mapper by lazy { LocationTileMapper(context.orCreateTestableResources.resources) }
 
     @Test
     fun mapsDisabledDataToInactiveState() {
@@ -57,9 +56,7 @@
 
     @Test
     fun mapsEnabledDataToOnIconState() {
-        val fakeDrawable = mock<Drawable>()
-        context.orCreateTestableResources.addOverride(R.drawable.qs_location_icon_on, fakeDrawable)
-        val expectedIcon = Icon.Loaded(fakeDrawable, null)
+        val expectedIcon = Icon.Resource(R.drawable.qs_location_icon_on, null)
 
         val tileState: QSTileState = mapper.map(qsTileConfig, LocationTileModel(true))
 
@@ -69,9 +66,7 @@
 
     @Test
     fun mapsDisabledDataToOffIconState() {
-        val fakeDrawable = mock<Drawable>()
-        context.orCreateTestableResources.addOverride(R.drawable.qs_location_icon_off, fakeDrawable)
-        val expectedIcon = Icon.Loaded(fakeDrawable, null)
+        val expectedIcon = Icon.Resource(R.drawable.qs_location_icon_off, null)
 
         val tileState: QSTileState = mapper.map(qsTileConfig, LocationTileModel(false))
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
similarity index 97%
rename from packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index c3294ff..9a748b9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -30,12 +30,15 @@
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.bouncer.domain.interactor.BouncerActionButtonInteractor
 import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
+import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
 import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
 import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
 import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.media.controls.pipeline.MediaDataManager
+import com.android.systemui.media.controls.ui.MediaHost
 import com.android.systemui.model.SysUiState
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
@@ -61,7 +64,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import junit.framework.Assert.assertTrue
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -188,6 +190,9 @@
 
     private val qsFlexiglassAdapter = FakeQSSceneAdapter(inflateDelegate = { _, _ -> mock<View>() })
 
+    @Mock private lateinit var mediaDataManager: MediaDataManager
+    @Mock private lateinit var mediaHost: MediaHost
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
@@ -240,6 +245,8 @@
                 shadeHeaderViewModel = shadeHeaderViewModel,
                 qsSceneAdapter = qsFlexiglassAdapter,
                 notifications = utils.notificationsPlaceholderViewModel(),
+                mediaDataManager = mediaDataManager,
+                mediaHost = mediaHost,
             )
 
         utils.deviceEntryRepository.setUnlocked(false)
@@ -273,6 +280,9 @@
     }
 
     @Test
+    fun startsInLockscreenScene() = testScope.runTest { assertCurrentScene(SceneKey.Lockscreen) }
+
+    @Test
     fun clickLockButtonAndEnterCorrectPin_unlocksDevice() =
         testScope.runTest {
             emulateUserDrivenTransition(SceneKey.Bouncer)
@@ -336,7 +346,7 @@
         testScope.runTest {
             val upDestinationSceneKey by collectLastValue(shadeSceneViewModel.upDestinationSceneKey)
             setAuthMethod(AuthenticationMethodModel.None, enableLockscreen = true)
-            assertTrue(deviceEntryInteractor.canSwipeToEnter.value)
+            assertThat(deviceEntryInteractor.canSwipeToEnter.value).isTrue()
             assertCurrentScene(SceneKey.Lockscreen)
 
             // Emulate a user swipe to dismiss the lockscreen.
@@ -775,11 +785,11 @@
     private suspend fun TestScope.dismissIme(
         showImeBeforeDismissing: Boolean = true,
     ) {
-        bouncerViewModel.authMethodViewModel.value?.apply {
+        (bouncerViewModel.authMethodViewModel.value as? PasswordBouncerViewModel)?.let {
             if (showImeBeforeDismissing) {
-                onImeVisibilityChanged(true)
+                it.onImeVisibilityChanged(true)
             }
-            onImeVisibilityChanged(false)
+            it.onImeVisibilityChanged(false)
             runCurrent()
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/WindowRootViewVisibilityRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index c4ec56c..3cb97e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -145,6 +145,18 @@
         }
 
     @Test
+    fun startsInLockscreenScene() =
+        testScope.runTest {
+            val currentSceneKey by collectLastValue(sceneInteractor.desiredScene.map { it.key })
+            prepareState()
+
+            underTest.start()
+            runCurrent()
+
+            assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+        }
+
+    @Test
     fun switchToLockscreenWhenDeviceLocks() =
         testScope.runTest {
             val currentSceneKey by collectLastValue(sceneInteractor.desiredScene.map { it.key })
@@ -467,7 +479,7 @@
             underTest.start()
             runCurrent()
 
-            bouncerInteractor.onImeHidden()
+            bouncerInteractor.onImeHiddenByUser()
             runCurrent()
 
             assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
similarity index 88%
rename from packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index e2640af..a2946cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -23,6 +23,8 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.Flags
+import com.android.systemui.media.controls.pipeline.MediaDataManager
+import com.android.systemui.media.controls.ui.MediaHost
 import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
 import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
@@ -35,6 +37,7 @@
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
 import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
@@ -42,6 +45,8 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
@@ -83,8 +88,12 @@
 
     private lateinit var underTest: ShadeSceneViewModel
 
+    @Mock private lateinit var mediaDataManager: MediaDataManager
+    @Mock private lateinit var mediaHost: MediaHost
+
     @Before
     fun setUp() {
+        MockitoAnnotations.initMocks(this)
         shadeHeaderViewModel =
             ShadeHeaderViewModel(
                 applicationScope = testScope.backgroundScope,
@@ -102,6 +111,8 @@
                 shadeHeaderViewModel = shadeHeaderViewModel,
                 qsSceneAdapter = qsFlexiglassAdapter,
                 notifications = utils.notificationsPlaceholderViewModel(),
+                mediaDataManager = mediaDataManager,
+                mediaHost = mediaHost,
             )
     }
 
@@ -174,4 +185,20 @@
 
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
         }
+
+    @Test
+    fun hasActiveMedia_mediaVisible() =
+        testScope.runTest {
+            whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true)
+
+            assertThat(underTest.isMediaVisible()).isTrue()
+        }
+
+    @Test
+    fun doesNotHaveActiveMedia_mediaNotVisible() =
+        testScope.runTest {
+            whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(false)
+
+            assertThat(underTest.isMediaVisible()).isFalse()
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
diff --git a/packages/SystemUI/res/drawable/notification_material_bg.xml b/packages/SystemUI/res/drawable/notification_material_bg.xml
index 9c08f5e..355e75d 100644
--- a/packages/SystemUI/res/drawable/notification_material_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_material_bg.xml
@@ -18,7 +18,7 @@
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         android:color="?android:attr/colorControlHighlight">
-    <item android:id="@+id/notification_background_color_layer">
+    <item>
         <shape>
             <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
         </shape>
diff --git a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
index af29cad..50241cd 100644
--- a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
+++ b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
@@ -111,107 +111,57 @@
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintTop_toBottomOf="@+id/bluetooth_toggle"
-                app:layout_constraintBottom_toTopOf="@+id/see_all_text" />
+                app:layout_constraintBottom_toTopOf="@+id/see_all_button" />
 
-            <androidx.constraintlayout.widget.Group
-                android:id="@+id/see_all_layout_group"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                app:constraint_referenced_ids="ic_arrow,see_all_text" />
-
-            <View
-                android:id="@+id/see_all_clickable_row"
+            <Button
+                android:id="@+id/see_all_button"
+                style="@style/BluetoothTileDialog.Device"
+                android:paddingEnd="0dp"
+                android:paddingStart="20dp"
+                android:background="@drawable/bluetooth_tile_dialog_bg_off"
                 android:layout_width="0dp"
-                android:layout_height="0dp"
+                android:layout_height="64dp"
                 android:contentDescription="@string/accessibility_bluetooth_device_settings_see_all"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintTop_toBottomOf="@+id/device_list"
-                app:layout_constraintBottom_toTopOf="@+id/pair_new_device_text" />
-
-            <ImageView
-                android:id="@+id/ic_arrow"
-                android:layout_marginStart="36dp"
-                android:layout_width="24dp"
-                android:layout_height="24dp"
-                android:importantForAccessibility="no"
-                android:gravity="center_vertical"
-                android:src="@drawable/ic_arrow_forward"
-                app:layout_constraintBottom_toTopOf="@+id/pair_new_device_text"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toStartOf="@id/see_all_text"
-                app:layout_constraintTop_toBottomOf="@id/device_list" />
-
-            <TextView
-                android:id="@+id/see_all_text"
-                style="@style/BluetoothTileDialog.Device"
-                android:layout_width="0dp"
-                android:layout_height="64dp"
-                android:maxLines="1"
-                android:ellipsize="end"
-                android:gravity="center_vertical"
-                android:importantForAccessibility="no"
-                android:clickable="false"
-                android:layout_marginStart="0dp"
-                android:paddingStart="20dp"
+                app:layout_constraintBottom_toTopOf="@+id/pair_new_device_button"
+                android:drawableStart="@drawable/ic_arrow_forward"
+                android:drawablePadding="20dp"
+                android:drawableTint="?android:attr/textColorPrimary"
                 android:text="@string/see_all_bluetooth_devices"
                 android:textSize="14sp"
                 android:textAppearance="@style/TextAppearance.Dialog.Title"
-                app:layout_constraintBottom_toTopOf="@+id/pair_new_device_text"
-                app:layout_constraintStart_toEndOf="@+id/ic_arrow"
-                app:layout_constraintTop_toBottomOf="@id/device_list"
-                app:layout_constraintEnd_toEndOf="parent" />
+                android:textDirection="locale"
+                android:textAlignment="viewStart"
+                android:maxLines="1"
+                android:ellipsize="end"
+                android:visibility="gone" />
 
-            <androidx.constraintlayout.widget.Group
-                android:id="@+id/pair_new_device_layout_group"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                app:constraint_referenced_ids="ic_add,pair_new_device_text" />
-
-            <View
-                android:id="@+id/pair_new_device_clickable_row"
+            <Button
+                android:id="@+id/pair_new_device_button"
+                style="@style/BluetoothTileDialog.Device"
+                android:paddingEnd="0dp"
+                android:paddingStart="20dp"
+                android:background="@drawable/bluetooth_tile_dialog_bg_off"
                 android:layout_width="0dp"
-                android:layout_height="0dp"
+                android:layout_height="64dp"
                 android:contentDescription="@string/accessibility_bluetooth_device_settings_pair_new_device"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintTop_toBottomOf="@+id/see_all_text"
-                app:layout_constraintBottom_toTopOf="@+id/done_button" />
-
-            <ImageView
-                android:id="@+id/ic_add"
-                android:layout_width="24dp"
-                android:layout_height="24dp"
-                android:layout_marginStart="36dp"
-                android:gravity="center_vertical"
-                android:importantForAccessibility="no"
-                android:src="@drawable/ic_add"
-                app:layout_constraintBottom_toTopOf="@id/done_button"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toStartOf="@id/pair_new_device_text"
-                app:layout_constraintTop_toBottomOf="@id/see_all_text"
-                android:tint="?android:attr/textColorPrimary" />
-
-            <TextView
-                android:id="@+id/pair_new_device_text"
-                style="@style/BluetoothTileDialog.Device"
-                android:layout_width="0dp"
-                android:layout_height="64dp"
-                android:maxLines="1"
-                android:ellipsize="end"
-                android:gravity="center_vertical"
-                android:importantForAccessibility="no"
-                android:clickable="false"
-                android:layout_marginStart="0dp"
-                android:paddingStart="20dp"
+                app:layout_constraintTop_toBottomOf="@+id/see_all_button"
+                app:layout_constraintBottom_toTopOf="@+id/done_button"
+                android:drawableStart="@drawable/ic_add"
+                android:drawablePadding="20dp"
+                android:drawableTint="?android:attr/textColorPrimary"
                 android:text="@string/pair_new_bluetooth_devices"
                 android:textSize="14sp"
                 android:textAppearance="@style/TextAppearance.Dialog.Title"
-                app:layout_constraintStart_toEndOf="@+id/ic_add"
-                app:layout_constraintTop_toBottomOf="@id/see_all_text"
-                app:layout_constraintEnd_toEndOf="parent" />
+                android:textDirection="locale"
+                android:textAlignment="viewStart"
+                android:maxLines="1"
+                android:ellipsize="end"
+                android:visibility="gone" />
 
             <Button
                 android:id="@+id/done_button"
@@ -227,7 +177,7 @@
                 android:maxLines="1"
                 android:text="@string/inline_done_button"
                 app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintTop_toBottomOf="@id/pair_new_device_text"
+                app:layout_constraintTop_toBottomOf="@id/pair_new_device_button"
                 app:layout_constraintBottom_toBottomOf="parent" />
         </androidx.constraintlayout.widget.ConstraintLayout>
     </androidx.core.widget.NestedScrollView>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 45a2e8a..09f3766 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Knoppie <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Op"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Af"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Links"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Regs"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Middel"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Spasie"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Kennisgewings"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Kortpadsleutels"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Wissel sleutelborduitleg"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Vee teks uit"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Kortpaaie"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Soek kortpaaie"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Geen kortpaaie gevind nie"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Invoer"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Maak apps oop"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Huidige app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Kry toegang tot kennisgewingskerm"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Neem ’n volle skermskoot"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Kry toegang tot lys met stelsel-/appkortpaaie"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Terug: gaan terug na vorige staat (terugknoppie)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Kry toegang tot tuisskerm"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Oorsig van oop apps"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Beweeg deur onlangse apps (vorentoe)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Beweeg deur onlangse apps (terug)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Kry toegang tot lys met alle apps en soektogte (d.w.s., Search/Lanseerder)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Versteek en wys (weer) taakbalk"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Kry toegang tot stelselinstellings"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Kry toegang tot Google Assistent"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Bekyk kennisgewings"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Neem skermskoot"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Wys kortpaaie"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Gaan terug"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Gaan na tuisskerm"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Bekyk onlangse apps"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Beweeg vorentoe deur onlangse apps"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Beweeg terug deur onlangse apps"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Maak appslys oop"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Wys taakbalk"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Maak instellings oop"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Maak Assistent oop"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Sluit skerm"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Haal Notas-app op vir vinnige memo"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Maak notas oop"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Verrig veelvuldige stelseltake"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Gaan by verdeelde skerm in met huidige app aan die regterkant"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Gaan by verdeelde skerm in met huidige app aan die linkerkant"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Skakel oor van verdeelde skerm na volskerm"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Tydens verdeelde skerm: verplaas ’n app van een skerm na ’n ander"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Gaan by verdeelde skerm in met huidige app aan die regterkant"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Gaan by verdeelde skerm in met huidige app aan die linkerkant"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Skakel oor van verdeelde skerm na volskerm"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Tydens verdeelde skerm: verplaas ’n app van een skerm na ’n ander"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Invoer"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Wissel invoertaal (volgende taal)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Wissel invoertaal (vorige taal)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Skakel oor na volgende taal"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Skakel oor na vorige taal"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Kry toegang tot emosiekone"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Kry toegang tot steminvoer"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Programme"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Bystand"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Blaaier (Chrome as verstek)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Blaaier"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakte"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-pos (Gmail as verstek)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-pos"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiek"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index bac72bf..9c07491 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"አዝራር <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"መነሻ"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"ተመለስ"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"ላይ"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"ወደታች"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ግራ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ቀኝ"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"የላይ ቀስት"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"የታች ቀስት"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"የግራ ቀስት"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"የቀኝ ቀስት"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"መሃል"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"ክፍተት"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"ማሳወቂያዎች"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"የቁልፍ ሰሌዳ አቋራጮች"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"የቁልፍ ሰሌዳ ገጽታ ለውጥ"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ጽሑፍን አጽዳ"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"ወይም"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"የፍለጋ መጠይቅን አጽዳ"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"አቋራጮች"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"አቋራጮችን ይፈልጉ"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ምንም አቋራጮች አልተገኙም"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ግቤት"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"የክፍት መተግበሪያዎች አጠቃላይ ዕይታ"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"የሥርዓት ቅንብሮች መዳረሻ"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"የGoogle ረዳት መዳረሻ"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"የፍለጋ ውጤቶችን በማሳየት ላይ"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"የስርዓት አቋራጮችን በማሳየት ላይ"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"የግብዓት አቋራጮችን በማሳየት ላይ"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"መተግበሪያዎችን የሚከፍቱ አቋራጮችን በማሳየት ላይ"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"ለአሁኑ መተግበሪያ አቋራጮችን በማሳየት ላይ"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"ማሳወቂያዎችን አሳይ"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ቅጽበታዊ ገጽ ዕይታን አንሳ"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"አቋራጮችን አሳይ"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ወደኋላ ተመለስ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ወደ መነሻ ማያ ገጽ ሂድ"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"የቅርብ ጊዜ መተግበሪያዎችን አሳይ"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"የቅርብ ጊዜ መተግበሪያዎች ላይ ወደ ፊት ዑደት ማድረግ።"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"የቅርብ ጊዜ መተግበሪያዎች ላይ ወደ ኋላ ዑደት ማድረግ።"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"የመተግበሪያ ዝርዝር ክፈት"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"የተግባር አሞሌን አሳይ"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"ቅንብሮችን ክፈት"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"ረዳትን ክፈት"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"ማያ ገፅ ቁልፍ"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"ለፈጣን ማስታወሻ የማስታወሻዎች መተግበሪያን ያወጣል"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"ማስታወሻዎችን ክፈት"</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="2454557648974553729">"ለአርኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገጽ ግባ"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"ለኤልኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገጽ ይግቡ"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"ከየተከፈለ ማያ ገጽ ወደ ሙሉ ገጽ ዕይታ ቀይር"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"በተከፈለ ማያ ገጽ ወቅት፡- መተግበሪያን ከአንዱ ወደ ሌላው ተካ"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"ወደ ቀጣዩ ቋንቋ ቀይር"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ወደ ቀዳሚ ቋንቋ ቀይር"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"የስሜት ገላጭ ምስል መዳረሻ"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"የድምፅ ትየባ መዳረሻ"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"መተግበሪያዎች"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"ረዳት"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"አሳሸ (Chrome እንደ ነባሪ)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"ረዳት"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"አሳሽ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"እውቂያዎች"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ኢሜይል (Gmail እንደ ነባሪ)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ኢሜይል"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"ኤስኤምኤስ"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ሙዚቃ"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"የቀን መቁጠሪያ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c188535..1c065bb 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"الزر <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"أعلى"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"أسفل"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"يسار"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"يمين"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"وسط"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"مسافة"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"الإشعارات"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"اختصارات لوحة المفاتيح"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"تبديل تنسيق لوحة المفاتيح"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"محو النص"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"الاختصارات"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"البحث في الاختصارات"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"لم يُعثَر على اختصارات."</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"إدخال"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"نظرة عامة على التطبيقات المفتوحة"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"الوصول إلى إعدادات النظام"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"‏الوصول إلى \"مساعد Google\""</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"عرض الإشعارات"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"أخذ لقطة شاشة"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"عرض الاختصارات"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"رجوع"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"الانتقال إلى الشاشة الرئيسية"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"عرض التطبيقات المستخدمة مؤخرًا"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"التنقّل للأمام بين التطبيقات المُستخدَمة مؤخرًا"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"التنقّل للوراء بين التطبيقات المُستخدَمة مؤخرًا"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"فتح قائمة التطبيقات"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"عرض شريط التطبيقات"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"فتح الإعدادات"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"‏فتح \"مساعد Google\""</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"شاشة القفل"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"‏سحب تطبيق Notes لإضافة مذكّرة سريعة"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"فتح تطبيق تدوين الملاحظات"</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="2454557648974553729">"تفعيل وضع \"تقسيم الشاشة\" مع عرض التطبيق الحالي على يسار الشاشة"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"تفعيل وضع \"تقسيم الشاشة\" مع عرض التطبيق الحالي على يمين الشاشة"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"التبديل من وضع \"تقسيم الشاشة\" إلى وضع \"ملء الشاشة\""</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"استبدال تطبيق بآخر في وضع \"تقسيم الشاشة\""</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"التبديل إلى اللغة التالية"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"التبديل إلى اللغة السابقة"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"الوصول إلى الرموز التعبيرية"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"الوصول إلى ميزة \"الكتابة بالصوت\""</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"التطبيقات"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"التطبيق المساعد"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"‏المتصفّح (فتح Chrome تلقائيًا)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"‏مساعد Google"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"المتصفح"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"جهات الاتصال"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"‏البريد الإلكتروني (فتح Gmail تلقائيًا)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"البريد الإلكتروني"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"‏الرسائل القصيرة SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"الموسيقى"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"التقويم"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 59eca3a..0c5f104 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> বুটাম"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"হ\'ম"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"উভতি যাওক"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"ওপৰলৈ"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"তললৈ"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"বাওঁফালে"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"সোঁফালে"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"স্ক্ৰীনৰ মাজত"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"স্পেচ"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"জাননীসমূহ"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"কীব\'ৰ্ড শ্বৰ্টকাটসমূহ"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"কীব\'ৰ্ডৰ সজ্জা সলনি কৰক"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"পাঠ মচক"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"শ্বৰ্টকাট"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"সন্ধানৰ শ্বৰ্টকাট"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"কোনো শ্বৰ্টকাট বিচাৰি পোৱা নাই"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ইনপুট"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"খোলা এপৰ ৰূপৰেখা"</string>
-    <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">"আটাইবোৰ এপ্ আৰু সন্ধানৰ এক্সেছৰ সূচী (যেনে, Search/Launcher)"</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 Assistant এক্সেছ কৰক"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"জাননী চাওক"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"স্ক্ৰীনশ্বট লওক"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"শ্বৰ্টকাট দেখুৱাওক"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"উভতি যাওক"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"গৃহ স্ক্ৰীনলৈ যাওক"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"শেহতীয়া এপ্‌সমূহ চাওক"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"শেহতীয়া এপ্‌সমূহ আগলৈ এটা এটাকৈ চাওক"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"শেহতীয়া এপ্‌সমূহ পিছলৈ এটা এটাকৈ চাওক"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"এপৰ সূচী খোলক"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"টাস্কবাৰ দেখুৱাওক"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"ছেটিং খোলক"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant খোলক"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"লক স্ক্ৰীন"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"ক্ষিপ্ৰ মেম’ৰ বাবে Notes এপ্ উলিয়াওক"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Notes এপ্ খোলক"</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="2454557648974553729">"বৰ্তমানৰ এপৰ জৰিয়তে বিভাজিত স্ক্ৰীনৰ সোঁফালৰ স্ক্ৰীনখনত সোমাওক"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"বৰ্তমানৰ এপৰ জৰিয়তে বিভাজিত স্ক্ৰীনৰ বাওঁফালৰ স্ক্ৰীনখনত সোমাওক"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"বিভাজিত স্ক্ৰীনৰ পৰা পূৰ্ণ স্ক্ৰীনলৈ সলনি কৰক"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"বিভাজিত স্ক্ৰীনৰ ব্যৱহাৰ কৰাৰ সময়ত: কোনো এপ্ এখন স্ক্ৰীনৰ পৰা আনখনলৈ নিয়ক"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"পৰৱৰ্তী ভাষাটোলৈ সলনি কৰক"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"পূৰ্বৰ ভাষালৈ সলনি কৰক"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ইম’জি এক্সেছ কৰক"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"ভইচ টাইপিং এক্সেছ কৰক"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"এপ্লিকেশ্বনসমূহ"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"সহায়"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ব্ৰাউজাৰ (ডিফ’ল্ট হিচাপে Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ব্ৰাউজাৰ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"সম্পৰ্কসূচী"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ইমেইল (ডিফ’ল্ট হিচাপে Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ইমেইল"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"এছএমএছ"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"সংগীত"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 121e276..b2ee455 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Düymə <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Əsas səhifə"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Geri"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Yuxarı"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Aşağı"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Sol"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Sağ"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Mərkəz"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Boşluq"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Bildirişlər"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Klaviatura qısa yolları"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Klaviatura düzümünü dəyişin"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Mətni silin"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Qısayollar"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Qısayollar axtarın"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Qısayol tapılmadı"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Daxiletmə"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Açıq tətbiqlər"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Cari tətbiq"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Bildiriş göstərişinə giriş"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Tam skrinşot çəkin"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Sistem siyahısına/tətbiq qısayollarına giriş"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Geri: əvvəlki vəziyyətə geri qayıdın (geri düyməsi)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Ana ekrana giriş"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Açıq tətbiqlərin icmalı"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Son tətbiqlər arasında keçid edin (irəli)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Son tətbiqlər arasında keçid edin (geri)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Tətbiqlər siyahısına və axtarışa (yəni Axtarış/Başladıcı) giriş"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"İşləmə panelini gizlədin və (yenidən) göstərin"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Sistem ayarlarına giriş"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Assistentə giriş"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Bildirişlərə baxın"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Skrinşot çəkin"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Qısayolları göstərin"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Geri qayıdın"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Əsas ekrana keçin"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Son tətbiqlərə baxın"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Son tətbiqlər boyunca irəli keçin"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Son tətbiqlər boyunca geri keçin"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Tətbiq siyahısını açın"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"İşləmə panelini göstərin"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ayarları açın"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistenti açın"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Kilid ekranı"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Sürətli qeyd üçün Qeydlər tətbiqini yuxarı dartın"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Qeydləri açın"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Sistemdə çoxsaylı tapşırıq icrası"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Cari tətbiq sağda olmaqla Bölünmüş ekrana daxil olun"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Cari tətbiq solda olmaqla Bölünmüş ekrana daxil olun"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Bölünmüş ekrandan tam ekrana dəyişin"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Bölünmüş ekran rejimində: tətbiqi birindən digərinə dəyişdirin"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Cari tətbiq sağda olmaqla bölünmüş ekrana daxil olun"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Cari tətbiq solda olmaqla bölünmüş ekrana daxil olun"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Bölünmüş ekrandan tam ekrana keçin"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran rejimində: tətbiqi birindən digərinə dəyişin"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Daxiletmə"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Daxiletmə dilini dəyişin (növbəti dil)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Daxiletmə dilini dəyişin (əvvəlki dil)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Növbəti dilə keçin"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Əvvəlki dilə keçin"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Emojiyə giriş"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Səslə yazmaya giriş"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Tətbiqlər"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Yardım"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Brauzer (defolt olaraq Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Brauzer"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontaktlar"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-poçt (defolt olaraq Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-poçt"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiqi"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Təqvim"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 4c535d8..ce734dc 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Dugme <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Taster Početna"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Taster Nazad"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Taster sa strelicom nagore"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Taster sa strelicom nadole"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Taster sa strelicom nalevo"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Taster sa strelicom nadesno"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Taster sa centralnom strelicom"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Razmak"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Obaveštenja"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Tasterske prečice"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Promeni raspored tastature"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Obrišite tekst"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Prečice"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pretražite prečice"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nisu pronađene prečice"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Unos"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Otvaranje aplik"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aktuelna aplik"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Pristup traci sa obaveštenjima"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Snimanje ekrana"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Pristup listi prečica za sistem/aplikacije"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Nazad: nazad na prethodno stanje (dugme Nazad)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Pristup početnom ekranu"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Pregled otvorenih aplikacija"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Pregled nedavnih aplikacija (napred)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Pregled nedavnih aplikacija (nazad)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Pristup listi svih alpikacija i pretraga (npr. Pretraga/Pokretač)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Skrivanje i ponovno prikazivanje trake zadataka"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Pristup podešavanjima sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Pristup Google pomoćniku"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Prikaži obaveštenja"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Napravi snimak ekrana"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Prikaži prečice"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Nazad"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Idi na početni ekran"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Pregledaj nedavno korišćene aplikacije"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Pregledaj nedavno korišćene aplikacije unapred"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Pregledaj nedavno korišćene aplikacije unazad"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvori listu aplikacija"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Prikaži traku zadataka"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvori podešavanja"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvori pomoćnika"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključavanje ekrana"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Otvaranje aplikacije Beleške za brzo pravljenje beleške"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Otvori beleške"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Obavljanje više zadataka sistema istovremeno"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Pokretanje podeljenog ekrana za aktuelnu aplikaciju na desnoj strani"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Pokretanje podeljenog ekrana za aktuelnu aplikaciju na levoj strani"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Prelazak sa podeljenog ekrana na ceo ekran"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Tokom podeljenog ekrana: zamena jedne aplikacije drugom"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Pokreni podeljeni ekran za aktuelnu aplikaciju na desnoj strani"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Pokreni podeljeni ekran za aktuelnu aplikaciju na levoj strani"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Pređi sa podeljenog ekrana na ceo ekran"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"U režimu podeljenog ekrana: zamena jedne aplikacije drugom"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Promena jezika unosa (sledeći jezik)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Promena jezika unosa (prethodni jezik)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Pređi na sledeći jezik"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Pređi na prethodni jezik"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Pristup emodžijima"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Pristup unosu teksta glasom"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikacije"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Aplikacija za pomoć"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Pregledač (podrazumevano Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Pomoćnik"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Pregledač"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakti"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Imejl (Gmail kao podrazumevani)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Imejl"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index ffde20e..74e46fc 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Кнопка <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Назад"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Уверх"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Уніз"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Улева"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Управа"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Цэнтр"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Прабел"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Апавяшчэнні"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Спалучэнні клавіш"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Пераключыць раскладку клавіятуры"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Выдаліць тэкст"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Ярлыкі"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Пошук ярлыкоў"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Ярлыкі не знойдзены"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Увод"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Агляд адкрытых праграм"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Перайсці да налад сістэмы"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Выклік Памочніка Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Праглядзець апавяшчэнні"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Зрабіць здымак экрана"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Паказаць спалучэнні клавіш"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Перайсці назад"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Перайсці на галоўны экран"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Праглядзець нядаўнія праграмы"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Пераходзіць паміж нядаўнімі праграмамі, перамяшчаючыся ўперад"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Пераходзіць паміж нядаўнімі праграмамі, перамяшчаючыся назад"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Адкрыць спіс праграм"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Паказаць панэль задач"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Адкрыць налады"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Выклікаць Памочніка"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Экран блакіроўкі"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Выклікаць праграму \"Нататкі\", каб зрабіць запіс"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Адкрыць нататкі"</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="2454557648974553729">"Перайсці ў рэжым падзеленага экрана з бягучай праграмай справа"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Перайсці ў рэжым падзеленага экрана з бягучай праграмай злева"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Пераключыцца з рэжыму падзеленага экрана на поўнаэкранны рэжым"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"У рэжыме падзеленага экрана замяніць адну праграму на іншую"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Пераключыцца на наступную мову"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Пераключыцца на папярэднюю мову"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Перайсці да эмодзі"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Актываваць галасавы ўвод"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Праграмы"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Памочнік"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Браўзер (стандартна выкарыстоўваецца Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Памочнік"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Браўзер"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Кантакты"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Электронная пошта (стандартна выкарыстоўваецца Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Электронная пошта"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS-паведамленні"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Каляндар"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index ad690e6..7a00ded 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Бутон „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Начало"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Назад"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Нагоре"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Надолу"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Наляво"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Надясно"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Център"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Интервал"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Известия"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Клавишни комбинации"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Превкл. на клавиат. подредба"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Изчистване на текста"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Клавишни комбинации"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Търсете комбинации"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Няма клавишни комбинации"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Въвеждане"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Общ преглед на отворените приложения"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Достъп до системните настройки"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Достъп до Google Асистент"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Преглед на известията"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Създаване на екранна снимка"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Показване на клавишните комбинации"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Назад"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Отваряне на началния екран"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Преглед на скорошните приложения"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Превъртане напред през скорошните приложения"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Превъртане назад през скорошните приложения"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Отваряне на списъка с приложения"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Показване на лентата на задачите"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Отваряне на настройките"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Отваряне на Асистент"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Заключване на екрана"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Отваряне на приложението за бележки с цел бързо записване"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Отваряне на бележките"</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="2454557648974553729">"Преминаване към разделен екран с текущото приложение отдясно"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Преминаване към разделен екран с текущото приложение отляво"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Превключване от разделен към цял екран"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"При разделен екран: замяна на дадено приложение с друго"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Превключване към следващия език"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Превключване към предишния език"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Достъп до емоджи"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Достъп до функцията за печатане с глас"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Приложения"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Помощно приложение"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Браузър (по подразбиране е Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Асистент"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Браузър"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Контакти"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Електронна поща (по подразбиране е Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Електронна поща"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 1383776..9954fbd 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> বোতাম"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"হোম"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"ফিরুন"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"উপরে"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"নিচে"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"বাঁ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ডান"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"কেন্দ্র"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"বিজ্ঞপ্তি"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"কীবোর্ড শর্টকাট"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"কীবোর্ড লে-আউট পাল্টান"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"টেক্সট মুছুন"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"শর্টকাট"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"শর্টকাট সার্চ করুন"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"কোনও শর্টকার্ট পাওয়া যায়নি"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ইনপুট"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"এক নজরে অফিসের অ্যাপ"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"সিস্টেমের সেটিংস অ্যাক্সেস করুন"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Assistant অ্যাক্সেস করুন"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"বিজ্ঞপ্তি দেখুন"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"স্ক্রিনশট নিন"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"শর্টকাট দেখুন"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ফিরে যান"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"হোম স্ক্রিনে যান"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"সম্প্রতি ব্যবহার করা হয়েছে এমন অ্যাপ দেখুন"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"সাম্প্রতিক অ্যাপের মাধ্যমে পরবর্তী জায়গায় যান"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"সাম্প্রতিক অ্যাপের মাধ্যমে আগের জায়গায় ফিরুন"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"অ্যাপের তালিকা খুলুন"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"টাস্কবার দেখুন"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"সেটিংস খুলুন"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant খুলুন"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"লক স্ক্রিন"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"দ্রুত মেমোর জন্য Notes অ্যাপ উপরের দিকে তুলুন"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"নোট খুলুন"</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="2454557648974553729">"ডানদিকে থাকা বর্তমান অ্যাপ ব্যবহার করে \'স্প্লিট স্ক্রিন\' যোগ করুন"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"বাঁদিকে থাকা বর্তমান অ্যাপ ব্যবহার করে \'স্প্লিট স্ক্রিন\' যোগ করুন"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"\'স্প্লিট স্ক্রিন\' থেকে ফুল স্ক্রিনে পাল্টান"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"\'স্প্লিট স্ক্রিন\' থাকাকালীন: একটি অ্যাপ থেকে অন্যটিতে পাল্টান"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"পরবর্তী ভাষায় পাল্টান"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"আগের ভাষায় পাল্টান"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ইমোজি অ্যাক্সেস করুন"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"ভয়েস টাইপিং অ্যাক্সেস করুন"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"অ্যাপ্লিকেশন"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"সহযোগিতা"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ব্রাউজার (ডিফল্ট হিসেবে Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ব্রাউজার"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"পরিচিতি"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ইমেল (ডিফল্ট হিসেবে Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ইমেল"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"সংগীত"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 0481288..041e3b6 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Dugme <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Tipka za početak"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Nazad"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Gore"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Dolje"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Lijevo"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Desno"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Sredina"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Tipka za razmak"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Obavještenja"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Prečice tastature"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Zamijeni raspored tastature"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Brisanje teksta"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Prečice"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pretraživanje prečica"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nisu pronađene prečice"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Unos"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Otvorene aplik."</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Trenutna aplik."</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Pristup lokaciji za obavještenja"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Snimanje cijelog ekrana"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Pristup listi prečica sistema/aplikacija"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Nazad: vraćanje na prethodno stanje (dugme za nazad)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Pristup početnom ekranu"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Pregled otvorenih aplikacija"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Pregled nedavnih aplikacija (unaprijed)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Pregled nedavnih aplikacija (unazad)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Pristup listi svih aplikacija i pretraživanje (Pretraživanje/Pokretač)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Sakrivanje i (ponovno) prikazivanje trake zadataka"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Pristup postavkama sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Pristup Google Asistentu"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Prikaz obavještenja"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Pravljenje snimka ekrana"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Prikaz prečica"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Nazad"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Odlazak na početni ekran"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Prikaz nedavnih aplikacija"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Kruženje kroz nedavne aplikacije unaprijed"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Kruženje kroz nedavne aplikacije unazad"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvaranje liste aplikacija"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Prikaz trake zadataka"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvaranje postavki"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvaranje Asistenta"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključavanje ekrana"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Preuzimanje aplikacije Bilješke za brzi podsjetnik"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Otvaranje Bilješki"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking sistema"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Otvaranje podijeljenog ekrana s trenutnom aplikacijom na desnoj strani"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Otvaranje podijeljenog ekrana s trenutnom aplikacijom na lijevoj strani"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Prebacivanje s podijeljenog ekrana na prikaz preko cijelog ekrana"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Za vrijeme podijeljenog ekrana: zamjena jedne aplikacije drugom"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Otvaranje podijeljenog ekrana s trenutnom aplikacijom na desnoj strani"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Otvaranje podijeljenog ekrana s trenutnom aplikacijom na lijevoj strani"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Prebacivanje s podijeljenog ekrana na prikaz preko cijelog ekrana"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Za vrijeme podijeljenog ekrana: zamjena jedne aplikacije drugom"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Promjena jezika unosa (sljedeći jezik)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Promjena jezika unosa (prethodni jezik)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Prebacivanje na sljedeći jezik"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Prebacivanje na prethodni jezik"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Pristup emoji sličicama"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Pristup pisanju govorom"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikacije"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Pomoć"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Preglednik (Chrome kao zadani)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Preglednik"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakti"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-pošta (Gmail kao zadana)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-pošta"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 03ef98d..eb652a1 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Botó <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Inici"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Enrere"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Amunt"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Avall"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Esquerra"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Dreta"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centre"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Espai"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notificacions"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Tecles de drecera"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Canvia disposició de teclat"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Esborra el text"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Dreceres"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Cerca dreceres"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"No s\'ha trobat cap drecera"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrada"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Obre aplicacions"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aplicació actual"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Accedeix a l\'àrea de notificacions"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Fes una captura de pantalla completa"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Accedeix a la llista de dreceres d\'aplicacions i del sistema"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Enrere: torna a l\'estat anterior (botó Enrere)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Accedeix a la pantalla d\'inici"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Informació general sobre les aplicacions obertes"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Recorre les aplicacions recents (endavant)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Recorre les aplicacions recents (enrere)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Accedeix a la llista de totes les apps i a la cerca (Cerca/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Amaga i torna a mostrar la barra de tasques"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Accedeix a la configuració del sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Accedeix a l\'Assistent de Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Mostra les notificacions"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Fes una captura de pantalla"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostra les dreceres"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Torna"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Ves a la pantalla d\'inici"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Mostra les aplicacions recents"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Desplaça\'t cap endavant per les aplicacions recents"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Desplaça\'t cap enrere per les aplicacions recents"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Obre la llista d\'aplicacions"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Mostra la barra de tasques"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Obre la configuració"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Obre l\'Assistent"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Pantalla de bloqueig"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Obre l\'aplicació Notes per prendre notes ràpides"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Obre les notes"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasques del sistema"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Entra al mode de pantalla dividida amb l\'aplicació actual a la dreta"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Entra al mode de pantalla dividida amb l\'aplicació actual a l\'esquerra"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Canvia de pantalla dividida a pantalla completa"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Durant el mode de pantalla dividida: substitueix una app per una altra"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Entra al mode de pantalla dividida amb l\'aplicació actual a la dreta"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Entra al mode de pantalla dividida amb l\'aplicació actual a l\'esquerra"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Canvia de pantalla dividida a pantalla completa"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Durant el mode de pantalla dividida: substitueix una app per una altra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Canvia l\'idioma d\'introducció (idioma següent)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Canvia l\'idioma d\'introducció (idioma anterior)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Canvia a l\'idioma següent"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Caniva a l\'idioma anterior"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Accedeix als emojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Accedeix a l\'escriptura per veu"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplicacions"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistència"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Navegador (Chrome com a predeterminat)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contactes"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Correu electrònic (Gmail com a predeterminat)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Correu electrònic"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 8b75a3e..05a20c1 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Tlačítko <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Zpět"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Nahoru"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Dolů"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Vlevo"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Vpravo"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Šipka nahoru"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Šipka dolů"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Šipka vlevo"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Šipka doprava"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Střed"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"TAB"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Mezerník"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Oznámení"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Klávesové zkratky"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Přepnout rozložení klávesnice"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Vymazat text"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"nebo"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Vymazat vyhledávaný dotaz"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Zkratky"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Vyhledat zkratky"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Žádné zkratky nenalezeny"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Vstup"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Otevřené aplikace"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aktuální aplikace"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Otevřít panel oznámení"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Pořídit snímek celé obrazovky"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Otevřít seznam zkratek do systému / aplikací"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Zpět: vrátit se k předchozímu stavu (tlačítko zpět)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Přejít na plochu"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Přehled otevřených aplikací"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Procházet nedávné aplikace (vpřed)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Procházet nedávné aplikace (zpět)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Otevřít seznam všech aplikací a vyhledávání (např. Vyhledávání/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Skrýt a (znovu) zobrazit panel aplikací"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Otevřít systémová nastavení"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Otevřít Asistenta Google"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Zobrazují se výsledky vyhledávání"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Zobrazují se systémové zkratky"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Zobrazují se zkratky pro zadávání"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Zobrazují se zkratky, které otevírají aplikace"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Zobrazují se zkratky pro aktuální aplikaci"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Zobrazit oznámení"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Pořídit snímek obrazovky"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Zobrazit zkratky"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Zpět"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Přejít na plochu"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Zobrazit nedávné aplikace"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Procházet nedávné aplikace směrem vpřed"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Procházet nedávné aplikace směrem zpět"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otevřít seznam aplikací"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Zobrazit panel aplikací"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otevřít nastavení"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otevřít Asistenta"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Uzamknout obrazovku"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Spustit aplikaci Poznámky a udělat rychlý zápis"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Otevřít poznámky"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Systémový multitasking"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Přepnout na rozdělenou obrazovku s aktuálními aplikacemi napravo"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Přepnout na rozdělenou obrazovku s aktuálními aplikacemi nalevo"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Přepnout z rozdělené obrazovky na celou obrazovku"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"V režimu rozdělené obrazovky: nahradit jednu aplikaci druhou"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Přepnout na rozdělenou obrazovku s aktuálními aplikacemi napravo"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Přepnout na rozdělenou obrazovku s aktuálními aplikacemi nalevo"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Přepnout z rozdělené obrazovky na celou obrazovku"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"V režimu rozdělené obrazovky: nahradit jednu aplikaci druhou"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vstup"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Přepnout jazyk vstupu (další jazyk)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Přepnout jazyk vstupu (předchozí jazyk)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Přepnout na další jazyk"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Přepnout na předchozí jazyk"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Otevřít smajlíky"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Otevřít hlasové zadávání"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikace"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Asistence"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Prohlížeč (výchozí je Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Prohlížeč"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakty"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-mail (výchozí je Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Hudba"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendář"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 9f5b600..1cfb005 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g>-knap"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Tilbage"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Op"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Ned"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Venstre"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Højre"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Midtertast"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Mellemrumstast"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifikationer"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Tastaturgenveje"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Skift tastaturlayout"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Ryd tekst"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Genveje"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Søg efter genveje"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Ingen genveje blev fundet"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Input"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Åbn apps"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aktuel app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Åbn notifikationspanel"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Tag et screenshot af hele skærmen"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Åbn liste over system-/appgenveje"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Forrige: Gå tilbage til den forrige tilstand (knappen Tilbage)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Åbn startskærm"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Oversigt over åbne apps"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Gennemgå seneste apps (næste)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Gennemgå seneste apps (forrige)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Åbn liste over alle apps, og søg (dvs. Søg/Starter)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Skjul, og vis proceslinjen (igen)"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Åbn systemindstillinger"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Åbn Google Assistent"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Se notifikationer"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Tag et screenshot"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Vis genveje"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Gå tilbage"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Gå til startskærm"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Se seneste apps"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Gå frem i dine seneste apps"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Gå tilbage i dine seneste apps"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Åbn appfortegnelse"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Vis proceslinje"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Åbn indstillinger"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Åbn Assistent"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lås skærm"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Åbn appen Notes for at skrive et hurtigt notat"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Åbn noter"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Systemmultitasking"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Start opdelt skærm med aktuel app til højre"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Start opdelt skærm med aktuel app til venstre"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Skift fra opdelt skærm til fuld skærm"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Ved opdelt skærm: Erstat en app med en anden app"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Start opdelt skærm med aktuel app til højre"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Start opdelt skærm med aktuel app til venstre"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Skift fra opdelt skærm til fuld skærm"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Ved opdelt skærm: Udskift én app med en anden"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Skift inputsprog (næste sprog)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Skift inputsprog (forrige sprog)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Skift til næste sprog"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Skift til forrige sprog"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Find emojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Åbn indtaling"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applikationer"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistance"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome som standard)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakter"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Mail (Gmail som standard)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 25d7202..5ce500d 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Taste <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Pos1"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Zurück"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Nach oben"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Nach unten"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Nach links"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Nach rechts"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Aufwärtspfeil"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Abwärtspfeil"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Linkspfeil"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Rechtspfeil"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Zentrieren"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tabulatortaste"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Leertaste"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Benachrichtigungen"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Tastenkürzel"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Tastaturlayout wechseln"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Text löschen"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"oder"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Suchanfrage löschen"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Tastenkombinationen"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Tastenkombinationen suchen"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Keine gefunden"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Eingabe"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Geöffnete Apps"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aktuelle App"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Auf Benachrichtigungsleiste zugreifen"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Vollbild-Screenshot aufnehmen"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Auf Liste mit System-/App-Verknüpfungen zugreifen"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Zurück: Vorherigen Zustand wiederherstellen (Schaltfläche „Zurück“)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Auf Startbildschirm zugreifen"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Übersicht über geöffnete Apps"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Zuletzt verwendete Apps vorwärts durchgehen"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Zuletzt verwendete Apps rückwärts durchgehen"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Auf Liste mit Apps und Suchmaschinen zugreifen, z. B. Google Suche / Google Now Launcher"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Taskleiste ausblenden und (wieder) einblenden"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Auf Systemeinstellungen zugreifen"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Auf Google Assistant zugreifen"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Suchergebnisse werden angezeigt"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Tastenkombinationen des Systems werden angezeigt"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Tastenkombinationen für die Eingabe werden angezeigt"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Tastenkombinationen zum Öffnen von Apps werden angezeigt"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Tastenkombinationen für die aktuelle App werden angezeigt"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Benachrichtigungen ansehen"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Screenshot erstellen"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Tastenkombinationen anzeigen"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Zurück"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Zum Startbildschirm wechseln"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Letzte Apps aufrufen"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Zuletzt verwendete Apps vorwärts durchgehen"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Zuletzt verwendete Apps rückwärts durchgehen"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Liste der Apps öffnen"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Taskleiste anzeigen"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Einstellungen öffnen"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant öffnen"</string>
     <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="group_system_quick_memo" msgid="6257072703041301265">"Notizen öffnen"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System-Multitasking"</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="system_multitasking_rhs" msgid="2454557648974553729">"Splitscreen aktivieren, aktuelle App rechts"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Splitscreen aktivieren, aktuelle App links"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Vom Splitscreen zum Vollbild wechseln"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Zur nächsten Sprache wechseln"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Zu vorheriger Sprache wechseln"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Auf Emoji zugreifen"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Auf Spracheingabe zugreifen"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Apps"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistent"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome ist Standard)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakte"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-Mail-Programm (Gmail ist Standard)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-Mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 9bd246a..fe8a07f 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Κουμπί <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Πίσω"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Πάνω"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Κάτω"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Αριστερά"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Δεξιά"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Επάνω βέλος"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Κάτω βέλος"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Αριστερό βέλος"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Δεξί βέλος"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Κέντρο"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Πλήκτρο διαστήματος"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Ειδοποιήσεις"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Συντομεύσεις πληκτρολογίου"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Αλλαγή διάταξης πληκτρολογίου"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Διαγραφή κειμένου"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"ή"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Διαγραφή ερωτήματος αναζήτησης"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Συντομεύσεις"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Αναζήτηση συντομεύσεων"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Δεν βρέθηκαν συντομεύσεις"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Είσοδος"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Επισκόπηση ανοιχτών εφαρμογών"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Πρόσβαση στις ρυθμίσεις συστήματος"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Πρόσβαση στον Βοηθό Google"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Εμφάνιση αποτελεσμάτων αναζήτησης"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Εμφάνιση συντομεύσεων συστήματος"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Εμφάνιση συντομεύσεων εισόδου"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Εμφάνιση συντομεύσεων για το άνοιγμα εφαρμογών"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Εμφάνιση συντομεύσεων για την τρέχουσα εφαρμογή"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Προβολή ειδοποιήσεων"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Λήψη στιγμιότυπου οθόνης"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Εμφάνιση συντομεύσεων"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Επιστροφή"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Μετάβαση στην αρχική οθόνη"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Προβολή πρόσφατων εφαρμογών"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Περιήγηση προς τα εμπρός σε πρόσφατες εφαρμογές"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Περιήγηση προς τα πίσω σε πρόσφατες εφαρμογές"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Άνοιγμα λίστας εφαρμογών"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Εμφάνιση γραμμής εργαλείων"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Άνοιγμα ρυθμίσεων"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Άνοιγμα Βοηθού"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Κλείδωμα οθόνης"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Εμφάνιση εφαρμογής Σημειώσεις για γρήγορη σύνταξη σημείωσης"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Άνοιγμα σημειώσεων"</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="2454557648974553729">"Ενεργοποίηση διαχωρισμού οθόνης με την τρέχουσα εφαρμογή στα δεξιά"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Ενεργοποίηση διαχωρισμού οθόνης με την τρέχουσα εφαρμογή στα αριστερά"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Εναλλαγή από διαχωρισμό οθόνης σε πλήρη οθόνη"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Κατά τον διαχωρισμό οθόνης: αντικατάσταση μιας εφαρμογής με άλλη"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Εναλλαγή στην επόμενη γλώσσα"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Εναλλαγή στην προηγούμενη γλώσσα"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Πρόσβαση στα emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Πρόσβαση στη φωνητική πληκτρολόγηση"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Εφαρμογές"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Υποβοήθηση"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Πρόγραμμα περιήγησης (Chrome ως προεπιλογή)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Βοηθός"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Πρόγραμμα περιήγησης"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Επαφές"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Ηλεκτρονικό ταχυδρομείο (Gmail ως προεπιλογή)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Ηλεκτρονικό ταχυδρομείο"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Μουσική"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Ημερολόγιο"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index b3dea8d..30b03b2 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Up"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centre"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifications"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Keyboard shortcuts"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Switch keyboard layout"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Clear text"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Shortcuts"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Search shortcuts"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"No shortcuts found"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Input"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Open apps"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Current app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Access notification shade"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Take a full screenshot"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Access list of system/apps shortcuts"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Back: Go back to previous state (back button)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Access home screen"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Overview of open apps"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Cycle through recent apps (forward)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Cycle through recent apps (back)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Access list of all apps and search (i.e. Search/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Hide and (re)show taskbar"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Access system settings"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Access Google Assistant"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"View notifications"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Take screenshot"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Show shortcuts"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Go back"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Go to home screen"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"View recent apps"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Cycle forwards through recent apps"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Cycle backwards through recent apps"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Open apps list"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Show taskbar"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Open settings"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Open Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lock screen"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Pull up Notes app for quick memo"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Open notes"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System multitasking"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Enter split screen with current app to right-hand side"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Enter split screen with current app to left-hand screen"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Switch from split screen to full screen"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"During split screen: Replace an app from one to another"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Switch from split screen to full screen"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Switch input language (next language)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Switch input language (previous language)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Access emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Access voice typing"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applications"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assist"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome as default)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacts"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (Gmail as default)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index bbfdcea..d349d6d 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Up"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Up arrow"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Down arrow"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Left arrow"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Right arrow"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Center"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifications"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Keyboard Shortcuts"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Switch keyboard layout"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Clear text"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"or"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Clear search query"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Shortcuts"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Search shortcuts"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"No shortcuts found"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Input"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Open apps"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Current app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Access notification shade"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Take a full screenshot"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Access list of system / apps shortcuts"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Back: go back to previous state (back button)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Access home screen"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Overview of open apps"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Cycle through recent apps (forward)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Cycle through recent apps (back)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Access list of all apps and search (i.e. Search/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Hide and (re)show taskbar"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Access system settings"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Access Google Assistant"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Showing search results"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Showing system shortcuts"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Showing input shortcuts"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Showing shortcuts that open apps"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Showing shortcuts for the current app"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"View notifications"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Take screenshot"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Show shortcuts"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Go back"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Go to home screen"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"View recent apps"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Cycle forward through recent apps"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Cycle backward through recent apps"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Open apps list"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Show taskbar"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Open settings"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Open assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lock screen"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Pull up Notes app for quick memo"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Open notes"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System multitasking"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Enter Split screen with current app to RHS"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Enter Split screen with current app to LHS"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Switch from Split screen to full screen"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"During Split screen: replace an app from one to another"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Switch from split screen to full screen"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: replace an app from one to another"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Switch input language (next language)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Switch input language (previous language)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Access emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Access voice typing"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applications"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assist"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome as default)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacts"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (Gmail as default)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
@@ -1194,7 +1200,7 @@
     <string name="mirror_display" msgid="2515262008898122928">"Mirror display"</string>
     <string name="dismiss_dialog" msgid="2195508495854675882">"Dismiss"</string>
     <string name="connected_display_icon_desc" msgid="6373560639989971997">"Display connected"</string>
-    <string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone &amp; Camera"</string>
+    <string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone and camera"</string>
     <string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app use"</string>
     <string name="privacy_dialog_more_button" msgid="7610604080293562345">"See recent access"</string>
     <string name="privacy_dialog_done_button" msgid="4504330708531434263">"Done"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index b3dea8d..30b03b2 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Up"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centre"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifications"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Keyboard shortcuts"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Switch keyboard layout"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Clear text"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Shortcuts"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Search shortcuts"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"No shortcuts found"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Input"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Open apps"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Current app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Access notification shade"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Take a full screenshot"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Access list of system/apps shortcuts"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Back: Go back to previous state (back button)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Access home screen"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Overview of open apps"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Cycle through recent apps (forward)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Cycle through recent apps (back)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Access list of all apps and search (i.e. Search/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Hide and (re)show taskbar"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Access system settings"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Access Google Assistant"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"View notifications"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Take screenshot"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Show shortcuts"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Go back"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Go to home screen"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"View recent apps"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Cycle forwards through recent apps"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Cycle backwards through recent apps"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Open apps list"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Show taskbar"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Open settings"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Open Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lock screen"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Pull up Notes app for quick memo"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Open notes"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System multitasking"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Enter split screen with current app to right-hand side"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Enter split screen with current app to left-hand screen"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Switch from split screen to full screen"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"During split screen: Replace an app from one to another"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Switch from split screen to full screen"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Switch input language (next language)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Switch input language (previous language)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Access emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Access voice typing"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applications"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assist"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome as default)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacts"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (Gmail as default)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index b3dea8d..30b03b2 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Up"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centre"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifications"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Keyboard shortcuts"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Switch keyboard layout"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Clear text"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Shortcuts"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Search shortcuts"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"No shortcuts found"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Input"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Open apps"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Current app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Access notification shade"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Take a full screenshot"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Access list of system/apps shortcuts"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Back: Go back to previous state (back button)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Access home screen"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Overview of open apps"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Cycle through recent apps (forward)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Cycle through recent apps (back)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Access list of all apps and search (i.e. Search/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Hide and (re)show taskbar"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Access system settings"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Access Google Assistant"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"View notifications"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Take screenshot"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Show shortcuts"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Go back"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Go to home screen"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"View recent apps"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Cycle forwards through recent apps"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Cycle backwards through recent apps"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Open apps list"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Show taskbar"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Open settings"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Open Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lock screen"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Pull up Notes app for quick memo"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Open notes"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"System multitasking"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Enter split screen with current app to right-hand side"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Enter split screen with current app to left-hand screen"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Switch from split screen to full screen"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"During split screen: Replace an app from one to another"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Switch from split screen to full screen"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Switch input language (next language)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Switch input language (previous language)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Access emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Access voice typing"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applications"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assist"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome as default)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacts"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (Gmail as default)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 5340b7b..9b46442 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎Button ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎Home‎‏‎‎‏‎"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‏‏‏‎Back‎‏‎‎‏‎"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎Up‎‏‎‎‏‎"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎Down‎‏‎‎‏‎"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‏‏‎‎‎‎Left‎‏‎‎‏‎"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎Right‎‏‎‎‏‎"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎Up arrow‎‏‎‎‏‎"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‎Down arrow‎‏‎‎‏‎"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‏‏‎‏‎Left arrow‎‏‎‎‏‎"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎Right arrow‎‏‎‎‏‎"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‎Center‎‏‎‎‏‎"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎Tab‎‏‎‎‏‎"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎Space‎‏‎‎‏‎"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎Notifications‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎Keyboard Shortcuts‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎Switch keyboard layout‎‏‎‎‏‎"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎Clear text‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎or‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎Clear search query‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎Shortcuts‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎Search shortcuts‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎No shortcuts found‎‏‎‎‏‎"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‏‎Input‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎Open apps‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‎Current app‎‏‎‎‏‎"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎Access notification shade‎‏‎‎‏‎"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎Take a full screenshot‎‏‎‎‏‎"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎Access list of system / apps shortcuts‎‏‎‎‏‎"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎Back: go back to previous state (back button)‎‏‎‎‏‎"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎Access home screen‎‏‎‎‏‎"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‎‎Overview of open apps‎‏‎‎‏‎"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎Cycle through recent apps (forward)‎‏‎‎‏‎"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎Cycle through recent apps (back)‎‏‎‎‏‎"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎Access list of all apps and search (i.e. Search/Launcher)‎‏‎‎‏‎"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎Hide and (re)show taskbar‎‏‎‎‏‎"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎Access system settings‎‏‎‎‏‎"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‎‎Access Google Assistant‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎Showing search results‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‎Showing system shortcuts‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎Showing input shortcuts‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎Showing shortcuts that open apps‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎Showing shortcuts for the current app‎‏‎‎‏‎"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎View notifications‎‏‎‎‏‎"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‎Take screenshot‎‏‎‎‏‎"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎Show shortcuts‎‏‎‎‏‎"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎Go back‎‏‎‎‏‎"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎Go to home screen‎‏‎‎‏‎"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‎‎‎‎View recent apps‎‏‎‎‏‎"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‏‏‏‎‏‎Cycle forward through recent apps‎‏‎‎‏‎"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‏‎‎Cycle backward through recent apps‎‏‎‎‏‎"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎Open apps list‎‏‎‎‏‎"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎Show taskbar‎‏‎‎‏‎"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎Open settings‎‏‎‎‏‎"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎Open assistant‎‏‎‎‏‎"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎Lock screen‎‏‎‎‏‎"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‏‎Pull up Notes app for quick memo‎‏‎‎‏‎"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎Open notes‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎System multitasking‎‏‎‎‏‎"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎Enter Split screen with current app to RHS‎‏‎‎‏‎"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎Enter Split screen with current app to LHS‎‏‎‎‏‎"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎Switch from Split screen to full screen‎‏‎‎‏‎"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎During Split screen: replace an app from one to another‎‏‎‎‏‎"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎Enter split screen with current app to RHS‎‏‎‎‏‎"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‎Enter split screen with current app to LHS‎‏‎‎‏‎"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎Switch from split screen to full screen‎‏‎‎‏‎"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎During split screen: replace an app from one to another‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎Input‎‏‎‎‏‎"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎‎‎‏‎Switch input language (next language)‎‏‎‎‏‎"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎Switch input language (previous language)‎‏‎‎‏‎"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎Switch to next language‎‏‎‎‏‎"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‏‎Switch to previous language‎‏‎‎‏‎"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‏‎Access emoji‎‏‎‎‏‎"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎Access voice typing‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎Applications‎‏‎‎‏‎"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‎‎Assist‎‏‎‎‏‎"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‏‎‎‎Browser (Chrome as default)‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎Assistant‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‏‎Browser‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎Contacts‎‏‎‎‏‎"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎Email (Gmail as default)‎‏‎‎‏‎"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎Email‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‎SMS‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎Music‎‏‎‎‏‎"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎Calendar‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 78f91b1..0bc807e 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Inicio"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Atrás"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Arriba"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Abajo"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Izquierda"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Derecha"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Flecha hacia arriba"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Flecha hacia abajo"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Flecha a la izquierda"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Flecha hacia la derecha"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centro"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Espacio"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notificaciones"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Ver combinaciones de teclas"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Cambiar diseño del teclado"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Borrar texto"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"o bien"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Borrar búsqueda"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Combinaciones de teclas"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Buscar comb. de teclas"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"No hay comb. de teclas"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrada"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Apps abiertas"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"App actual"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Acceder al panel de notificaciones"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Tomar una captura de pantalla completa"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Acceder a una lista de combinación de teclas del sistema/apps"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Atrás: Vuelve al estado anterior (botón Atrás)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Acceder a la pantalla principal"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Obtener una descripción general de las apps abiertas"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Desplazar por las apps recientes (adelante)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Desplazar por las apps recientes (atrás)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Acceder a lista de apps y búsquedas (p. ej. Búsqueda/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Esconder y volver a mostrar la barra de tareas"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Acceder a la configuración del sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Acceder a Asistente de Google"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Mostrando los resultados de la búsqueda"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Mostrando combinaciones de teclas del sistema"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Mostrando entradas de combinaciones de teclas"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Mostrando combinaciones de teclas que abren apps"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Mostrando combinaciones de teclas para la app actual"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Ver notificaciones"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Tomar captura de pantalla"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar accesos directos"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Atrás"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Ir a la pantalla principal"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Ver apps recientes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Desplazar por las apps recientes (adelante)"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Desplazar por las apps recientes (atrás)"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Abrir lista de apps"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Mostrar Barra de tareas"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir configuración"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir Asistente"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Bloquear la pantalla"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Mostrar la app de Notas para crear un recordatorio rápido"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir notas"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Tareas múltiples del sistema"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Activar pantalla dividida con la app actual en el lado derecho (RHS)"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Activar pantalla dividida con la app actual en el lado izquierdo (LHS)"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Cambiar de pantalla dividida a pantalla completa"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Durante pantalla dividida: Reemplaza una app con otra"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Activar pantalla dividida con la app actual en el lado derecho (RHS)"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Activar pantalla dividida con la app actual en el lado izquierdo (LHS)"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Cambiar de pantalla dividida a pantalla completa"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Durante pantalla dividida: Reemplaza una app con otra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Cambiar el idioma de escritura (próximo idioma)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Cambiar el idioma de escritura (idioma anterior)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar al próximo idioma"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Cambiar al idioma anterior"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Acceder a los emojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Acceder al dictado por voz"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplicaciones"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Asistencia"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Navegador (Chrome como predeterminado)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistente"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contactos"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Correo electrónico (Gmail como predeterminado)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Correo electrónico"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 59802ad..f642386 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Inicio"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Atrás"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Arriba"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Abajo"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Izquierda"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Derecha"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centro"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tabulador"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Espacio"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notificaciones"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Ver combinaciones de teclas"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Cambiar diseño del teclado"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Borrar texto"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Combinaciones de teclas"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Buscar combinaciones de teclas"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Ninguna encontrada"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrada"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Apps abiertas"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"App en uso"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Acceder a la pantalla de notificaciones"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Hacer una captura de pantalla completa"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Acceder a la lista de combinaciones de teclas de apps y del sistema"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Atrás: volver al estado anterior (botón para volver)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Acceder a la pantalla de inicio"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Vista general de aplicaciones abiertas"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Recorrer aplicaciones recientes (hacia delante)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Recorrer aplicaciones recientes (hacia atrás)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Acceder a la lista de todas las apps y a la búsqueda (Buscar/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ocultar y mostrar la barra de tareas"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Acceder a los ajustes del sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Acceder al Asistente de Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Ver notificaciones"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Hacer captura de pantalla"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar accesos directos"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Volver"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Ir a la pantalla de inicio"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Ver aplicaciones recientes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Desplazarse por las aplicaciones recientes (adelante)"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Desplazarse por las aplicaciones recientes (atrás)"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Abrir lista de aplicaciones"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Mostrar la barra de tareas"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir ajustes"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir el Asistente"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Pantalla de bloqueo"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Abrir la aplicación de notas para tomar una nota rápida"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir notas"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Función multitarea del sistema"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Iniciar pantalla dividida con esta aplicación en el lado derecho"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Iniciar pantalla dividida con esta aplicación en el lado izquierdo"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Cambiar de pantalla dividida a pantalla completa"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Con pantalla dividida: reemplazar una aplicación por otra"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Iniciar pantalla dividida con esta aplicación en el lado derecho"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Iniciar pantalla dividida con esta aplicación en el lado izquierdo"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Cambiar de pantalla dividida a pantalla completa"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Con pantalla dividida: reemplazar una aplicación por otra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Cambiar idioma de entrada (idioma siguiente)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Cambiar idioma de entrada (idioma anterior)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar al siguiente idioma"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Cambiar al idioma anterior"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Acceder a los emojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Acceder a Escribir por voz"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplicaciones"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Asistencia"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Navegador (Chrome como predeterminado)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistente"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contactos"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Correo (Gmail como predeterminado)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Correo electrónico"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index ec65920..8e9616f 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Nupp <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Avakuva"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Tagasi"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Üles"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Alla"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Vasakule"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Paremale"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Keskele"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Tühik"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Märguanded"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Klaviatuuri otseteed"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Klaviatuuripaigutuse vahetus"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Teksti kustutamine"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Otseteed"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Otseteede otsing"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Otseteid ei leitud"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Sisend"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Rakenduste avamine"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Praegune rakendus"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Juurdepääs märguandealale"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Täisekraanipildi jäädvustamine"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Juurdepääs süsteemi/rakenduste otseteede loendile"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Tagasi: eelmisesse olekusse naasmine (tagasinupp)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Juurdepääs avakuvale"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Avatud rakenduste ülevaade"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Hiljutiste rakenduste sirvimine (edasi)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Hiljutiste rakenduste sirvimine (tagasi)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Juurdepääs kõigi rakenduste ja otsingute loendile (st Otsing/Käivitusprogramm)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Tegumiriba peitmine ja kuvamine"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Juurdepääs süsteemi seadetele"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Juurdepääs Google\'i assistendile"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Märguannete vaatamine"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ekraanipildi jäädvustamine"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Otseteede kuvamine"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Tagasiliikumine"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Avakuvale liikumine"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Hiljutiste rakenduste vaatamine"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Hiljutiste rakenduste hulgas edasi liikumine"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Hiljutiste rakenduste hulgas tagasi liikumine"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Rakenduste loendi avamine"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Tegumiriba kuvamine"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Seadete avamine"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistendi avamine"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lukustuskuva"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Rakenduse Märkmed avamine kiirmemo jaoks"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Märkmete avamine"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Süsteemi multitegumtöö"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Ekraanikuva jagamine, nii et praegune rakendus on paremal"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Ekraanikuva jagamine, nii et praegune rakendus on vasakul"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Jagatud ekraanikuvalt täisekraanile lülitamine"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Ekraanikuva jagamise ajal: ühe rakenduse asendamine teisega"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Ekraanikuva jagamine, nii et praegune rakendus on paremal"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Ekraanikuva jagamine, nii et praegune rakendus on vasakul"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Jagatud ekraanikuvalt täisekraanile lülitamine"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Ekraanikuva jagamise ajal: ühe rakenduse asendamine teisega"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Sisend"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Sisendkeele vahetamine (järgmine keel)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Sisendkeele vahetamine (eelmine keel)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Järgmisele keelele lülitamine"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Eelmisele keelele lülitamine"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Juurdepääs emotikonile"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Juurdepääs häälsisestusele"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Rakendused"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Abi"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Brauser (vaikimisi Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Brauser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontaktid"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-post (vaikimisi Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-post"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muusika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index b5a12cf..fe04218 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> botoia"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Hasiera"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Atzera"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Gora"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Behera"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Ezkerrera"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Eskuinera"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Erdiratu"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Zuriunea"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Jakinarazpenak"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Lasterbideak"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Aldatu tekl. diseinua"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Garbitu testua"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Lasterbideak"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Bilatu lasterbideak"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Ez da aurkitu lasterbiderik"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Sarrera"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Irekitako aplikazioak"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Uneko aplikazioa"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Atzitu jakinarazpenen panela"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Atera pantaila osoaren argazki bat"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Atzitu sistemaren edo aplikazioetarako lasterbideen zerrenda"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Atzera: itzuli aurreko egoerara (atzera egiteko botoia)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Atzitu hasierako pantaila"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Ikusi irekitako aplikazioen ikuspegi orokorra"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Joan azkenaldian erabilitako aplikazio batetik bestera (aurrera)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Joan azkenaldian erabilitako aplikazio batetik bestera (atzera)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Atzitu aplikazio guztien zerrenda eta bilatu (adibidez, bilatzeko aukeraren edo Exekutatzeko tresna aplikazioaren bidez)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ezkutatu eta erakutsi (berriro) zereginen barra"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Atzitu sistemaren ezarpenak"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Atzitu Google-ren Laguntzailea"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Ikusi jakinarazpenak"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Atera pantaila-argazki bat"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Erakutsi lasterbideak"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Egin atzera"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Joan hasierako pantailara"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Ikusi azkenaldiko aplikazioak"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Ikusi azken aplikazioak banan-banan (aurrerantz)"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Ikusi azken aplikazioak banan-banan (atzerantz)"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ireki aplikazioen zerrenda"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Erakutsi zereginen barra"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ireki ezarpenak"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Ireki Laguntzailea"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Blokeatu pantaila"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Ireki Oharrak aplikazioa oharrak bizkor idazteko"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Ireki oharrak"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Zereginen aldibereko sistemaren exekuzioa"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Sartu pantaila zatituaren eskuineko aldean uneko aplikazioarekin"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Sartu pantaila zatituaren ezkerreko aldean uneko aplikazioarekin"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Aldatu pantaila zatitutik pantaila osora"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Pantaila zatituan zaudela: ordeztu aplikazio bat beste batekin"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Sartu pantaila zatituaren eskuineko aldean oraingo aplikazioarekin"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Sartu pantaila zatituaren ezkerreko aldean oraingo aplikazioarekin"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Aldatu pantaila zatitutik pantaila osora"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Pantaila zatituan zaudela, ordeztu aplikazio bat beste batekin"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Sarrera"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Aldatu idazteko hizkuntza (hurrengo hizkuntza)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Aldatu idazteko hizkuntza (aurreko hizkuntza)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Aldatu hurrengo hizkuntzara"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Aldatu aurreko hizkuntzara"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Atzitu emojiak"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Atzitu ahozko idazketa"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikazioak"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Laguntzailea"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Ireki arakatzailea (Chrome, modu lehenetsian)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Laguntzailea"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Arakatzailea"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontaktuak"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Ireki posta elektronikoa (Gmail, modu lehenetsian)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Posta"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMSak"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 055ea3b..2f17835 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"دکمه <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"ابتدا"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"برگشت"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"بالا"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"پایین"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"چپ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"راست"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"مرکز"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"اعلان‌ها"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"میان‌برهای صفحه‌کلید"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"تغییر جانمایی صفحه‌کلید"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"پاک کردن نوشتار"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"میان‌برها"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"جستجوی میان‌برها"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"میان‌بری پیدا نشد"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ورودی"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"نمای کلی برنامه‌های باز"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"دسترسی به تنظیمات سیستم"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"‏دسترسی به «‏‫دستیار Google‬»"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"مشاهده اعلان‌ها"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"گرفتن نماگرفت"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"نمایش میان‌برها"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"برگشتن"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"رفتن به صفحه اصلی"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"مشاهده برنامه‌های اخیر"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"چرخش به جلو در برنامه‌های اخیر"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"چرخش به عقب در برنامه‌های اخیر"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"باز کردن فهرست برنامه‌ها"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"نمایش نوار وظیفه"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"باز کردن تنظیمات"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"باز کردن «دستیار»"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"قفل صفحه"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"برای یادداشت سریع، برنامه «یادداشت‌ها» را بالا بکشید"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"باز کردن یادداشت‌ها"</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="2454557648974553729">"وارد شدن به صفحهٔ دونیمه با برنامه فعلی در سمت راست"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"وارد شدن به صفحهٔ دونیمه با برنامه فعلی در سمت چپ"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"جابه‌جایی از صفحهٔ دونیمه به تمام صفحه"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"درحین صفحهٔ دونیمه: برنامه‌ای را با دیگری جابه‌جا می‌کند"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"رفتن به زبان بعدی"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"رفتن به زبان قبلی"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"دسترسی به اموجی"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"دسترسی به تایپ صوتی"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"برنامه‌ها"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"دستیار"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"‏مرورگر (Chrome به‌عنوان پیش‌فرض)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"دستیار"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"مرورگر"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"مخاطبین"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"‏ایمیل (Gmail به‌عنوان پیش‌فرض)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ایمیل"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"پیامک"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"موسیقی"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"تقویم"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 82e5231..d1bd05b 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Painike <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Takaisin"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Ylös"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Alas"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Vasemmalle"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Oikealle"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Keskelle"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Välilyönti"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Ilmoitukset"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Pikanäppäimet"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Vaihda näppäimistöasettelu"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Tyhjennä teksti"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Pikanäppäimet"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Hae pikanäppäimiä"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Pikanäppäimiä ei löytynyt"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Syöttötapa"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Avoimet"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Sovelluslista"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Käytä ilmoitusaluetta"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Ota kuvakaappaus"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Käytä järjestelmän ja sovellusten pikakuvakkeita"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Takaisin: siirry takaisin edelliseen tilaan (takaisin-painike)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Käytä aloitusnäyttöä"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Avointen sovellusten yleiskatsaus"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Selaa viimeaikaisia sovelluksia (eteenpäin)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Selaa viimeaikaisia sovelluksia (takaisin)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Sovellusten ja haun luettelon käyttö (esim. Haku/Käynnistysohjelma)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Piilota ja tuo tehtäväpalkki näkyviin"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Käytä järjestelmäasetuksia"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Käytä Google Assistantia"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Katso ilmoitukset"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ota kuvakaappaus"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Näytä pikakuvakkeet"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Takaisin"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Siirry aloitusnäytölle"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Katso viimeisimmät sovellukset"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Siirry eteenpäin viimeaikaisten sovellusten kautta"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Siirry takaisin viimeaikaisten sovellusten kautta"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Avaa sovelluslista"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Näytä tehtäväpalkki"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Avaa asetukset"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Avaa Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lukitusnäyttö"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Avaa muistiinpanosovellus pikaisia merkintöjä varten"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Avaa muistiinpanot"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Järjestelmän monikäyttö"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Siirry jaettuun näyttöön (sovellus oikeanpuoleiseen näyttöön)"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Siirry jaettuun näyttöön (sovellus vasemmanpuoleiseen näyttöön)"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Vaihda jaetusta näytöstä koko näyttöön"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Jaetun näytön aikana: korvaa sovellus toisella"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Siirry jaettuun näyttöön (sovellus oikeanpuoleiseen näyttöön)"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Siirry jaettuun näyttöön (sovellus vasemmanpuoleiseen näyttöön)"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Vaihda jaetusta näytöstä koko näyttöön"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Jaetun näytön aikana: korvaa sovellus toisella"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Syöttötapa"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Vaihda syöttökieli (seuraava kieli)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Vaihda syöttökieli (edellinen kieli)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Vaihda seuraavaan kieleen"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Vaihda aiempaan kieleen"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Emojin käyttö"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Puhekirjoituksen käyttö"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Sovellukset"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Apusovellus"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Selain (oletuksena Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Selain"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Yhteystiedot"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Sähköposti (oletuksena Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Sähköposti"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Tekstiviesti"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiikki"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalenteri"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 619c7f8..bcf0e96 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Bouton <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Accueil"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Précédent"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Haut"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Bas"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Gauche"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Droite"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centrer"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Espace"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifications"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Raccourcis clavier"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Changer la disposition du clavier"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Effacer le texte"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Raccourcis"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Recherchez des raccourcis"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Aucun raccourci trouvé"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrée"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Ouvrir applis"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Appli actuelle"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Accéder au volet de notification"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Prendre une capture d\'écran complète"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Accéder à la liste des raccourcis du système/des applications"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Retour : retour à l\'état précédent (bouton précédent)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Accéder à l\'écran d\'accueil"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Aperçu des applications ouvertes"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Parcourir les applications récentes (avancer)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Parcourir les applications récentes (retour)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Accéder à la liste des applis et à la recherche (recherche/lanceur)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Masquer et (ré)afficher la barre des tâches"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Accéder aux paramètres système"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Accéder à l\'Assistant Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Afficher les notifications"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Prendre une capture d\'écran"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Afficher les raccourcis"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Retour"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Aller à l’écran d’accueil"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Afficher les applications récentes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Parcourir les applications récentes"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Parcourir les applications récentes en sens inverse"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ouvrir la liste des applications"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Afficher la barre des tâches"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ouvrir les paramètres"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Ouvrir l\'Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Écran de verrouillage"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Ouvrir l\'application de prise de notes pour prendre des notes rapides"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Ouvrir les notes"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitâche du système"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Passer à l\'écran partagé avec l\'application actuelle à droite"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Passer à l\'écran partagé avec l\'application actuelle à gauche"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Passer de l\'écran partagé au plein écran"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"En mode d\'écran partagé : remplacer une application par une autre"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Passer à l\'écran divisé avec l\'application actuelle à droite"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Passer à l\'écran divisé avec l\'application actuelle à gauche"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Passer de l\'écran divisé au plein écran"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une application par une autre"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrée"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Changer la langue d\'entrée (langue suivante)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Changer la langue d\'entrée (langue précédente)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Passer à la langue précédente"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Accéder aux émojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Accéder à l\'entrée vocale"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applications"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistance"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Navigateur (Chrome par défaut)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navigateur"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacts"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Courriel (Gmail par défaut)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Courriel"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Messages texte"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musique"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 9f22a57..6555f27 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Bouton <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Accueil"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Précédent"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Vers le haut"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Vers le bas"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Vers la gauche"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Vers la droite"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Flèche vers le haut"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Flèche vers le bas"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Flèche vers la gauche"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Flèche vers la droite"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centre"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Espace"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifications"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Raccourcis clavier"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Changer disposition du clavier"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Effacer le texte"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"ou"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Effacer la requête de recherche"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Raccourcis"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Raccourcis de recherche"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Aucun raccourci trouvé"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Saisie"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Applis ouvertes"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Appli actuelle"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Accéder au volet des notifications"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Prendre une capture d\'écran complète"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Accéder à la liste des raccourcis d\'applis/système"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Retour : revenir à l\'état précédent (bouton Retour)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Accéder à l\'écran d\'accueil"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Aperçu des applis ouvertes"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Parcourir les applis récentes (avancer)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Parcourir les applis récentes (reculer)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Accéder à la liste d\'applis et rechercher (Recherche/Lanceur d\'applis)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Masquer et (ré)afficher la barre des tâches"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Accéder aux paramètres système"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Accéder à l\'Assistant Google"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Affichage des résultats de recherche"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Affichage des raccourcis système"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Affichage des raccourcis clavier"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Affichage des raccourcis pour ouvrir les applications"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Affichage des raccourcis pour l\'application actuelle"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Afficher les notifications"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Prendre une capture d\'écran"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Afficher les raccourcis"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Retour"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Accéder à l\'écran d\'accueil"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Afficher les applis récentes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Aller vers les applications récentes"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Revenir sur les applications récentes"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ouvrir la liste d\'applications"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Afficher la barre des tâches"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ouvrir les paramètres"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Ouvrir l\'Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Verrouiller l\'écran"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Tirer l\'appli de notes vers le haut pour une note rapide"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Ouvrir les notes"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitâche du système"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Passer en écran partagé avec l\'appli actuelle affichée à droite"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Passer en écran partagé avec l\'appli actuelle affichée à gauche"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Passer de l\'écran partagé au plein écran"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"En mode écran partagé : remplacer une appli par une autre"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Passer en écran partagé avec l\'appli actuelle affichée à droite"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Passer en écran partagé avec l\'appli actuelle affichée à gauche"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Passer de l\'écran partagé au plein écran"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode écran partagé : Remplacer une appli par une autre"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Saisie"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Changer la langue de saisie (langue suivante)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Changer la langue de saisie (langue précédente)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Passer à la langue précédente"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Accéder aux emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Accéder à la saisie vocale"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applications"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistance"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Parcourir (Chrome par défaut)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navigateur"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacts"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-mail (Gmail par défaut)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Messagerie"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musique"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index a7341b0..716fcf2 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Inicio"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Volver"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Arriba"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Abaixo"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Esquerda"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Dereita"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centro"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Espazo"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notificacións"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Atallos de teclado"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Cambiar deseño do teclado"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Borrar o texto"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Atallos"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Buscar atallos"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Non se atoparon atallos"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrada"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Abrir aplicacións"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"App actual"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Acceder ao panel despregable"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Facer captura de pantalla completa"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Acceder á lista de atallos do sistema ou das aplicacións"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Atrás: Volver ao estado anterior (botón Atrás)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Acceder á pantalla de inicio"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Visión xeral de aplicacións abertas"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Percorrer aplicacións recentes (adiante)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Percorrer aplicacións recentes (atrás)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Acceder á lista de apps e á busca (por exemplo, a Busca ou Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ocultar e volver mostrar barra de tarefas"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Acceder á configuración do sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Acceder ao Asistente de Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Ver notificacións"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Facer captura de pantalla"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar atallos"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Volver"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Ir á pantalla de inicio"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Ver aplicacións recentes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Percorrer aplicacións recentes cara adiante"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Percorrer aplicacións recentes cara atrás"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Abrir lista de aplicacións"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Mostrar barra de tarefas"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir configuración"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir Asistente"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Pantalla de bloqueo"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Abrir aplicación Notas para facer unha nota rápida"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir notas"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitarefa do sistema"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Activar pantalla dividida con esta aplicación no lado dereito"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Activar pantalla dividida con esta aplicación no lado esquerdo"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Cambiar de pantalla dividida a pantalla completa"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"En modo de pantalla dividida: Substituír unha aplicación por outra"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Activar pantalla dividida con esta aplicación no lado dereito"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Activar pantalla dividida con esta aplicación no lado esquerdo"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Cambiar de pantalla dividida a pantalla completa"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"En modo de pantalla dividida: Substituír unha aplicación por outra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Cambiar idioma de escritura (seguinte idioma)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Cambiar idioma de escritura (idioma anterior)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar ao seguinte idioma"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Cambiar ao idioma anterior"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Acceder aos emojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Acceder á escritura por voz"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplicacións"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Asistente"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Navegador (predeterminado: Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistente"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contactos"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Correo electrónico (predeterminado: Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Correo electrónico"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 2ca21c5..8379865 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"બટન <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Up"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Center"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"નોટિફિકેશન"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"કીબોર્ડ શૉર્ટકટ"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"કીબોર્ડ લેઆઉટ સ્વિચ કરો"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ટેક્સ્ટ સાફ કરો"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"શૉર્ટકટ"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"શૉર્ટકટ શોધો"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"કોઈ શૉર્ટકટ મળ્યો નથી"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ઇનપુટ"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"ખુલ્લી ઍપનો ઓવરવ્યૂ"</string>
-    <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">"તમામ ઍપ અને શોધની સૂચિ (દા.ત. Search/Launcher) ઍક્સેસ કરો"</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 Assistant ઍક્સેસ કરો"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"નોટિફિકેશન જુઓ"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"સ્ક્રીનશૉટ લો"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"શૉર્ટકટ બતાવો"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"પાછળ જાઓ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"હોમ સ્ક્રીન પર જાઓ"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"તાજેતરની ઍપ જુઓ"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"તાજેતરની ઍપ પર આગળ જાઓ"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"તાજેતરની ઍપ પર પાછળ જાઓ"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ઍપની સૂચિ ખોલો"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"ટાસ્કબાર બતાવો"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"સેટિંગ ખોલો"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ખોલો"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"લૉક સ્ક્રીન"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"ઝડપી મેમો માટે Notes ઍપ ખોલો"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"નોંધ ખોલો"</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="2454557648974553729">"જમણી બાજુ પર હાલની ઍપ સાથે વિભાજિત સ્ક્રીનમાં દાખલ થાઓ"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"ડાબી બાજુ પર હાલની ઍપ સાથે વિભાજિત સ્ક્રીનમાં દાખલ થાઓ"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"વિભાજિત સ્ક્રીનથી પૂર્ણ સ્ક્રીન પર સ્વિચ કરો"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"વિભાજિત સ્ક્રીન દરમિયાન: એક ઍપને બીજી ઍપમાં બદલો"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"આગલી ભાષા પર સ્વિચ કરો"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"પાછલી ભાષા પર સ્વિચ કરો"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ઇમોજી ઍક્સેસ કરો"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"વૉઇસ ટાઇપિંગ ઍક્સેસ કરો"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ઍપ્લિકેશનો"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"સહાય"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"બ્રાઉઝર (ડિફૉલ્ટ તરીકે Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"બ્રાઉઝર"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"સંપર્કો"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ઇમેઇલ (ડિફૉલ્ટ તરીકે Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ઇમેઇલ"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"મ્યુઝિક"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 6a7d143..ab01d2b 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"बटन <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"ऊपर तीर"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"नीचे तीर"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"बायां तीर"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"दायां तीर"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"मध्य तीर"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"सूचनाएं"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"कीबोर्ड शॉर्टकट"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"कीबोर्ड लेआउट बदलें"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"टेक्स्ट मिटाएं"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"शॉर्टकट"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"शॉर्टकट खोजें"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"कोई शॉर्टकट नहीं मिला"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"इनपुट"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"खुले हुए ऐप्लिकेशन की जानकारी"</string>
-    <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">"सभी ऐप्लिकेशन और की गई खोजों की सूची ऐक्सेस करें (जैसे, Search/लॉन्चर)"</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 Assistant को ऐक्सेस करें"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"सूचनाएं देखें"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"स्क्रीनशॉट लें"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"शॉर्टकट दिखाएं"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"वापस जाएं"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"होम स्क्रीन पर जाएं"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखें"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन के अगले पेज पर जाएं"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन के पिछले पेज पर जाएं"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ऐप्लिकेशन की सूची खोलें"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"टास्कबार दिखाएं"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"सेटिंग खोलें"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Google Assistant खोलें"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"लॉक स्क्रीन"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"तेज़ी से मेमो बनाने के लिए Notes ऐप्लिकेशन का इस्तेमाल करें"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Notes ऐप्लिकेशन खोलें"</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="2454557648974553729">"स्प्लिट स्क्रीन का इस्तेमाल करके, मौजूदा ऐप्लिकेशन को दाईं ओर ले जाएं"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"स्प्लिट स्क्रीन का इस्तेमाल करके, मौजूदा ऐप्लिकेशन को बाईं ओर ले जाएं"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"स्प्लिट स्क्रीन से फ़ुल स्क्रीन मोड पर स्विच करें"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीन के दौरान: एक ऐप्लिकेशन को दूसरे ऐप्लिकेशन से बदलें"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"अगली भाषा पर स्विच करें"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"इस्तेमाल की गई पिछली भाषा पर स्विच करें"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"इमोजी ऐक्सेस करें"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"बोली को लिखाई में बदलने की सुविधा ऐक्सेस करें"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ऐप्लिकेशन"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"सहायक"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ब्राउज़र (डिफ़ॉल्ट के तौर पर Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ब्राउज़र"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"संपर्क"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ईमेल (डिफ़ॉल्ट के तौर पर Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ईमेल"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"मैसेज (एसएमएस) करें"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"संगीत"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 4469d78..7584e8a 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Tipka <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Početak"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Natrag"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Gore"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Dolje"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Lijevo"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Desno"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Sredina"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Razmaknica"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Obavijesti"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Tipkovni prečaci"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Promjena rasporeda tipkovnice"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Ukloni tekst"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Prečaci"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pretražite prečace"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nema nijednog prečaca"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Unos"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Otvaranje aplikacija"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Trenutačna aplikacija"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Pristupanje zaslonu obavijesti"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Izrada snimke cijelog zaslona"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Pristupanje popisu prečaca sustava/aplikacija"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Natrag: povratak na prethodno stanje (gumb za natrag)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Pristupanje početnom zaslonu"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Pregled otvorenih aplikacija"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Pregledavanje nedavnih aplikacija (unaprijed)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Pregledavanje nedavnih aplikacija (unatrag)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Pristupanje popisu svih aplikacija i pretraživanja (npr. Pretraživanje/Pokretač)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Sakrivanje i (ponovno) prikazivanje trake sa zadacima"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Pristupanje postavkama sustava"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Pristupanje Google asistentu"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Prikaži obavijesti"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Snimi zaslon"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Prikaži prečace"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Natrag"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Idi na početni zaslon"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Prikaži nedavne aplikacije"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Kruži unaprijed kroz nedavne aplikacije"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Kruži unatrag kroz nedavne aplikacije"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvori popis aplikacija"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Pokaži traku sa zadacima"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvori postavke"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvori Asistenta"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključavanje zaslona"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Izvlačenje aplikacije Bilješke za brzu bilješku"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Otvori bilješke"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Obavljanje više zadataka sustava"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Otvorite podijeljeni zaslon s trenutačnom aplikacijom s desne strane"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Otvorite podijeljeni zaslon s trenutačnom aplikacijom s lijeve strane"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Prijelaz s podijeljenog zaslona na cijeli zaslon"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Tijekom podijeljenog zaslona: zamijenite aplikaciju drugom"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Otvori podijeljeni zaslon s trenutačnom aplikacijom s desne strane"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Otvori podijeljeni zaslon s trenutačnom aplikacijom s lijeve strane"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Prijeđi s podijeljenog zaslona na cijeli zaslon"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijekom podijeljenog zaslona: zamijeni aplikaciju drugom"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Prebacivanje jezika unosa (sljedeći jezik)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Prebacivanje jezika unosa (prethodni jezik)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Prijeđi na sljedeći jezik"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Prijeđi na prethodni jezik"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Pristupanje emojijima"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Pristupanje unosu teksta govorom"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikacije"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Pomoć"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Preglednik (Chrome kao zadani)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Preglednik"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakti"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-pošta (Gmail kao zadani)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-pošta"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Glazba"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 51c3932..85fe455 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> gomb"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Kezdőképernyő"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Vissza"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Fel"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Le"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Balra"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Jobbra"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Középre"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Szóköz"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Értesítések"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Billentyűkódok"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Billentyűzetkiosztás váltása"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Szöveg törlése"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Billentyűparancsok"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Billentyűparancs keresése"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nincs billentyűparancs"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Bevitel"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Futó appok"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aktuális app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Ugrás az értesítési felületre"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Teljes képernyőkép készítése"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Ugrás a rendszer-/alkalmazás-parancsikonok listájához"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Vissza: visszaváltás az előző állapotra (vissza gomb)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Ugrás a kezdőképernyőre"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Megnyitott alkalmazások áttekintése"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Lépegetés a legutóbbi appok között (előre)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Lépegetés a legutóbbi appok között (visszafelé)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Ugrás az összes app listájához és a kereséshez (pl. Kereső/Indító)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Elrejtés és a feladatsáv (újbóli) megjelenítése"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Ugrás a rendszerbeállításokhoz"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Ugrás a Google Segédhez"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Értesítések megtekintése"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Képernyőkép készítése"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Parancsikonok megjelenítése"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Vissza"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Ugrás a kezdőképernyőre"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Legutóbbi alkalmazások megtekintése"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Lépegetés előrefelé a legutóbbi alkalmazások között"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Lépegetés visszafelé a legutóbbi alkalmazások között"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Alkalmazáslista megnyitása"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Feladatsáv megjelenítése"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Beállítások megnyitása"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"A Segéd megnyitása"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lezárási képernyő"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"A jegyzetkészítő app megnyitása gyors feljegyzés készítéséhez"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Jegyzetek megnyitása"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Rendszermultitasking"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Osztott képernyő aktiválása, az aktuális app kerüljön jobbra"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Osztott képernyő aktiválása, az aktuális app kerüljön balra"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Váltás osztott képernyőről teljes képernyőre"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Osztott képernyőn: az egyik app lecserélése egy másikra"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Osztott képernyő aktiválása; az aktuális alkalmazás kerüljön jobbra"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Osztott képernyő aktiválása; az aktuális alkalmazás kerüljön balra"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Váltás osztott képernyőről teljes képernyőre"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Osztott képernyőn: az egyik alkalmazás lecserélése egy másikra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Bevitel"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Beviteli nyelv váltása (következő nyelv)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Beviteli nyelv váltása (előző nyelv)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Váltás a következő nyelvre"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Váltás az előző nyelvre"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Ugrás az emojikhoz"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Ugrás a hangvezérelt íráshoz"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Alkalmazások"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Segédalkalmazás"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Böngésző (alapértelmezés szerint: Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Segéd"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Böngésző"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Névjegyek"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-mail-alkalmazás (alapértelmezés szerint: Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS-üzenetek"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Zene"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Naptár"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 917fb77..5be6a87 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> կոճակ"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Գլխավոր էջ"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Հետ"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Վերև"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Ներքև"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Ձախ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Աջ"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Կենտրոն"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Բացատ"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Ծանուցումներ"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Ստեղնային դյուրանցումներ"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Դասավորության փոխարկում"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Ջնջել տեքստը"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Դյուրանցումներ"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Դյուրանցումների որոնում"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Դյուրանցումներ չեն գտնվել"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Ներածում"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Բաց հավելվածների համատեսք"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Բացել համակարգի կարգավորումները"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Գործարկել Google Օգնականը"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Դիտել ծանուցումները"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Սքրինշոթ անել"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Ցույց տալ դյուրանցումները"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Հետ գնալ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Անցնել հիմնական էկրան"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Դիտել վերջին հավելվածները"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Առաջ անցնել վերջին հավելվածների միջով"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Հետ անցնել վերջին հավելվածների միջով"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Բացել հավելվածների ցանկը"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Ցուցադրել հավելվածների վահանակը"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Բացել կարգավորումները"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Բացել Օգնականը"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Կողպէկրան"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Բացել «Նշումներ» հավելվածը՝ արագ նշում ստեղծելու համար"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Բացել նշումները"</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="2454557648974553729">"Միացնել էկրանի տրոհումը՝ ընթացիկ հավելվածն աջ կողմում"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Միացնել էկրանի տրոհումը՝ ընթացիկ հավելվածը ձախ կողմում"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Տրոհված էկրանից անցնել լիաէկրան ռեժիմ"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Տրոհված էկրանի ռեժիմում մեկ հավելվածը փոխարինել մյուսով"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Անցնել հաջորդ լեզվին"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Անցնել նախորդ լեզվին"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Բացել էմոջիները"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Ակտիվացնել ձայնային ներածումը"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Հավելվածներ"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Օգնություն"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Դիտարկիչ (Chrome-ը որպես կանխադրված)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Օգնական"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Դիտարկիչ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Կոնտակտներ"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Էլփոստ (Gmail-ը որպես կանխադրված)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Էլփոստ"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Երաժշտություն"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Օրացույց"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 83db83b..8d372dc 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Tombol <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Up"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Center"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifikasi"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Pintasan keyboard"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Ganti tata letak keyboard"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Hapus teks"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Pintasan"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pintasan penelusuran"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Tidak ditemukan pintasan"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Input"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Aplikasi yang terbuka"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aplikasi saat ini"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Akses menu notifikasi"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Ambil screenshot penuh"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Akses daftar sistem/pintasan aplikasi"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Kembali: kembali ke status sebelumnya (tombol kembali)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Akses layar utama"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Ringkasan aplikasi yang terbuka"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Berpindah-pindah antara aplikasi terbaru (maju)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Berpindah-pindah antara aplikasi terbaru (mundur)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Akses daftar semua aplikasi dan penelusuran (yaitu Penelusuran/Peluncur)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Sembunyikan dan tampilkan (kembali) taskbar"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Akses setelan sistem"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Akses Asisten Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Lihat notifikasi"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ambil screenshot"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Tampilkan pintasan"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Kembali"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Buka layar utama"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Lihat aplikasi terbaru"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Menavigasi maju pada aplikasi terbaru"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Menavigasi mundur pada aplikasi terbaru"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Buka daftar aplikasi"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Tampilkan taskbar"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Buka setelan"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Buka Asisten"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Kunci layar"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Buka aplikasi Catatan untuk memo cepat"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Buka catatan"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking sistem"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Masuk ke Layar terpisah dengan aplikasi saat ini ke RHS"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Masuk ke Layar terpisah dengan aplikasi saat ini ke LHS"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Beralih dari Layar terpisah ke layar penuh"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Dalam Layar terpisah: ganti dari satu aplikasi ke aplikasi lainnya"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Masuk ke layar terpisah dengan aplikasi saat ini ke RHS"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Masuk ke layar terpisah dengan aplikasi saat ini ke LHS"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Beralih dari layar terpisah ke layar penuh"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Dalam layar terpisah: ganti salah satu aplikasi dengan yang lain"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Beralih bahasa input (bahasa berikutnya)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Beralih bahasa input (bahasa sebelumnya)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Beralih ke bahasa berikutnya"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Beralih ke bahasa sebelumnya"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Akses emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Akses dikte"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikasi"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Bantuan"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome sebagai default)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asisten"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontak"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (Gmail sebagai default)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index bf0b73d..102e8b8 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Hnappur <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Til baka"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Upp"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Niður"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Vinstri"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Hægri"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Ör upp"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Ör niður"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Ör til vinstri"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Ör til hægri"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Miðja"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Bilslá"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Tilkynningar"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Flýtilyklar"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Skipta um lyklaskipan"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Hreinsa texta"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"eða"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Hreinsa leitarfyrirspurn"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Flýtileiðir"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Leita að flýtileiðum"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Engar flýtileiðir fundust"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Innsláttur"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Opna forrit"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Gildandi forrit"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Opna tilkynningaglugga"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Taka heildarskjámynd"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Opna lista yfir flýtileiðir fyrir kerfi/forrit"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Til baka: Fara til baka í fyrri stöðu (bakkhnappur)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Opna heimaskjá"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Yfirlit yfir opin forrit"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Fletta í gegnum nýleg forrit (áfram)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Fletta í gegnum nýleg forrit (til baka)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Opna lista yfir öll forrit og leit (þ.e. Leit/Ræsiforrit)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Fela og sýna (aftur) forritastiku"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Opna kerfisstillingar"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Opna Google-hjálpara"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Sýnir leitarniðurstöður"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Sýnir flýtileiðir fyrir kerfi"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Sýnir flýtileiðir fyrir innslátt"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Sýnir flýtileiðir til að opna forrit"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Sýnir flýtileiðir fyrir núverandi forrit"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Skoða tilkynningar"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Taka skjámynd"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Sýna flýtilykla"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Til baka"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Opna heimaskjáinn"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Skoða nýleg forrit"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Fletta áfram í gegnum nýleg forrit"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Fletta aftur á bak í gegnum nýleg forrit"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Opna forritalista"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Sýna forritastiku"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Opna stillingar"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Opna Hjálpara"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lásskjár"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Opna glósuforrit til að skrá minnispunkt á fljótlegan hátt"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Opna glósur"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Fjölvinnsla kerfis"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Opna skjáskiptingu hægra megin með núverandi forriti"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Opna skjáskiptingu vinstra megin með núverandi forriti"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Skipta úr skjáskiptingu yfir í allan skjáinn"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Í skjáskiptingu: Skipta forriti út fyrir annað forrit"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Opna skjáskiptingu hægra megin með núverandi forriti"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Opna skjáskiptingu vinstra megin með núverandi forriti"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Skipta úr skjáskiptingu yfir á allan skjáinn"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Í skjáskiptingu: Skipta forriti út fyrir annað forrit"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Innsláttur"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Breyta innsláttartungumáli (næsta tungumál)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Breyta innsláttartungumáli (fyrra tungumál)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Skipta yfir í næsta tungumál"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Skipta yfir í fyrra tungumál"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Opna emoji-tákn"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Opna raddinnslátt"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Forrit"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Aðstoð"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Vafri (Chrome sem sjálfgefinn)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Hjálpari"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Vafri"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Tengiliðir"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Tölvupóstur (Gmail sem sjálfgefinn)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Tölvupóstur"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS-skilaboð"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Tónlist"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Dagatal"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index e65e3aa..aad1e56 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Pulsante <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home page"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Indietro"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Su"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Giù"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Sinistra"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Destra"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Al centro"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Spazio"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifiche"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Scorciatoie da tastiera"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Cambia layout della tastiera"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Cancella testo"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Scorciatoie"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Cerca scorciatoie"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Scorciatoie non trovate"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Inserimento"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"App aperte"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"App corrente"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Accedi all\'area notifiche"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Acquisisci uno screenshot completo"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Accedi all\'elenco di scorciatoie app e di sistema"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Indietro: torna allo stato precedente (pulsante Indietro)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Accedi alla schermata Home"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Panoramica delle app aperte"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Scorri le app recenti (in avanti)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Scorri le app recenti (a ritroso)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Accedi all\'elenco di tutte le app e alla ricerca (Ricerca/Avvio app)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Nascondi e mostra di nuovo la barra delle app"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Accedi alle impostazioni di sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Accedi all\'Assistente Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Visualizza notifiche"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Acquisisci screenshot"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostra scorciatoie"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Indietro"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Vai alla schermata Home"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Visualizza app recenti"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Spostati avanti tra le app recenti"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Spostati indietro tra le app recenti"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Apri elenco di app"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Mostra barra delle app"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Apri impostazioni"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Apri l\'assistente"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Blocca lo schermo"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Visualizza l\'app Note per appunti rapidi"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Apri note"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking di sistema"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Attiva lo schermo diviso con l\'app corrente a destra"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Attiva lo schermo diviso con l\'app corrente a sinistra"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Passa da schermo diviso a schermo intero"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Con lo schermo diviso: sostituisci un\'app con un\'altra"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Attiva lo schermo diviso con l\'app corrente a destra"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Attiva lo schermo diviso con l\'app corrente a sinistra"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Passa da schermo diviso a schermo intero"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Con lo schermo diviso: sostituisci un\'app con un\'altra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Inserimento"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Cambia lingua di inserimento (lingua successiva)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Cambia lingua di inserimento (lingua precedente)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passa alla prossima lingua"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Passa alla lingua precedente"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Accedi all\'emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Accedi alla digitazione vocale"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applicazioni"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistenza"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (quello predefinito è Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistente"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contatti"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (l\'app predefinita è Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musica"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index a14aa1b..bbfbe32 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"לחצן <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"דף הבית"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"הקודם"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"למעלה"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"למטה"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"שמאלה"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ימינה"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"חץ למעלה"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"חץ למטה"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"חץ שמאלה"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"חץ ימינה"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"מרכז"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"רווח"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"התראות"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"מקשי קיצור במקלדת"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"החלפה של פריסת מקלדת"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"מחיקת הטקסט"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"או"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"ניקוי שאילתת החיפוש"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"מקשי קיצור"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"חיפוש מקשי קיצור"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"לא נמצאו מקשי קיצור"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"קלט"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"סקירה כללית של האפליקציות הפתוחות"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"גישה להגדרות המערכת"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"‏גישה ל-Google Assistant"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"מוצגות: תוצאות החיפוש"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"מוצגים: קיצורי הדרך של המערכת"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"מוצגים: קיצורי הדרך של הקלט"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"מוצגים: קיצורי הדרך לפתיחת אפליקציות"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"מוצגים: קיצורי הדרך של האפליקציה הנוכחית"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"הצגת הודעות"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"צילום המסך"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"הצגת מקשי הקיצור"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"חזרה"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"מעבר למסך הבית"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"הצגת האפליקציות האחרונות"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"דפדוף קדימה באפליקציות האחרונות"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"דפדוף אחורה באפליקציות האחרונות"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"פתיחה של רשימת האפליקציות"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"הצגת סרגל האפליקציות"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"פתיחת ההגדרות"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"‏לפתיחת Google Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"מסך הנעילה"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"אפשר למשוך למעלה את אפליקציית הפתקים לשימוש מהיר"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"פתיחה של אפליקציית הפתקים"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ריבוי משימות מערכת"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"‏כניסה למסך מפוצל עם האפליקציה הנוכחית ל-RHS"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"‏כניסה למסך מפוצל עם האפליקציה הנוכחית ל-LHS"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"החלפה ממסך מפוצל למסך מלא"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"כשהמסך מפוצל: החלפה בין אפליקציה אחת לאחרת"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"‏כניסה למסך מפוצל עם האפליקציה הנוכחית ל-RHS"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"‏כניסה למסך מפוצל עם האפליקציה הנוכחית ל-LHS"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"החלפה ממסך מפוצל למסך מלא"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"כשהמסך מפוצל: החלפה בין אפליקציה אחת לאחרת"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"מעבר לשפה הבאה"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"מעבר לשפה הקודמת"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"גישה לאמוג\'י"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"גישה להכתבה בקול"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"אפליקציות"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"אסיסטנט"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"‏דפדפן (Chrome כברירת מחדל)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"דפדפן"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"אנשי קשר"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"‏אימייל (Gmail כברירת מחדל)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"אימייל"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"מוזיקה"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"יומן"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 75166d9..c8a0a54 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> ボタン"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"戻る"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"上"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"下"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"左"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"右"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"中央"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"通知"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"キーボード ショートカット"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"キーボード レイアウトの切り替え"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"テキストを消去"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"ショートカット"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ショートカットの検索"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ショートカットがありません"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"入力"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"開いているアプリの概要"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"システム設定にアクセス"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google アシスタントにアクセス"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"お知らせを表示する"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"スクリーンショットを撮る"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"ショートカットを表示する"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"戻る"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ホーム画面に移動する"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"最近使ったアプリを表示する"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"最近使ったアプリを確認する"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"最近使ったアプリを確認する(逆方向)"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"アプリの一覧を開く"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"タスクバーを表示する"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"設定を開く"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"アシスタントを開く"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"画面をロック"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"クイックメモのためにメモアプリを表示"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"メモを開く"</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="2454557648974553729">"分割画面にして現在のアプリを右側に設定する"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"分割画面にして現在のアプリを左側に設定する"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"分割画面から全画面に切り替える"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"分割画面中: アプリを順に置換する"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"次の言語に切り替える"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"前の言語に切り替える"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"絵文字にアクセス"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"音声入力にアクセス"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"アプリ"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"アシスト"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ブラウザ(デフォルト: Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"アシスタント"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ブラウザ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"連絡先"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"メール(デフォルト: Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"メール"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音楽"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"カレンダー"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index b363f99..c6c4a57 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"ღილაკი „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"უკან"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"ზემოთ"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"ქვემოთ"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"მარცხნივ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"მარჯვნივ"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"ზემოთ მიმართული ისარი"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"ქვემოთ მიმართული ისარი"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"მარცხნივ მიმართული ისარი"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"მარჯვნივ მიმართული ისარი"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"ცენტრში"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"შორისი"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"შეტყობინებები"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"კლავიატურის მალსახმობები"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"კლავიატურის განლაგების გადართვა"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ტექსტის გასუფთავება"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"ან"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"საძიებო ფრაზის გასუფთავება"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"მალსახმობები"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"მალსახმობების ძიება"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"მალსახმობები ვერ მოიძებნა"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"შეყვანა"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"ღია აპების მიმოხილვა"</string>
-    <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">"ყველა აპსა და ძიებაზე წვდომის სია (ე.ი. Search/გამშვები)"</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="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"ნაჩვენებია ძიების შედეგები"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"ნაჩვენებია სისტემის მალსახმობები"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"ნაჩვენებია შენატანის მალსახმობები"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"ნაჩვენებია მალსახმობები, რომლებიც ხსნის აპებს"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"ნაჩვენებია მალსახმობები მიმდინარე აპისთვის"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"შეტყობინებების ნახვა"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ეკრანის ანაბეჭდის გადაღება"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"მალსახმობების ჩვენება"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"უკან დაბრუნება"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"მთავარ ეკრანზე გადასვლა"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"ბოლო აპების ნახვა"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"წინ გადასვლა ბოლოდროინდელი აპების მეშვეობით"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"უკან გადასვლა ბოლოდროინდელი აპების მეშვეობით"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"აპების სიის გახსნა"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"ამოცანათა ზოლის ჩვენება"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"პარამეტრების გახსნა"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"ასისტენტის გახსნა"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"ჩაკეტილი ეკრანი"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"ჩანიშვნების აპის ამოწევა სწრაფი ჩანაწერისთვის"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"ჩანიშვნების გახსნა"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"სისტემის მრავალამოცანიანი რეჟიმი"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"ეკრანის გაყოფის შეყვანა მიმდინარე აპით RHS-ში"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"ეკრანის გაყოფის შეყვანა მიმდინარე აპით LHS-ში"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"გადართვა ეკრანის გაყოფიდან სრულ ეკრანზე"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"ეკრანის გაყოფის დროს: ერთი აპის მეორით ჩანაცვლება"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"ეკრანის გაყოფის შეყვანა მიმდინარე აპით RHS-ში"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"ეკრანის გაყოფის შეყვანა მიმდინარე აპით LHS-ში"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"გადართვა ეკრანის გაყოფიდან სრულ ეკრანზე"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"ეკრანის გაყოფის დროს: ერთი აპის მეორით ჩანაცვლება"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"შემდეგ ენაზე გადართვა"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"წინა ენაზე გადართვა"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"emoji-ზე წვდომა"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"ხმოვან აკრეფაზე წვდომა"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"აპლიკაციები"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"დახმარება"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ბრაუზერი (Chrome ნაგულისხმევად)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"ასისტენტი"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ბრაუზერი"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"კონტაქტები"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ელფოსტა (Gmail ნაგულისხმევად)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ელფოსტა"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"მუსიკა"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"კალენდარი"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index b887e4b..2831cf9 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> түймесі"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Артқа"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Жоғары"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Төмен"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Сол"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Оң"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Орталық"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Бос орын"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Хабарландырулар"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Перне тіркесімдері"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Пернетақта форматын ауыстыру"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Мәтінді өшіру"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Перне тіркесімдері"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Перне тіркесімдерін іздеу"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Перне тіркесімдері табылмады."</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Енгізу"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Ашылған қолданбаларға шолу"</string>
-    <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">"Барлық қолданба мен іздеу нәтижесі тізімін (яғни Search/Launcher) пайдалану"</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 Assistant-ке кіру"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Хабарландыруларды көру"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Скриншот жасау"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Жылдам пәрмендерді көрсету"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Артқа"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Негізгі экранға өту"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Соңғы қолданбаларды көру"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Соңғы қолданбаларға алға өту"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Соңғы қолданбаларға артқа өту"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Қолданбалар тізімін ашу"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Тапсырмалар жолағын көрсету"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Параметрлерді ашу"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant-ті ашу"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Экранды құлыптау"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Жылдам ескертпе жасау үшін ескертпелер қолданбасын ашу"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Ескертпелерді ашу"</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="2454557648974553729">"Бөлінген экран режиміне кіру (ағымдағы қолданбаны оңға орналастыру)"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Бөлінген экран режиміне кіру (ағымдағы қолданбаны солға орналастыру)"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Бөлінген экран режимінен толық экран режиміне ауысу"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлу кезінде: бір қолданбаны басқасымен алмастыру"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Келесі тілге ауысу"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Алдыңғы тілге ауысу"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Эмоджи пайдалану"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Дауыспен теру функциясын пайдалану"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Қолданбалар"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Көмекші"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Браузер (әдепкісінше Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Браузер"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Контактілер"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Электрондық пошта (әдепкісінше Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Электрондық пошта"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Мәтіндік хабар"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Mузыка"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Күнтізбе"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 0a4c2d8..aff6ef7 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"ប៊ូតុង <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Up"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Center"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"ការជូនដំណឹង"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"ផ្លូវកាត់ក្ដារចុច"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"ប្ដូរប្លង់ក្ដារចុច"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"សម្អាតអក្សរ"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"ផ្លូវកាត់"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ស្វែងរកផ្លូវកាត់"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"រកផ្លូវកាត់មិនឃើញទេ"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"បញ្ចូល"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"ទិដ្ឋភាពរួមអំពីកម្មវិធីដែលបើក"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"ចូលប្រើប្រាស់ការ​កំណត់​ប្រព័ន្ធ"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"ចូលប្រើប្រាស់ Google Assistant"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"មើលការជូនដំណឹង"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ថតរូប​អេក្រង់"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"បង្ហាញផ្លូវកាត់"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ថយ​ក្រោយ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ចូលទៅកាន់អេក្រង់ដើម"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"មើលកម្មវិធីថ្មីៗ"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"រុករកទៅមុខ ដើម្បីមើលកម្មវិធីថ្មីៗ"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"រុករកថយក្រោយ ដើម្បីមើលកម្មវិធីថ្មីៗ"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"បើកបញ្ជីកម្មវិធី"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"បង្ហាញរបារកិច្ចការ"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"បើកការកំណត់"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"បើក​ជំនួយការ"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"ចាក់​សោ​អេក្រង់"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"ទាញកម្មវិធីកំណត់ចំណាំឡើងលើ ដើម្បីប្រើកំណត់ហេតុរហ័ស"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"បើក​កំណត់ចំណាំ"</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="2454557648974553729">"ចូលក្នុងមុខងារបំបែកអេក្រង់ដោយប្រើកម្មវិធីបច្ចុប្បន្ននៅខាងស្ដាំដៃ"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"ចូលក្នុងមុខងារ​បំបែកអេក្រង់ដោយប្រើកម្មវិធីបច្ចុប្បន្ននៅខាងឆ្វេងដៃ"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"ប្ដូរពីមុខងារ​បំបែកអេក្រង់ទៅជាអេក្រង់ពេញ"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"ក្នុងអំឡុងពេលប្រើមុខងារបំបែកអេក្រង់៖ ជំនួសកម្មវិធីពីមួយទៅមួយទៀត"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"ប្ដូរទៅភាសាបន្ទាប់"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ប្ដូរទៅភាសាមុន"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ចូលប្រើប្រាស់រូបអារម្មណ៍"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"ចូលប្រើប្រាស់ការវាយបញ្ចូលដោយប្រើសំឡេង"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"កម្មវិធី"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"ជំនួយ"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"កម្មវិធីរុករកតាមអ៊ីនធឺណិត (Chrome តាមលំនាំដើម)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Google Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"កម្មវិធីរុករក"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"ទំនាក់ទំនង"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"អ៊ីមែល (Gmail តាមលំនាំដើម)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"អ៊ីមែល"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"សារ SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"តន្ត្រី"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ប្រតិទិន"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 850bb0a..5be72d8 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> ಬಟನ್"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"ಹಿಂದೆ"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"ಮೇಲೆ"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"ಕೆಳಗೆ"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ಎಡ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ಬಲ"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"ಮಧ್ಯ"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"ಸ್ಪೇಸ್"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"ನೋಟಿಫಿಕೇಶನ್‌ಗಳು"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"ಕೀಬೋರ್ಡ್‌ ಲೇಔಟ್‌ ಬದಲಾಯಿಸಿ"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ಪಠ್ಯ ತೆರವುಗೊಳಿಸಿ"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ಯಾವುದೇ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳಿಲ್ಲ"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ಇನ್‌ಪುಟ್"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"ತೆರೆದ ಆ್ಯಪ್‌ಗಳ ಅವಲೋಕನ"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"ಸಿಸ್ಟಂ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಿ"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Access Google Assistant ಅನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಿ"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ತೋರಿಸಿ"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ಹಿಂತಿರುಗಿ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಹೋಗಿ"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"ಇತ್ತೀಚೆಗೆ ಬಳಸಿದ ಆ್ಯಪ್‌ಗಳ ಸಹಾಯದಿಂದ ಮುಂದಕ್ಕೆ ಹೋಗಿ"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"ಇತ್ತೀಚೆಗೆ ಬಳಸಿದ ಆ್ಯಪ್‌ಗಳ ಸಹಾಯದಿಂದ ಹಿಂದಕ್ಕೆ ಹೋಗಿ"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ಆ್ಯಪ್‌ಗಳ ಪಟ್ಟಿಯನ್ನು ತೆರೆಯಿರಿ"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"ಟಾಸ್ಕ್‌ಬಾರ್ ಅನ್ನು ತೋರಿಸಿ"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"ಸೆಟ್ಟಿಂಗ್‍ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"assistant ಅನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಮಾಡಿ"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"ತ್ವರಿತ ಮೆಮೊಗಾಗಿ ಟಿಪ್ಪಣಿಗಳ ಆ್ಯಪ್ ಅನ್ನು ಮೇಲಕ್ಕೆ ಎಳೆಯಿರಿ"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"ಟಿಪ್ಪಣಿಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ಸಿಸ್ಟಂ ಮಲ್ಟಿಟಾಸ್ಕಿಂಗ್"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"RHS ಗೆ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಜೊತೆಗೆ ಪರದೆ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"LHS ಗೆ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಜೊತೆಗೆ ಪರದೆ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"ಪರದೆ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್‌ನಿಂದ ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ಗೆ ಬದಲಿಸಿ"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"ಪರದೆ ಬೇರ್ಪಡಿಸುವ ಸಮಯದಲ್ಲಿ: ಒಂದು ಆ್ಯಪ್‌ನಿಂದ ಮತ್ತೊಂದು ಆ್ಯಪ್‌ಗೆ ಬದಲಾಯಿಸಿ"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHS ಗೆ ಇರುವ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಸಹಾಯದಿಂದ ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ನಮೂದಿಸಿ"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHS ಗೆ ಇರುವ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಸಹಾಯದಿಂದ ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ನಮೂದಿಸಿ"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್‌ನಿಂದ ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ಗೆ ಬದಲಿಸಿ"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸುವ ಸಮಯದಲ್ಲಿ: ಒಂದು ಆ್ಯಪ್‌ನಿಂದ ಮತ್ತೊಂದು ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"ಮುಂದಿನ ಭಾಷೆಗೆ ಬದಲಿಸಿ"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ಹಿಂದಿನ ಭಾಷೆಗೆ ಬದಲಿಸಿ"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ಎಮೋಜಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಿ"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"ಧ್ವನಿ ಟೈಪಿಂಗ್ ಅನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಿ"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"ಸಹಾಯ ಮಾಡು"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ಬ್ರೌಸರ್ (ಡೀಫಾಲ್ಟ್ ಆಗಿ Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ಬ್ರೌಸರ್"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"ಸಂಪರ್ಕಗಳು"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ಇಮೇಲ್ (ಡೀಫಾಲ್ಟ್ ಆಗಿ Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ಇಮೇಲ್"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"ಎಸ್ಎಂಎಸ್"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ಸಂಗೀತ"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index a9395b2..71c0a35 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> 버튼"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"뒤로"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"위쪽"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"아래쪽"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"왼쪽"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"오른쪽"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"중앙"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"알림"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"단축키"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"키보드 레이아웃 전환"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"텍스트 삭제"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"단축키"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"단축키 검색"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"단축키 없음"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"입력"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"열린 앱 개요"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"시스템 설정에 액세스"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google 어시스턴트에 액세스"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"알림 보기"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"스크린샷 촬영"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"단축키 표시"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"돌아가기"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"홈 화면으로 이동"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"최근 앱 보기"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"최근 앱 간 앞으로 순환"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"최근 앱 간 뒤로 순환"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"앱 목록 열기"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"태스크 바 표시"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"설정 열기"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"어시스턴트 열기"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"잠금 화면"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"빠른 메모를 위해 노트 앱 불러오기"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"메모 열기"</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="2454557648974553729">"현재 앱을 오른쪽으로 보내는 화면 분할 입력"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"현재 앱을 왼쪽으로 보내는 화면 분할 입력"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"화면 분할에서 전체 화면으로 전환"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"화면 분할 중: 다른 앱으로 바꾸기"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"다음 언어로 전환"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"이전 언어로 전환"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"이모티콘에 액세스"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"음성 입력에 액세스"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"애플리케이션"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"지원"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"브라우저(Chrome을 기본값으로 설정)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"어시스턴트"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"브라우저"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"연락처"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"이메일(Gmail을 기본값으로 설정)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"이메일"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"음악"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"캘린더"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 73e7647..6276160 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> баскычы"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Башкы бет"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Артка"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Өйдө"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Төмөн"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Солго"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Оңго"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Ортолотуу"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Боштук"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Билдирмелер"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Ыкчам баскычтар"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Баскычтоп калыбын которуштуруу"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Текстти тазалоо"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Ыкчам баскычтар"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Ыкчам баскычтарды издөө"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Ыкчам баскычтар жок"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Киргизүү"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Ачылып турган колдонмолордун тизмесин көрүү"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Система параметрлерине кирүү"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Жардамчыны иштетүү"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Билдирмелерди көрүү"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Скриншот тартуу"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Ыкчам баскычтарды көрсөтүү"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Артка кайтуу"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Башкы экранга өтүү"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Акыркы колдонмолорду көрүү"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Соңку колдонмолордо алдыга өтүү"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Соңку колдонмолордо артка кайтуу"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Колдонмолордун тизмесин ачуу"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Тапшырмалар панелин көрсөтүү"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Параметрлерди ачуу"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Жардамчыны ачуу"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Экранды кулпулоо"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Ыкчам кыска жазууну түзүү"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Кыска жазууларды ачуу"</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="2454557648974553729">"Учурда оң жактагы колдонмо менен экранды бөлүүнү иштетүү"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Учурда сол жактагы колдонмо менен экранды бөлүүнү иштетүү"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Экранды бөлүү режиминен толук экранга которулуу"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлүү режиминде бир колдонмону экинчисине алмаштыруу"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Кийинки тилге которулуу"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Мурунку тилге которулуу"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Быйтыкчаларды көрүү"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Айтып терүүнү иштетүү"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Колдонмолор"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Көмөкчү"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Серепчи (демейки шартта Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Жардамчы"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Серепчи"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Байланыштар"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Электрондук почта (демейки шартта Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Электрондук почта"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Жылнаама"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index e9f6a19..5da52a5 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"ປຸ່ມ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"ກັບຄືນ"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"ຂຶ້ນ"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"ລົງ"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ຊ້າຍ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ຂວາ"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"ເຄິ່ງກາງ"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"ການແຈ້ງເຕືອນ"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"ປຸ່ມລັດແປ້ນພິມ"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"ສະຫຼັບແປ້ນພິມ"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ລຶບລ້າງຂໍ້ຄວາມ"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"ທາງລັດ"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ທາງລັດການຊອກຫາ"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ບໍ່ພົບທາງລັດ"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ການປ້ອນຂໍ້ມູນ"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"ພາບຮວມຂອງແອັບທີ່ເປີດຢູ່"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"ເຂົ້າເຖິງການຕັ້ງຄ່າລະບົບ"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"ເຂົ້າເຖິງຜູ້ຊ່ວຍ Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"ເບິ່ງການແຈ້ງເຕືອນ"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ຖ່າຍຮູບໜ້າຈໍ"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"ສະແດງທາງລັດ"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ກັບຄືນ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ເຂົ້າໄປໂຮມສະກຣີນ"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"ເບິ່ງແອັບຫຼ້າສຸດ"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"ສະຫຼັບລະຫວ່າງແອັບຫຼ້າສຸດແບບໄປໜ້າ"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"ສະຫຼັບລະຫວ່າງແອັບຫຼ້າສຸດແບບກັບຫຼັງ"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ເປີດລາຍຊື່ແອັບ"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"ສະແດງແຖບໜ້າວຽກ"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"ເປີດການຕັ້ງຄ່າ"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"ເປີດຜູ້ຊ່ວຍ"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"ໜ້າຈໍລັອກ"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"ດຶງແອັບ Notes ຂຶ້ນມາເພື່ອບັນທຶກຢ່າງວ່ອງໄວ"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"ເປີດບັນທຶກ"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ການເຮັດຫຼາຍໜ້າວຽກພ້ອມກັນຂອງລະບົບ"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"ເຂົ້າສູ່ແບ່ງໜ້າຈໍດ້ວຍແອັບປັດຈຸບັນໄປຫາ RHS"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"ເຂົ້າສູ່ແບ່ງໜ້າຈໍດ້ວຍແອັບປັດຈຸບັນໄປຫາ LHS"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"ສະຫຼັບຈາກແບ່ງໜ້າຈໍໄປເປັນເຕັມຈໍ"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"ໃນລະຫວ່າງແບ່ງໜ້າຈໍ: ປ່ຽນແທນຈາກແອັບໜຶ່ງໄປຫາແອັບອື່ນ"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"ເຂົ້າສູ່ແບ່ງໜ້າຈໍດ້ວຍແອັບປັດຈຸບັນໄປຫາ RHS"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"ເຂົ້າສູ່ແບ່ງໜ້າຈໍດ້ວຍແອັບປັດຈຸບັນໄປຫາ LHS"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"ສະຫຼັບຈາກແບ່ງໜ້າຈໍໄປເປັນເຕັມຈໍ"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"ໃນລະຫວ່າງແບ່ງໜ້າຈໍ: ໃຫ້ປ່ຽນຈາກແອັບໜຶ່ງເປັນອີກແອັບໜຶ່ງ"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"ສະຫຼັບເປັນພາສາຖັດໄປ"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ສະຫຼັບເປັນພາສາກ່ອນໜ້າ"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ເຂົ້າເຖິງອີໂມຈິ"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"ເຂົ້າເຖິງການພິມດ້ວຍສຽງ"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ແອັບພລິເຄຊັນ"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"ຕົວຊ່ວຍ"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ໂປຣແກຣມທ່ອງເວັບ (Chrome ເປັນຄ່າເລີ່ມຕົ້ນ)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"ຜູ້ຊ່ວຍ"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ໂປຣແກຣມທ່ອງເວັບ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"ລາຍຊື່ຜູ້ຕິດຕໍ່"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ອີເມວ (Gmail ເປັນຄ່າເລີ່ມຕົ້ນ)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ອີເມວ"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"ຂໍ້ຄວາມສັ້ນ(SMS)"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ດົນຕີ"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ປະຕິທິນ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 0e9e940..34c06bd 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Mygtukas <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Pagrindinis"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Atgal"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Aukštyn"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Žemyn"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Kairėn"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Dešinėn"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centras"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Tarpas"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Pranešimai"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Spartieji klavišai"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Perjungti klaviat. išdėstymą"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Išvalyti tekstą"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Spartieji klavišai"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Ieškoti sparčiųjų klavišų"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Sparčiųjų klavišų nerasta"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Įvestis"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Atidar. progr."</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Esama programa"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Pasiekti pranešimų skydelį"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Padaryti viso ekrano kopiją"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Pasiekti sistemos sąrašą / programų šaukinius"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Atgal: grįžti prie ankstesnės būsenos (mygtukas „Atgal“)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Pasiekti pagrindinį ekraną"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Peržiūrėti atidarytas programas"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Pereiti prie naujausių programų (į priekį)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Pereiti prie naujausių programų (atgal)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Visų progr. ir paiešk. prieig. sąrašas (t. y. Paieška, paleid. priem.)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Slėpti ir (iš naujo) parodyti užduočių juostą"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Pasiekti sistemos nustatymus"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Pasiekti „Google“ padėjėją"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Peržiūrėti pranešimus"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Padaryti ekrano kopiją"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Rodyti sparčiuosius klavišus"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Grįžti"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Grįžti į pagrindinį ekraną"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Peržiūrėti naujausias programas"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Pereiti į priekį per naujausias programas"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Pereiti atgal per naujausias programas"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Atidaryti programų sąrašą"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Rodyti užduočių juostą"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Atidaryti nustatymus"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Atidaryti Padėjėją"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Užrakinti ekraną"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Gauti pastabų programą trumpiems užrašams"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Atidaryti pastabas"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Kelių užduočių atlikimas sistemoje"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Eiti į išskaidyto ekrano režimą su dabartine programa dešinėje"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Eiti į išskaidyto ekrano režimą su dabartine programa kairėje"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Perjungti iš išskaidyto ekrano režimo į viso ekrano režimą"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Išskaidyto ekrano režimu: pakeisti iš vienos programos į kitą"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Eiti į išskaidyto ekrano režimą su dabartine programa dešinėje"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Eiti į išskaidyto ekrano režimą su dabartine programa kairėje"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Perjungti iš išskaidyto ekrano režimo į viso ekrano režimą"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Išskaidyto ekrano režimu: pakeisti iš vienos programos į kitą"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Įvestis"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Perjungti įvesties kalbą (kita kalba)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Perjungti įvesties kalbą (ankstesnė kalba)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Perjungti į kitą kalbą"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Perjungti ankstesnę kalbą"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Pasiekti jaustuką"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Pasiekti rašymą balsu"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Programos"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Pagalbinė programa"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Naršyti („Chrome“ kaip numatytoji naršyklė)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Padėjėjas"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Naršyklė"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontaktai"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"El. paštas („Gmail“ kaip numatytasis el. paštas)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"El. paštas"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendorius"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 8c7af63..66933bc 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Poga <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Sākumvietas taustiņš"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Atpakaļ"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Uz augšu"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Uz leju"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Pa kreisi"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Pa labi"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centrā"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Atstarpe"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Paziņojumi"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Īsinājumtaustiņi"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Mainīt tastatūras izkārtojumu"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Notīrīt tekstu"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Īsinājumtaustiņi"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Meklēt īsinājumtaustiņus"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nav atrasti"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Ievade"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Atvērtās"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Pašreizējā"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Piekļūt paziņojumu panelim"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Izveidot visa ekrāna ekrānuzņēmumu"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Piekļūt sistēmas/lietotnes saīšņu sarakstam"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Atpakaļ: atgriezties iepriekšējā stāvoklī (poga Atpakaļ)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Piekļūt sākuma ekrānam"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Atvērto lietotņu kopsavilkums"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Secīgi pārlūkot nesen izmantotās lietotnes (pāriet uz nākamo)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Secīgi pārlūkot nesen izmantotās lietotnes (pāriet uz iepriekšējo)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Visu lietotņu saraksts un meklēšana (meklēšana / Palaišanas programma)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Paslēpt vai (atkārtoti) parādīt uzdevumu joslu"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Piekļūt sistēmas iestatījumiem"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Piekļūt Google asistentam"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Skatīt paziņojumus"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Izveidot ekrānuzņēmumu"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Rādīt īsinājumtaustiņus"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Atpakaļ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Pāriet uz sākuma ekrānu"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Skatīt nesen izmantotās lietotnes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Secīgi pārlūkot nesen izmantotās lietotnes (pāriet uz nākamo)"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Secīgi pārlūkot nesen izmantotās lietotnes (pāriet uz iepriekšējo)"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Atvērt lietotņu sarakstu"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Rādīt uzdevumu joslu"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Atvērt iestatījumus"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Atvērt Asistentu"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Bloķēt ekrānu"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Atvērt piezīmju lietotni, lai izveidotu piezīmi"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Atvērt piezīmes"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Sistēmas vairākuzdevumu režīms"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Pāriet ekrāna sadalīšanas režīmā ar pašreizējo lietotni pa labi"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Pāriet ekrāna sadalīšanas režīmā ar pašreizējo lietotni pa kreisi"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Pārslēgties no ekrāna sadalīšanas režīma uz pilnekrāna režīmu"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Ekrāna sadalīšanas režīmā: pārvietot lietotni no viena uz otru"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Pāriet ekrāna sadalīšanas režīmā ar pašreizējo lietotni pa labi"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Pāriet ekrāna sadalīšanas režīmā ar pašreizējo lietotni pa kreisi"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Pārslēgties no ekrāna sadalīšanas režīma uz pilnekrāna režīmu"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Ekrāna sadalīšanas režīmā: pārvietot lietotni no viena ekrāna uz otru"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ievade"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Pārslēgt ievades valodu (uz nākamo valodu)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Pārslēgt ievades valodu (uz iepriekšējo valodu)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Pārslēgt uz nākamo valodu"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Pārslēgt uz iepriekšējo valodu"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Piekļūt emocijzīmēm"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Piekļūt rakstīšanai ar balsi"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Lietojumprogrammas"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Palīgs"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Pārlūks (pēc noklusējuma Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistents"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Pārlūkprogramma"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontaktpersonas"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-pasts (pēc noklusējuma Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-pasts"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Īsziņas"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Mūzika"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendārs"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 6c577ce..44f6e0c 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -401,11 +401,9 @@
     <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="communal_tutorial_indicator_text" msgid="4503010353591430123">"Повлечете налево за да го започнете заедничкото упатство"</string>
-    <!-- no translation found for button_to_open_widget_editor (5599945944349057600) -->
-    <skip />
+    <string name="button_to_open_widget_editor" msgid="5599945944349057600">"Го отвора уредникот на виџети"</string>
     <string name="button_to_remove_widget" msgid="1511255853677835341">"Отстранува виџет"</string>
-    <!-- no translation found for hub_mode_add_widget_button_text (3956587989338301487) -->
-    <skip />
+    <string name="hub_mode_add_widget_button_text" msgid="3956587989338301487">"Додајте виџет"</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>
@@ -642,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Копче <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home-копче"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Назад"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Стрелка нагоре"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Стрелка надолу"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Стрелка налево"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Стрелка надесно"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Центар"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -673,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Известувања"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Кратенки на тастатурата"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Промени јазик на тастатура"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Избришете го текстот"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Кратенки"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Пребарувајте кратенки"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Не се пронајдени кратенки"</string>
@@ -681,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Внесување"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Преглед на отворените апликации"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Пристапете до поставките на системот"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Пристапете до „Помошник на Google“"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Прегледајте ги известувањата"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Направете слика од екранот"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Прикажи кратенки"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Вратете се назад"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Одете на почетниот екран"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Прегледајте ги неодамнешните апликации"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Прелистувајте ги неодамнешните апликации нанапред"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Прелистувајте ги неодамнешните апликации наназад"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Отворете го списокот со апликации"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Прикажи „Лента со задачи“"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Отворете „Поставки“"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Отворете го „Помошникот“"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Заклучен екран"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Отворете ја апликацијата „Белешки“ за брз меморандум"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Отворете „Белешки“"</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="2454557648974553729">"Активирајте поделен екран со тековната апликација десно"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Активирајте поделен екран со тековната апликација лево"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Префрлете од поделен екран во цел екран"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"При поделен екран: префрлете ги аплик. од едната на другата страна"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Префрлете на следниот јазик"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Префрлете на претходниот јазик"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Пристапете до емоџијата"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Пристапете до гласовното пишување"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Апликации"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Помош"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Прелистувач (Chrome е стандардна опција)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Помошник"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Прелистувач"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Контакти"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Е-пошта (Gmail е стандардна опција)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Е-пошта"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 7354e91..4644fa5 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"ബട്ടൺ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"ഹോം"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"ബാക്ക്"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"മുകളിലേക്ക്"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"താഴേക്ക്"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ഇടത്"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"വലത്"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"മധ്യം"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"TAB"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"സ്പെയ്സ്"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"അറിയിപ്പുകൾ"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"കീബോർഡ് കുറുക്കുവഴികൾ"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"കീബോർഡ് ലേഔട്ട് മാറുക"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ടെക്‌സ്റ്റ് മായ്‌ക്കുക"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"കുറുക്കുവഴികൾ"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"കുറുക്കുവഴികൾ തിരയുക"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"കുറുക്കുവഴി കണ്ടെത്തിയില്ല"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ഇൻപുട്ട്"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"തുറന്ന ആപ്പുകളുടെ അവലോകനം"</string>
-    <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">"ആപ്പ്, തിരയൽ ലിസ്റ്റുകളെല്ലാം ആക്സസ് ചെയ്യൂ (Search/Launcher എന്നിവ)"</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 Assistant ആക്സസ് ചെയ്യുക"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"അറിയിപ്പുകൾ കാണുക"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"സ്ക്രീൻഷോട്ട് എടുക്കുക"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"കുറുക്കുവഴികൾ കാണിക്കുക"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"മടങ്ങുക"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ഹോം സ്ക്രീനിലേക്ക് പോകുക"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"അടുത്തിടെയുള്ള ആപ്പുകൾ കാണുക"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"സമീപകാലത്തെ ആപ്പുകളിലൂടെ പോകുക (മുന്നോട്ട്)"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"സമീപകാലത്തെ ആപ്പുകളിലൂടെ പോകുക (പിന്നോട്ട്)"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ആപ്പ് ലിസ്റ്റ് തുറക്കുക"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"ടാസ്‌ക്ബാർ കാണിക്കുക"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"ക്രമീകരണം തുറക്കുക"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant തുറക്കുക"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"ലോക്ക് സ്‌ക്രീൻ"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"അതിവേഗ മെമോ തയ്യാറാക്കുന്നതിന് നോട്ട്‌സ് ആപ്പ് തുറക്കുക"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"കുറിപ്പുകൾ തുറക്കുക"</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="2454557648974553729">"നിലവിലെ ആപ്പ് വലതുവശത്ത് വരുന്ന രീതിയിൽ സ്ക്രീൻ വിഭജന മോഡിൽ കടക്കുക"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"നിലവിലെ ആപ്പ് ഇടതുവശത്ത് വരുന്ന രീതിയിൽ സ്ക്രീൻ വിഭജന മോഡിൽ കടക്കുക"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"സ്‌ക്രീൻ വിഭജന മോഡിൽ നിന്ന് പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറുക"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"സ്‌ക്രീൻ വിഭജന മോഡിൽ: ഒരു ആപ്പിൽ നിന്ന് മറ്റൊന്നിലേക്ക് മാറുക"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"അടുത്ത ഭാഷയിലേക്ക് മാറുക"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"മുമ്പത്തെ ഭാഷയിലേക്ക് മാറുക"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ഇമോജി ആക്സസ് ചെയ്യുക"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"വോയ്‌സ് ടൈപ്പിംഗ് ആക്സസ് ചെയ്യുക"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"അപ്ലിക്കേഷനുകൾ"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"അസിസ്റ്റ്"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ബ്രൗസർ (ഡിഫോൾട്ടായി Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ബ്രൗസർ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"കോൺടാക്റ്റുകൾ"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ഇമെയിൽ (ഡിഫോൾട്ടായി Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ഇമെയിൽ"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS:"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"സംഗീതം"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index e6dc9e5..217eeb1 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> товчлуур"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Нүүр хуудас"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Буцах"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Дээш"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Доош"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Зүүн"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Баруун"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Гол хэсэг"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Зай"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Мэдэгдэл"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Гарын товчлол"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Гарын бүдүүвч рүү сэлгэх"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Текстийг арилгах"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Товчлолууд"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Товчлолууд хайх"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Ямар ч товчлол олдсонгүй"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Оролт"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Нээлттэй аппуудын тойм"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Системийн тохиргоонд хандах"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Туслахад хандах"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Мэдэгдлийг харах"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Дэлгэцийн агшныг авах"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Товчлол харуулах"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Буцах"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Үндсэн нүүр лүү очих"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Саяхны аппуудыг харах"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Саяхны аппуудаар урагш гүйлгэх"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Саяхны аппуудаар арагш гүйлгэх"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Аппуудын жагсаалтыг нээх"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Ажлын хэсгийг харуулах"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Тохиргоог нээх"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Туслахыг нээх"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Түгжээтэй дэлгэц"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Шуурхай тэмдэглэхийн тулд Notes аппыг харуулах"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Тэмдэглэлүүдийг нээх"</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="2454557648974553729">"Одоогийн аппаар баруун гар талд дэлгэц хуваахад орох"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Одоогийн аппаар зүүн гар талд дэлгэц хуваахад орох"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Дэлгэц хуваахаас бүтэн дэлгэц рүү сэлгэх"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Дэлгэц хуваах үеэр: аппыг нэгээс нөгөөгөөр солих"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Дараагийн хэл рүү сэлгэх"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Өмнөх хэл рүү сэлгэх"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Эможид хандах"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Дуу хоолойгоор бичихэд хандах"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Апп"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Дэмжлэг"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Хөтөч (Chrome-г өгөгдмөлөөр тохируулах)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Туслах"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Хөтөч"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Харилцагчид"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Имэйл (Gmail-г өгөгдмөлөөр тохируулах)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Имэйл"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Хөгжим"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календарь"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index a5d0afa..f768881 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"बटण <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"परत"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"वर"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"खाली"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"डावा"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"उजवा"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"मध्यवर्ती"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"सूचना"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"कीबोर्ड शॉर्टकट"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"कीबोर्ड लेआउट स्विच करा"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"मजकूर साफ करा"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"शॉर्टकट"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"शॉर्टकट शोधा"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"एकही शॉर्टकट आढळला नाहीत"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"इनपुट"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"उघड्या असलेल्या अ‍ॅप्सचे अवलोकन"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"सिस्टीम सेटिंग्ज अ‍ॅक्सेस करा"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Assistant अ‍ॅक्सेस करा"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"सूचना पहा"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"स्क्रीनशॉट घ्या"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"शॉर्टकट दाखवा"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"मागे जा"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"होम स्क्रीनवर जा"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"अलीकडील अ‍ॅप्स पहा"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"अलीकडील ॲप्सवरून पुढे जा"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"अलीकडील ॲप्सवरून मागे जा"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ॲप्सची सूची उघडा"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"टास्कबार दाखवा"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"सेटिंग्ज उघडा"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant उघडा"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"लॉक स्क्रीन"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"झटपट मेमोसाठी Notes अ‍ॅप वर ओढा"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"टिपा उघडा"</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="2454557648974553729">"उजव्या बाजूला सध्याचे अ‍ॅप असलेल्या स्प्लिट स्क्रीनवर जा"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"डाव्या बाजूला सध्याचे अ‍ॅप असलेल्या स्प्लिट स्क्रीनवर जा"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"स्प्लिट स्क्रीनवरून फुल स्क्रीनवर स्विच करा"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीनदरम्यान: एक अ‍ॅप दुसऱ्या अ‍ॅपने बदला"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"पुढील भाषेवर स्विच करा"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"मागील भाषेवर स्विच करा"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"इमोजी अ‍ॅक्सेस करा"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"व्हॉइस टायपिंग अ‍ॅक्सेस करा"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ॲप्लिकेशन"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assist"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ब्राउझर (डीफॉल्ट म्हणून Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ब्राउझर"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"संपर्क"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ईमेल (डीफॉल्ट म्हणून Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ईमेल"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"एसएमएस"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"संगीत"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"कॅलेंडर"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index bf0a60c..db53890 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Butang <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Skrin Utama"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Kembali"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Ke atas"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Ke bawah"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Ke kiri"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Ke kanan"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Tengah"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Pemberitahuan"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Pintasan Papan Kekunci"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Tukar reka letak papan kekunci"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Kosongkan teks"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Pintasan"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Cari pintasan"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Tiada pintasan ditemukan"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Input"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Apl yang dibuka"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Apl semasa"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Akses bidai pemberitahuan"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Ambil tangkapan skrin penuh"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Akses senarai pintasan sistem / apl"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Kembali: kembali kepada keadaan sebelumnya (butang kembali)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Akses skrin utama"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Gambaran keseluruhan apl yang dibuka"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Mengitar apl terbaharu (hadapan)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Mengitar apl terbaharu (belakang)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Akses senarai semua apl dan cari (iaitu Carian/Pelancar)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Sembunyikan dan tunjukkan (semula) bar tugas"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Akses tetapan sistem"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Akses Google Assistant"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Lihat pemberitahuan"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ambil tangkapan skrin"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Tunjukkan pintasan"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Kembali"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Akses skrin utama"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Lihat apl terbaharu"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Kitar ke hadapan menerusi apl terbaharu"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Kitar ke belakang menerusi apl terbaharu"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Buka senarai apl"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Tunjukkan bar tugas"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Buka tetapan"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Buka Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Kunci skrin"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Tarik ke atas apl Nota untuk memo pantas"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Buka nota"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Berbilang tugas sistem"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Masuk skrin Pisah dengan apl semasa pada sisi kanan"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Masuk skrin Pisah dengan apl semasa pada sisi kiri"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Tukar daripada skrin Pisah kepada skrin penuh"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Semasa skrin Pisah: gantikan apl daripada satu apl kepada apl lain"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Masuk skrin pisah dengan apl semasa pada sisi kanan"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Masuk skrin pisah dengan apl semasa pada sisi kiri"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Beralih daripada skrin pisah kepada skrin penuh"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Semasa skrin pisah: gantikan apl daripada satu apl kepada apl lain"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Tukar bahasa input (bahasa seterusnya)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Tukar bahasa input (bahasa sebelumnya)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Beralih kepada bahasa seterusnya"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Beralih kepada bahasa sebelumnya"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Akses emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Akses penaipan suara"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikasi"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Bantu"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Penyemak imbas (Chrome sebagai lalai)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Penyemak imbas"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kenalan"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-mel (Gmail sebagai lalai)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-mel"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 5568fa7..6221ca1 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -401,11 +401,9 @@
     <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="communal_tutorial_indicator_text" msgid="4503010353591430123">"အများသုံးရှင်းလင်းပို့ချချက် စတင်ရန် ဘယ်သို့ပွတ်ဆွဲပါ"</string>
-    <!-- no translation found for button_to_open_widget_editor (5599945944349057600) -->
-    <skip />
+    <string name="button_to_open_widget_editor" msgid="5599945944349057600">"ဝိဂျက်တည်းဖြတ်စနစ် ဖွင့်ရန်"</string>
     <string name="button_to_remove_widget" msgid="1511255853677835341">"ဝိဂျက် ဖယ်ရှားရန်"</string>
-    <!-- no translation found for hub_mode_add_widget_button_text (3956587989338301487) -->
-    <skip />
+    <string name="hub_mode_add_widget_button_text" msgid="3956587989338301487">"ဝိဂျက် ထည့်ရန်"</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>
@@ -642,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"ခလုတ် <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"ပင်မ"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"နောက်သို့"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"အပေါ်"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"အောက်"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ဘယ်"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ညာ"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"ဌာန"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -673,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"အကြောင်းကြားချက်များ"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"ကီးဘုတ် ဖြတ်လမ်းများ"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"ကီးဘုတ်အပြင်အဆင် ပြောင်းခြင်း"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"စာသား ဖယ်ရှားရန်"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"ဖြတ်လမ်းလင့်ခ်များ"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ဖြတ်လမ်းလင့်ခ်များ ရှာပါ"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ဖြတ်လမ်းလင့်ခ် မတွေ့ပါ"</string>
@@ -681,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"စာရိုက်ခြင်း"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"ဖွင့်ထားသောအက်ပ်များ အနှစ်ချုပ်"</string>
-    <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">"အက်ပ်အားလုံးစာရင်းကို ဝင်ကြည့်ပြီး ရှာပါ (ဥပမာ- Search/Launcher)"</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 Assistant သုံးရန်"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"အကြောင်းကြားချက်များ ကြည့်ရန်"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ဖန်သားပြင်ဓာတ်ပုံ ရိုက်ရန်"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"ဖြတ်လမ်းလင့်ခ်များ ပြပါ"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ပြန်သွားရန်"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ပင်မစာမျက်နှာသို့သွားရန်"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"မကြာသေးမီကအက်ပ်များ ကြည့်ရန်"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"မကြာသေးမီက အက်ပ်များကို အဝိုင်းပုံရှေ့သို့လှည့်ရန်"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"မကြာသေးမီက အက်ပ်များကို အဝိုင်းပုံနောက်ပြန်လှည့်ရန်"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"အက်ပ်ပြသမှု ဖွင့်ရန်"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Taskbar ပြပါ"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"ဆက်တင်များ ဖွင့်ရန်"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ဖွင့်ရန်"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"လော့ခ်မျက်နှာပြင်"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"အမြန်မှတ်သားရန် မှတ်စုရေးသောအက်ပ် ဖွင့်ပါ"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"မှတ်စုများ ဖွင့်ရန်"</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="2454557648974553729">"လက်ရှိအက်ပ်ကို မျက်နှာပြင် ခွဲ၍ပြသမှု၏ ညာဘက်တွင်ထည့်ရန်"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"လက်ရှိအက်ပ်ကို မျက်နှာပြင် ခွဲ၍ပြသမှု၏ ဘယ်ဘက်တွင်ထည့်ရန်"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"မျက်နှာပြင် ခွဲ၍ပြသမှုမှ မျက်နှာပြင်အပြည့်သို့ ပြောင်းရန်"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"မျက်နှာပြင် ခွဲ၍ပြသစဉ်- အက်ပ်တစ်ခုကို နောက်တစ်ခုနှင့် အစားထိုးရန်"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"နောက်ဘာသာစကားသို့ ပြောင်းရန်"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ယခင်ဘာသာစကားသို့ ပြောင်းရန်"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"အီမိုဂျီ သုံးရန်"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"အသံဖြင့်စာရိုက်ခြင်း သုံးရန်"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"အက်ပ်များ"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"အထောက်အကူ"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ဘရောင်ဇာ (Chrome ကို မူရင်းအဖြစ်)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ဘရောင်ဇာ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"အဆက်အသွယ်များ"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"အီးမေးလ် (Gmail ကို မူရင်းအဖြစ်)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"အီးမေးလ်"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS စာတိုစနစ်"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ပြက္ခဒိန်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index c654397..9fc3625 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -510,7 +510,7 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiver"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Lyd og vibrering"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Innstillinger"</string>
-    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Senk volumet til et tryggere nivå"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volumet er senket til et tryggere nivå"</string>
     <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volumet på hodetelefonene har vært høyt lenger enn anbefalt"</string>
     <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volumet på hodetelefonene har overskredet sikkerhetsgrensen for denne uken"</string>
     <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Fortsett å lytte"</string>
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g>-knappen"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Startskjerm"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Tilbake"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Opp"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Ned"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Venstre"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Høyre"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Midttasten"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Mellomrom"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Varsler"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Hurtigtaster"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Bytt tastaturoppsett"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Fjern teksten"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Hurtigtaster"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Søk etter hurtigtaster"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Fant ingen hurtigtaster"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Inndata"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Åpne apper"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aktiv app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Åpne varselpanelet"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Ta en skjermdump av hele skjermen"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Se hurtigtastene for systemet/apper"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Tilbake: Gå tilbake til forrige tilstand (tilbakeknapp)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Åpne startskjermen"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Oversikt over åpne apper"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Bla gjennom nylige apper (fremover)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Bla gjennom nylige apper (bakover)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Se alle apper og søk (dvs. Søk/Appoversikt)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Skjul og vis oppgavelinjen"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Åpne systeminnstillingene"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Aktiver Google-assistenten"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Se varsler"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ta skjermdump"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Vis snarveier"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Gå tilbake"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Gå til startskjermen"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Se nylige apper"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Gå forover gjennom nylige apper"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Gå bakover gjennom nylige apper"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Åpne applisten"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Vis oppgavelinje"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Åpne innstillingene"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Åpne assistenten"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Låseskjerm"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Åpne Notes-appen for å ta notater raskt"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Åpne notatene"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking på systemet"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Åpne delt skjerm med den aktive appen til høyre"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Åpne delt skjerm med den aktive appen til venstre"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Bytt fra delt skjerm til fullskjerm"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"I delt skjerm: Bytt ut en app"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Åpne delt skjerm med den aktive appen til høyre"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Åpne delt skjerm med den aktive appen til venstre"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Bytt fra delt skjerm til fullskjerm"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"I delt skjerm: Bytt ut en app"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Skrivespråk"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Bytt skrivespråk (neste språk)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Bytt skrivespråk (forrige språk)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Bytt til neste språk"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Bytt til forrige språk"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Se emojier"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Bruk stemmestyrt skriving"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Apper"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assist"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Nettleser (Chrome som standard)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Nettleser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakter"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-post (Gmail som standard)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-post"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musikk"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
@@ -1165,7 +1182,7 @@
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Trykk på og hold inne snarveien"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Bytt skjerm nå"</string>
-    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Brett ut telefonen"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Åpne telefonen"</string>
     <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vil du bytte skjerm?"</string>
     <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Bruk baksidekameraet for å få høyere oppløsning"</string>
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Brett ut telefonen for å få høyere oppløsning"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 71fa4e5..79cb703 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> बटन"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"पछाडि"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"माथि"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"तल"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"बायाँ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"दायाँ"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"केन्द्र"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"स्पेस"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"सूचनाहरू"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"किबोर्ड सर्टकटहरू"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"किबोर्डको लेआउट बदल्नुहोस्"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"टेक्स्ट हटाउनुहोस्"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"सर्टकटहरू"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"सर्टकटहरू खोज्नुहोस्"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"कुनै पनि सर्टकट भेटिएन"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"इनपुट"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"खोलिएका एपहरूको विवरण"</string>
-    <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">"सबै एप र खोज (अर्थात्, Search/लन्चर) को सूची हेर्नुहोस्"</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>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"सूचनाहरू हेर्नुहोस्"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"स्क्रिनसट खिच्नुहोस्"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"सर्टकटहरू देखाइऊन्"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"पछाडि जानुहोस्"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"होम स्क्रिनमा जानुहोस्"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"हालसालै चलाइएका एपहरू हेर्ने तरिका"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"हालसालै चलाइएका एपहरू अगाडिबाट हेर्दै जानुहोस्"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"हालसालै चलाइएका एपहरू पछाडिबाट हेर्दै जानुहोस्"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"एपहरूको सूची खोल्नुहोस्"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"टास्कबार देखाइयोस्"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"सेटिङ खोल्नुहोस्"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"एसिस्टेन्ट खोल्नुहोस्"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"स्क्रिन लक गर्नुहोस्"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"झट्टै कुनै टिपोट लेख्न Notes एप प्रयोग गर्नुहोस्"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"नोटहरू खोल्नुहोस्"</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="2454557648974553729">"हालको एप दायाँतर्फ रहने गरी स्प्लिट स्क्रिन मोड सुरु गर्नुहोस्"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"हालको एप बायाँतर्फ रहने गरी स्प्लिट स्क्रिन मोड सुरु गर्नुहोस्"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"स्प्लिट स्क्रिनको साटो फुल स्क्रिन प्रयोग गर्नुहोस्"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रिन प्रयोग गरिएका बेला: एउटा स्क्रिनमा भएको एप अर्कोमा लैजानुहोस्"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"अर्को भाषा प्रयोग गर्नुहोस्"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"अघिल्लो भाषा प्रयोग गर्नुहोस्"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"इमोजी प्रयोग गर्नुहोस्"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"भ्वाइस टाइपिङ प्रयोग गर्नुहोस्"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"एपहरू"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"सहायता"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ब्राउजर (डिफल्ट ब्राउजर: Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"एसिस्टेन्ट"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ब्राउजर"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"कन्ट्याक्टहरू"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"इमेल (डिफल्ट एप: Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"इमेल"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"सङ्गीत"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"पात्रो"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index d9385c7..bcc3c83 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -104,4 +104,7 @@
     <!-- Internet Dialog -->
     <color name="connected_network_primary_color">@color/material_dynamic_primary80</color>
     <color name="connected_network_secondary_color">@color/material_dynamic_secondary80</color>
+
+    <!-- Keyboard shortcut helper dialog -->
+    <color name="ksh_key_item_color">@*android:color/system_on_surface_variant_dark</color>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index c8f6c58..60ddb89 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Knop <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Terug"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Omhoog"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Omlaag"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Links"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Rechts"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Midden"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Spatiebalk"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Meldingen"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Sneltoetsen"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Toetsenbordindeling wisselen"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Tekst wissen"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Sneltoetsen"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Sneltoetsen zoeken"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Geen sneltoetsen gevonden"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Invoer"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Apps openen"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Huidige app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Het meldingenpaneel openen"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Een volledige schermafbeeldingen maken"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Lijst van snelkoppelingen voor systeem/apps openen"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Terug: terug naar de vorige status (terugknop)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Het startscherm openen"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Overzicht van geopende apps"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Door recente apps navigeren (vooruit)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Door recente apps navigeren (terug)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Toegangslijst van alle apps en zoekopties (bijv. Zoeken/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Taakbalk verbergen en (opnieuw) tonen"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Systeeminstellingen openen"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"De Google Assistent activeren"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Meldingen bekijken"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Screenshot maken"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Snelkoppelingen tonen"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Terug"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Naar het startscherm gaan"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Recente apps bekijken"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Vooruitbladeren door recente apps"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Terugbladeren door recente apps"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Lijst met apps openen"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Taakbalk tonen"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Instellingen openen"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistent openen"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Scherm vergrendelen"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Notitie-app tevoorschijn halen voor snelle notitie"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Notities openen"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Systeem-multitasking"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Gesplitst scherm openen met huidige app rechts"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Gesplitst scherm openen met huidige app links"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Van gesplitst scherm naar volledig scherm schakelen"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Tijdens gesplitst scherm: een app vervangen door een andere"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Gesplitst scherm openen met huidige app rechts"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Gesplitst scherm openen met huidige app links"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Van gesplitst scherm naar volledig scherm schakelen"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijdens gesplitst scherm: een app vervangen door een andere"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Invoer"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Invoertaal veranderen (volgende taal)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Invoertaal veranderen (vorige taal)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Overschakelen naar volgende taal"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Overschakelen naar vorige taal"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Emoji\'s openen"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Spraakgestuurd typen activeren"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Apps"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistentie"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome als standaard)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacten"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-mail (Gmail als standaard)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muziek"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index c62519da..e02a5a7 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"ବଟନ୍‍ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"ହୋମ"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"ଫେରନ୍ତୁ"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"ଉପର"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"ତଳ"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ବାମ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ଡାହାଣ"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"କେନ୍ଦ୍ର"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"ସ୍ପେସ୍‍"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"ବିଜ୍ଞପ୍ତି"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"କୀବୋର୍ଡ ସର୍ଟକଟ"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"କୀ\'ବୋର୍ଡ୍‍ର ଲେଆଉଟ୍‍କୁ ବଦଳାନ୍ତୁ"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ଟେକ୍ସଟ ଖାଲି କରନ୍ତୁ"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"ସର୍ଟକଟଗୁଡ଼ିକ"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ସର୍ଟକଟ ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"କୌଣସି ସର୍ଟକଟ ମିଳିଲା ନାହିଁ"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ଇନପୁଟ କରନ୍ତୁ"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"ଖୋଲାଥିବା ଆପ୍ସର ଓଭରଭିଉ"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"ସିଷ୍ଟମ ସେଟିଂସର ଆକ୍ସେସ"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Assistantକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଭ୍ୟୁ କରନ୍ତୁ"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ସ୍କ୍ରିନସଟ ନିଅନ୍ତୁ"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"ସର୍ଟକଟଗୁଡ଼ିକ ଦେଖାନ୍ତୁ"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ପଛକୁ ଫେରନ୍ତୁ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ହୋମ ସ୍କ୍ରିନକୁ ଯାଆନ୍ତୁ"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"ବର୍ତ୍ତମାନର ଆପ୍ସ ଭ୍ୟୁ କରନ୍ତୁ"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"ବର୍ତ୍ତମାନର ଆପ୍ସ ମଧ୍ୟରେ ଆଗକୁ ଯାଆନ୍ତୁ"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"ବର୍ତ୍ତମାନର ଆପ୍ସ ମଧ୍ୟରେ ପଛକୁ ଯାଆନ୍ତୁ"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ଆପ୍ସ ତାଲିକା ଖୋଲନ୍ତୁ"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"ଟାସ୍କବାର ଦେଖାନ୍ତୁ"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"ସେଟିଂସ ଖୋଲନ୍ତୁ"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ଖୋଲନ୍ତୁ"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"ଲକ ସ୍କ୍ରିନ"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"କ୍ୱିକ ମେମୋ ପାଇଁ Notes ଆପ ଖୋଲନ୍ତୁ"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Notes ଖୋଲନ୍ତୁ"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ସିଷ୍ଟମ ମଲ୍ଟିଟାସ୍କିଂ"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"RHSରେ ବର୍ତ୍ତମାନର ଆପ ସହ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ପ୍ରବେଶ କରାନ୍ତୁ"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"LHSରେ ବର୍ତ୍ତମାନର ଆପ ସହ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ପ୍ରବେଶ କରାନ୍ତୁ"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନରୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ସ୍ଵିଚ କରନ୍ତୁ"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ସମୟରେ: କୌଣସି ଆପକୁ ଗୋଟିଏରୁ ଅନ୍ୟ ଏକ ଆପରେ ବଦଳାନ୍ତୁ"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHSରେ ବର୍ତ୍ତମାନର ଆପ ସହ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ପ୍ରବେଶ କରାନ୍ତୁ"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHSରେ ବର୍ତ୍ତମାନର ଆପ ସହ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ପ୍ରବେଶ କରାନ୍ତୁ"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନରୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ସୁଇଚ କରନ୍ତୁ"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ସମୟରେ: କୌଣସି ଆପକୁ ଗୋଟିଏରୁ ଅନ୍ୟ ଏକ ଆପରେ ବଦଳାନ୍ତୁ"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"ପରବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ପୂର୍ବବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ଇମୋଜି ଆକ୍ସେସ କରନ୍ତୁ"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"ଭଏସ ଟାଇପିଂ ଆକ୍ସେସ କରନ୍ତୁ"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ଆପ୍ଲିକେସନ୍‌"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"ସହାୟତା"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ବ୍ରାଉଜର (ଡିଫଲ୍ଟ ଭାବେ Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ବ୍ରାଉଜର୍"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"କଣ୍ଟାକ୍ଟ"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ଇମେଲ (ଡିଫଲ୍ଟ ଭାବେ Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ଇମେଲ୍"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ମ୍ୟୁଜିକ୍‍"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"କ୍ୟାଲେଣ୍ଡର"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 3f75dfe..4ab6e8be 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"ਬਟਨ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Up"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Center"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"ਸੂਚਨਾਵਾਂ"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"ਕੀ-ਬੋਰਡ ਖਾਕਾ ਬਦਲੋ"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ਲਿਖਤ ਕਲੀਅਰ ਕਰੋ"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"ਸ਼ਾਰਟਕੱਟ"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ਸ਼ਾਰਟਕੱਟਾਂ ਨੂੰ ਖੋਜੋ"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਨਹੀਂ ਮਿਲਿਆ"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ਇਨਪੁੱਟ"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"ਐਪਾਂ ਖੋਲ੍ਹੋ ਦੀ ਰੂਪ-ਰੇਖਾ"</string>
-    <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">"ਸਾਰੀਆਂ ਐਪਾਂ ਦੀ ਸੂਚੀ ਤੱਕ ਪਹੁੰਚ ਕਰੋ ਅਤੇ ਖੋਜੋ (ਜਿਵੇਂ ਕਿ, Search/ਲਾਂਚਰ)"</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 Assistant ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"ਸੂਚਨਾਵਾਂ ਦੇਖੋ"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਓ"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"ਸ਼ਾਰਟਕੱਟ ਦਿਖਾਓ"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ਵਾਪਸ ਜਾਓ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਜਾਓ"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"ਹਾਲੀਆ ਐਪਾਂ ਦੇਖੋ"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"ਹਾਲ ਹੀ ਵਿੱਚ ਖੋਲ੍ਹੀਆਂ ਗਈਆਂ ਐਪਾਂ \'ਤੇ ਅੱਗੇ ਜਾਓ"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"ਹਾਲ ਹੀ ਵਿੱਚ ਖੋਲ੍ਹੀਆਂ ਗਈਆਂ ਐਪਾਂ \'ਤੇ ਵਾਪਸ ਜਾਓ"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ਐਪਾਂ ਦੀ ਸੂਚੀ ਖੋਲ੍ਹੋ"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"ਟਾਸਕਬਾਰ ਦਿਖਾਓ"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ਖੋਲ੍ਹੋ"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"ਲਾਕ ਸਕ੍ਰੀਨ"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"ਤੁਰੰਤ ਮੈਮੋ ਲਈ \'ਨੋਟ-ਕਥਨ\' ਐਪ ਨੂੰ ਉੱਪਰ ਵੱਲ ਖਿੱਚੋ"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"ਨੋਟਸ ਖੋਲ੍ਹੋ"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"ਸਿਸਟਮ ਮਲਟੀਟਾਸਕਿੰਗ"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"RHS ਲਈ ਮੌਜੂਦਾ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"LHS ਲਈ ਮੌਜੂਦਾ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਤੋਂ ਪੂਰੀ ਸਕ੍ਰੀਨ ਵਿੱਚ ਸਵਿੱਚ ਕਰੋ"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੌਰਾਨ: ਇੱਕ ਐਪ ਨਾਲ ਦੂਜੀ ਐਪ ਬਦਲੋ"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHS ਲਈ ਮੌਜੂਦਾ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHS ਲਈ ਮੌਜੂਦਾ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਤੋਂ ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੌਰਾਨ: ਇੱਕ ਐਪ ਨਾਲ ਦੂਜੀ ਐਪ ਨੂੰ ਬਦਲੋ"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"ਅਗਲੀ ਭਾਸ਼ਾ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ਪਿਛਲੀ ਭਾਸ਼ਾ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ਇਮੋਜੀ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"ਅਵਾਜ਼ੀ ਟਾਈਪਿੰਗ ਤੱਕ ਪਹੁੰਚ"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ਐਪਲੀਕੇਸ਼ਨਾਂ"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"ਸਹਾਇਕ"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"ਬ੍ਰਾਊਜ਼ਰ (ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਵਜੋਂ Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ਬ੍ਰਾਊਜ਼ਰ"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"ਸੰਪਰਕ"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ਈਮੇਲ (ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਵਜੋਂ Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ਈਮੇਲ"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"ਸੰਗੀਤ"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index a26a5b5..3647bd4 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Przycisk <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Wstecz"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"W górę"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"W dół"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"W lewo"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"W prawo"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Do środka"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Spacja"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Powiadomienia"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Skróty klawiszowe"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Przełącz układ klawiatury"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Czyszczenie tekstu"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Skróty"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Wyszukiwanie skrótów"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nie znaleziono skrótów"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Wprowadzanie"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Otwieranie aplikacji"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Bieżąca aplikacja"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Otwieranie obszaru powiadomień"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Robienie pełnego zrzutu ekranu"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Otwieranie listy skrótów do systemu/aplikacji"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Wstecz: powrót do poprzedniego stanu (przycisk Wstecz)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Otwieranie ekranu głównego"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Przegląd otwartych aplikacji"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Przełączanie się między ostatnimi aplikacjami (do przodu)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Przełączanie się między ostatnimi aplikacjami (wstecz)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Otwieranie listy wszystkich aplikacji i wyszukiwanie (tj. wyszukiwarka/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ukrywanie i ponowne pokazywanie paska aplikacji"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Otwieranie ustawień systemu"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Otwieranie Asystenta Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Wyświetlanie powiadomień"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Robienie zrzutu ekranu"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Pokazywanie skrótów"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Przechodzenie wstecz"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Wyświetlanie ekranu głównego"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Wyświetlanie ostatnich aplikacji"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Przełączanie się do przodu między ostatnimi aplikacjami"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Przełączanie się wstecz między ostatnimi aplikacjami"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otwieranie listy aplikacji"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Pokazywanie paska aplikacji"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otwieranie ustawień"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otwieranie asystenta"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Blokada ekranu"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Otwieranie aplikacji do notatek w przypadku szybkich notatek"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Otwieranie notatek"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Wielozadaniowość w systemie"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Uruchamianie trybu podzielonego ekranu z bieżącą aplikacją po prawej"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Uruchamianie trybu podzielonego ekranu z bieżącą aplikacją po lewej"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Przełączanie podzielonego ekranu na pełny ekran"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Podczas podzielonego ekranu: zastępowanie aplikacji"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Uruchamianie trybu podzielonego ekranu z bieżącą aplikacją po prawej"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Uruchamianie trybu podzielonego ekranu z bieżącą aplikacją po lewej"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Przełącz podzielony ekran na pełny ekran"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Podczas podzielonego ekranu: zastępowanie aplikacji"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Wprowadzanie"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Przełączanie języka wprowadzania (następny język)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Przełączanie języka wprowadzania (poprzedni język)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Przełączanie na następny język"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Przełączanie na poprzedni język"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Otwieranie emotikonów"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Otwieranie pisania głosowego"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikacje"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Pomoc"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Przeglądarka (domyślnie Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asystent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Przeglądarka"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakty"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-mail (domyślnie Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzyka"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendarz"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 4b56060..329f40a 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Botão <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Voltar"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Para cima"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Para baixo"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Para a esquerda"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Para a direita"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centralizar"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notificações"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Atalhos do teclado"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Alterar layout do teclado"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Apagar texto"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Atalhos"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Atalhos de pesquisa"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nenhum atalho encontrado"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrada"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Apps abertos"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"App atual"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Acessar a aba de notificações"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Capturar toda a tela"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Acessar lista de atalhos do sistema / de apps"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Voltar ao estado anterior (botão \"Voltar\")"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Acessar a tela inicial"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Visão geral dos apps abertos"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Percorrer apps recentes (avançar)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Percorrer apps recentes (voltar)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Acessar lista de todos os apps e pesquisa (por exemplo, Pesquisa/Tela de início)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ocultar e mostrar a barra de tarefas"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Acessar configurações do sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Acessar o Google Assistente"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Mostrar as notificações"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Fazer uma captura de tela"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar atalhos"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Voltar"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Ir para a tela inicial"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Conferir os apps recentes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Avançar pela lista de apps recentes"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Voltar pela lista de apps recentes"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Abrir lista de apps"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Mostrar a Barra de tarefas"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir configurações"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir o Google Assistente"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Tela de bloqueio"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Fazer uma anotação rápida no app Notes"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir observações"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitarefa do sistema"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Usar a tela dividida com o app atual à direita"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Usar a tela dividida com o app atual à esquerda"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Mudar de tela dividida para tela cheia"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Com a tela dividida: substituir um app por outro"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Usar a tela dividida com o app atual à direita"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Usar a tela dividida com o app atual à esquerda"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Mudar da tela dividida para a tela cheia"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Trocar o idioma de entrada (próximo)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Trocar o idioma de entrada (anterior)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para o próximo idioma"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Mudar para o idioma anterior"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Acessar emojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Acessar a digitação por voz"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplicativos"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistente"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Navegador (Chrome por padrão)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Google Assistente"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contatos"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-mail (Gmail por padrão)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 09c48cb..1b22929 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Botão <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Início"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Anterior"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Para cima"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Para baixo"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Para a esquerda"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Para a direita"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Seta para cima"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Seta para baixo"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Seta para a esquerda"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Seta para a direita"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Ao centro"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Espaço"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notificações"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Atalhos de teclado"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Alterar esquema de teclado"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Limpar texto"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"ou"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Limpar consulta de pesquisa"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Atalhos"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pesquise atalhos"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nenhum atalho encontrado"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrada"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Apps abertas"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"App atual"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Aceda ao painel de notificações"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Faça uma captura de ecrã completa"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Aceda à lista dos atalhos de apps/sistema"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Anterior: volte ao estado anterior (botão anterior)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Aceda ao ecrã principal"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Vista geral das apps abertas"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Percorra as apps recentes (para a frente)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Percorra as apps recentes (para trás)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Aceda à lista de todas as apps e pesquise (por ex., Pesquisa/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Oculte e volte a apresentar a barra de tarefas"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Aceda às definições do sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Aceda ao Assistente Google"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"A mostrar resultados da pesquisa"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"A mostrar atalhos do sistema"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"A mostrar atalhos de introdução"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"A mostrar atalhos que abrem apps"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"A mostrar atalhos para a app atual"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Ver notificações"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Fazer captura de ecrã"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar atalhos"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Voltar"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Aceder ao ecrã principal"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Ver apps recentes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Percorrer apps recentes para a frente"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Percorrer apps recentes para trás"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Abrir lista de apps"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Mostrar barra de tarefas"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir definições"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir Assistente"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Ecrã de bloqueio"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Inicie a app Notas para criar uma nota rápida"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir notas"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Execução de várias tarefas em simultâneo no sistema"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Aceda ao ecrã dividido com a app atual para RHS"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Aceda ao ecrã dividido com a app atual para LHS"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Mude do ecrã dividido para o ecrã inteiro"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Durante o ecrã dividido: substitua uma app por outra"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Aceder ao ecrã dividido com a app atual para RHS"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Aceder ao ecrã dividido com a app atual para LHS"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Mude de ecrã dividido para ecrã inteiro"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Durante o ecrã dividido: substituir uma app por outra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Mude de idioma de entrada (idioma seguinte)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Mude de idioma de entrada (idioma anterior)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para idioma seguinte"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Mudar para idioma anterior"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Aceda a emojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Aceda à digitação por voz"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Apps"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistência"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Navegador (Chrome como predefinição)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistente"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contactos"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (Gmail como predefinição)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendário"</string>
@@ -1076,7 +1082,7 @@
     <string name="person_available" msgid="2318599327472755472">"Disponível"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ocorreu um problema ao ler o medidor da bateria"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para obter mais informações"</string>
-    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme defin."</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"introduzir bloqueio de ecrã"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressões digitais"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 4b56060..329f40a 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Botão <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Voltar"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Para cima"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Para baixo"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Para a esquerda"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Para a direita"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centralizar"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notificações"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Atalhos do teclado"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Alterar layout do teclado"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Apagar texto"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Atalhos"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Atalhos de pesquisa"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nenhum atalho encontrado"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrada"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Apps abertos"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"App atual"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Acessar a aba de notificações"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Capturar toda a tela"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Acessar lista de atalhos do sistema / de apps"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Voltar ao estado anterior (botão \"Voltar\")"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Acessar a tela inicial"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Visão geral dos apps abertos"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Percorrer apps recentes (avançar)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Percorrer apps recentes (voltar)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Acessar lista de todos os apps e pesquisa (por exemplo, Pesquisa/Tela de início)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ocultar e mostrar a barra de tarefas"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Acessar configurações do sistema"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Acessar o Google Assistente"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Mostrar as notificações"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Fazer uma captura de tela"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar atalhos"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Voltar"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Ir para a tela inicial"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Conferir os apps recentes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Avançar pela lista de apps recentes"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Voltar pela lista de apps recentes"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Abrir lista de apps"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Mostrar a Barra de tarefas"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir configurações"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir o Google Assistente"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Tela de bloqueio"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Fazer uma anotação rápida no app Notes"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Abrir observações"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitarefa do sistema"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Usar a tela dividida com o app atual à direita"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Usar a tela dividida com o app atual à esquerda"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Mudar de tela dividida para tela cheia"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Com a tela dividida: substituir um app por outro"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Usar a tela dividida com o app atual à direita"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Usar a tela dividida com o app atual à esquerda"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Mudar da tela dividida para a tela cheia"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Trocar o idioma de entrada (próximo)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Trocar o idioma de entrada (anterior)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para o próximo idioma"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Mudar para o idioma anterior"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Acessar emojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Acessar a digitação por voz"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplicativos"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Assistente"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Navegador (Chrome por padrão)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Google Assistente"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navegador"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contatos"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-mail (Gmail por padrão)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Música"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index aaf20f3..73da4e7 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -107,7 +107,7 @@
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Începe înregistrarea"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Înregistrează audio"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Conținutul audio de la dispozitiv"</string>
-    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sunetul de la dispozitiv, precum muzică, apeluri și tonuri de sonerie"</string>
+    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sunetul de la dispozitiv, precum muzică, apeluri și tonuri de apel"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"Microfon"</string>
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Conținutul audio de la dispozitiv și microfon"</string>
     <string name="screenrecord_continue" msgid="4055347133700593164">"Începe"</string>
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Butonul <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"La început"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Înapoi"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"În sus"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"În jos"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"La stânga"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"La dreapta"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Săgeată în sus"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Săgeată în jos"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Săgeată spre stânga"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Săgeată spre dreapta"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"În centru"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Spațiu"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notificări"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Comenzi rapide de la tastatură"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Schimbă aspectul tastaturii"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Șterge textul"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"sau"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Șterge termenul de căutare"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Comenzi rapide"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Caută comenzi rapide"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nu există comenzi rapide"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Introducere"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Aplicații deschise"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aplicația actuală"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Accesează fereastra de notificări"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Fă o captură de ecran completă"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Accesează lista comenzilor rapide pentru sistem / aplicații"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Înapoi: revino la starea anterioară (butonul înapoi)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Accesează ecranul de pornire"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Prezentare generală a aplicațiilor deschise"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Parcurge aplicațiile recente (înainte)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Parcurge aplicațiile recente (înapoi)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Accesează lista tuturor aplicațiilor și caută (Căutare / Lansator)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ascunde și reafișează bara de activități"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Accesează setările de sistem"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Accesează Asistentul Google"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Se afișează rezultatele căutării"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Se afișează comenzile rapide de sistem"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Se afișează comenzile rapide pentru introducere"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Se afișează comenzile rapide care deschid aplicațiile"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Se afișează comenzile rapide pentru aplicația actuală"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Vezi notificările"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Fă o captură de ecran"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Afișează comenzile rapide"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Înapoi"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Accesează ecranul de pornire"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Vezi aplicațiile recente"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Parcurge aplicațiile recente înainte"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Parcurge aplicațiile recente înapoi"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Deschide lista de aplicații"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Afișează bara de activități"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Deschide setările"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Deschide Asistentul"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Ecranul de blocare"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Accesează aplicația Note pentru notițe rapide"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Deschide notele"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking pe sistem"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Accesează ecranul împărțit cu aplicația actuală în dreapta"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Accesează ecranul împărțit cu aplicația actuală în stânga"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Comută de la ecranul împărțit la ecranul complet"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"În modul ecran împărțit: înlocuiește o aplicație cu alta"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Accesează ecranul împărțit cu aplicația actuală în dreapta"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Accesează ecranul împărțit cu aplicația actuală în stânga"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Comută de la ecranul împărțit la ecranul complet"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"În modul ecran împărțit: înlocuiește o aplicație cu alta"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Introducere"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Schimbă limba de introducere a textului (limba următoare)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Schimbă limba de introducere a textului (limba anterioară)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Comută la următoarea limbă"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Comută la limba anterioară"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Accesează emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Accesează tastarea vocală"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplicații"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Asistent"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome este setat ca prestabilit)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Agendă"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-mail (aplicația Gmail este setată ca prestabilită)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzică"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 3836a29..ee3945d 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Кнопка <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Главный экран"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Назад"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Стрелка вверх"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Стрелка вниз"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Стрелка влево"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Стрелка вправо"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Центральная стрелка"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Пробел"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Уведомления"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Быстрые клавиши"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Переключение раскладки"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Очистить строку поиска"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Сочетания клавиш"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Поиск сочетаний клавиш"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Нет сочетаний клавиш."</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Ввод"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Открыть список запущенных приложений"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Открыть настройки системы"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Запустить Google Ассистента"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Посмотреть уведомления"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Сделать скриншот"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Показать сочетания клавиш"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Вернуться назад"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Перейти на главный экран"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Посмотреть недавние приложения"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Прокрутить вперед список недавних приложений"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Прокрутить назад список недавних приложений"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Открыть список приложений"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Показать панель задач"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Открыть настройки"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Открыть Ассистента"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Заблокировать экран"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Создать быструю заметку"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Открыть заметки"</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="2454557648974553729">"Включить разделение экрана с текущим приложением справа"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Включить разделение экрана с текущим приложением слева"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Изменить режим разделения экрана на полноэкранный режим"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"В режиме разделения экрана заменить одно приложение другим"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Выбрать следующий язык"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Выбрать предыдущий язык"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Открыть список эмодзи"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Активировать голосовой ввод"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Приложения"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Помощник"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Браузер (по умолчанию Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Открыть Ассистента"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Браузер"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Контакты"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Электронная почта (по умолчанию Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Эл. почта"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музыка"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календарь"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 409379c..e03c7c0 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> බොත්තම"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home යතුර"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"ආපසු"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"උඩු"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"යටි"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"වම්"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"දකුණු"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"මැද"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"ඉඩ යතුර"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"දැනුම්දීම්"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"යතුරු පුවරු කෙටිමං"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"යතුරුපුවරු පිරිසැලසුම මාරු කරන්න"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"පෙළ හිස් කරන්න"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"කෙටිමං"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"කෙටිමං සොයන්න"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"කෙටිමං හමු නොවුණි"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ආදානය"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"විවෘත යෙදුම් පිළිබඳ දළ විශ්ලේෂණය"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"පද්ධති සැකසීම් වෙත ප්‍රවේශ වන්න"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google සහායක වෙත ප්‍රවේශ වන්න"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"දැනුම්දීම් බලන්න"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"තිර රුව ගන්න"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"කෙටිමං පෙන්වන්න"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ආපසු යන්න"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"මුල් තිරය වෙත යන්න"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"මෑත යෙදුම් බලන්න"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"මෑත යෙදුම් හරහා ඉදිරියට කාලක්‍රම කරන්න"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"මෑත යෙදුම් හරහා ආපස්සට කාලක්‍රම කරන්න"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"යෙදුම් ලැයිස්තුව විවෘත කරන්න"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"කාර්ය තීරුව පෙන්වන්න"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"සැකසීම් විවෘත කරන්න"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"සහායක විවෘත කරන්න"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"තිරය අගුළු දමන්න"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"ඉක්මන් සිහිපත සඳහා සටහන් යෙදුම අදින්න"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"සටහන් විවෘත කරන්න"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"පද්ධති බහු කාර්ය"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"RHS වෙත වත්මන් යෙදුම සමග බෙදුම් තිරයට ඇතුළු වන්න"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"LHS වෙත වත්මන් යෙදුම සමග බෙදුම් තිරයට ඇතුළු වන්න"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"බෙදුම් තිරයේ සිට පූර්ණ තිරයට මාරු වන්න"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"බෙදුම් තිරය අතරතුර: යෙදුමක් එකකින් තවත් එකක් ප්‍රතිස්ථාපනය කරන්න"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHS වෙත වත්මන් යෙදුම සමග බෙදුම් තිරයට ඇතුළු වන්න"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHS වෙත වත්මන් යෙදුම සමග බෙදුම් තිරයට ඇතුළු වන්න"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"බෙදුම් තිරයේ සිට පූර්ණ තිරයට මාරු වන්න"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"බෙදුම් තිරය අතරතුර: යෙදුමක් එකකින් තවත් එකක් ප්‍රතිස්ථාපනය කරන්න"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"මීළඟ භාෂාවට මාරු වන්න"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"පෙර භාෂාවට මාරු වන්න"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ඉමොජි වෙත ප්‍රවේශ වන්න"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"හඬ ටයිප් කිරීමට ප්‍රවේශ වන්න"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"යෙදුම්"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"සහාය"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"බ්‍රව්සරය (Chrome පෙරනිමිය ලෙස)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"සහායක"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"බ්‍රවුසරය"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"සම්බන්ධතා"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ඉ-තැපෑල (Gmail පෙරනිමිය ලෙස)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ඊ-තැපෑල"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"සංගීතය"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"දින දර්ශනය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index b4bf8d3..ca49d66 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Tlačidlo <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Domov"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Späť"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Nahor"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Nadol"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Doľava"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Doprava"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Do stredu"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Medzerník"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Upozornenia"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Klávesové skratky"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Prepnúť rozloženie klávesnice"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Vymazať text"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Skratky"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Hľadajte skratky"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nenašli sa žiadne skratky"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Vstup"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Otvorenie apl."</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aktuálna aplik."</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Prístup k panelu upozornení"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Vytvorenie snímky celej obrazovky"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Zoznam prístupov systému a odkazy do aplikácií"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Späť: prechod na predchádzajúci stav (tlačidlo Späť)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Prístup k ploche"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Prehľad otvorených aplikácií"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Cyklické prechádzanie nedávnymi aplikáciami (dopredu)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Cyklické prechádzanie nedávnymi aplikáciami (dozadu)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Zoznam prístupov všet. aplik. a vyhľad. (teda Vyhľadávanie a Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Skrytie a opätovné zobrazenie panela úloh"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Prístup k nastaveniam systému"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Prístup k Asistentovi Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Zobrazenie upozornení"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Vytvorenie snímky obrazovky"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Zobrazenie skratiek"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Prechod späť"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Prechod na plochu"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Zobrazenie nedávnych aplikácií"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Cyklické prechádzanie dopredu po nedávnych aplikáciách"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Cyklické prechádzanie dozadu po nedávnych aplikáciách"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvorenie zoznamu aplikácií"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Zobrazenie panela aplikácií"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvorenie nastavení"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvorenie Asistenta"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Zamknúť obrazovku"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Otvorenie aplikácie Poznámky na rýchle zapisovanie"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Otvorenie poznámok"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking systému"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Rozdelenie obrazovky s aktuálnou aplikáciou vpravo"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Rozdelenie obrazovky s aktuálnou aplikáciou vľavo"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Prepnutie rozdelenej obrazovky na celú"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Počas rozdelenej obrazovky: nahradenie aplikácie inou"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Rozdelenie obrazovky s aktuálnou aplikáciou vpravo"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Rozdelenie obrazovky s aktuálnou aplikáciou vľavo"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Prepnutie rozdelenej obrazovky na celú"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Počas rozdelenej obrazovky: nahradenie aplikácie inou"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vstup"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Prepnutie vstupného jazyka (ďalší jazyk)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Prepnutie vstupného jazyka (predchádzajúci jazyk)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Prepnutie na ďalší jazyk"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Prepnutie na predchádzajúci jazyk"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Prístup k emodži"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Prístup k hlasovému zadávaniu"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikácie"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Pomocná aplikácia"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Prehliadač (Chrome ako predvolený)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Prehliadač"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakty"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Pošta (Gmail ako predvolená služba)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-mail"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Hudba"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendár"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8c4bd73..b03d7ff 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Gumb <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Začetek"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Nazaj"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Gor"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Dol"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Levo"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Desno"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Puščica gor"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Puščica dol"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Puščica levo"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Puščica desno"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Sredina"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Preslednica"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Obvestila"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Bližnjične tipke"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Preklop postavitve tipkovnice"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Izbris besedila"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"ali"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Čiščenje iskalne poizvedbe"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Bližnjice"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Iskanje bližnjic"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Ni najdenih bližnjic."</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Vnos"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Odprte aplikacije"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Trenutna aplikacija"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Dostop do zaslona z obvestili"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Ustvarjanje posnetka celotnega zaslona"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Dostop do seznama sistemskih bližnjic in bližnjic do aplikacij"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Nazaj: Vrnitev v prejšnje stanje (gumb za vrnitev)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Dostop do začetnega zaslona"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Pregled odprtih aplikacij"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Krožno preklapljanje med nedavnimi aplikacijami (naprej)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Krožno preklapljanje med nedavnimi aplikacijami (nazaj)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Dostop do seznama vseh aplikacij in iskanja (tj. iskanje/zaganjalnik)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Skritje in (vnovični) prikaz opravilne vrstice"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Dostop do sistemskih nastavitev"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Dostop do Pomočnika Google"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Prikaz rezultatov iskanja"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Prikaz sistemskih bližnjic"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Prikaz bližnjic za vnos"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Prikaz bližnjic, s katerimi odprete aplikacije"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Prikaz bližnjic za trenutno aplikacijo"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Ogled obvestil"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ustvarjanje posnetka zaslona"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Prikaz bližnjic"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Nazaj"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Pomik na začetni zaslon"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Ogled nedavnih aplikacij"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Pomikanje naprej po nedavnih aplikacijah"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Pomikanje nazaj po nedavnih aplikacijah"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Odpiranje seznama aplikacij"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Prikaz opravilne vrstice"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Odpiranje nastavitev"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Odpiranje Pomočnika"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaklepanje zaslona"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Priklic aplikacije za zapiske za zapis hitre zabeležke"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Odpiranje zapiskov"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Sistemska večopravilnost"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Vklop razdeljenega zaslona s trenutno aplikacijo na desni"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Vklop razdeljenega zaslona s trenutno aplikacijo na levi"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Preklop iz razdeljenega zaslona v celozaslonski način"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Pri razdeljenem zaslonu: Medsebojna zamenjava aplikacij"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Vklop razdeljenega zaslona s trenutno aplikacijo na desni"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Vklop razdeljenega zaslona s trenutno aplikacijo na levi"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Preklop iz razdeljenega zaslona v celozaslonski način"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Pri razdeljenem zaslonu: medsebojna zamenjava aplikacij"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vnosna naprava"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Preklop jezika vnosa (naslednji jezik)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Preklop jezika vnosa (prejšnji jezik)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Preklop na naslednji jezik"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Preklop na prejšnji jezik"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Dostop do emodžijev"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Dostop do glasovnega tipkanja"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikacije"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Pomoč"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Brskalnik (privzeto Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Pomočnik"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Brskalnik"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Stiki"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-pošta (privzeto Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-pošta"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sporočila SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Glasba"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Koledar"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 5a1cd59..c779b65 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -401,11 +401,9 @@
     <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet ngadalë • Plot për <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> • Po karikohet • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
     <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Rrëshqit shpejt majtas për të filluar udhëzuesin e përbashkët"</string>
-    <!-- no translation found for button_to_open_widget_editor (5599945944349057600) -->
-    <skip />
+    <string name="button_to_open_widget_editor" msgid="5599945944349057600">"Hap modifikuesin e miniaplikacionit"</string>
     <string name="button_to_remove_widget" msgid="1511255853677835341">"Hiq një miniaplikacion"</string>
-    <!-- no translation found for hub_mode_add_widget_button_text (3956587989338301487) -->
-    <skip />
+    <string name="hub_mode_add_widget_button_text" msgid="3956587989338301487">"Shto miniaplikacionin"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Ndërro përdorues"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyja me tërheqje poshtë"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string>
@@ -642,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Butoni <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Kreu"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Prapa"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Lart"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Poshtë"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Majtas"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Djathtas"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Qendror"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Hapësirë"</string>
@@ -673,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Njoftimet"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Shkurtoret e tastierës"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Ndërro strukturën e tastierës"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Pastro tekstin"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Shkurtoret"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Kërko shkurtoret"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nuk u gjet shkurtore"</string>
@@ -681,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Hyrja"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Apl. e hapura"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Apl. aktual"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Qasu te streha e njoftimeve"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Bëj një pamje të plotë ekrani"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Qasu te lista e sistemeve/shkurtoreve të aplikacioneve"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Pas: kthehu pas te gjendja e mëparshme (butoni pas)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Qasu tek ekrani bazë"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Përmbledhje e aplikacioneve të hapura"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Lëviz mes aplikacioneve të fundit (përpara)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Lëviz mes aplikacioneve të fundit (pas)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Qasu te lista e aplikacioneve dhe kërko (p.sh. Kërko/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Fshih dhe (ri)shfaq shiritin e detyrave"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Qasu te cilësimet e sistemit"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Qasu tek \"Asistenti i Google\""</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Shiko njoftimet"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Nxirr një pamje ekrani"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Shfaq shkurtoret"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Kthehu prapa"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Shko tek ekrani bazë"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Shiko aplikacionet e fundit"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Lëviz përpara përmes aplikacioneve të fundit"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Lëviz prapa përmes aplikacioneve të fundit"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Hap listën e aplikacioneve"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Shfaq shiritin e detyrave"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Hap cilësimet"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Hap \"Asistentin\""</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Ekrani i kyçjes"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Hap aplikacionin \"Shënimet\" për një memorandum të shpejtë"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Hap \"Shënimet\""</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Kryerja e shumë detyrave nga sistemi"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Fut ekranin e ndarë me aplikacionin aktual te RHS-ja"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Fut ekranin e ndarë me aplikacionin aktual te LHS-ja"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Kalo nga ekrani i ndarë në ekranin e plotë"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Gjatë ekranit të ndarë: zëvendëso një aplikacion nga një te një tjetër"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Hyr në ekranin e ndarë me aplikacionin aktual në anën e djathtë"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Hyr në ekranin e ndarë me aplikacionin aktual në anën e majtë"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Kalo nga ekrani i ndarë në ekranin e plotë"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Gjatë ekranit të ndarë: zëvendëso një aplikacion me një tjetër"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Hyrja"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Ndërro gjuhën e hyrjes (gjuha tjetër)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Ndërro gjuhën e hyrjes (gjuha e mëparshme)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Kalo te gjuha tjetër"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Kalo te gjuha e mëparshme"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Qasu te emoji-t"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Qasu te shkrimi me zë"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikacionet"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Asistenti"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Shfletuesi (Chrome si i parazgjedhur)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistenti"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Shfletuesi"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontaktet"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (Gmail si i parazgjedhur)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email-i"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muzikë"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendari"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 887f5c6..48673b9 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Дугме <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Тастер Почетна"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Тастер Назад"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Тастер са стрелицом нагоре"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Тастер са стрелицом надоле"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Тастер са стрелицом налево"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Тастер са стрелицом надесно"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Тастер са централном стрелицом"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Размак"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Обавештења"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Тастерске пречице"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Промени распоред тастатуре"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Обришите текст"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Пречице"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Претражите пречице"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Нису пронађене пречице"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Унос"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Преглед отворених апликација"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Приступ подешавањима система"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Приступ Google помоћнику"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Прикажи обавештења"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Направи снимак екрана"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Прикажи пречице"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Назад"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Иди на почетни екран"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Прегледај недавно коришћене апликације"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Прегледај недавно коришћене апликације унапред"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Прегледај недавно коришћене апликације уназад"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Отвори листу апликација"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Прикажи траку задатака"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Отвори подешавања"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Отвори помоћника"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Закључавање екрана"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Отварање апликације Белешке за брзо прављење белешке"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Отвори белешке"</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="2454557648974553729">"Покрени подељени екран за актуелну апликацију на десној страни"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Покрени подељени екран за актуелну апликацију на левој страни"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Пређи са подељеног екрана на цео екран"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"У режиму подељеног екрана: замена једне апликације другом"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Пређи на следећи језик"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Пређи на претходни језик"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Приступ емоџијима"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Приступ уносу текста гласом"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Апликације"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Апликација за помоћ"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Прегледач (подразумевано Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Помоћник"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Прегледач"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Контакти"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Имејл (Gmail као подразумевани)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Имејл"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 3f9e45c..0b2cab0 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Knappen <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Start"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Tillbaka"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Upp"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Ned"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Vänster"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Höger"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Centrera"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Blanksteg"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Aviseringar"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Kortkommandon"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Byt tangentbordslayout"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Rensa text"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Kortkommandon"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Sök efter kortkommando"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Inga resultat"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Inmatning"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Öppna appar"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Aktuell app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Öppna meddelandepanelen"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Ta en skärmbild av hela skärmen"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Öppna lista över system- och appgenvägar"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Bakåt: gå tillbaka till föregående läge (bakåtknapp)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Öppna startskärmen"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Översikt över öppna appar"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Bläddra igenom de senaste apparna (framåt)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Bläddra igenom de senaste apparna (bakåt)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Öppna en lista över alla appar och sökningar (t.ex. Sök/Appstartaren)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Dölj och visa aktivitetsfältet"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Öppna systeminställningarna"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Öppna Google Assistent"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Se aviseringar"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ta skärmbild"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Se genvägar"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Tillbaka"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Öppna startskärmen"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Se de senaste apparna"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Bläddra framåt bland de senaste apparna"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Bläddra bakåt bland de senaste apparna"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Öppna applistan"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Se aktivitetsfält"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Öppna inställningarna"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Öppna assistenten"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Lås skärmen"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Ta fram anteckningsappen för en snabb anteckning"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Öppna anteckningar"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Systemets multikörning"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Öppna delad skärm med aktuell app till höger"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Öppna delad skärm med aktuell app till vänster"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Byt mellan delad skärm och helskärm"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Med delad skärm: ersätt en app med en annan"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Öppna delad skärm med aktuell app till höger"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Öppna delad skärm med aktuell app till vänster"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Byt mellan delad skärm och helskärm"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Med delad skärm: ersätt en app med en annan"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Inmatning"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Byt inmatningsspråk (nästa språk)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Byt inmatningsspråk (föregående språk)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Byt till nästa språk"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Byt till föregående språk"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Öppna emojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Öppna röststyrning"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Appar"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Hjälp"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Webbläsare (Chrome som standard)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Webbläsare"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontakter"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-post (Gmail som standard)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-post"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 007f0d3..3cd5345 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -640,10 +640,10 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Kitufe cha <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Mwanzo"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Nyuma"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Juu"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Chini"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Kushoto"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Kulia"</string>
+    <string name="keyboard_key_dpad_up" msgid="7199805608386368673">"Kishale cha juu"</string>
+    <string name="keyboard_key_dpad_down" msgid="3354221123220737397">"Kishale cha chini"</string>
+    <string name="keyboard_key_dpad_left" msgid="144176368026538621">"Kishale cha kushoto"</string>
+    <string name="keyboard_key_dpad_right" msgid="8485763312139820037">"Kishale cha kulia"</string>
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Katikati"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +671,8 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Arifa"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Mikato ya Kibodi"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Badili mkao wa kibodi"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Futa maandishi"</string>
+    <string name="keyboard_shortcut_join" msgid="3578314570034512676">"au"</string>
+    <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Futa hoja ya utafutaji"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Njia za mkato"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Tafuta njia za mkato"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Hakuna njia za mkato zilizopatikana"</string>
@@ -679,35 +680,40 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Vifaa vya kuingiza data"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Fungua programu"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Programu ya sasa"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Fikia sehemu ya arifa"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Piga picha kamili ya skrini"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Orodha ya ufikiaji ya mfumo / njia za mikato za programu"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Nyuma: rudi kwenye hali ya awali (kitufe cha nyuma)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Fikia skrini ya kwanza"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Muhtasari wa programu zilizofunguliwa"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Pitia programu za hivi karibuni (mbele)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Pitia programu za hivi karibuni (nyuma)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Orodha ya ufikiaji ya programu na utafutaji wote (k.m. Utafutaji/Kifungua programu)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ficha na uonyeshe upya upauzana"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Fikia mipangilio ya mfumo"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Fikia programu ya Mratibu wa Google"</string>
+    <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Inaonyesha matokeo ya utafutaji"</string>
+    <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Inaonyesha njia za mkato za mfumo"</string>
+    <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Inaonyesha njia za mkato za kuingiza data"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Inaonyesha njia za mkato za kufungua programu"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Inaonyesha njia za mkato za programu unayotumia kwa sasa"</string>
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Tazama arifa"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Kupiga picha ya skrini"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Onyesha njia za mkato"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Rudi nyuma"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Nenda kwenye skrini ya kwanza"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Angalia programu ulizofungua hivi majuzi"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Nenda mbele kwenye programu ulizofungua awali"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Rudi nyuma kwenye programu ulizofungua awali"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Fungua orodha ya programu"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Onyesha upauzana"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Fungua mipangilio"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Fungua programu ya Mratibu wa Google"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Funga skrini"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Fungua programu ya Madokezo ili uandike taarifa"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Fungua madokezo"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Majukumu mengi ya mfumo"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Weka Skrini iliyogawanywa na programu ya sasa kwenye upande wa kulia"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Weka Skrini iliyogawanywa na programu ya sasa kwenye upande wa kushoto"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Badilisha kutoka Skrini iliyogawanywa utumie skrini nzima"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Wakati wa Skrini iliyogawanywa: badilisha kutoka programu moja hadi nyingine"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Tumia programu kwenye skrini iliyogawanywa upande wa kulia"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Tumia programu kwenye skrini iliyogawanywa upande wa kushoto"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Badilisha kutoka skrini iliyogawanywa utumie skrini nzima"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Ukigawanya skrini: badilisha kutoka programu moja hadi nyingine"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vifaa vya kuingiza data"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Badilisha lugha ya kuweka data (lugha inayofuata)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Badilisha lugha ya kuweka data (lugha ya awali)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Badilisha utumie lugha inayofuata"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Badilisha utumie lugha iliyotangulia"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Fikia emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Fikia kuandika kwa kutamka"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Programu"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Programu ya usaidizi"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Kivinjari (Chrome iwe chaguomsingi)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Programu ya Mratibu"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Kivinjari"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Anwani"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Barua pepe (Gmail iwe chaguomsingi)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Barua pepe"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Muziki"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalenda"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index e5cf3b2..7989a35 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> பட்டன்"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"ஹோம்"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"பேக்"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"மேலே"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"கீழே"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"இடது"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"வலது"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"நடு"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"ஸ்பேஸ்"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"அறிவிப்புகள்"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"கீபோர்டு ஷார்ட்கட்கள்"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"கீபோர்டு லே அவுட்டை மாற்று"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"வார்த்தைகளை அழிக்கும்"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"ஷார்ட்கட்கள்"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ஷார்ட்கட்களைத் தேடுக"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ஷார்ட்கட்கள் எதுவுமில்லை"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"உள்ளீடு"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"திறந்திருக்கும் ஆப்ஸைப் பார்த்தல்"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"சிஸ்டம் அமைப்புகளுக்கான அணுகல்"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Assistantடிற்கான அணுகல்"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"அறிவிப்புகளைக் காட்டுதல்"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ஸ்கிரீன்ஷாட் எடுத்தல்"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"ஷார்ட்கட்களைக் காட்டுதல்"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"பின்செல்லுதல்"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"முகப்புத் திரைக்குச் செல்லுதல்"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"சமீபத்திய ஆப்ஸைக் காட்டுதல்"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"சமீபத்திய ஆப்ஸுக்கு முன்னோக்கிச் செல்லுதல்"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"சமீபத்திய ஆப்ஸுக்குப் பின்னோக்கிச் செல்லுதல்"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ஆப்ஸ் பட்டியலைத் திறத்தல்"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"செயல் பட்டியைக் காட்டுதல்"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"அமைப்புகளைத் திறத்தல்"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistantடைத் திறத்தல்"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"பூட்டுத் திரை"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"மெமோவை விரைவாகத் தயாரிக்க Notes ஆப்ஸைப் பயன்படுத்துதல்"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"குறிப்புகளைத் திறத்தல்"</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="2454557648974553729">"வலதுபுறத்தில் தற்போதைய ஆப்ஸ் தோன்றுமாறு திரைப் பிரிப்பை அமைத்தல்"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"இடதுபுறத்தில் தற்போதைய ஆப்ஸ் தோன்றுமாறு திரைப் பிரிப்பை அமைத்தல்"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"திரைப் பிரிப்பு பயன்முறையிலிருந்து முழுத்திரைக்கு மாற்றுதல்"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"திரைப் பிரிப்பின்போது: ஓர் ஆப்ஸுக்குப் பதிலாக மற்றொன்றை மாற்றுதல்"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"அடுத்த மொழிக்கு மாற்றுதல்"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"முந்தைய மொழிக்கு மாற்றுதல்"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ஈமோஜிக்கான அணுகல்"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"குரல் டைப்பிங்கிற்கான அணுகல்"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ஆப்ஸ்"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"அசிஸ்ட்"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"உலாவி (இயல்பாக Chrome இருக்கும்)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"உலாவி"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"தொடர்புகள்"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"மின்னஞ்சல் (இயல்பாக Gmail இருக்கும்)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"மின்னஞ்சல்"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"மியூசிக்"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 8ec3905..6b2c032 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"బటన్ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"వెనుకకు"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"పైకి"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"కిందికి"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ఎడమ"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"కుడి"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"మధ్య"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"అంతరం"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"నోటిఫికేషన్‌లు"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"కీబోర్డ్ షార్ట్‌కట్‌లు"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"కీబోర్డ్ లేఅవుట్‌ను మార్చండి"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"టెక్స్ట్‌ను క్లియర్ చేయండి"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"షార్ట్‌కట్‌లు"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"షార్ట్‌కట్స్ సెర్చ్ చేయండి"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"షార్ట్‌కట్‌లు ఏవీ లేవు"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ఇన్‌పుట్"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Overview of open apps"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"సిస్టమ్ సెట్టింగ్‌లను యాక్సెస్ చేయండి"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Assistantను యాక్సెస్ చేయండి"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"నోటిఫికేషన్‌లను చూడండి"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"స్క్రీన్‌షాట్‌ను తీయండి"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"షార్ట్‌కట్‌లను చూపించండి"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"వెనుకకు వెళ్లండి"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"మొదటి స్క్రీన్‌కు వెళ్లండి"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"ఇటీవలి యాప్‌లను చూడండి"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"ఇటీవల ఉపయోగించిన యాప్‌ల తదుపరి పేజీకి వెళ్లండి"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"ఇటీవల ఉపయోగించిన యాప్‌ల మునుపటి పేజీకి వెళ్లండి"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"యాప్‌ల లిస్ట్‌ను తెరవండి"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"టాస్క్‌బార్‌ను చూపండి"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"సెట్టింగ్‌లను తెరవండి"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"అసిస్టెంట్‌ను తెరవండి"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"లాక్ స్క్రీన్"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"క్విక్ మెమో కోసం Notes యాప్‌ను లాగండి"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"నోట్స్‌ను తెరవండి"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"సిస్టమ్ మల్టీ-టాస్కింగ్"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"RHSకు ప్రస్తుత యాప్‌తో స్ప్లిట్  స్క్రీన్‌ను ఎంటర్ చేయండి"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"LHSకు ప్రస్తుత యాప్‌తో స్ప్లిట్  స్క్రీన్‌ను ఎంటర్ చేయండి"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"స్ప్లిట్  స్క్రీన్‌ను ఫుల్ స్క్రీన్‌కు మార్చండి"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"స్ప్లిట్  స్క్రీన్ సమయంలో: యాప్‌ను ఒకదాని నుండి మరొకదానికి రీప్లేస్ చేయండి"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHSకు ప్రస్తుత యాప్‌తో స్ప్లిట్ స్క్రీన్‌ను ఎంటర్ చేయండి"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHSకు ప్రస్తుత యాప్‌తో స్ప్లిట్ స్క్రీన్‌ను ఎంటర్ చేయండి"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"స్ప్లిట్ స్క్రీన్‌ను ఫుల్ స్క్రీన్‌కు మార్చండి"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"స్ప్లిట్ స్క్రీన్ సమయంలో: ఒక దాన్నుండి మరో దానికి యాప్ రీప్లేస్ చేయండి"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"తర్వాత భాషకు స్విచ్ అవ్వండి"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"మునుపటి భాషకు స్విచ్ అవ్వండి"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ఎమోజిని యాక్సెస్ చేయండి"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"వాయిస్ టైపింగ్‌ను యాక్సెస్ చేయండి"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"అప్లికేషన్‌లు"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"సహాయకం"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"బ్రౌజర్ (ఆటోమేటిక్ సెట్టింగ్‌గా Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"బ్రౌజర్"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"కాంటాక్ట్‌లు"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"ఈమెయిల్ (ఆటోమేటిక్ సెట్టింగ్‌గా Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ఈమెయిల్‌"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"మ్యూజిక్"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2f13280..3c5396f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"ปุ่ม <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"กลับ"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"ขึ้น"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"ลง"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ซ้าย"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ขวา"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"กึ่งกลาง"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"วรรค"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"การแจ้งเตือน"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"แป้นพิมพ์ลัด"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"สลับรูปแบบแป้นพิมพ์"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ล้างข้อความ"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"แป้นพิมพ์ลัด"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ค้นหาแป้นพิมพ์ลัด"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ไม่พบแป้นพิมพ์ลัด"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"อินพุต"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"ภาพรวมของแอปที่เปิดอยู่"</string>
-    <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">"เข้าถึงรายการแอปและการค้นหา (เช่น Search/Launcher)"</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 Assistant"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"ดูการแจ้งเตือน"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"ถ่ายภาพหน้าจอ"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"แสดงแป้นพิมพ์ลัด"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"ย้อนกลับ"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ไปที่หน้าจอหลัก"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"ดูแอปล่าสุด"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"สลับระหว่างแอปล่าสุดแบบไปข้างหน้า"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"สลับระหว่างแอปล่าสุดแบบกลับหลัง"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"เปิดรายชื่อแอป"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"แสดงแถบงาน"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"เปิดการตั้งค่า"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"เปิด Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"ล็อกหน้าจอ"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"เปิดแอปโน้ตเพื่อจดบันทึก"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"เปิดโน้ต"</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="2454557648974553729">"เข้าสู่โหมดแยกหน้าจอโดยแอปปัจจุบันอยู่ด้านขวา"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"เข้าสู่โหมดแยกหน้าจอโดยแอปปัจจุบันอยู่ด้านซ้าย"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"เปลี่ยนจากโหมดแยกหน้าจอเป็นเต็มหน้าจอ"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"ระหว่างใช้โหมดแยกหน้าจอ: เปลี่ยนแอปหนึ่งเป็นอีกแอปหนึ่ง"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"เปลี่ยนเป็นภาษาถัดไป"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"เปลี่ยนเป็นภาษาก่อนหน้า"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"เข้าถึงอีโมจิ"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"เข้าถึงการพิมพ์ด้วยเสียง"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"แอปพลิเคชัน"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"ผู้ช่วย"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"เบราว์เซอร์ (Chrome เป็นค่าเริ่มต้น)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"เบราว์เซอร์"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"รายชื่อติดต่อ"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"อีเมล (Gmail เป็นค่าเริ่มต้น)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"อีเมล"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"เพลง"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ปฏิทิน"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 11c75c6..21111a4 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Button na <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Up"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Down"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Left"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Right"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Center"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Mga Notification"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Mga Keyboard Shortcut"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Magpalit ng layout ng keyboard"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"I-clear ang text"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Mga Shortcut"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Maghanap ng mga shortcut"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Walang nakitang shortcut"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Input"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Buksan ang app"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Kasalukuyang app"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"I-access ang notification shade"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Kumuha ng buong screenshot"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"I-access ang listahan ng mga shortcut ng system / mga app"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Bumalik: bumalik sa nakaraang status (button na bumalik)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"I-access ang home screen"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Pangkalahatang-ideya ng mga bukas na app"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Mag-cycle sa mga kamakailang app (sumulong)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Mag-cycle sa mga kamakailang app (bumalik)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"I-access ang listahan ng lahat ng app at paghahanap (ibig sabihin, Search/Launcher)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Itago at ipakita (ulit) ang taskbar"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"I-access ang mga setting ng system"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"I-access ang Google Assistant"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Tumingin ng mga notification"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Kumuha ng screenshot"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Ipakita ang mga shortcut"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Bumalik"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Pumunta sa home screen"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Tingnan ang mga kamakailang app"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Mag-cycle pasulong sa mga kamakailang app"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Mag-cycle pabalik sa mga kamakailang app"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Buksan ang listahan ng mga app"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Ipakita ang taskbar"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Buksan ang mga setting"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Buksan ang assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"I-lock ang screen"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Buksan ang Notes app para sa mabilis na memo"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Buksan ang mga tala"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Multitasking ng system"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Lumipat sa Split screen nang nasa RHS ang kasalukuyang app"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Lumipat sa Split screen nang nasa LHS ang kasalukuyang app"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Lumipat sa full screen mula sa Split screen"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Habang nasa Split screen: magpalit-palit ng app"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Lumipat sa split screen nang nasa RHS ang kasalukuyang app"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Lumipat sa split screen nang nasa LHS ang kasalukuyang app"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Lumipat sa full screen mula sa split screen"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Habang nasa split screen: magpalit-palit ng app"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Magpalit ng wika ng pag-input (susunod na wika)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Magpalit ng wika ng pag-input (nakaraang wika)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Lumipat sa susunod na wika"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Lumipat sa dating wika"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"I-access ang emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"I-access ang voice typing"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Mga Application"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Tulong"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Browser (Chrome bilang default)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Mga Contact"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (Gmail bilang default)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Music"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendaryo"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 3f578d2..08b0251 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> düğmesi"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Geri"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Yukarı"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Aşağı"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Sol"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Sağ"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Orta"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Boşluk"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Bildirimler"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Klavye Kısayolları"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Klavye düzenini değiştir"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Metni temizle"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Kısayollar"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Kısayol araması yapın"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Kısayol bulunamadı"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Giriş"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Uygulamaları açma"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Mevcut uygulama"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Bildirim gölgesine erişin"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Tam ekran görüntüsü alın"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Sistem/uygulama kısayolları listesine erişin"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Geri: Önceki duruma geri dönün (geri düğmesi)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Ana ekrana erişin"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Açık uygulamalara genel bakış"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Son uygulamalar arasında gezinin (ileri)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Son uygulamalar arasında gezinin (geri)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Tüm uygulama ve arama (ör. Arama/Launcher) listesine erişin"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Görev çubuğunu gizleyin ve (yeniden) gösterin"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Sistem ayarlarına erişin"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Asistan\'a erişin"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Bildirimleri görüntüle"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ekran görüntüsü al"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Kısayolları göster"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Geri dön"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Ana ekrana git"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Son uygulamaları görüntüle"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Son uygulamalarda ileriye doğru git"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Son uygulamalarda geriye doğru git"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Uygulama listesini aç"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Görev çubuğunu göster"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ayarları aç"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Asistan\'ı aç"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Kilit ekranı"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Hızlıca not almak için Notlar uygulamasını açın"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Notları aç"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Sistem çoklu görevi"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Mevcut uygulamayı sağ tarafa alarak bölünmüş ekrana geçin"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Mevcut uygulamayı sol tarafa alarak bölünmüş ekrana geçin"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Bölünmüş ekrandan tam ekrana geçin"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Bölünmüş ekran etkinken: Bir uygulamayı başkasıyla değiştirin"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Mevcut uygulamayı sağ tarafa alarak bölünmüş ekrana geç"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Mevcut uygulamayı sol tarafa alarak bölünmüş ekrana geç"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Bölünmüş ekrandan tam ekrana geç"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran etkinken: Bir uygulamayı başkasıyla değiştir"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Giriş"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Giriş dilini değiştirin (sonraki dil)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Giriş dilini değiştirin (önceki dil)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Sonraki dile geç"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Önceki dile geç"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Emojilere erişin"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Sesle yazma özelliğine erişin"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Uygulamalar"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Asistan"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Tarayıcı (varsayılan olarak Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Asistan"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Tarayıcı"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kişiler"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"E-posta (varsayılan olarak Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"E-posta"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Müzik"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Takvim"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 90dc097..9048b63 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -401,11 +401,9 @@
     <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="communal_tutorial_indicator_text" msgid="4503010353591430123">"Проведіть пальцем уліво, щоб відкрити спільний навчальний посібник"</string>
-    <!-- no translation found for button_to_open_widget_editor (5599945944349057600) -->
-    <skip />
+    <string name="button_to_open_widget_editor" msgid="5599945944349057600">"Відкрити редактор віджетів"</string>
     <string name="button_to_remove_widget" msgid="1511255853677835341">"Вилучити віджет"</string>
-    <!-- no translation found for hub_mode_add_widget_button_text (3956587989338301487) -->
-    <skip />
+    <string name="hub_mode_add_widget_button_text" msgid="3956587989338301487">"Додати віджет"</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>
@@ -642,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Кнопка <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Назад"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Стрілка вгору"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Стрілка вниз"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Стрілка вліво"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Стрілка вправо"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Центр"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Пробіл"</string>
@@ -673,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Сповіщення"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Комбінації клавіш"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Змінити розкладку клавіатури"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Видалити текст"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Швидкі команди"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Пошук швидких команд"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Швидк. команд не знайдено"</string>
@@ -681,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Метод введення"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"Огляд відкритих додатків"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"Відкрити налаштування системи"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Відкрити Google Асистента"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Переглянути сповіщення"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Зробити знімок екрана"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Показати комбінації клавіш"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Назад"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Перейти на головний екран"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Переглянути нещодавні додатки"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Перемикатися між нещодавніми додатками вперед"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Перемикатися між нещодавніми додатками назад"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Відкрити список додатків"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Показати панель завдань"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Відкрити налаштування"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Відкрити додаток Асистент"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Заблокувати екран"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Відкривати додаток \"Нотатки\" для швидких приміток"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Відкрити нотатки"</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="2454557648974553729">"Розділити екран із поточним додатком праворуч"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Розділити екран із поточним додатком ліворуч"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Перейти з розділення екрана на весь екран"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Під час розділення екрана: замінити додаток іншим"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Вибрати наступну мову"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Вибрати попередню мову"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Відкрити смайли"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Відкрити голосовий ввід"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Додатки"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Помічник"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Веб-переглядач (за умовчанням – Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Асистент"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Веб-переглядач"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Контакти"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Електронна пошта (за умовчанням – Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Електронна пошта"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Музика"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 137c8ab..d9bb0ae 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"بٹن <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"پیچھے"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"اوپر"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"نیچے"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"بائیں"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"دائیں"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"سینٹر"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"اطلاعات"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"کی بورڈ شارٹ کٹس"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"کی بورڈ لے آؤٹ سوئچ کریں"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"ٹیکسٹ صاف کریں"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"شارٹ کٹس"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"شارٹ کٹس تلاش کریں"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"کوئی شارٹ کٹ نہیں ملا"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"ان پٹ"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"کھلی ایپس کا مجموعی جائزہ"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"سسٹم کی ترتیبات تک رسائی"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"‏Google اسسٹنٹ تک رسائی حاصل کریں"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"اطلاعات دیکھیں"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"اسکرین شاٹ لیں"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"شارٹ کٹس دکھائيں"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"واپس جائیں"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"ہوم اسکرین پر جائیں"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"حالیہ ایپس دیکھیں"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"حالیہ ایپس کے ذریعے آگے کی طرف سائیکل کریں"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"حالیہ ایپس کے ذریعے پیچھے کی طرف سائیکل کریں"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ایپس کی فہرست کھولیں"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"ٹاسک بار دکھائیں"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"ترتیبات کھولیں"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"اسسٹنٹ کھولیں"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"مقفل اسکرین"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"فوری میمو کے ليے نوٹس ایپ حاصل کریں"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"نوٹس کھولیں"</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="2454557648974553729">"موجودہ ایپ کے ساتھ دائیں جانب اسپلٹ اسکرین انٹر کریں"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"موجودہ ایپ کے ساتھ بائیں جانب اسپلٹ اسکرین انٹر کریں"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"اسپلٹ اسکرین سے پوری سکرین پر سوئچ کریں"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"اسپلٹ اسکرین کے دوران: ایک ایپ کو دوسرے سے تبدیل کریں"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"اگلی زبان پر سوئچ کریں"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"پچھلی زبان پر سوئچ کریں"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ایموجی تک رسائی"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"صوتی ٹائپنگ تک رسائی"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ایپلیکیشنز"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"اسسٹ"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"‏براؤزر (بطور ڈیفالٹ Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"اسسٹنٹ"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"براؤزر"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"رابطے"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"‏ای میل (بطور ڈیفالٹ Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ای میل"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"موسیقی"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"کیلنڈر"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 601d773..5696c61 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> tugmasi"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Bosh ekran"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Orqaga"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Tepaga qaragan ko‘rsatkichli chiziq"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Pastga qaragan ko‘rsatkichli chiziq"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Chapga qaragan ko‘rsatkichli chiziq"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"O‘ngga qaragan ko‘rsatkichli chiziq"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Markaziy ko‘rsatkichli chiziq"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Probel"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Bildirishnomalar"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Tezkor tugmalar"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Klaviatura terilmasini almashtirish"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Matnni tozalash"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Tezkor tugmalar"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Tezkor tugmalar qidiruvi"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Tezkor tugmalar topilmadi"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Kiritish"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Ochiq ilovalar"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Joriy ilova"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Bildirishnoma soyasiga ruxsat"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Butun skrinshot olish"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Tizim va ilovalar tezkor tugmalari roʻyxatiga ruxsat"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Orqaga: avvalgi holatga qaytish (orqaga tugmasi)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Bosh ekranga ruxsat"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Ochiq ilovalar bilan tanishish"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Oxirgi ilovalarni varaqlash (faol rejimda)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Oxirgi ilovalarni varaqlash (fonda)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Barcha ilovalar va qidiruv roʻyxatiga ruxsat (Qidiruv/Launcher kabi)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Vazifalar panelini ochish va yopish"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Tizim sozlamalariga ruxsat"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Google Assistentga ruxsat"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Bildirishnomalarni ochish"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Skrinshot olish"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Yorliqlarni ochish"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Orqaga"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Bosh ekranni ochish"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Oxirgi ilovalarni ochish"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Oxirgi ilovalarni oldinga varaqlash"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Oxirgi ilovalarni orqaga varaqlash"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ilovalar roʻyxatini ochish"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Vazifalar panelini chiqarish"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Sozlamalarni ochish"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistentni ochish"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Ekran qulfi"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Tezkor eslatma uchun Qaydlar ilovasini ochish"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Qaydlarni ochish"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Tizimdagi multi-vazifalik"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Oʻng tomondagi ajratilgan ekran rejimiga kirish"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Chap tomondagi ajratilgan ekran rejimiga kirish"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Ajratilgan ekran rejimidan butun ekranga qaytish"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Ajratilgan rejimda ilovalarni oʻzaro almashtirish"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Oʻng tomondagi ajratilgan ekran rejimiga kirish"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Chap tomondagi ajratilgan ekran rejimiga kirish"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Ajratilgan ekran rejimidan butun ekranga almashtirish"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Ajratilgan rejimda ilovalarni oʻzaro almashtirish"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Kiritish"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Kiritish tili tugmasi (keyingi til)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Kiritish tili tugmasi (avvalgi til)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Keyingi tilga almashtirish"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Avvalgi tilga almashtirish"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Emojilarga ruxsat"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Ovoz bilan yozishga ruxsat"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Ilovalar"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Yordamchi"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Brauzer (birlamchisi Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistent"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Brauzer"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Kontaktlar"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (birlamchisi Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musiqa"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Taqvim"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index b67c789..c281d90 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Nút <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Quay lại"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Lên"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Xuống"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Trái"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Phải"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Giữa"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Dấu cách"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Thông báo"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Phím tắt"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Chuyển đổi bố cục bàn phím"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Xoá văn bản"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Lối tắt"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Lối tắt tìm kiếm"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Không tìm thấy lối tắt"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Đầu vào"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Ứng dụng đang mở"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Ứng dụng hiện tại"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Truy cập ngăn thông báo"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Chụp toàn màn hình"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Danh sách truy cập lối tắt ứng dụng/hệ thống"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Quay lại: quay lại trạng thái trước đó (nút quay lại)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Truy cập màn hình khoá"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Tổng quan về những ứng dụng đang mở"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Xoay vòng qua các ứng dụng gần đây (xuôi)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Xoay vòng qua các ứng dụng gần đây (ngược)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"D.sách truy cập mọi ứng dụng/n.dung tìm kiếm (VD: Tìm kiếm/Trình chạy)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Ẩn và hiện (lại) thanh tác vụ"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Truy cập chế độ cài đặt hệ thống"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Truy cập Trợ lý Google"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Xem thông báo"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Chụp ảnh màn hình"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Hiện phím tắt"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Quay lại"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Chuyển đến màn hình chính"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Xem các ứng dụng gần đây"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Di chuyển tiến trong danh sách các ứng dụng gần đây"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Di chuyển lùi trong danh sách các ứng dụng gần đây"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Mở danh sách ứng dụng"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Hiện thanh tác vụ"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Mở phần cài đặt"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Mở Trợ lý"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Màn hình khoá"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Mở ứng dụng Ghi chú để ghi chú nhanh"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Mở ghi chú"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Xử lý đa nhiệm trong hệ thống"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Vào chế độ Chia đôi màn hình, ứng dụng hiện tại sang màn hình bên phải"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Vào chế độ Chia đôi màn hình, ứng dụng hiện tại sang màn hình bên trái"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Chuyển từ chế độ Chia đôi màn hình sang chế độ toàn màn hình"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Trong chế độ Chia đôi màn hình: thay ứng dụng này bằng ứng dụng khác"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Vào chế độ chia đôi màn hình, ứng dụng hiện tại ở màn hình bên phải"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Vào chế độ chia đôi màn hình, ứng dụng hiện tại ở màn hình bên trái"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Chuyển từ chế độ chia đôi màn hình sang chế độ toàn màn hình"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Trong chế độ chia đôi màn hình: thay ứng dụng này bằng ứng dụng khác"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Đầu vào"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Chuyển ngôn ngữ nhập (ngôn ngữ tiếp theo)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Chuyển ngôn ngữ nhập (ngôn ngữ trước đó)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Chuyển sang ngôn ngữ tiếp theo"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Chuyển sang ngôn ngữ trước"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Truy cập biểu tượng cảm xúc"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Truy cập tính năng nhập liệu bằng giọng nói"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Ứng dụng"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Trợ lý"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Trình duyệt (mặc định là Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Trợ lý"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Trình duyệt"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Danh bạ"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"Email (mặc định là Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"Email"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Âm nhạc"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Lịch"</string>
@@ -826,7 +843,7 @@
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi đang tắt"</string>
-    <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth tắt"</string>
+    <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth đang tắt"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Không làm phiền tắt"</string>
     <string name="dnd_is_on" msgid="7009368176361546279">"Chế độ Không làm phiền đang bật"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Không làm phiền đã được một quy tắc tự động (<xliff:g id="ID_1">%s</xliff:g>) bật."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 576cbc7..7cde292 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g>按钮"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"返回"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"向上"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"向下"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"向左"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"向右"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"中心"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"空格"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"通知"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"键盘快捷键"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"切换键盘布局"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"清除文字"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"快捷键"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"搜索快捷键"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"未找到任何快捷键"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"输入"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"已开应用概览"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"访问系统设置"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"访问 Google 助理"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"查看通知"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"截取屏幕截图"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"显示快捷键"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"返回"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"前往主屏幕"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"查看最近运行过的应用"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"向前循环浏览近期使用的应用"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"向后循环浏览近期使用的应用"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"打开应用列表"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"显示任务栏"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"打开设置"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"打开 Google 助理"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"锁定屏幕"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"调出记事应用快速做记录"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"打开笔记"</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="2454557648974553729">"进入分屏模式,当前应用显示于右侧"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"进入分屏模式,当前应用显示于左侧"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"从分屏模式切换为全屏"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"在分屏期间:将一个应用替换为另一个应用"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"切换到下一种语言"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"切换到上一种语言"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"访问表情符号"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"访问语音输入"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"应用"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"助理"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"浏览器(默认为 Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Google 助理"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"浏览器"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"通讯录"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"电子邮件(默认为 Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"电子邮件"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"短信"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音乐"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日历"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index bcf7478..a997d06 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> 鍵"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"返回"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"向上"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"向下"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"向左"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"向右"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"箭咀中央"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"空格"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"通知"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"鍵盤快速鍵"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"切換鍵盤配置"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"清除文字"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"快速鍵"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"搜尋快速鍵"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"找不到快速鍵"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"輸入"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"「已開啟的應用程式」概覽"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"存取系統設定"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"存取「Google 助理」"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"查看通知"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"擷取螢幕截圖"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"顯示快速鍵"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"返回"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"前往主畫面"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"查看最近使用的應用程式"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"輪流切換最近使用的應用程式 (向前)"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"輪流切換最近使用的應用程式 (向後)"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"開啟應用程式清單"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"顯示工作列"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"開啟設定"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"開啟「Google 助理」"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"上鎖畫面"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"開啟「筆記」應用程式快速寫筆記"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"開啟筆記"</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="2454557648974553729">"進入分割螢幕模式,並將目前的應用程式顯示在右側"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"進入分割螢幕模式,並將目前的應用程式顯示在左側"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"將分割螢幕切換為全螢幕"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割螢幕期間:更換應用程式"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"切換至下一個語言"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"切換至上一個語言"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"存取 Emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"存取語音輸入內容"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"應用程式"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"小幫手"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"瀏覽器 (預設為 Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Google 助理"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"瀏覽器"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"通訊錄"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"電郵 (預設為 Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"電郵"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"短訊"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音樂"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日曆"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 76d11ec..9900adf 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -401,11 +401,9 @@
     <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="communal_tutorial_indicator_text" msgid="4503010353591430123">"向左滑動即可啟動通用教學課程"</string>
-    <!-- no translation found for button_to_open_widget_editor (5599945944349057600) -->
-    <skip />
+    <string name="button_to_open_widget_editor" msgid="5599945944349057600">"開啟小工具編輯器"</string>
     <string name="button_to_remove_widget" msgid="1511255853677835341">"移除小工具"</string>
-    <!-- no translation found for hub_mode_add_widget_button_text (3956587989338301487) -->
-    <skip />
+    <string name="hub_mode_add_widget_button_text" msgid="3956587989338301487">"新增小工具"</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>
@@ -642,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> 按鈕"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home 鍵"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"返回"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"向上鍵"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"向下鍵"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"向左鍵"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"向右鍵"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"中央鍵"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"空格鍵"</string>
@@ -673,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"通知"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"鍵盤快速鍵"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"切換鍵盤配置"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"清除文字"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"快速鍵"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"搜尋快速鍵"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"找不到快速鍵"</string>
@@ -681,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"輸入"</string>
     <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_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_overview_open_apps" msgid="6897128761003265350">"「已開啟的應用程式」總覽"</string>
-    <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_access_system_settings" msgid="7961639365383008053">"存取系統設定"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"存取 Google 助理"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"查看通知"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"拍攝螢幕截圖"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"顯示快速鍵"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"返回"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"前往主畫面"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"查看最近開啟的應用程式"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"前往最近開啟的應用程式"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"返回最近開啟的應用程式"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"開啟應用程式清單"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"顯示工作列"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"開啟設定"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"開啟 Google 助理"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"螢幕鎖定"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"打開「記事」應用程式快速做筆記"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"開啟記事"</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="2454557648974553729">"進入分割畫面模式,並將目前的應用程式顯示於右側"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"進入分割畫面模式,並將目前的應用程式顯示於左側"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"從分割畫面切換到完整畫面"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割畫面期間:更換應用程式"</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>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"切換到下一個語言"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"切換到上一個語言"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"存取表情符號"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"存取語音輸入內容"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"應用程式"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"小幫手"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"瀏覽器 (預設為 Chrome)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Google 助理"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"瀏覽器"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"聯絡人"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"電子郵件 (預設為 Gmail)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"電子郵件"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"簡訊"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"音樂"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日曆"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 591a63e..42ddb35 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -640,10 +640,14 @@
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Inkinobho <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Ekhaya"</string>
     <string name="keyboard_key_back" msgid="4185420465469481999">"Emuva"</string>
-    <string name="keyboard_key_dpad_up" msgid="2164184320424941416">"Phezulu"</string>
-    <string name="keyboard_key_dpad_down" msgid="2110172278574325796">"Phansi"</string>
-    <string name="keyboard_key_dpad_left" msgid="8329738048908755640">"Kwesobunxele"</string>
-    <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"Kwesokudla"</string>
+    <!-- no translation found for keyboard_key_dpad_up (7199805608386368673) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (3354221123220737397) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (144176368026538621) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (8485763312139820037) -->
+    <skip />
     <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"Maphakathi"</string>
     <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
     <string name="keyboard_key_space" msgid="6980847564173394012">"Isikhala"</string>
@@ -671,7 +675,10 @@
     <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Izaziso"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Izinqamulelo Zekhibhodi"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Shintsha isakhiwo sekhibhodi"</string>
-    <string name="keyboard_shortcut_clear_text" msgid="4679927133259287577">"Sula umbhalo"</string>
+    <!-- no translation found for keyboard_shortcut_join (3578314570034512676) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_clear_text (6631051796030377857) -->
+    <skip />
     <string name="keyboard_shortcut_search_list_title" msgid="1156178106617830429">"Izinqamuleli"</string>
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Sesha izinqamuleli"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Azikho izinqamuleli ezitholakele"</string>
@@ -679,35 +686,45 @@
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Okokufaka"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Vula ama-app"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"I-app yamanje"</string>
-    <string name="group_system_access_notification_shade" msgid="7116898151485382275">"Finyelela umthunzi wesaziso"</string>
-    <string name="group_system_full_screenshot" msgid="7389040853798023211">"Thatha isithombe-skrini esigcwele"</string>
-    <string name="group_system_access_system_app_shortcuts" msgid="4421497579210445641">"Uhlu lokufinyelela lwezinqamuleli zesistimu / zama-app"</string>
-    <string name="group_system_go_back" msgid="8838454003680364227">"Emuva: buyela esimweni sangaphambilini (inkinobho yokubuyela emuva)"</string>
-    <string name="group_system_access_home_screen" msgid="1857344316928441909">"Finyelela isikrini sasekhaya"</string>
-    <string name="group_system_overview_open_apps" msgid="6897128761003265350">"Amazwibela ama-app avuliwe"</string>
-    <string name="group_system_cycle_forward" msgid="9202444850838205990">"Zungeza ama-app akamuva (phambili)"</string>
-    <string name="group_system_cycle_back" msgid="5163464503638229131">"Zungeza ama-app akamuva (emuva)"</string>
-    <string name="group_system_access_all_apps_search" msgid="488070738028991753">"Uhlu lokufinyelela lawo wonke ama-app nokusesha (isb, Sesha/Isiqalisa)"</string>
-    <string name="group_system_hide_reshow_taskbar" msgid="3809304065624351131">"Fihla futhi ubonise(kabusha) ibha yomsebenzi"</string>
-    <string name="group_system_access_system_settings" msgid="7961639365383008053">"Finyelela amasethingi esistimu"</string>
-    <string name="group_system_access_google_assistant" msgid="1186152943161483864">"Finyelela ku-Google Assistant"</string>
+    <!-- no translation found for keyboard_shortcut_a11y_show_search_results (2865241062981833705) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_system (7744143131119370483) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_input (4589316004510335529) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_open_apps (6175417687221004059) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_a11y_filter_current_app (7944592357493737911) -->
+    <skip />
+    <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Buka izaziso"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Thatha isithombe-skrini"</string>
+    <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Bonisa izinqamuleli"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Buyela emuva"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Iya kusikrini sasekhaya"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Buka ama-app akamuva"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Zungeza ubheke phambili ngama-app akamuva"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Zungeza ubuyele emuva ngama-app akamuva"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Vula uhlu lwama-app"</string>
+    <string name="group_system_hide_reshow_taskbar" msgid="6108733797075862081">"Bonisa i-taskbar"</string>
+    <string name="group_system_access_system_settings" msgid="8731721963449070017">"Vula amasethingi"</string>
+    <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Vula umsizi"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Khiya isikrini"</string>
-    <string name="group_system_quick_memo" msgid="2914234890158583919">"Donsela phezulu i-app yamanothi ukuze uthole imemo esheshayo"</string>
+    <string name="group_system_quick_memo" msgid="6257072703041301265">"Vula amanothi"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="1065232949510862593">"Ukwenza imisebenzi eminingi yesistimu"</string>
-    <string name="system_multitasking_rhs" msgid="6593269428880305699">"Faka Ukuhlukanisa isikrini nge-app yamanje kuya ku-RHS"</string>
-    <string name="system_multitasking_lhs" msgid="8839380725557952846">"Faka Ukuhlukanisa isikrini nge-app yamanje kuya ku-LHS"</string>
-    <string name="system_multitasking_full_screen" msgid="1962084334200006297">"Shintsha usuka Ekuhlukaniseni isikrini uye kusikrini esigcwele"</string>
-    <string name="system_multitasking_replace" msgid="844285282472557186">"Ngesikhathi sokuhlukaniswa kwesikrini: shintsha i-app ngenye"</string>
+    <string name="system_multitasking_rhs" msgid="2454557648974553729">"Faka ukuhlukanisa isikrini nge-app yamanje kuya ku-RHS"</string>
+    <string name="system_multitasking_lhs" msgid="3516599774920979402">"Faka ukuhlukanisa isikrini nge-app yamanje kuya ku-LHS"</string>
+    <string name="system_multitasking_full_screen" msgid="336048080383640562">"Shintsha usuka ekuhlukaniseni isikrini uye kusikrini esigcwele"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"Ngesikhathi sokuhlukaniswa kwesikrini: shintsha i-app ngenye"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Okokufaka"</string>
-    <string name="input_switch_input_language_next" msgid="3394291576873633793">"Shintsha ulimi lokokufaka (ulimi olulandelayo)"</string>
-    <string name="input_switch_input_language_previous" msgid="8823659252918609216">"Shintsha ulimi lokokufaka (ulimi lwangaphambilini)"</string>
+    <string name="input_switch_input_language_next" msgid="3782155659868227855">"Shintshela olimini olulandelayo"</string>
+    <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Shintshela olimini lwangaphambili"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Finyelela i-emoji"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Finyelela ukuthayipha ngezwi"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Izinhlelo zokusebenza"</string>
-    <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Siza"</string>
-    <string name="keyboard_shortcut_group_applications_browser" msgid="7328131901589876868">"Ibhrawuza (i-Chrome yokuzenzakalelayo)"</string>
+    <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Umsizi"</string>
+    <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Isiphequluli"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Oxhumana nabo"</string>
-    <string name="keyboard_shortcut_group_applications_email" msgid="7480359963463803511">"I-imeyili (i-Gmail yokuzenzakalelayo)"</string>
+    <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"I-imeyili"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"I-SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Umculo"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Ikhalenda"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index e124aa0..5f6a39a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -119,7 +119,7 @@
 
     <!-- Keyboard shortcuts colors -->
     <color name="ksh_application_group_color">#fff44336</color>
-    <color name="ksh_key_item_color">?androidprv:attr/materialColorOnSurfaceVariant</color>
+    <color name="ksh_key_item_color">@*android:color/system_on_surface_variant_light</color>
     <color name="ksh_key_item_background">?androidprv:attr/materialColorSurfaceContainerHighest</color>
 
     <color name="instant_apps_color">#ff4d5a64</color>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
index c9e57b4..b33f6fa 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
@@ -32,8 +32,7 @@
     override val isHomeActivity: Boolean?
         get() = _isHomeActivity
 
-    private var _isHomeActivity: Boolean? = null
-
+    @Volatile private var _isHomeActivity: Boolean? = null
 
     override fun init() {
         _isHomeActivity = activityManager.isOnHomeActivity()
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt
index 3b8d318..baa8889 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt
@@ -18,18 +18,19 @@
 import android.hardware.devicestate.DeviceStateManager
 import com.android.systemui.unfold.updates.FoldProvider
 import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
+import java.util.concurrent.ConcurrentHashMap
 import java.util.concurrent.Executor
 import javax.inject.Inject
 import javax.inject.Singleton
 
 @Singleton
-class DeviceStateManagerFoldProvider @Inject constructor(
-    private val deviceStateManager: DeviceStateManager,
-    private val context: Context
-) : FoldProvider {
+class DeviceStateManagerFoldProvider
+@Inject
+constructor(private val deviceStateManager: DeviceStateManager, private val context: Context) :
+    FoldProvider {
 
-    private val callbacks: MutableMap<FoldCallback,
-            DeviceStateManager.DeviceStateCallback> = hashMapOf()
+    private val callbacks =
+        ConcurrentHashMap<FoldCallback, DeviceStateManager.DeviceStateCallback>()
 
     override fun registerCallback(callback: FoldCallback, executor: Executor) {
         val listener = FoldStateListener(context, callback)
@@ -39,13 +40,9 @@
 
     override fun unregisterCallback(callback: FoldCallback) {
         val listener = callbacks.remove(callback)
-        listener?.let {
-            deviceStateManager.unregisterCallback(it)
-        }
+        listener?.let { deviceStateManager.unregisterCallback(it) }
     }
 
-    private inner class FoldStateListener(
-        context: Context,
-        listener: FoldCallback
-    ) : DeviceStateManager.FoldStateListener(context, { listener.onFoldUpdated(it) })
+    private inner class FoldStateListener(context: Context, listener: FoldCallback) :
+        DeviceStateManager.FoldStateListener(context, { listener.onFoldUpdated(it) })
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
index 7b67e3f..7af9917 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
@@ -15,24 +15,29 @@
 package com.android.systemui.unfold.system
 
 import android.os.Handler
+import android.os.HandlerThread
+import android.os.Looper
+import android.os.Process
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
-import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
+import com.android.systemui.unfold.dagger.UnfoldBg
 import com.android.systemui.unfold.dagger.UnfoldMain
+import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
 import com.android.systemui.unfold.updates.FoldProvider
 import com.android.systemui.unfold.util.CurrentActivityTypeProvider
 import dagger.Binds
 import dagger.Module
+import dagger.Provides
 import java.util.concurrent.Executor
+import javax.inject.Singleton
 
 /**
- * Dagger module with system-only dependencies for the unfold animation.
- * The code that is used to calculate unfold transition progress
- * depends on some hidden APIs that are not available in normal
- * apps. In order to re-use this code and use alternative implementations
- * of these classes in other apps and hidden APIs here.
+ * Dagger module with system-only dependencies for the unfold animation. The code that is used to
+ * calculate unfold transition progress depends on some hidden APIs that are not available in normal
+ * apps. In order to re-use this code and use alternative implementations of these classes in other
+ * apps and hidden APIs here.
  */
 @Module
 abstract class SystemUnfoldSharedModule {
@@ -61,4 +66,22 @@
     @Binds
     @UnfoldSingleThreadBg
     abstract fun backgroundExecutor(@UiBackground executor: Executor): Executor
+
+    companion object {
+        @Provides
+        @UnfoldBg
+        @Singleton
+        fun unfoldBgProgressHandler(@UnfoldBg looper: Looper): Handler {
+            return Handler(looper)
+        }
+
+        @Provides
+        @UnfoldBg
+        @Singleton
+        fun provideBgLooper(): Looper {
+            return HandlerThread("UnfoldBg", Process.THREAD_PRIORITY_FOREGROUND)
+                .apply { start() }
+                .looper
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
index b704f3c..1edb551 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
@@ -71,7 +71,7 @@
     private final DisplayTracker mDisplayTracker;
     private final AccessibilityLogger mA11yLogger;
 
-    private WindowMagnificationConnectionImpl mWindowMagnificationConnectionImpl;
+    private MagnificationConnectionImpl mMagnificationConnectionImpl;
     private SysUiState mSysUiState;
 
     @VisibleForTesting
@@ -220,7 +220,7 @@
     }
 
     @MainThread
-    void setScale(int displayId, float scale) {
+    void setScaleForWindowMagnification(int displayId, float scale) {
         final WindowMagnificationController windowMagnificationController =
                 mMagnificationControllerSupplier.get(displayId);
         if (windowMagnificationController != null) {
@@ -321,37 +321,37 @@
     final WindowMagnifierCallback mWindowMagnifierCallback = new WindowMagnifierCallback() {
         @Override
         public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) {
-            if (mWindowMagnificationConnectionImpl != null) {
-                mWindowMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame);
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame);
             }
         }
 
         @Override
         public void onSourceBoundsChanged(int displayId, Rect sourceBounds) {
-            if (mWindowMagnificationConnectionImpl != null) {
-                mWindowMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds);
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds);
             }
         }
 
         @Override
         public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) {
-            if (mWindowMagnificationConnectionImpl != null) {
-                mWindowMagnificationConnectionImpl.onPerformScaleAction(
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onPerformScaleAction(
                         displayId, scale, updatePersistence);
             }
         }
 
         @Override
         public void onAccessibilityActionPerformed(int displayId) {
-            if (mWindowMagnificationConnectionImpl != null) {
-                mWindowMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId);
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId);
             }
         }
 
         @Override
         public void onMove(int displayId) {
-            if (mWindowMagnificationConnectionImpl != null) {
-                mWindowMagnificationConnectionImpl.onMove(displayId);
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onMove(displayId);
             }
         }
 
@@ -394,8 +394,8 @@
                 @Override
                 public void onMagnifierScale(int displayId, float scale,
                         boolean updatePersistence) {
-                    if (mWindowMagnificationConnectionImpl != null) {
-                        mWindowMagnificationConnectionImpl.onPerformScaleAction(
+                    if (mMagnificationConnectionImpl != null) {
+                        mMagnificationConnectionImpl.onPerformScaleAction(
                                 displayId, scale, updatePersistence);
                     }
                     mA11yLogger.logThrottled(
@@ -454,8 +454,8 @@
             if (magnificationSettingsController != null) {
                 magnificationSettingsController.closeMagnificationSettings();
             }
-            if (mWindowMagnificationConnectionImpl != null) {
-                mWindowMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode);
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode);
             }
         }
     }
@@ -500,12 +500,12 @@
     }
 
     private void setWindowMagnificationConnection() {
-        if (mWindowMagnificationConnectionImpl == null) {
-            mWindowMagnificationConnectionImpl = new WindowMagnificationConnectionImpl(this,
+        if (mMagnificationConnectionImpl == null) {
+            mMagnificationConnectionImpl = new MagnificationConnectionImpl(this,
                     mHandler);
         }
         mAccessibilityManager.setWindowMagnificationConnection(
-                mWindowMagnificationConnectionImpl);
+                mMagnificationConnectionImpl);
     }
 
     private void clearWindowMagnificationConnection() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
rename to packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
index 5666851..5f0d496 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
@@ -32,7 +32,7 @@
  *
  * @see IWindowMagnificationConnection
  */
-class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.Stub {
+class MagnificationConnectionImpl extends IWindowMagnificationConnection.Stub {
 
     private static final String TAG = "WindowMagnificationConnectionImpl";
 
@@ -40,7 +40,7 @@
     private final Magnification mMagnification;
     private final Handler mHandler;
 
-    WindowMagnificationConnectionImpl(@NonNull Magnification magnification,
+    MagnificationConnectionImpl(@NonNull Magnification magnification,
             @Main Handler mainHandler) {
         mMagnification = magnification;
         mHandler = mainHandler;
@@ -57,8 +57,8 @@
     }
 
     @Override
-    public void setScale(int displayId, float scale) {
-        mHandler.post(() -> mMagnification.setScale(displayId, scale));
+    public void setScaleForWindowMagnification(int displayId, float scale) {
+        mHandler.post(() -> mMagnification.setScaleForWindowMagnification(displayId, scale));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 1ac4163..ab23564 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -30,6 +30,7 @@
 import android.graphics.PixelFormat;
 import android.hardware.biometrics.BiometricAuthenticator.Modality;
 import android.hardware.biometrics.BiometricConstants;
+import android.hardware.biometrics.BiometricManager.Authenticators;
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.face.FaceSensorPropertiesInternal;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -168,7 +169,7 @@
     // HAT received from LockSettingsService when credential is verified.
     @Nullable private byte[] mCredentialAttestation;
 
-    // TODO(b/287311775): remove when legacy prompt is replaced
+    // TODO(b/313469218): remove when legacy prompt is replaced
     @Deprecated
     static class Config {
         Context mContext;
@@ -220,6 +221,9 @@
             mHandler.postDelayed(() -> {
                 addCredentialView(false /* animatePanel */, true /* animateContents */);
             }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS);
+
+            // TODO(b/313469218): Remove Config
+            mConfig.mPromptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt
index 8d1d905..04c2351 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt
@@ -37,17 +37,25 @@
 
     @MainThread
     fun enable(onShadeInteraction: Runnable) {
-        if (shadeExpansionCollectorJob == null) {
-            shadeExpansionCollectorJob =
-                scope.launch {
-                    // wait for it to emit true once
-                    shadeInteractorLazy.get().isUserInteracting.first { it }
-                    onShadeInteraction.run()
-                }
-            shadeExpansionCollectorJob?.invokeOnCompletion { shadeExpansionCollectorJob = null }
-        } else {
+        if (shadeExpansionCollectorJob != null) {
             Log.e(TAG, "Already enabled")
+            return
         }
+        //TODO(b/313957306) delete this check
+        if (shadeInteractorLazy.get().isUserInteracting.value) {
+            // Workaround for b/311266890. This flow is in an error state that breaks this.
+            Log.e(TAG, "isUserInteracting already true, skipping enable")
+            return
+        }
+        shadeExpansionCollectorJob =
+            scope.launch {
+                Log.i(TAG, "Enable detector")
+                // wait for it to emit true once
+                shadeInteractorLazy.get().isUserInteracting.first { it }
+                Log.i(TAG, "Detector detected shade interaction")
+                onShadeInteraction.run()
+            }
+        shadeExpansionCollectorJob?.invokeOnCompletion { shadeExpansionCollectorJob = null }
     }
 
     @MainThread
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 72d14ba..bb6ef41 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -74,6 +74,8 @@
 import com.android.systemui.biometrics.udfps.SinglePointerTouchProcessor;
 import com.android.systemui.biometrics.udfps.TouchProcessor;
 import com.android.systemui.biometrics.udfps.TouchProcessorResult;
+import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel;
+import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.dagger.SysUISingleton;
@@ -102,6 +104,8 @@
 import com.android.systemui.util.concurrency.Execution;
 import com.android.systemui.util.time.SystemClock;
 
+import dagger.Lazy;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -164,6 +168,10 @@
     @NonNull private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
     @Nullable private final TouchProcessor mTouchProcessor;
     @NonNull private final SessionTracker mSessionTracker;
+    @NonNull private final Lazy<DeviceEntryUdfpsTouchOverlayViewModel>
+            mDeviceEntryUdfpsTouchOverlayViewModel;
+    @NonNull private final Lazy<DefaultUdfpsTouchOverlayViewModel>
+            mDefaultUdfpsTouchOverlayViewModel;
     @NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor;
     @NonNull private final InputManager mInputManager;
     @NonNull private final UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate;
@@ -284,7 +292,9 @@
                         mAlternateBouncerInteractor,
                         mUdfpsKeyguardAccessibilityDelegate,
                         mKeyguardTransitionInteractor,
-                        mSelectedUserInteractor
+                        mSelectedUserInteractor,
+                        mDeviceEntryUdfpsTouchOverlayViewModel,
+                        mDefaultUdfpsTouchOverlayViewModel
                     )));
         }
 
@@ -501,11 +511,13 @@
                     + mOverlay.getRequestId());
             return false;
         }
-        if ((mLockscreenShadeTransitionController.getQSDragProgress() != 0f
-                && !mAlternateBouncerInteractor.isVisibleState())
-                || mPrimaryBouncerInteractor.isInTransit()) {
-            Log.w(TAG, "ignoring touch due to qsDragProcess or primaryBouncerInteractor");
-            return false;
+        if (!DeviceEntryUdfpsRefactor.isEnabled()) {
+            if ((mLockscreenShadeTransitionController.getQSDragProgress() != 0f
+                    && !mAlternateBouncerInteractor.isVisibleState())
+                    || mPrimaryBouncerInteractor.isInTransit()) {
+                Log.w(TAG, "ignoring touch due to qsDragProcess or primaryBouncerInteractor");
+                return false;
+            }
         }
         if (event.getAction() == MotionEvent.ACTION_DOWN
                 || event.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
@@ -657,7 +669,9 @@
             @NonNull Provider<UdfpsKeyguardViewModels> udfpsKeyguardViewModelsProvider,
             @NonNull SelectedUserInteractor selectedUserInteractor,
             @NonNull FpsUnlockTracker fpsUnlockTracker,
-            @NonNull KeyguardTransitionInteractor keyguardTransitionInteractor) {
+            @NonNull KeyguardTransitionInteractor keyguardTransitionInteractor,
+            Lazy<DeviceEntryUdfpsTouchOverlayViewModel> deviceEntryUdfpsTouchOverlayViewModel,
+            Lazy<DefaultUdfpsTouchOverlayViewModel> defaultUdfpsTouchOverlayViewModel) {
         mContext = context;
         mExecution = execution;
         mVibrator = vibrator;
@@ -706,6 +720,8 @@
 
         mTouchProcessor = singlePointerTouchProcessor;
         mSessionTracker = sessionTracker;
+        mDeviceEntryUdfpsTouchOverlayViewModel = deviceEntryUdfpsTouchOverlayViewModel;
+        mDefaultUdfpsTouchOverlayViewModel = defaultUdfpsTouchOverlayViewModel;
 
         mDumpManager.registerDumpable(TAG, this);
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 2d54f7a..452cd6a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -46,7 +46,10 @@
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
+import com.android.systemui.biometrics.ui.binder.UdfpsTouchOverlayBinder
 import com.android.systemui.biometrics.ui.view.UdfpsTouchOverlay
+import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel
+import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
@@ -62,6 +65,7 @@
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import dagger.Lazy
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
 private const val TAG = "UdfpsControllerOverlay"
@@ -102,6 +106,8 @@
     private val udfpsKeyguardAccessibilityDelegate: UdfpsKeyguardAccessibilityDelegate,
     private val transitionInteractor: KeyguardTransitionInteractor,
     private val selectedUserInteractor: SelectedUserInteractor,
+    private val deviceEntryUdfpsTouchOverlayViewModel: Lazy<DeviceEntryUdfpsTouchOverlayViewModel>,
+    private val defaultUdfpsTouchOverlayViewModel: Lazy<DefaultUdfpsTouchOverlayViewModel>,
 ) {
     private var overlayViewLegacy: UdfpsView? = null
         private set
@@ -184,12 +190,19 @@
                             importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
                         }
                         windowManager.addView(this, coreLayoutParams.updateDimensions(null))
+                        when (requestReason) {
+                            REASON_AUTH_KEYGUARD ->
+                                UdfpsTouchOverlayBinder.bind(
+                                    view = this,
+                                    viewModel = deviceEntryUdfpsTouchOverlayViewModel.get(),
+                                )
+                            else ->
+                                UdfpsTouchOverlayBinder.bind(
+                                    view = this,
+                                    viewModel = defaultUdfpsTouchOverlayViewModel.get(),
+                                )
+                        }
                     }
-                    // TODO (b/305234447): Bind view model to UdfpsTouchOverlay here to control
-                    // the visibility (sometimes, even if UDFPS is running, the UDFPS UI can be
-                    // obscured and we don't want to accept touches. ie: for enrollment don't accept
-                    // touches when the shade is expanded and for keyguard: don't accept touches
-                    // depending on the keyguard & shade state
                 } else {
                     overlayViewLegacy = (inflater.inflate(
                             R.layout.udfps_view, null, false
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/UdfpsTouchOverlayBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/UdfpsTouchOverlayBinder.kt
new file mode 100644
index 0000000..bb6a68b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/UdfpsTouchOverlayBinder.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.binder
+
+import androidx.core.view.isInvisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.biometrics.ui.view.UdfpsTouchOverlay
+import com.android.systemui.biometrics.ui.viewmodel.UdfpsTouchOverlayViewModel
+import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
+import com.android.systemui.lifecycle.repeatWhenAttached
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
+
+@ExperimentalCoroutinesApi
+object UdfpsTouchOverlayBinder {
+
+    /**
+     * Updates visibility for the UdfpsTouchOverlay which controls whether the view will receive
+     * touches or not.
+     */
+    @JvmStatic
+    fun bind(
+        view: UdfpsTouchOverlay,
+        viewModel: UdfpsTouchOverlayViewModel,
+    ) {
+        if (DeviceEntryUdfpsRefactor.isUnexpectedlyInLegacyMode()) return
+        view.repeatWhenAttached {
+            repeatOnLifecycle(Lifecycle.State.CREATED) {
+                launch {
+                    viewModel.shouldHandleTouches.collect { shouldHandleTouches ->
+                        view.isInvisible = !shouldHandleTouches
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModel.kt
new file mode 100644
index 0000000..f8338ae
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModel.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.statusbar.phone.SystemUIDialogManager
+import com.android.systemui.statusbar.phone.hideAffordancesRequest
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+
+/**
+ * Default view model for the UdfpsTouchOverlay.
+ *
+ * By default, don't handle touches if any of the following are true:
+ * - shade is fully or partially expanded
+ * - any SysUI dialogs are obscuring the display
+ */
+@ExperimentalCoroutinesApi
+class DefaultUdfpsTouchOverlayViewModel
+@Inject
+constructor(
+    shadeInteractor: ShadeInteractor,
+    systemUIDialogManager: SystemUIDialogManager,
+) : UdfpsTouchOverlayViewModel {
+    private val shadeExpandedOrExpanding: Flow<Boolean> = shadeInteractor.isAnyExpanded
+    override val shouldHandleTouches: Flow<Boolean> =
+        combine(
+            shadeExpandedOrExpanding,
+            systemUIDialogManager.hideAffordancesRequest,
+        ) { shadeExpandedOrExpanding, dialogRequestingHideAffordances ->
+            !shadeExpandedOrExpanding && !dialogRequestingHideAffordances
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModel.kt
new file mode 100644
index 0000000..c19ea19
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModel.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryIconViewModel
+import com.android.systemui.statusbar.phone.SystemUIDialogManager
+import com.android.systemui.statusbar.phone.hideAffordancesRequest
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+
+/**
+ * View model for the UdfpsTouchOverlay for when UDFPS is being requested for device entry. Handles
+ * touches as long as the device entry views are visible.
+ */
+@ExperimentalCoroutinesApi
+class DeviceEntryUdfpsTouchOverlayViewModel
+@Inject
+constructor(
+    deviceEntryIconViewModel: DeviceEntryIconViewModel,
+    systemUIDialogManager: SystemUIDialogManager,
+) : UdfpsTouchOverlayViewModel {
+    // TODO (b/305234447): AlternateBouncer showing overrides sysuiDialogHideAffordancesRequest
+    override val shouldHandleTouches: Flow<Boolean> =
+        combine(
+            deviceEntryIconViewModel.deviceEntryViewAlpha,
+            systemUIDialogManager.hideAffordancesRequest,
+        ) { deviceEntryViewAlpha, dialogRequestingHideAffordances ->
+            deviceEntryViewAlpha > ALLOW_TOUCH_ALPHA_THRESHOLD && !dialogRequestingHideAffordances
+        }
+
+    companion object {
+        // only allow touches if the view is still mostly visible
+        const val ALLOW_TOUCH_ALPHA_THRESHOLD = .9f
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
index 11a5d8b..3defec5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
@@ -485,8 +485,7 @@
     ): Int =
         if (isPendingConfirmation) {
             when (sensorType) {
-                FingerprintSensorType.POWER_BUTTON ->
-                    R.string.security_settings_sfps_enroll_find_sensor_message
+                FingerprintSensorType.POWER_BUTTON -> -1
                 else -> R.string.fingerprint_dialog_authenticated_confirmation
             }
         } else if (isAuthenticating || isAuthenticated) {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/UdfpsTouchOverlayViewModel.kt
similarity index 66%
copy from packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
copy to packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/UdfpsTouchOverlayViewModel.kt
index cc92f60..3943fc4 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/UdfpsTouchOverlayViewModel.kt
@@ -14,8 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.common
+package com.android.systemui.biometrics.ui.viewmodel
 
-enum class CredentialType {
-    UNKNOWN, PASSKEY, PASSWORD,
-}
\ No newline at end of file
+import kotlinx.coroutines.flow.Flow
+
+/** Models the UI state for the UdfpsTouchOverlay. */
+interface UdfpsTouchOverlayViewModel {
+    /** Whether the UDFPS touch overlay should allow touches to be handled. */
+    val shouldHandleTouches: Flow<Boolean>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
index a721100..84f7dd5 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
@@ -18,7 +18,6 @@
 
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
-import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -30,10 +29,9 @@
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.asStateFlow
 
 /** Encapsulates business logic for interacting with the lock-screen alternate bouncer. */
 @SysUISingleton
@@ -54,15 +52,19 @@
     private val alternateBouncerUiAvailableFromSource: HashSet<String> = HashSet()
     private val alternateBouncerSupported: StateFlow<Boolean> =
         if (DeviceEntryUdfpsRefactor.isEnabled) {
-            fingerprintPropertyRepository.sensorType
-                .map { sensorType ->
-                    sensorType.isUdfps() || sensorType == FingerprintSensorType.POWER_BUTTON
-                }
-                .stateIn(
-                    scope = scope,
-                    started = SharingStarted.Eagerly,
-                    initialValue = false,
-                )
+            // The device entry udfps refactor doesn't currently support the alternate bouncer.
+            // TODO: Re-enable when b/287599719 is ready.
+            MutableStateFlow(false).asStateFlow()
+            //            fingerprintPropertyRepository.sensorType
+            //                .map { sensorType ->
+            //                    sensorType.isUdfps() || sensorType ==
+            // FingerprintSensorType.POWER_BUTTON
+            //                }
+            //                .stateIn(
+            //                    scope = scope,
+            //                    started = SharingStarted.Eagerly,
+            //                    initialValue = false,
+            //                )
         } else {
             bouncerRepository.alternateBouncerUIAvailable
         }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index b598631..7c46339 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -105,9 +105,9 @@
     val isUserSwitcherVisible: Boolean
         get() = repository.isUserSwitcherVisible
 
-    private val _onImeHidden = MutableSharedFlow<Unit>()
-    /** Provide the onImeHidden events from the bouncer */
-    val onImeHidden: SharedFlow<Unit> = _onImeHidden
+    private val _onImeHiddenByUser = MutableSharedFlow<Unit>()
+    /** Emits a [Unit] each time the IME (keyboard) is hidden by the user. */
+    val onImeHiddenByUser: SharedFlow<Unit> = _onImeHiddenByUser
 
     init {
         if (flags.isEnabled()) {
@@ -230,9 +230,9 @@
         repository.setMessage(errorMessage(authenticationInteractor.getAuthenticationMethod()))
     }
 
-    /** Notifies the interactor that the input method editor has been hidden. */
-    suspend fun onImeHidden() {
-        _onImeHidden.emit(Unit)
+    /** Notifies that the input method editor (software keyboard) has been hidden by the user. */
+    suspend fun onImeHiddenByUser() {
+        _onImeHiddenByUser.emit(Unit)
     }
 
     private fun promptMessage(authMethod: AuthenticationMethodModel): String {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
index 8024874..e379dab 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
@@ -46,9 +46,6 @@
      */
     val animateFailure: StateFlow<Boolean> = _animateFailure.asStateFlow()
 
-    /** Whether the input method editor (for example, the software keyboard) is visible. */
-    private var isImeVisible: Boolean = false
-
     /** The authentication method that corresponds to this view model. */
     abstract val authenticationMethod: AuthenticationMethodModel
 
@@ -68,7 +65,7 @@
     /**
      * Notifies that the UI has been hidden from the user (after any transitions have completed).
      */
-    fun onHidden() {
+    open fun onHidden() {
         clearInput()
         interactor.resetMessage()
     }
@@ -79,18 +76,6 @@
     }
 
     /**
-     * Notifies that the input method editor (for example, the software keyboard) has been shown or
-     * hidden.
-     */
-    suspend fun onImeVisibilityChanged(isVisible: Boolean) {
-        if (isImeVisible && !isVisible) {
-            interactor.onImeHidden()
-        }
-
-        isImeVisible = isVisible
-    }
-
-    /**
      * Notifies that the failure animation has been shown. This should be called to consume a `true`
      * value in [animateFailure].
      */
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
index a15698e..45d18128 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
@@ -21,8 +21,11 @@
 import com.android.systemui.res.R
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.stateIn
 
 /** Holds UI state and handles user input for the password bouncer UI. */
 class PasswordBouncerViewModel(
@@ -45,6 +48,32 @@
 
     override val throttlingMessageId = R.string.kg_too_many_failed_password_attempts_dialog_message
 
+    /** Whether the input method editor (for example, the software keyboard) is visible. */
+    private var isImeVisible: Boolean = false
+
+    /** Whether the text field element currently has focus. */
+    private val isTextFieldFocused = MutableStateFlow(false)
+
+    /** Whether the UI should request focus on the text field element. */
+    val isTextFieldFocusRequested =
+        combine(
+                interactor.isThrottled,
+                isTextFieldFocused,
+            ) { isThrottled, hasFocus ->
+                !isThrottled && !hasFocus
+            }
+            .stateIn(
+                scope = viewModelScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = !interactor.isThrottled.value && !isTextFieldFocused.value,
+            )
+
+    override fun onHidden() {
+        super.onHidden()
+        isImeVisible = false
+        isTextFieldFocused.value = false
+    }
+
     override fun clearInput() {
         _password.value = ""
     }
@@ -72,4 +101,21 @@
             tryAuthenticate()
         }
     }
+
+    /**
+     * Notifies that the input method editor (for example, the software keyboard) has been shown or
+     * hidden.
+     */
+    suspend fun onImeVisibilityChanged(isVisible: Boolean) {
+        if (isImeVisible && !isVisible && !interactor.isThrottled.value) {
+            interactor.onImeHiddenByUser()
+        }
+
+        isImeVisible = isVisible
+    }
+
+    /** Notifies that the password text field has gained or lost focus. */
+    fun onTextFieldFocusChanged(isFocused: Boolean) {
+        isTextFieldFocused.value = isFocused
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index 12df96e..5b1082a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -380,7 +380,7 @@
 
     static void logDebug(String msg) {
         if (DEBUG) {
-            logDebug(msg);
+            Log.d(TAG, msg);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index d9e0629..e7b8773 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -19,6 +19,7 @@
 import com.android.systemui.BootCompleteCacheImpl;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.Dependency;
+import com.android.systemui.Flags;
 import com.android.systemui.InitController;
 import com.android.systemui.SystemUIAppComponentFactoryBase;
 import com.android.systemui.dagger.qualifiers.PerUser;
@@ -35,6 +36,7 @@
 import com.android.systemui.unfold.FoldStateLoggingProvider;
 import com.android.systemui.unfold.SysUIUnfoldComponent;
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
+import com.android.systemui.unfold.dagger.UnfoldBg;
 import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.bubbles.Bubbles;
@@ -144,7 +146,15 @@
         getConnectingDisplayViewModel().init();
         getFoldStateLoggingProvider().ifPresent(FoldStateLoggingProvider::init);
         getFoldStateLogger().ifPresent(FoldStateLogger::init);
-        getUnfoldTransitionProgressProvider()
+
+        Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider;
+
+        if (Flags.unfoldAnimationBackgroundProgress()) {
+            unfoldTransitionProgressProvider = getBgUnfoldTransitionProgressProvider();
+        } else {
+            unfoldTransitionProgressProvider = getUnfoldTransitionProgressProvider();
+        }
+        unfoldTransitionProgressProvider
                 .ifPresent(
                         (progressProvider) ->
                                 getUnfoldTransitionProgressForwarder()
@@ -170,7 +180,14 @@
     ContextComponentHelper getContextComponentHelper();
 
     /**
-     * Creates a UnfoldTransitionProgressProvider.
+     * Creates a UnfoldTransitionProgressProvider that calculates progress in the background.
+     */
+    @SysUISingleton
+    @UnfoldBg
+    Optional<UnfoldTransitionProgressProvider> getBgUnfoldTransitionProgressProvider();
+
+    /**
+     * Creates a UnfoldTransitionProgressProvider that calculates progress in the main thread.
      */
     @SysUISingleton
     Optional<UnfoldTransitionProgressProvider> getUnfoldTransitionProgressProvider();
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/DeviceEntryModule.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/DeviceEntryModule.kt
index c3aaef7..cd764c0 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/DeviceEntryModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/DeviceEntryModule.kt
@@ -2,7 +2,9 @@
 
 import com.android.systemui.deviceentry.data.repository.DeviceEntryHapticsRepositoryModule
 import com.android.systemui.deviceentry.data.repository.DeviceEntryRepositoryModule
+import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import dagger.Module
+import dagger.multibindings.Multibinds
 
 @Module(
     includes =
@@ -11,4 +13,9 @@
             DeviceEntryHapticsRepositoryModule::class,
         ],
 )
-object DeviceEntryModule
+abstract class DeviceEntryModule {
+    /**
+     * A set of DeviceEntryIconTransitions. Ensures that this can be injected even if it's empty.
+     */
+    @Multibinds abstract fun deviceEntryIconTransitionSet(): Set<DeviceEntryIconTransition>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index 715fb17..4cddb9c 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -103,8 +103,11 @@
                 initialValue = false,
             )
 
-    // Authenticated by a TrustAgent like trusted device, location, etc or by face auth.
-    private val passivelyAuthenticated =
+    /**
+     * Whether the user is currently authenticated by a TrustAgent like trusted device, location,
+     * etc., or by face auth.
+     */
+    private val isPassivelyAuthenticated =
         merge(
                 trustRepository.isCurrentUserTrusted,
                 deviceEntryFaceAuthRepository.isAuthenticated,
@@ -117,25 +120,31 @@
      * mechanism like face or trust manager. This returns `false` whenever the lockscreen has been
      * dismissed.
      *
+     * A value of `null` is meaningless and is used as placeholder while the actual value is still
+     * being loaded in the background.
+     *
      * Note: `true` doesn't mean the lockscreen is visible. It may be occluded or covered by other
      * UI.
      */
-    val canSwipeToEnter =
+    val canSwipeToEnter: StateFlow<Boolean?> =
         combine(
                 // This is true when the user has chosen to show the lockscreen but has not made it
                 // secure.
                 authenticationInteractor.authenticationMethod.map {
                     it == AuthenticationMethodModel.None && repository.isLockscreenEnabled()
                 },
-                passivelyAuthenticated,
+                isPassivelyAuthenticated,
                 isDeviceEntered
-            ) { isSwipeAuthMethod, passivelyAuthenticated, isDeviceEntered ->
-                (isSwipeAuthMethod || passivelyAuthenticated) && !isDeviceEntered
+            ) { isSwipeAuthMethod, isPassivelyAuthenticated, isDeviceEntered ->
+                (isSwipeAuthMethod || isPassivelyAuthenticated) && !isDeviceEntered
             }
             .stateIn(
                 scope = applicationScope,
                 started = SharingStarted.Eagerly,
-                initialValue = false,
+                // Starts as null to prevent downstream collectors from falsely assuming that the
+                // user can or cannot swipe to enter the device while the real value is being loaded
+                // from upstream data sources.
+                initialValue = null,
             )
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
index 26c5ea6..c93b8e1 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
@@ -29,7 +29,6 @@
 import com.android.app.tracing.traceSection
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.data.DisplayEvent
 import com.android.systemui.util.Compile
@@ -93,7 +92,7 @@
 constructor(
     private val displayManager: DisplayManager,
     @Background backgroundHandler: Handler,
-    @Application applicationScope: CoroutineScope,
+    @Background bgApplicationScope: CoroutineScope,
     @Background backgroundCoroutineDispatcher: CoroutineDispatcher
 ) : DisplayRepository {
     private val allDisplayEvents: Flow<DisplayEvent> =
@@ -141,8 +140,7 @@
     private val enabledDisplays =
         allDisplayEvents
             .map { getDisplays() }
-            .flowOn(backgroundCoroutineDispatcher)
-            .shareIn(applicationScope, started = SharingStarted.WhileSubscribed(), replay = 1)
+            .shareIn(bgApplicationScope, started = SharingStarted.WhileSubscribed(), replay = 1)
 
     override val displays: Flow<Set<Display>> = enabledDisplays
 
@@ -203,9 +201,8 @@
             }
             .distinctUntilChanged()
             .debugLog("connectedDisplayIds")
-            .flowOn(backgroundCoroutineDispatcher)
             .stateIn(
-                applicationScope,
+                bgApplicationScope,
                 started = SharingStarted.WhileSubscribed(),
                 // The initial value is set to empty, but connected displays are gathered as soon as
                 // the flow starts being collected. This is to ensure the call to get displays (an
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 2a0d6a8..ff65b31 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -240,11 +240,6 @@
     @JvmField
     val WALLPAPER_PICKER_PREVIEW_ANIMATION = releasedFlag("wallpaper_picker_preview_animation")
 
-    /** Flag to enable rest to unlock feature. */
-    // TODO(b/303672286): Tracking bug
-    @JvmField
-    val REST_TO_UNLOCK: UnreleasedFlag = unreleasedFlag("rest_to_unlock")
-
     /**
      * TODO(b/278086361): Tracking bug
      * Complete rewrite of the interactions between System UI and Window Manager involving keyguard
@@ -545,28 +540,12 @@
             unreleasedFlag("clipboard_shared_transitions", teamfood = true)
 
     /**
-     * Whether the scene container (Flexiglass) is enabled. Note that [SCENE_CONTAINER] should be
-     * checked and toggled together with [SCENE_CONTAINER_ENABLED] so that ProGuard can remove
-     * unused code from our APK at compile time.
+     * Whether the scene container (Flexiglass) is enabled. Note that SceneContainerFlags#isEnabled
+     * should be checked and toggled together with [SCENE_CONTAINER_ENABLED] so that ProGuard can
+     * remove unused code from our APK at compile time.
      */
     // TODO(b/283300105): Tracking Bug
     @JvmField val SCENE_CONTAINER_ENABLED = false
-    @Deprecated(
-        message = """
-            Do not use this flag directly. Please use
-            [com.android.systemui.scene.shared.flag.SceneContainerFlags#isEnabled].
-
-            (Not really deprecated but using this as a simple way to bring attention to the above).
-        """,
-        replaceWith = ReplaceWith(
-            "com.android.systemui.scene.shared.flag.SceneContainerFlags#isEnabled",
-        ),
-        level = DeprecationLevel.WARNING,
-    )
-    @JvmField val SCENE_CONTAINER = resourceBooleanFlag(
-        R.bool.config_sceneContainerFrameworkEnabled,
-        "scene_container",
-    )
 
     // 1900
     @JvmField val NOTE_TASKS = releasedFlag("keycode_flag")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java
index b870f58..4f5a6fe 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java
@@ -18,6 +18,10 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.app.tracing.TraceUtils;
+
+import kotlin.Unit;
+
 import java.util.ArrayList;
 import java.util.Objects;
 import java.util.function.BiConsumer;
@@ -28,7 +32,7 @@
  */
 public class Lifecycle<T> {
 
-    private ArrayList<T> mObservers = new ArrayList<>();
+    private final ArrayList<T> mObservers = new ArrayList<>();
 
     public void addObserver(@NonNull T observer) {
         mObservers.add(Objects.requireNonNull(observer));
@@ -40,7 +44,11 @@
 
     public void dispatch(Consumer<T> consumer) {
         for (int i = 0; i < mObservers.size(); i++) {
-            consumer.accept(mObservers.get(i));
+            final T observer = mObservers.get(i);
+            TraceUtils.trace(() -> "dispatch#" + consumer.toString(), () -> {
+                consumer.accept(observer);
+                return Unit.INSTANCE;
+            });
         }
     }
 
@@ -49,7 +57,11 @@
      */
     public <U> void dispatch(BiConsumer<T, U> biConsumer, U arg) {
         for (int i = 0; i < mObservers.size(); i++) {
-            biConsumer.accept(mObservers.get(i), arg);
+            final T observer = mObservers.get(i);
+            TraceUtils.trace(() -> "dispatch#" + biConsumer.toString(), () -> {
+                biConsumer.accept(observer, arg);
+                return Unit.INSTANCE;
+            });
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
index f9b89b1..7354cfc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
@@ -18,6 +18,7 @@
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
 import com.android.app.tracing.traceSection
+import java.util.concurrent.CopyOnWriteArrayList
 import javax.inject.Inject
 import javax.inject.Singleton
 
@@ -29,7 +30,7 @@
         screenLifecycle.addObserver(this)
     }
 
-    private val listeners: MutableList<ScreenListener> = mutableListOf()
+    private val listeners: MutableList<ScreenListener> = CopyOnWriteArrayList()
 
     override fun removeCallback(listener: ScreenListener) {
         listeners.remove(listener)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index 7337292..a988a5c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -32,13 +32,19 @@
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.wallet.controller.QuickAccessWalletController
 import com.android.systemui.wallet.util.getPaymentCards
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import javax.inject.Inject
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlinx.coroutines.withContext
 
 /** Quick access wallet quick affordance data source. */
 @SysUISingleton
@@ -46,6 +52,7 @@
 @Inject
 constructor(
     @Application private val context: Context,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
     private val walletController: QuickAccessWalletController,
     private val activityStarter: ActivityStarter,
 ) : KeyguardQuickAffordanceConfig {
@@ -56,6 +63,7 @@
 
     override val pickerIconResourceId = R.drawable.ic_wallet_lockscreen
 
+    @OptIn(ExperimentalCoroutinesApi::class)
     override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
         conflatedCallbackFlow {
             val callback =
@@ -63,11 +71,7 @@
                     override fun onWalletCardsRetrieved(response: GetWalletCardsResponse) {
                         val hasCards = getPaymentCards(response.walletCards)?.isNotEmpty() == true
                         trySendWithFailureLogging(
-                            state(
-                                isFeatureEnabled = isWalletAvailable(),
-                                hasCard = hasCards,
-                                tileIcon = walletController.walletClient.tileIcon,
-                            ),
+                            hasCards,
                             TAG,
                         )
                     }
@@ -75,7 +79,7 @@
                     override fun onWalletCardRetrievalError(error: GetWalletCardsError) {
                         Log.e(TAG, "Wallet card retrieval error, message: \"${error?.message}\"")
                         trySendWithFailureLogging(
-                            KeyguardQuickAffordanceConfig.LockScreenState.Hidden,
+                            null,
                             TAG,
                         )
                     }
@@ -86,8 +90,12 @@
                 QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE,
                 QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
             )
-            walletController.updateWalletPreference()
-            walletController.queryWalletCards(callback)
+
+            withContext(backgroundDispatcher) {
+                // Both must be called on background thread
+                walletController.updateWalletPreference()
+                walletController.queryWalletCards(callback)
+            }
 
             awaitClose {
                 walletController.unregisterWalletChangeObservers(
@@ -95,6 +103,19 @@
                     QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
                 )
             }
+        }.flatMapLatest { hasCards ->
+            // If hasCards is null, this indicates an error occurred upon card retrieval
+            val state =
+                if (hasCards == null) {
+                    KeyguardQuickAffordanceConfig.LockScreenState.Hidden
+                } else {
+                    state(
+                        isWalletAvailable(),
+                        hasCards,
+                        walletController.walletClient.tileIcon,
+                    )
+                }
+            flowOf(state)
         }
 
     override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
@@ -131,25 +152,33 @@
     }
 
     private suspend fun queryCards(): List<WalletCard> {
-        return suspendCancellableCoroutine { continuation ->
-            val callback =
-                object : QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
-                    override fun onWalletCardsRetrieved(response: GetWalletCardsResponse) {
-                        continuation.resumeWith(
-                            Result.success(getPaymentCards(response.walletCards) ?: emptyList())
-                        )
-                    }
+        return withContext(backgroundDispatcher) {
+            suspendCancellableCoroutine { continuation ->
+                val callback =
+                    object : QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
+                        override fun onWalletCardsRetrieved(response: GetWalletCardsResponse) {
+                            continuation.resumeWith(
+                                Result.success(getPaymentCards(response.walletCards))
+                            )
+                        }
 
-                    override fun onWalletCardRetrievalError(error: GetWalletCardsError) {
-                        continuation.resumeWith(Result.success(emptyList()))
+                        override fun onWalletCardRetrievalError(error: GetWalletCardsError) {
+                            continuation.resumeWith(Result.success(emptyList()))
+                        }
                     }
-                }
-            walletController.queryWalletCards(callback)
+                // Must be called on background thread
+                walletController.queryWalletCards(callback)
+            }
         }
     }
 
-    private fun isWalletAvailable() =
-        with(walletController.walletClient) { isWalletServiceAvailable && isWalletFeatureAvailable }
+    private suspend fun isWalletAvailable() =
+        withContext(backgroundDispatcher) {
+            with(walletController.walletClient) {
+                // Must be called on background thread
+                isWalletServiceAvailable && isWalletFeatureAvailable
+            }
+        }
 
     private fun state(
         isFeatureEnabled: Boolean,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index bd73d60..62a0b0e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -131,13 +131,16 @@
                 when (toState) {
                     KeyguardState.DREAMING -> TO_DREAMING_DURATION
                     KeyguardState.AOD -> TO_AOD_DURATION
+                    KeyguardState.LOCKSCREEN -> TO_LOCKSCREEN_DURATION
                     else -> DEFAULT_DURATION
                 }.inWholeMilliseconds
         }
     }
+
     companion object {
         private val DEFAULT_DURATION = 500.milliseconds
         val TO_DREAMING_DURATION = 933.milliseconds
         val TO_AOD_DURATION = 1300.milliseconds
+        val TO_LOCKSCREEN_DURATION = DEFAULT_DURATION
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 152d217..cbfd17ff 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -380,6 +380,8 @@
                     KeyguardState.DREAMING -> TO_DREAMING_DURATION
                     KeyguardState.OCCLUDED -> TO_OCCLUDED_DURATION
                     KeyguardState.AOD -> TO_AOD_DURATION
+                    KeyguardState.DOZING -> TO_DOZING_DURATION
+                    KeyguardState.DREAMING_LOCKSCREEN_HOSTED -> TO_DREAMING_HOSTED_DURATION
                     else -> DEFAULT_DURATION
                 }.inWholeMilliseconds
         }
@@ -388,7 +390,9 @@
     companion object {
         const val TAG = "FromLockscreenTransitionInteractor"
         private val DEFAULT_DURATION = 400.milliseconds
+        val TO_DOZING_DURATION = 500.milliseconds
         val TO_DREAMING_DURATION = 933.milliseconds
+        val TO_DREAMING_HOSTED_DURATION = 933.milliseconds
         val TO_OCCLUDED_DURATION = 450.milliseconds
         val TO_AOD_DURATION = 500.milliseconds
         val TO_PRIMARY_BOUNCER_DURATION = DEFAULT_DURATION
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 706aba3c..f7d1543 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -72,6 +72,10 @@
     val fromDreamingTransition: Flow<TransitionStep> =
         repository.transitions.filter { step -> step.from == DREAMING }
 
+    /** LOCKSCREEN->(any) transition information. */
+    val fromLockscreenTransition: Flow<TransitionStep> =
+        repository.transitions.filter { step -> step.from == LOCKSCREEN }
+
     /** (any)->Lockscreen transition information */
     val anyStateToLockscreenTransition: Flow<TransitionStep> =
         repository.transitions.filter { step -> step.to == LOCKSCREEN }
@@ -113,9 +117,16 @@
     val goneToDreamingLockscreenHostedTransition: Flow<TransitionStep> =
         repository.transition(GONE, DREAMING_LOCKSCREEN_HOSTED)
 
+    /** GONE->LOCKSCREEN transition information. */
+    val goneToLockscreenTransition: Flow<TransitionStep> = repository.transition(GONE, LOCKSCREEN)
+
     /** LOCKSCREEN->AOD transition information. */
     val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
 
+    /** LOCKSCREEN->DOZING transition information. */
+    val lockscreenToDozingTransition: Flow<TransitionStep> =
+        repository.transition(LOCKSCREEN, DOZING)
+
     /** LOCKSCREEN->DREAMING transition information. */
     val lockscreenToDreamingTransition: Flow<TransitionStep> =
         repository.transition(LOCKSCREEN, DREAMING)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
index 594865d3..d1d323f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
@@ -49,7 +49,7 @@
         swipeUpAnywhereGestureHandler: SwipeUpAnywhereGestureHandler,
         tapGestureDetector: TapGestureDetector,
     ) {
-        DeviceEntryUdfpsRefactor.isUnexpectedlyInLegacyMode()
+        if (DeviceEntryUdfpsRefactor.isUnexpectedlyInLegacyMode()) return
         scope.launch {
             // forcePluginOpen is necessary to show over occluded apps.
             // This cannot be tied to the view's lifecycle because setting this allows the view
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
index 99025ace..abd79ab 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
@@ -30,9 +30,7 @@
 import androidx.core.view.updateLayoutParams
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.app.animation.Interpolators
 import com.android.settingslib.Utils
-import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.animation.view.LaunchableImageView
 import com.android.systemui.common.shared.model.Icon
@@ -40,6 +38,7 @@
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.util.doOnEnd
 import kotlinx.coroutines.flow.Flow
@@ -48,9 +47,7 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
 
-/**
- * This is only for a SINGLE Quick affordance
- */
+/** This is only for a SINGLE Quick affordance */
 object KeyguardQuickAffordanceViewBinder {
 
     private const val EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS = 250L
@@ -135,28 +132,12 @@
         vibratorHelper: VibratorHelper?,
     ) {
         if (!viewModel.isVisible) {
-            view.alpha = 1f
-            view
-                    .animate()
-                    .alpha(0f)
-                    .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
-                    .setDuration(EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS)
-                    .withEndAction { view.isInvisible = true }
-                    .start()
+            view.isInvisible = true
             return
         }
 
         if (!view.isVisible) {
             view.isVisible = true
-            if (viewModel.animateReveal) {
-                view.alpha = 0f
-                view
-                    .animate()
-                    .alpha(1f)
-                    .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
-                    .setDuration(EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS)
-                    .start()
-            }
         }
 
         IconViewBinder.bind(viewModel.icon, view)
@@ -216,13 +197,14 @@
         view.isClickable = viewModel.isClickable
         if (viewModel.isClickable) {
             if (viewModel.useLongPress) {
-                val onTouchListener = KeyguardQuickAffordanceOnTouchListener(
-                    view,
-                    viewModel,
-                    messageDisplayer,
-                    vibratorHelper,
-                    falsingManager,
-                )
+                val onTouchListener =
+                    KeyguardQuickAffordanceOnTouchListener(
+                        view,
+                        viewModel,
+                        messageDisplayer,
+                        vibratorHelper,
+                        falsingManager,
+                    )
                 view.setOnTouchListener(onTouchListener)
                 view.setOnClickListener {
                     messageDisplayer.invoke(R.string.keyguard_affordance_press_too_short)
@@ -241,9 +223,7 @@
                         KeyguardBottomAreaVibrations.ShakeAnimationDuration.inWholeMilliseconds
                     shakeAnimator.interpolator =
                         CycleInterpolator(KeyguardBottomAreaVibrations.ShakeAnimationCycles)
-                    shakeAnimator.doOnEnd {
-                        view.translationX = 0f
-                    }
+                    shakeAnimator.doOnEnd { view.translationX = 0f }
                     shakeAnimator.start()
 
                     vibratorHelper?.vibrate(KeyguardBottomAreaVibrations.Shake)
@@ -268,18 +248,18 @@
         alphaFlow: Flow<Float>,
     ) {
         combine(viewModel.map { it.isDimmed }, alphaFlow) { isDimmed, alpha ->
-            if (isDimmed) DIM_ALPHA else alpha
-        }
+                if (isDimmed) DIM_ALPHA else alpha
+            }
             .collect { view.alpha = it }
     }
 
     private fun loadFromResources(view: View): ConfigurationBasedDimensions {
         return ConfigurationBasedDimensions(
             buttonSizePx =
-            Size(
-                view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width),
-                view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height),
-            ),
+                Size(
+                    view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width),
+                    view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height),
+                ),
         )
     }
 
@@ -337,11 +317,9 @@
         }
 
         override fun onLongClickUseDefaultHapticFeedback(view: View) = false
-
     }
 
     private data class ConfigurationBasedDimensions(
         val buttonSizePx: Size,
     )
-
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/SideFpsProgressBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/SideFpsProgressBarViewBinder.kt
index 0bee48a..560e4ad 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/SideFpsProgressBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/SideFpsProgressBarViewBinder.kt
@@ -19,11 +19,10 @@
 import android.animation.ValueAnimator
 import android.graphics.Point
 import com.android.systemui.CoreStartable
+import com.android.systemui.Flags
 import com.android.systemui.biometrics.SideFpsController
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.flags.FeatureFlagsClassic
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.ui.view.SideFpsProgressBar
 import com.android.systemui.keyguard.ui.viewmodel.SideFpsProgressBarViewModel
 import com.android.systemui.log.SideFpsLogger
@@ -50,11 +49,10 @@
     private val sfpsController: dagger.Lazy<SideFpsController>,
     private val logger: SideFpsLogger,
     private val commandRegistry: CommandRegistry,
-    private val featureFlagsClassic: FeatureFlagsClassic,
 ) : CoreStartable {
 
     override fun start() {
-        if (!featureFlagsClassic.isEnabled(Flags.REST_TO_UNLOCK)) {
+        if (!Flags.restToUnlock()) {
             return
         }
         // When the rest to unlock feature is disabled by the user, stop any coroutines that are
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 a2e930c..59c798b 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
@@ -84,6 +84,7 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.runBlocking
 
 /** Renders the preview of the lock screen. */
@@ -158,7 +159,6 @@
 
     init {
         if (keyguardBottomAreaRefactor()) {
-            keyguardRootViewModel.enablePreviewMode()
             quickAffordancesCombinedViewModel.enablePreviewMode(
                 initiallySelectedSlotId =
                     bundle.getString(
@@ -287,6 +287,10 @@
             return
         }
 
+        if (smartSpaceView != null) {
+            parentView.removeView(smartSpaceView)
+        }
+
         smartSpaceView = lockscreenSmartspaceController.buildAndConnectDateView(parentView)
 
         val topPadding: Int =
@@ -334,26 +338,27 @@
             ),
         )
     }
-
     @OptIn(ExperimentalCoroutinesApi::class)
     private fun setupKeyguardRootView(previewContext: Context, rootView: FrameLayout) {
         val keyguardRootView = KeyguardRootView(previewContext, null)
-        disposables.add(
-            KeyguardRootViewBinder.bind(
-                keyguardRootView,
-                keyguardRootViewModel,
-                configuration,
-                featureFlags,
-                occludingAppDeviceEntryMessageViewModel,
-                chipbarCoordinator,
-                screenOffAnimationController,
-                shadeInteractor,
-                null, // clock provider only needed for burn in
-                null, // jank monitor not required for preview mode
-                null, // device entry haptics not required for preview mode
-                null, // device entry haptics not required for preview mode
+        if (!keyguardBottomAreaRefactor()) {
+            disposables.add(
+                KeyguardRootViewBinder.bind(
+                    keyguardRootView,
+                    keyguardRootViewModel,
+                    configuration,
+                    featureFlags,
+                    occludingAppDeviceEntryMessageViewModel,
+                    chipbarCoordinator,
+                    screenOffAnimationController,
+                    shadeInteractor,
+                    null, // clock provider only needed for burn in
+                    null, // jank monitor not required for preview mode
+                    null, // device entry haptics not required preview mode
+                    null, // device entry haptics not required for preview mode
+                )
             )
-        )
+        }
         rootView.addView(
             keyguardRootView,
             FrameLayout.LayoutParams(
@@ -362,12 +367,13 @@
             ),
         )
 
+        setUpUdfps(previewContext, rootView)
+
         disposables.add(
             PreviewKeyguardBlueprintViewBinder.bind(keyguardRootView, keyguardBlueprintViewModel) {
                 if (keyguardBottomAreaRefactor()) {
                     setupShortcuts(keyguardRootView)
                 }
-                setUpUdfps(previewContext, rootView)
 
                 if (!shouldHideClock) {
                     setUpClock(previewContext, rootView)
@@ -387,30 +393,30 @@
     }
 
     private fun setupShortcuts(keyguardRootView: ConstraintLayout) {
-        keyguardRootView.findViewById<LaunchableImageView?>(R.id.start_button)?.let {
+        keyguardRootView.findViewById<LaunchableImageView?>(R.id.start_button)?.let { imageView ->
             shortcutsBindings.add(
                 KeyguardQuickAffordanceViewBinder.bind(
-                    it,
-                    quickAffordancesCombinedViewModel.startButton,
-                    keyguardRootViewModel.alpha,
-                    falsingManager,
-                    vibratorHelper,
-                ) {
-                    indicationController.showTransientIndication(it)
+                    view = imageView,
+                    viewModel = quickAffordancesCombinedViewModel.startButton,
+                    alpha = flowOf(1f),
+                    falsingManager = falsingManager,
+                    vibratorHelper = vibratorHelper,
+                ) { message ->
+                    indicationController.showTransientIndication(message)
                 }
             )
         }
 
-        keyguardRootView.findViewById<LaunchableImageView?>(R.id.end_button)?.let {
+        keyguardRootView.findViewById<LaunchableImageView?>(R.id.end_button)?.let { imageView ->
             shortcutsBindings.add(
                 KeyguardQuickAffordanceViewBinder.bind(
-                    it,
-                    quickAffordancesCombinedViewModel.endButton,
-                    keyguardRootViewModel.alpha,
-                    falsingManager,
-                    vibratorHelper,
-                ) {
-                    indicationController.showTransientIndication(it)
+                    view = imageView,
+                    viewModel = quickAffordancesCombinedViewModel.endButton,
+                    alpha = flowOf(1f),
+                    falsingManager = falsingManager,
+                    vibratorHelper = vibratorHelper,
+                ) { message ->
+                    indicationController.showTransientIndication(message)
                 }
             )
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
index 55df466..cd46d6c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
@@ -61,7 +61,7 @@
                 KeyguardQuickAffordanceViewBinder.bind(
                     constraintLayout.requireViewById(R.id.start_button),
                     keyguardQuickAffordancesCombinedViewModel.startButton,
-                    keyguardRootViewModel.alpha,
+                    keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
                     falsingManager,
                     vibratorHelper,
                 ) {
@@ -71,7 +71,7 @@
                 KeyguardQuickAffordanceViewBinder.bind(
                     constraintLayout.requireViewById(R.id.end_button),
                     keyguardQuickAffordancesCombinedViewModel.endButton,
-                    keyguardRootViewModel.alpha,
+                    keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
                     falsingManager,
                     vibratorHelper,
                 ) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
index 0f6a966..2a68f26 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
@@ -25,14 +25,12 @@
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.RIGHT
 import com.android.systemui.Flags.keyguardBottomAreaRefactor
-import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordancesCombinedViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.KeyguardIndicationController
 import com.android.systemui.statusbar.VibratorHelper
 import javax.inject.Inject
@@ -61,7 +59,7 @@
                 KeyguardQuickAffordanceViewBinder.bind(
                     constraintLayout.requireViewById(R.id.start_button),
                     keyguardQuickAffordancesCombinedViewModel.startButton,
-                    keyguardRootViewModel.alpha,
+                    keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
                     falsingManager,
                     vibratorHelper,
                 ) {
@@ -71,7 +69,7 @@
                 KeyguardQuickAffordanceViewBinder.bind(
                     constraintLayout.requireViewById(R.id.end_button),
                     keyguardQuickAffordancesCombinedViewModel.endButton,
-                    keyguardRootViewModel.alpha,
+                    keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
                     falsingManager,
                     vibratorHelper,
                 ) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
index 14de01b..1864437 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
@@ -55,6 +55,14 @@
             onStep = { 1f },
         )
 
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 167.milliseconds,
+            startTime = 67.milliseconds,
+            onStep = { it },
+            onCancel = { 0f },
+        )
+
     val deviceEntryBackgroundViewAlpha: Flow<Float> =
         deviceEntryUdfpsInteractor.isUdfpsSupported.flatMapLatest { isUdfps ->
             if (isUdfps) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
index 27fb8a3..a728a28 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 
@@ -41,6 +42,13 @@
             transitionFlow = interactor.dozingToLockscreenTransition,
         )
 
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 150.milliseconds,
+            onStep = { it },
+            onCancel = { 0f },
+        )
+
     override val deviceEntryParentViewAlpha: Flow<Float> =
         transitionAnimation.immediatelyTransitionTo(1f)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt
new file mode 100644
index 0000000..58235ae
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingHostedToLockscreenTransitionViewModel.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromDreamingLockscreenHostedTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class DreamingHostedToLockscreenTransitionViewModel
+@Inject
+constructor(
+    interactor: KeyguardTransitionInteractor,
+) {
+
+    private val transitionAnimation =
+        KeyguardTransitionAnimationFlow(
+            transitionDuration = TO_LOCKSCREEN_DURATION,
+            transitionFlow = interactor.dreamingLockscreenHostedToLockscreenTransition
+        )
+
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { it },
+            onCancel = { 0f },
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
index a3b8b85..f943bdf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt
@@ -96,6 +96,14 @@
             onStep = { it },
         )
 
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            startTime = 233.milliseconds,
+            duration = 250.milliseconds,
+            onStep = { it },
+            onCancel = { 0f },
+        )
+
     val deviceEntryBackgroundViewAlpha =
         deviceEntryUdfpsInteractor.isUdfpsSupported.flatMapLatest { isUdfps ->
             if (isUdfps) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt
new file mode 100644
index 0000000..5804a20
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToLockscreenTransitionViewModel.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromGoneTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class GoneToLockscreenTransitionViewModel
+@Inject
+constructor(
+    interactor: KeyguardTransitionInteractor,
+) {
+
+    private val transitionAnimation =
+        KeyguardTransitionAnimationFlow(
+            transitionDuration = TO_LOCKSCREEN_DURATION,
+            transitionFlow = interactor.goneToLockscreenTransition
+        )
+
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { it },
+            onCancel = { 0f },
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
index 02ea550..188be24 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -32,6 +33,7 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
 
 @OptIn(ExperimentalCoroutinesApi::class)
 class KeyguardQuickAffordancesCombinedViewModel
@@ -39,6 +41,22 @@
 constructor(
     private val quickAffordanceInteractor: KeyguardQuickAffordanceInteractor,
     private val keyguardInteractor: KeyguardInteractor,
+    shadeInteractor: ShadeInteractor,
+    aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
+    dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
+    dreamingHostedToLockscreenTransitionViewModel: DreamingHostedToLockscreenTransitionViewModel,
+    dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel,
+    goneToLockscreenTransitionViewModel: GoneToLockscreenTransitionViewModel,
+    occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
+    offToLockscreenTransitionViewModel: OffToLockscreenTransitionViewModel,
+    primaryBouncerToLockscreenTransitionViewModel: PrimaryBouncerToLockscreenTransitionViewModel,
+    lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel,
+    lockscreenToDozingTransitionViewModel: LockscreenToDozingTransitionViewModel,
+    lockscreenToDreamingHostedTransitionViewModel: LockscreenToDreamingHostedTransitionViewModel,
+    lockscreenToDreamingTransitionViewModel: LockscreenToDreamingTransitionViewModel,
+    lockscreenToGoneTransitionViewModel: LockscreenToGoneTransitionViewModel,
+    lockscreenToOccludedTransitionViewModel: LockscreenToOccludedTransitionViewModel,
+    lockscreenToPrimaryBouncerTransitionViewModel: LockscreenToPrimaryBouncerTransitionViewModel,
 ) {
 
     data class PreviewMode(
@@ -60,6 +78,39 @@
     private val selectedPreviewSlotId =
         MutableStateFlow(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
 
+    /** alpha while fading the quick affordances out */
+    private val fadeInAlpha: Flow<Float> =
+        merge(
+            aodToLockscreenTransitionViewModel.shortcutsAlpha,
+            dozingToLockscreenTransitionViewModel.shortcutsAlpha,
+            dreamingHostedToLockscreenTransitionViewModel.shortcutsAlpha,
+            dreamingToLockscreenTransitionViewModel.shortcutsAlpha,
+            goneToLockscreenTransitionViewModel.shortcutsAlpha,
+            occludedToLockscreenTransitionViewModel.shortcutsAlpha,
+            offToLockscreenTransitionViewModel.shortcutsAlpha,
+            primaryBouncerToLockscreenTransitionViewModel.shortcutsAlpha,
+        )
+
+    /** alpha while fading the quick affordances in */
+    private val fadeOutAlpha: Flow<Float> =
+        merge(
+            lockscreenToAodTransitionViewModel.shortcutsAlpha,
+            lockscreenToDozingTransitionViewModel.shortcutsAlpha,
+            lockscreenToDreamingHostedTransitionViewModel.shortcutsAlpha,
+            lockscreenToDreamingTransitionViewModel.shortcutsAlpha,
+            lockscreenToGoneTransitionViewModel.shortcutsAlpha,
+            lockscreenToOccludedTransitionViewModel.shortcutsAlpha,
+            lockscreenToPrimaryBouncerTransitionViewModel.shortcutsAlpha,
+            shadeInteractor.qsExpansion.map { 1 - it },
+        )
+
+    /** The source of truth of alpha for all of the quick affordances on lockscreen */
+    val transitionAlpha: Flow<Float> =
+        merge(
+            fadeInAlpha,
+            fadeOutAlpha,
+        )
+
     /**
      * Whether quick affordances are "opaque enough" to be considered visible to and interactive by
      * the user. If they are not interactive, user input should not be allowed on them.
@@ -73,7 +124,7 @@
      * interactive/clickable unless "fully opaque" to avoid issues like in b/241830987.
      */
     private val areQuickAffordancesFullyOpaque: Flow<Boolean> =
-        keyguardInteractor.keyguardAlpha
+        transitionAlpha
             .map { alpha -> alpha >= AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD }
             .distinctUntilChanged()
 
@@ -89,7 +140,7 @@
      * Notifies that a slot with the given ID has been selected in the preview experience that is
      * rendering in the wallpaper picker. This is ignored for the real lock screen experience.
      *
-     * @see [KeyguardRootViewModel.enablePreviewMode]
+     * @see [enablePreviewMode]
      */
     fun onPreviewSlotSelected(slotId: String) {
         selectedPreviewSlotId.value = slotId
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 524fa1e..f63afeb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -47,13 +47,11 @@
 import javax.inject.Provider
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.flow.onStart
@@ -74,16 +72,6 @@
     private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
     screenOffAnimationController: ScreenOffAnimationController,
 ) {
-
-    data class PreviewMode(val isInPreviewMode: Boolean = false)
-
-    /**
-     * Whether this view-model instance is powering the preview experience that renders exclusively
-     * in the wallpaper picker application. This should _always_ be `false` for the real lock screen
-     * experience.
-     */
-    private val previewMode = MutableStateFlow(PreviewMode())
-
     var clockControllerProvider: Provider<ClockController>? = null
 
     /** System insets that keyguard needs to stay out of */
@@ -103,14 +91,7 @@
         keyguardInteractor.notificationContainerBounds
 
     /** An observable for the alpha level for the entire keyguard root view. */
-    val alpha: Flow<Float> =
-        previewMode.flatMapLatest {
-            if (it.isInPreviewMode) {
-                flowOf(1f)
-            } else {
-                keyguardInteractor.keyguardAlpha.distinctUntilChanged()
-            }
-        }
+    val alpha: Flow<Float> = keyguardInteractor.keyguardAlpha.distinctUntilChanged()
 
     private fun burnIn(): Flow<BurnInModel> {
         val dozingAmount: Flow<Float> =
@@ -147,55 +128,29 @@
     val lockscreenStateAlpha: Flow<Float> = aodToLockscreenTransitionViewModel.lockscreenAlpha
 
     /** For elements that appear and move during the animation -> AOD */
-    val burnInLayerAlpha: Flow<Float> =
-        previewMode.flatMapLatest {
-            if (it.isInPreviewMode) {
-                flowOf(1f)
-            } else {
-                goneToAodTransitionViewModel.enterFromTopAnimationAlpha
-            }
-        }
+    val burnInLayerAlpha: Flow<Float> = goneToAodTransitionViewModel.enterFromTopAnimationAlpha
 
     val translationY: Flow<Float> =
-        previewMode.flatMapLatest {
-            if (it.isInPreviewMode) {
-                flowOf(0f)
-            } else {
-                keyguardInteractor.configurationChange.flatMapLatest { _ ->
-                    val enterFromTopAmount =
-                        context.resources.getDimensionPixelSize(
-                            R.dimen.keyguard_enter_from_top_translation_y
-                        )
-                    combine(
-                        keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
-                        burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) },
-                        goneToAodTransitionViewModel
-                            .enterFromTopTranslationY(enterFromTopAmount)
-                            .onStart { emit(0f) },
-                    ) { keyguardTransitionY, burnInTranslationY, goneToAodTransitionTranslationY ->
-                        // All 3 values need to be combined for a smooth translation
-                        keyguardTransitionY + burnInTranslationY + goneToAodTransitionTranslationY
-                    }
-                }
+        keyguardInteractor.configurationChange.flatMapLatest { _ ->
+            val enterFromTopAmount =
+                context.resources.getDimensionPixelSize(
+                    R.dimen.keyguard_enter_from_top_translation_y
+                )
+            combine(
+                keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
+                burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) },
+                goneToAodTransitionViewModel.enterFromTopTranslationY(enterFromTopAmount).onStart {
+                    emit(0f)
+                },
+            ) { keyguardTransitionY, burnInTranslationY, goneToAodTransitionTranslationY ->
+                // All 3 values need to be combined for a smooth translation
+                keyguardTransitionY + burnInTranslationY + goneToAodTransitionTranslationY
             }
         }
 
-    val translationX: Flow<Float> =
-        previewMode.flatMapLatest {
-            if (it.isInPreviewMode) {
-                flowOf(0f)
-            } else {
-                burnIn().map { it.translationX.toFloat() }
-            }
-        }
+    val translationX: Flow<Float> = burnIn().map { it.translationX.toFloat() }
 
-    val scale: Flow<Pair<Float, Boolean>> =
-        previewMode.flatMapLatest { previewMode ->
-            burnIn().map {
-                val scale = if (previewMode.isInPreviewMode) 1f else it.scale
-                Pair(scale, it.scaleClockOnly)
-            }
-        }
+    val scale: Flow<Pair<Float, Boolean>> = burnIn().map { Pair(it.scale, it.scaleClockOnly) }
 
     /** Is the notification icon container visible? */
     val isNotifIconContainerVisible: Flow<AnimatedValue<Boolean>> =
@@ -238,20 +193,7 @@
             }
             .distinctUntilChanged()
 
-    /**
-     * Puts this view-model in "preview mode", which means it's being used for UI that is rendering
-     * the lock screen preview in wallpaper picker / settings and not the real experience on the
-     * lock screen.
-     */
-    fun enablePreviewMode() {
-        previewMode.value = PreviewMode(true)
-    }
-
     fun onNotificationContainerBoundsChanged(top: Float, bottom: Float) {
-        // Notifications should not be visible in preview mode
-        if (previewMode.value.isInPreviewMode) {
-            return
-        }
 
         keyguardInteractor.setNotificationContainerBounds(NotificationContainerBounds(top, bottom))
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
index 2bf12e8..8e8fd75c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
@@ -57,6 +57,15 @@
                     onFinish = { 0f },
                 ),
         )
+
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { 1 - it },
+            onFinish = { 0f },
+            onCancel = { 1f },
+        )
+
     override val deviceEntryParentViewAlpha: Flow<Float> =
         deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest {
             isUdfpsEnrolledAndEnabled ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
new file mode 100644
index 0000000..263ed11
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.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.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DOZING_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class LockscreenToDozingTransitionViewModel
+@Inject
+constructor(
+    interactor: KeyguardTransitionInteractor,
+) {
+
+    private val transitionAnimation =
+        KeyguardTransitionAnimationFlow(
+            transitionDuration = TO_DOZING_DURATION,
+            transitionFlow = interactor.lockscreenToDozingTransition
+        )
+
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { 1 - it },
+            onFinish = { 0f },
+            onCancel = { 1f },
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.kt
new file mode 100644
index 0000000..1701505
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingHostedTransitionViewModel.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.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_HOSTED_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class LockscreenToDreamingHostedTransitionViewModel
+@Inject
+constructor(
+    interactor: KeyguardTransitionInteractor,
+) {
+
+    private val transitionAnimation =
+        KeyguardTransitionAnimationFlow(
+            transitionDuration = TO_DREAMING_HOSTED_DURATION,
+            transitionFlow = interactor.lockscreenToDreamingLockscreenHostedTransition
+        )
+
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { 1 - it },
+            onFinish = { 0f },
+            onCancel = { 1f },
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
index 5229613..401c0ff 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
@@ -62,6 +62,14 @@
             onStep = { 1f - it },
         )
 
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { 1 - it },
+            onFinish = { 0f },
+            onCancel = { 1f },
+        )
+
     override val deviceEntryParentViewAlpha: Flow<Float> =
         shadeDependentFlows.transitionFlow(
             flowWhenShadeIsNotExpanded = lockscreenAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
index 59e5aa8..cfb4bf5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 
@@ -43,6 +44,14 @@
             transitionFlow = interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.GONE),
         )
 
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { 1 - it },
+            onFinish = { 0f },
+            onCancel = { 1f },
+        )
+
     override val deviceEntryParentViewAlpha: Flow<Float> =
         transitionAnimation.immediatelyTransitionTo(0f)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
index d49bc49..a6136f9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
@@ -50,6 +50,14 @@
             onStep = { 1f - it },
         )
 
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { 1 - it },
+            onFinish = { 0f },
+            onCancel = { 1f },
+        )
+
     /** Lockscreen views y-translation */
     fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
         return transitionAnimation.createFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
index f04b67a..07dd4ef 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
@@ -26,6 +26,7 @@
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
 
 /**
  * Breaks down LOCKSCREEN->PRIMARY BOUNCER transition into discrete steps for corresponding views to
@@ -46,6 +47,11 @@
                 interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER),
         )
 
+    val shortcutsAlpha: Flow<Float> =
+        interactor.transition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER).map {
+            1 - it.value
+        }
+
     override val deviceEntryParentViewAlpha: Flow<Float> =
         shadeDependentFlows.transitionFlow(
             flowWhenShadeIsNotExpanded =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
index 0bdc85d..58be093 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
@@ -58,6 +58,13 @@
         )
     }
 
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { it },
+            onCancel = { 0f },
+        )
+
     /** Lockscreen views alpha */
     val lockscreenAlpha: Flow<Float> =
         transitionAnimation.createFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.kt
new file mode 100644
index 0000000..c3bc799
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModel.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.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class OffToLockscreenTransitionViewModel
+@Inject
+constructor(
+    interactor: KeyguardTransitionInteractor,
+) {
+
+    private val transitionAnimation =
+        KeyguardTransitionAnimationFlow(
+            transitionDuration = 250.milliseconds,
+            transitionFlow = interactor.offToLockscreenTransition
+        )
+
+    val shortcutsAlpha: Flow<Float> =
+        transitionAnimation.createFlow(
+            duration = 250.milliseconds,
+            onStep = { it },
+            onCancel = { 0f },
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
index 3cf793a..7ef8374 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
@@ -28,6 +28,7 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
 
 /**
  * Breaks down PRIMARY BOUNCER->LOCKSCREEN transition into discrete steps for corresponding views to
@@ -57,6 +58,11 @@
             }
         }
 
+    val shortcutsAlpha: Flow<Float> =
+        interactor.transition(KeyguardState.PRIMARY_BOUNCER, KeyguardState.LOCKSCREEN).map {
+            it.value
+        }
+
     override val deviceEntryParentViewAlpha: Flow<Float> =
         transitionAnimation.immediatelyTransitionTo(1f)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt
index a0f5baf..2d0712c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt
@@ -20,14 +20,13 @@
 import android.content.Context
 import android.graphics.Point
 import androidx.core.animation.doOnEnd
+import com.android.systemui.Flags
 import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
 import com.android.systemui.biometrics.domain.interactor.SideFpsSensorInteractor
 import com.android.systemui.biometrics.shared.model.DisplayRotation
 import com.android.systemui.biometrics.shared.model.isDefaultOrientation
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.flags.FeatureFlagsClassic
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
@@ -58,7 +57,6 @@
     private val sfpsSensorInteractor: SideFpsSensorInteractor,
     displayStateInteractor: DisplayStateInteractor,
     @Application private val applicationScope: CoroutineScope,
-    private val featureFlagsClassic: FeatureFlagsClassic,
 ) {
     private val _progress = MutableStateFlow(0.0f)
     private val _visible = MutableStateFlow(false)
@@ -155,7 +153,7 @@
         sfpsSensorInteractor.isProlongedTouchRequiredForAuthentication
 
     init {
-        if (featureFlagsClassic.isEnabled(Flags.REST_TO_UNLOCK)) {
+        if (Flags.restToUnlock()) {
             launchAnimator()
         }
     }
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 a252470..9cdf857 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
@@ -271,6 +271,10 @@
     private val isReorderingAllowed: Boolean
         get() = visualStabilityProvider.isReorderingAllowed
 
+    /** Size provided by the scene framework container */
+    private var widthInSceneContainerPx = 0
+    private var heightInSceneContainerPx = 0
+
     init {
         dumpManager.registerDumpable(TAG, this)
         mediaFrame = inflateMediaCarousel()
@@ -581,6 +585,15 @@
         }
     }
 
+    fun setSceneContainerSize(width: Int, height: Int) {
+        if (width == widthInSceneContainerPx && height == heightInSceneContainerPx) {
+            return
+        }
+        widthInSceneContainerPx = width
+        heightInSceneContainerPx = height
+        updatePlayers(recreateMedia = true)
+    }
+
     private fun reorderAllPlayers(
         previousVisiblePlayerKey: MediaPlayerData.MediaSortKey?,
         key: String? = null
@@ -638,6 +651,11 @@
                     .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
             if (existingPlayer == null) {
                 val newPlayer = mediaControlPanelFactory.get()
+                if (mediaFlags.isSceneContainerEnabled()) {
+                    newPlayer.mediaViewController.widthInSceneContainerPx = widthInSceneContainerPx
+                    newPlayer.mediaViewController.heightInSceneContainerPx =
+                        heightInSceneContainerPx
+                }
                 newPlayer.attachPlayer(
                     MediaViewHolder.create(LayoutInflater.from(context), mediaContent)
                 )
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index cce4cda..04883c3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -81,7 +81,6 @@
 import com.android.internal.widget.CachingIconView;
 import com.android.settingslib.widget.AdaptiveIcon;
 import com.android.systemui.ActivityIntentHelper;
-import com.android.systemui.res.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.GhostedViewLaunchAnimatorController;
 import com.android.systemui.bluetooth.BroadcastDialogController;
@@ -102,6 +101,7 @@
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData;
 import com.android.systemui.media.controls.pipeline.MediaDataManager;
 import com.android.systemui.media.controls.util.MediaDataUtils;
+import com.android.systemui.media.controls.util.MediaFlags;
 import com.android.systemui.media.controls.util.MediaUiEventLogger;
 import com.android.systemui.media.controls.util.SmallHash;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
@@ -109,6 +109,7 @@
 import com.android.systemui.monet.Style;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.res.R;
 import com.android.systemui.shared.system.SysUiStatsLog;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -190,6 +191,7 @@
     @VisibleForTesting static final long TURBULENCE_NOISE_PLAY_DURATION = 7500L;
 
     private final SeekBarViewModel mSeekBarViewModel;
+    private final MediaFlags mMediaFlags;
     private SeekBarObserver mSeekBarObserver;
     protected final Executor mBackgroundExecutor;
     private final DelayableExecutor mMainExecutor;
@@ -280,7 +282,8 @@
             NotificationLockscreenUserManager lockscreenUserManager,
             BroadcastDialogController broadcastDialogController,
             FeatureFlags featureFlags,
-            GlobalSettings globalSettings
+            GlobalSettings globalSettings,
+            MediaFlags mediaFlags
     ) {
         mContext = context;
         mBackgroundExecutor = backgroundExecutor;
@@ -299,6 +302,7 @@
         mActivityIntentHelper = activityIntentHelper;
         mLockscreenUserManager = lockscreenUserManager;
         mBroadcastDialogController = broadcastDialogController;
+        mMediaFlags = mediaFlags;
 
         mSeekBarViewModel.setLogSeek(() -> {
             if (mPackageName != null && mInstanceId != null) {
@@ -575,7 +579,10 @@
         // to something which might impact the measurement
         // State refresh interferes with the translation animation, only run it if it's not running.
         if (!mMetadataAnimationHandler.isRunning()) {
-            mMediaViewController.refreshState();
+            // Don't refresh in scene framework, because it will calculate with invalid layout sizes
+            if (!mMediaFlags.isSceneContainerEnabled()) {
+                mMediaViewController.refreshState();
+            }
         }
 
         // Turbulence noise
@@ -805,7 +812,14 @@
         // Capture width & height from views in foreground for artwork scaling in background
         int width = mMediaViewHolder.getAlbumView().getMeasuredWidth();
         int height = mMediaViewHolder.getAlbumView().getMeasuredHeight();
+        if (mMediaFlags.isSceneContainerEnabled() && (width <= 0 || height <= 0)) {
+            // TODO(b/312714128): ensure we have a valid size before setting background
+            width = mMediaViewController.getWidthInSceneContainerPx();
+            height = mMediaViewController.getHeightInSceneContainerPx();
+        }
 
+        final int finalWidth = width;
+        final int finalHeight = height;
         mBackgroundExecutor.execute(() -> {
             // Album art
             ColorScheme mutableColorScheme = null;
@@ -815,7 +829,8 @@
             WallpaperColors wallpaperColors = getWallpaperColor(artworkIcon);
             if (wallpaperColors != null) {
                 mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT);
-                artwork = addGradientToPlayerAlbum(artworkIcon, mutableColorScheme, width, height);
+                artwork = addGradientToPlayerAlbum(artworkIcon, mutableColorScheme, finalWidth,
+                        finalHeight);
                 isArtworkBound = true;
             } else {
                 // If there's no artwork, use colors from the app icon
@@ -857,8 +872,10 @@
                         TransitionDrawable transitionDrawable = new TransitionDrawable(
                                 new Drawable[]{mPrevArtwork, artwork});
 
-                        scaleTransitionDrawableLayer(transitionDrawable, 0, width, height);
-                        scaleTransitionDrawableLayer(transitionDrawable, 1, width, height);
+                        scaleTransitionDrawableLayer(transitionDrawable, 0, finalWidth,
+                                finalHeight);
+                        scaleTransitionDrawableLayer(transitionDrawable, 1, finalWidth,
+                                finalHeight);
                         transitionDrawable.setLayerGravity(0, Gravity.CENTER);
                         transitionDrawable.setLayerGravity(1, Gravity.CENTER);
                         transitionDrawable.setCrossFadeEnabled(true);
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 9d6e9b4..35456d5 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
@@ -43,6 +43,7 @@
 import com.android.systemui.dreams.DreamOverlayStateController
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.media.controls.pipeline.MediaDataManager
+import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.media.dream.MediaDreamComplication
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.res.R
@@ -108,6 +109,7 @@
     @Application private val coroutineScope: CoroutineScope,
     private val splitShadeStateController: SplitShadeStateController,
     private val logger: MediaViewLogger,
+    private val mediaFlags: MediaFlags,
 ) {
 
     /** Track the media player setting status on lock screen. */
@@ -215,6 +217,7 @@
     }
 
     private val mediaHosts = arrayOfNulls<MediaHost>(LOCATION_COMMUNAL_HUB + 1)
+
     /**
      * The last location where this view was at before going to the desired location. This is useful
      * for guided transitions.
@@ -1041,6 +1044,17 @@
 
     private fun updateHostAttachment() =
         traceSection("MediaHierarchyManager#updateHostAttachment") {
+            if (mediaFlags.isSceneContainerEnabled()) {
+                // No need to manage transition states - just update the desired location directly
+                logger.logMediaHostAttachment(desiredLocation)
+                mediaCarouselController.onDesiredLocationChanged(
+                    desiredLocation = desiredLocation,
+                    desiredHostState = getHost(desiredLocation),
+                    animate = false,
+                )
+                return
+            }
+
             var newLocation = resolveLocationForFading()
             // Don't use the overlay when fading or when we don't have active media
             var canUseOverlay = !isCurrentlyFading() && hasActiveMediaOrRecommendation
@@ -1124,6 +1138,7 @@
             (!bypassController.bypassEnabled && (statusbarState == StatusBarState.KEYGUARD))
         val location =
             when {
+                mediaFlags.isSceneContainerEnabled() -> desiredLocation
                 dreamOverlayActive && dreamMediaComplicationActive -> LOCATION_DREAM_OVERLAY
                 (qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS
                 qsExpansion > 0.4f && onLockscreen -> LOCATION_QS
@@ -1282,7 +1297,7 @@
             MediaHierarchyManager.LOCATION_QQS,
             MediaHierarchyManager.LOCATION_LOCKSCREEN,
             MediaHierarchyManager.LOCATION_DREAM_OVERLAY,
-            MediaHierarchyManager.LOCATION_COMMUNAL_HUB
+            MediaHierarchyManager.LOCATION_COMMUNAL_HUB,
         ]
 )
 @Retention(AnnotationRetention.SOURCE)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
index d277f32..a99c51c2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.animation.MeasurementInput
 import com.android.systemui.util.animation.MeasurementOutput
 import com.android.systemui.util.animation.TransitionLayout
 import com.android.systemui.util.animation.TransitionLayoutController
@@ -207,6 +208,10 @@
     var isGutsVisible = false
         private set
 
+    /** Size provided by the scene framework container */
+    var widthInSceneContainerPx = 0
+    var heightInSceneContainerPx = 0
+
     init {
         mediaHostStatesManager.addController(this)
         layoutController.sizeChangedListener = { width: Int, height: Int ->
@@ -420,6 +425,10 @@
         state: MediaHostState?,
         isGutsAnimation: Boolean = false
     ): TransitionViewState? {
+        if (mediaFlags.isSceneContainerEnabled()) {
+            return obtainSceneContainerViewState()
+        }
+
         if (state == null || state.measurementInput == null) {
             return null
         }
@@ -670,6 +679,24 @@
         refreshState()
     }
 
+    /** Get a view state based on the width and height set by the scene */
+    private fun obtainSceneContainerViewState(): TransitionViewState? {
+        logger.logMediaSize("scene container", widthInSceneContainerPx, heightInSceneContainerPx)
+
+        // Similar to obtainViewState: Let's create a new measurement
+        val result =
+            transitionLayout?.calculateViewState(
+                MeasurementInput(widthInSceneContainerPx, heightInSceneContainerPx),
+                expandedLayout,
+                TransitionViewState()
+            )
+        result?.let {
+            // And then ensure the guts visibility is set correctly
+            setGutsViewState(it)
+        }
+        return result
+    }
+
     /**
      * Retrieves the [TransitionViewState] and [MediaHostState] of a [@MediaLocation]. In the event
      * of [location] not being visible, [locationWhenHidden] will be used instead.
@@ -681,6 +708,10 @@
      */
     private fun obtainViewStateForLocation(@MediaLocation location: Int): TransitionViewState? {
         val mediaHostState = mediaHostStatesManager.mediaHostStates[location] ?: return null
+        if (mediaFlags.isSceneContainerEnabled()) {
+            return obtainSceneContainerViewState()
+        }
+
         val viewState = obtainViewState(mediaHostState)
         if (viewState != null) {
             // update the size of the viewstate for the location with the override
@@ -708,6 +739,21 @@
     /** Clear all existing measurements and refresh the state to match the view. */
     fun refreshState() =
         traceSection("MediaViewController#refreshState") {
+            if (mediaFlags.isSceneContainerEnabled()) {
+                // We don't need to recreate measurements for scene container, since it's a known
+                // size. Just get the view state and update the layout controller
+                obtainSceneContainerViewState()?.let {
+                    // Get scene container state, then setCurrentState
+                    layoutController.setState(
+                        state = it,
+                        applyImmediately = true,
+                        animate = false,
+                        isGuts = false,
+                    )
+                }
+                return
+            }
+
             // Let's clear all of our measurements and recreate them!
             viewStates.clear()
             if (firstRefresh) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
index 44232ff..15747b9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
@@ -55,7 +55,7 @@
     /** Check whether we allow remote media to generate resume controls */
     fun isRemoteResumeAllowed() = featureFlags.isEnabled(Flags.MEDIA_REMOTE_RESUME)
 
-    /** Check whether to use flexiglass layout */
-    fun isFlexiglassEnabled() =
+    /** Check whether to use scene framework */
+    fun isSceneContainerEnabled() =
         sceneContainerFlags.isEnabled() && MediaInSceneContainerFlag.isEnabled
 }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
index 5bfc7dc..039d0e0 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
@@ -105,8 +105,8 @@
         float height = mRadius * 2 + additionalHeight;
         float additionalWidth = mAdditionalWidthForAnimation * mPulseAnimationProgress;
         float width = getWidth() + additionalWidth;
-        float x = -(additionalWidth / 2);
-        float y = navHeight - mBottom - height - (additionalHeight / 2);
+        float x = -additionalWidth;
+        float y = navHeight - mBottom - height + (additionalHeight / 2);
         float adjustedRadius = height / 2;
         canvas.drawRoundRect(x, y, width, y + height, adjustedRadius, adjustedRadius, mPaint);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index eba1c25..3884184 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -36,11 +36,11 @@
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.qs.tileimpl.HeightOverrideable;
 import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.concurrency.DelayableExecutor;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
@@ -64,6 +64,7 @@
 
     private static final String TAG = "QSAnimator";
 
+    private static final int ANIMATORS_UPDATE_DELAY_MS = 100;
     private static final float EXPANDED_TILE_DELAY = .86f;
     //Non first page delays
     private static final float QS_TILE_LABEL_FADE_OUT_START = 0.15f;
@@ -133,7 +134,7 @@
     private int mLastQQSTileHeight;
     private float mLastPosition;
     private final QSHost mHost;
-    private final Executor mExecutor;
+    private final DelayableExecutor mExecutor;
     private boolean mShowCollapsedOnKeyguard;
     private int mQQSTop;
 
@@ -144,7 +145,7 @@
     public QSAnimator(@RootView View rootView, QuickQSPanel quickPanel,
             QSPanelController qsPanelController,
             QuickQSPanelController quickQSPanelController, QSHost qsTileHost,
-            @Main Executor executor, TunerService tunerService,
+            @Main DelayableExecutor executor, TunerService tunerService,
             QSExpansionPathInterpolator qsExpansionPathInterpolator) {
         mQsRootView = rootView;
         mQuickQsPanel = quickPanel;
@@ -753,7 +754,10 @@
     public void onTilesChanged() {
         // Give the QS panels a moment to generate their new tiles, then create all new animators
         // hooked up to the new views.
-        mExecutor.execute(mUpdateAnimators);
+        mExecutor.executeDelayed(mUpdateAnimators, ANIMATORS_UPDATE_DELAY_MS);
+
+        // Also requests a lazy animators update in case the animation starts before the executor.
+        requestAnimatorUpdate();
     }
 
     private final TouchAnimator.Listener mNonFirstPageListener =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 11db69b..6c930b1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -255,6 +255,10 @@
             for (QSTile tile : tiles) {
                 addTile(tile, collapsedView);
             }
+        } else {
+            for (QSPanelControllerBase.TileRecord record : mRecords) {
+                record.tile.addCallback(record.callback);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt
index a321eef..6f5dea3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt
@@ -18,17 +18,19 @@
 
 import android.content.ComponentName
 import android.content.Context
+import android.content.SharedPreferences
 import android.service.quicksettings.Tile
 import android.util.Log
 import com.android.internal.annotations.VisibleForTesting
+import javax.inject.Inject
 import org.json.JSONException
 import org.json.JSONObject
-import javax.inject.Inject
 
 data class TileServiceKey(val componentName: ComponentName, val user: Int) {
     private val string = "${componentName.flattenToString()}:$user"
     override fun toString() = string
 }
+
 private const val STATE = "state"
 private const val LABEL = "label"
 private const val SUBTITLE = "subtitle"
@@ -44,12 +46,7 @@
  * It persists the state from a [Tile] necessary to present the view in the same state when
  * retrieved, with the exception of the icon.
  */
-class CustomTileStatePersister @Inject constructor(context: Context) {
-    companion object {
-        private const val FILE_NAME = "custom_tiles_state"
-    }
-
-    private val sharedPreferences = context.getSharedPreferences(FILE_NAME, 0)
+interface CustomTileStatePersister {
 
     /**
      * Read the state from [SharedPreferences].
@@ -58,7 +55,31 @@
      *
      * Any fields that have not been saved will be set to `null`
      */
-    fun readState(key: TileServiceKey): Tile? {
+    fun readState(key: TileServiceKey): Tile?
+    /**
+     * Persists the state into [SharedPreferences].
+     *
+     * The implementation does not store fields that are `null` or icons.
+     */
+    fun persistState(key: TileServiceKey, tile: Tile)
+    /**
+     * Removes the state for a given tile, user pair.
+     *
+     * Used when the tile is removed by the user.
+     */
+    fun removeState(key: TileServiceKey)
+}
+
+// TODO(b/299909989) Merge this class into into CustomTileRepository
+class CustomTileStatePersisterImpl @Inject constructor(context: Context) :
+    CustomTileStatePersister {
+    companion object {
+        private const val FILE_NAME = "custom_tiles_state"
+    }
+
+    private val sharedPreferences: SharedPreferences = context.getSharedPreferences(FILE_NAME, 0)
+
+    override fun readState(key: TileServiceKey): Tile? {
         val state = sharedPreferences.getString(key.toString(), null) ?: return null
         return try {
             readTileFromString(state)
@@ -68,23 +89,13 @@
         }
     }
 
-    /**
-     * Persists the state into [SharedPreferences].
-     *
-     * The implementation does not store fields that are `null` or icons.
-     */
-    fun persistState(key: TileServiceKey, tile: Tile) {
+    override fun persistState(key: TileServiceKey, tile: Tile) {
         val state = writeToString(tile)
 
         sharedPreferences.edit().putString(key.toString(), state).apply()
     }
 
-    /**
-     * Removes the state for a given tile, user pair.
-     *
-     * Used when the tile is removed by the user.
-     */
-    fun removeState(key: TileServiceKey) {
+    override fun removeState(key: TileServiceKey) {
         sharedPreferences.edit().remove(key.toString()).apply()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 69fe46a..529d684 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -109,7 +109,7 @@
     // Only read and modified in main thread (where click events come through).
     private int mClickEventId = 0;
 
-    private final ArrayList<Callback> mCallbacks = new ArrayList<>();
+    private final ArraySet<Callback> mCallbacks = new ArraySet<>();
     private final Object mStaleListener = new Object();
     protected TState mState;
     private TState mTmpState;
@@ -444,9 +444,9 @@
     }
 
     private void handleStateChanged() {
-        if (mCallbacks.size() != 0) {
+        if (!mCallbacks.isEmpty()) {
             for (int i = 0; i < mCallbacks.size(); i++) {
-                mCallbacks.get(i).onStateChanged(mState);
+                mCallbacks.valueAt(i).onStateChanged(mState);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt
index 94137c8..4a34276 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.qs.tiles.di
 
+import com.android.systemui.qs.external.CustomTileStatePersister
+import com.android.systemui.qs.external.CustomTileStatePersisterImpl
 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerImpl
 import com.android.systemui.qs.tiles.impl.custom.di.CustomTileComponent
@@ -52,4 +54,7 @@
     fun bindQSTileIntentUserInputHandler(
         impl: QSTileIntentUserInputHandlerImpl
     ): QSTileIntentUserInputHandler
+
+    @Binds
+    fun bindCustomTileStatePersister(impl: CustomTileStatePersisterImpl): CustomTileStatePersister
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt
index 5bdb592..db3cf0f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt
@@ -81,10 +81,8 @@
     private lateinit var toggleView: Switch
     private lateinit var subtitleTextView: TextView
     private lateinit var doneButton: View
-    private lateinit var seeAllViewGroup: View
-    private lateinit var pairNewDeviceViewGroup: View
-    private lateinit var seeAllRow: View
-    private lateinit var pairNewDeviceRow: View
+    private lateinit var seeAllButton: View
+    private lateinit var pairNewDeviceButton: View
     private lateinit var deviceListView: RecyclerView
 
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -99,10 +97,8 @@
         toggleView = requireViewById(R.id.bluetooth_toggle)
         subtitleTextView = requireViewById(R.id.bluetooth_tile_dialog_subtitle) as TextView
         doneButton = requireViewById(R.id.done_button)
-        seeAllViewGroup = requireViewById(R.id.see_all_layout_group)
-        pairNewDeviceViewGroup = requireViewById(R.id.pair_new_device_layout_group)
-        seeAllRow = requireViewById(R.id.see_all_clickable_row)
-        pairNewDeviceRow = requireViewById(R.id.pair_new_device_clickable_row)
+        seeAllButton = requireViewById(R.id.see_all_button)
+        pairNewDeviceButton = requireViewById(R.id.pair_new_device_button)
         deviceListView = requireViewById<RecyclerView>(R.id.device_list)
 
         setupToggle()
@@ -110,8 +106,8 @@
 
         subtitleTextView.text = context.getString(subtitleResIdInitialValue)
         doneButton.setOnClickListener { dismiss() }
-        seeAllRow.setOnClickListener { bluetoothTileDialogCallback.onSeeAllClicked(it) }
-        pairNewDeviceRow.setOnClickListener {
+        seeAllButton.setOnClickListener { bluetoothTileDialogCallback.onSeeAllClicked(it) }
+        pairNewDeviceButton.setOnClickListener {
             bluetoothTileDialogCallback.onPairNewDeviceClicked(it)
         }
     }
@@ -134,8 +130,8 @@
             }
             if (isActive) {
                 deviceItemAdapter.refreshDeviceItemList(deviceItem) {
-                    seeAllViewGroup.visibility = if (showSeeAll) VISIBLE else GONE
-                    pairNewDeviceViewGroup.visibility = if (showPairNewDevice) VISIBLE else GONE
+                    seeAllButton.visibility = if (showSeeAll) VISIBLE else GONE
+                    pairNewDeviceButton.visibility = if (showPairNewDevice) VISIBLE else GONE
                     lastUiUpdateMs = systemClock.elapsedRealtime()
                     lastItemRow = itemRow
                     logger.logDeviceUiUpdate(lastUiUpdateMs - start)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt
index 34c2aba..5d5e747 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt
@@ -20,7 +20,6 @@
 import android.content.Intent
 import android.os.Bundle
 import android.view.View
-import androidx.annotation.VisibleForTesting
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.animation.DialogCuj
@@ -40,6 +39,8 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.channels.produce
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
@@ -63,26 +64,25 @@
 
     private var job: Job? = null
 
-    @VisibleForTesting internal var dialog: BluetoothTileDialog? = null
-
     /**
      * Shows the dialog.
      *
      * @param context The context in which the dialog is displayed.
      * @param view The view from which the dialog is shown.
      */
+    @kotlinx.coroutines.ExperimentalCoroutinesApi
     fun showDialog(context: Context, view: View?) {
-        dismissDialog()
-
-        var updateDeviceItemJob: Job? = null
-        var updateDialogUiJob: Job? = null
+        cancelJob()
 
         job =
             coroutineScope.launch(mainDispatcher) {
-                dialog = createBluetoothTileDialog(context)
+                var updateDeviceItemJob: Job?
+                var updateDialogUiJob: Job? = null
+                val dialog = createBluetoothTileDialog(context)
+
                 view?.let {
                     dialogLaunchAnimator.showFromView(
-                        dialog!!,
+                        dialog,
                         it,
                         animateBackgroundBoundsChange = true,
                         cuj =
@@ -92,9 +92,8 @@
                             )
                     )
                 }
-                    ?: dialog!!.show()
+                    ?: dialog.show()
 
-                updateDeviceItemJob?.cancel()
                 updateDeviceItemJob = launch {
                     deviceItemInteractor.updateDeviceItems(context, DeviceFetchTrigger.FIRST_LOAD)
                 }
@@ -102,7 +101,7 @@
                 bluetoothStateInteractor.bluetoothStateUpdate
                     .filterNotNull()
                     .onEach {
-                        dialog!!.onBluetoothStateUpdated(it, getSubtitleResId(it))
+                        dialog.onBluetoothStateUpdated(it, getSubtitleResId(it))
                         updateDeviceItemJob?.cancel()
                         updateDeviceItemJob = launch {
                             deviceItemInteractor.updateDeviceItems(
@@ -129,7 +128,7 @@
                     .onEach {
                         updateDialogUiJob?.cancel()
                         updateDialogUiJob = launch {
-                            dialog?.onDeviceItemUpdated(
+                            dialog.onDeviceItemUpdated(
                                 it.take(MAX_DEVICE_ITEM_ENTRY),
                                 showSeeAll = it.size > MAX_DEVICE_ITEM_ENTRY,
                                 showPairNewDevice = bluetoothStateInteractor.isBluetoothEnabled
@@ -138,15 +137,15 @@
                     }
                     .launchIn(this)
 
-                dialog!!
-                    .bluetoothStateToggle
+                dialog.bluetoothStateToggle
                     .onEach { bluetoothStateInteractor.isBluetoothEnabled = it }
                     .launchIn(this)
 
-                dialog!!
-                    .deviceItemClick
+                dialog.deviceItemClick
                     .onEach { deviceItemInteractor.updateDeviceItemOnClick(it) }
                     .launchIn(this)
+
+                produce<Unit> { awaitClose { dialog.cancel() } }
             }
     }
 
@@ -161,7 +160,7 @@
                 logger,
                 context
             )
-            .apply { SystemUIDialog.registerDismissListener(this) { dismissDialog() } }
+            .apply { SystemUIDialog.registerDismissListener(this) { cancelJob() } }
     }
 
     override fun onDeviceItemGearClicked(deviceItem: DeviceItem, view: View) {
@@ -188,15 +187,13 @@
         startSettingsActivity(Intent(ACTION_PAIR_NEW_DEVICE), view)
     }
 
-    private fun dismissDialog() {
+    private fun cancelJob() {
         job?.cancel()
         job = null
-        dialog?.dismiss()
-        dialog = null
     }
 
     private fun startSettingsActivity(intent: Intent, view: View) {
-        dialog?.run {
+        if (job?.isActive == true) {
             intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
             activityStarter.postStartActivityDismissingKeyguard(
                 intent,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt
index 76fbf8e..fcd45a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt
@@ -168,26 +168,30 @@
         )
     }
 
-    internal fun updateDeviceItemOnClick(deviceItem: DeviceItem) {
-        logger.logDeviceClick(deviceItem.cachedBluetoothDevice.address, deviceItem.type)
+    internal suspend fun updateDeviceItemOnClick(deviceItem: DeviceItem) {
+        withContext(backgroundDispatcher) {
+            logger.logDeviceClick(deviceItem.cachedBluetoothDevice.address, deviceItem.type)
 
-        deviceItem.cachedBluetoothDevice.apply {
-            when (deviceItem.type) {
-                DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE -> {
-                    disconnect()
-                    uiEventLogger.log(BluetoothTileDialogUiEvent.ACTIVE_DEVICE_DISCONNECT)
-                }
-                DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> {
-                    setActive()
-                    uiEventLogger.log(BluetoothTileDialogUiEvent.CONNECTED_DEVICE_SET_ACTIVE)
-                }
-                DeviceItemType.CONNECTED_BLUETOOTH_DEVICE -> {
-                    disconnect()
-                    uiEventLogger.log(BluetoothTileDialogUiEvent.CONNECTED_OTHER_DEVICE_DISCONNECT)
-                }
-                DeviceItemType.SAVED_BLUETOOTH_DEVICE -> {
-                    connect()
-                    uiEventLogger.log(BluetoothTileDialogUiEvent.SAVED_DEVICE_CONNECT)
+            deviceItem.cachedBluetoothDevice.apply {
+                when (deviceItem.type) {
+                    DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE -> {
+                        disconnect()
+                        uiEventLogger.log(BluetoothTileDialogUiEvent.ACTIVE_DEVICE_DISCONNECT)
+                    }
+                    DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> {
+                        setActive()
+                        uiEventLogger.log(BluetoothTileDialogUiEvent.CONNECTED_DEVICE_SET_ACTIVE)
+                    }
+                    DeviceItemType.CONNECTED_BLUETOOTH_DEVICE -> {
+                        disconnect()
+                        uiEventLogger.log(
+                            BluetoothTileDialogUiEvent.CONNECTED_OTHER_DEVICE_DISCONNECT
+                        )
+                    }
+                    DeviceItemType.SAVED_BLUETOOTH_DEVICE -> {
+                        connect()
+                        uiEventLogger.log(BluetoothTileDialogUiEvent.SAVED_DEVICE_CONNECT)
+                    }
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt
index c390695b..cfb5442 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt
@@ -16,8 +16,9 @@
 
 package com.android.systemui.qs.tiles.impl.airplane.domain
 
-import android.content.Context
+import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
 import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
@@ -26,29 +27,27 @@
 import javax.inject.Inject
 
 /** Maps [AirplaneModeTileModel] to [QSTileState]. */
-class AirplaneModeMapper @Inject constructor(private val context: Context) :
+class AirplaneModeMapper @Inject constructor(@Main private val resources: Resources) :
     QSTileDataToStateMapper<AirplaneModeTileModel> {
 
     override fun map(config: QSTileConfig, data: AirplaneModeTileModel): QSTileState =
-        QSTileState.build(context, config.uiConfig) {
+        QSTileState.build(resources, config.uiConfig) {
             val icon =
-                Icon.Loaded(
-                    context.getDrawable(
-                        if (data.isEnabled) {
-                            R.drawable.qs_airplane_icon_on
-                        } else {
-                            R.drawable.qs_airplane_icon_off
-                        }
-                    )!!,
+                Icon.Resource(
+                    if (data.isEnabled) {
+                        R.drawable.qs_airplane_icon_on
+                    } else {
+                        R.drawable.qs_airplane_icon_off
+                    },
                     contentDescription = null
                 )
             this.icon = { icon }
             if (data.isEnabled) {
                 activationState = QSTileState.ActivationState.ACTIVE
-                secondaryLabel = context.resources.getStringArray(R.array.tile_states_airplane)[2]
+                secondaryLabel = resources.getStringArray(R.array.tile_states_airplane)[2]
             } else {
                 activationState = QSTileState.ActivationState.INACTIVE
-                secondaryLabel = context.resources.getStringArray(R.array.tile_states_airplane)[1]
+                secondaryLabel = resources.getStringArray(R.array.tile_states_airplane)[1]
             }
             contentDescription = label
             supportedActions =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/commons/TileExt.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/commons/TileExt.kt
new file mode 100644
index 0000000..869f6f32
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/commons/TileExt.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.custom.commons
+
+import android.service.quicksettings.Tile
+
+fun Tile.copy(): Tile =
+    Tile().also {
+        it.icon = icon
+        it.label = label
+        it.subtitle = subtitle
+        it.contentDescription = contentDescription
+        it.stateDescription = stateDescription
+        it.activityLaunchForClick = activityLaunchForClick
+        it.state = state
+    }
+
+fun Tile.setFrom(otherTile: Tile) {
+    if (otherTile.icon != null) {
+        icon = otherTile.icon
+    }
+    if (otherTile.customLabel != null) {
+        label = otherTile.customLabel
+    }
+    if (otherTile.subtitle != null) {
+        subtitle = otherTile.subtitle
+    }
+    if (otherTile.contentDescription != null) {
+        contentDescription = otherTile.contentDescription
+    }
+    if (otherTile.stateDescription != null) {
+        stateDescription = otherTile.stateDescription
+    }
+    activityLaunchForClick = otherTile.activityLaunchForClick
+    state = otherTile.state
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt
new file mode 100644
index 0000000..ca5302e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.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.qs.tiles.impl.custom.data.repository
+
+import android.graphics.drawable.Icon
+import android.os.UserHandle
+import android.service.quicksettings.Tile
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.qs.external.CustomTileStatePersister
+import com.android.systemui.qs.external.TileServiceKey
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.tiles.impl.custom.commons.copy
+import com.android.systemui.qs.tiles.impl.custom.commons.setFrom
+import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
+import kotlinx.coroutines.withContext
+
+/**
+ * Repository store the [Tile] associated with the custom tile. It lives on [QSTileScope] which
+ * allows it to survive service rebinding. Given that, it provides the last received state when
+ * connected again.
+ */
+interface CustomTileRepository {
+
+    /**
+     * Restores the [Tile] if it's [isPersistable]. Restored [Tile] will be available via [getTile]
+     * (but there is no guarantee that restoration is synchronous) and emitted in [getTiles] for a
+     * corresponding [user].
+     */
+    suspend fun restoreForTheUserIfNeeded(user: UserHandle, isPersistable: Boolean)
+
+    /** Returns [Tile] updates for a [user]. */
+    fun getTiles(user: UserHandle): Flow<Tile>
+
+    /**
+     * Return current [Tile] for a [user] or null if the [user] doesn't match currently cached one.
+     * Suspending until [getTiles] returns something is a way to wait for this to become available.
+     *
+     * @throws IllegalStateException when there is no current tile.
+     */
+    fun getTile(user: UserHandle): Tile?
+
+    /**
+     * Updates tile with the non-null values from [newTile]. Overwrites the current cache when
+     * [user] differs from the cached one. [isPersistable] tile will be persisted to be possibly
+     * loaded when the [restoreForTheUserIfNeeded].
+     */
+    suspend fun updateWithTile(
+        user: UserHandle,
+        newTile: Tile,
+        isPersistable: Boolean,
+    )
+
+    /**
+     * Updates tile with the values from [defaults]. Overwrites the current cache when [user]
+     * differs from the cached one. [isPersistable] tile will be persisted to be possibly loaded
+     * when the [restoreForTheUserIfNeeded].
+     */
+    suspend fun updateWithDefaults(
+        user: UserHandle,
+        defaults: CustomTileDefaults,
+        isPersistable: Boolean,
+    )
+}
+
+@QSTileScope
+class CustomTileRepositoryImpl
+@Inject
+constructor(
+    private val tileSpec: TileSpec.CustomTileSpec,
+    private val customTileStatePersister: CustomTileStatePersister,
+    @Background private val backgroundContext: CoroutineContext,
+) : CustomTileRepository {
+
+    private val tileUpdateMutex = Mutex()
+    private val tileWithUserState =
+        MutableSharedFlow<TileWithUser>(onBufferOverflow = BufferOverflow.DROP_OLDEST, replay = 1)
+
+    override suspend fun restoreForTheUserIfNeeded(user: UserHandle, isPersistable: Boolean) {
+        if (isPersistable && getCurrentTileWithUser()?.user != user) {
+            withContext(backgroundContext) {
+                customTileStatePersister.readState(user.getKey())?.let {
+                    updateWithTile(
+                        user,
+                        it,
+                        true,
+                    )
+                }
+            }
+        }
+    }
+
+    override fun getTiles(user: UserHandle): Flow<Tile> =
+        tileWithUserState.filter { it.user == user }.map { it.tile }
+
+    override fun getTile(user: UserHandle): Tile? {
+        val tileWithUser =
+            getCurrentTileWithUser() ?: throw IllegalStateException("Tile is not set")
+        return if (tileWithUser.user == user) {
+            tileWithUser.tile
+        } else {
+            null
+        }
+    }
+
+    override suspend fun updateWithTile(
+        user: UserHandle,
+        newTile: Tile,
+        isPersistable: Boolean,
+    ) = updateTile(user, isPersistable) { setFrom(newTile) }
+
+    override suspend fun updateWithDefaults(
+        user: UserHandle,
+        defaults: CustomTileDefaults,
+        isPersistable: Boolean,
+    ) {
+        if (defaults is CustomTileDefaults.Result) {
+            updateTile(user, isPersistable) {
+                // Update the icon if it's not set or is the default icon.
+                val updateIcon = (icon == null || icon.isResourceEqual(defaults.icon))
+                if (updateIcon) {
+                    icon = defaults.icon
+                }
+                setDefaultLabel(defaults.label)
+            }
+        }
+    }
+
+    private suspend fun updateTile(
+        user: UserHandle,
+        isPersistable: Boolean,
+        update: Tile.() -> Unit
+    ): Unit =
+        tileUpdateMutex.withLock {
+            val currentTileWithUser = getCurrentTileWithUser()
+            val tileToUpdate =
+                if (currentTileWithUser?.user == user) {
+                    currentTileWithUser.tile.copy()
+                } else {
+                    Tile()
+                }
+            tileToUpdate.update()
+            if (isPersistable) {
+                withContext(backgroundContext) {
+                    customTileStatePersister.persistState(user.getKey(), tileToUpdate)
+                }
+            }
+            tileWithUserState.tryEmit(TileWithUser(user, tileToUpdate))
+        }
+
+    private fun getCurrentTileWithUser(): TileWithUser? = tileWithUserState.replayCache.lastOrNull()
+
+    /** Compare two icons, only works for resources. */
+    private fun Icon.isResourceEqual(icon2: Icon?): Boolean {
+        if (icon2 == null) {
+            return false
+        }
+        if (this === icon2) {
+            return true
+        }
+        if (type != Icon.TYPE_RESOURCE || icon2.type != Icon.TYPE_RESOURCE) {
+            return false
+        }
+        if (resId != icon2.resId) {
+            return false
+        }
+        return resPackage == icon2.resPackage
+    }
+
+    private fun UserHandle.getKey() = TileServiceKey(tileSpec.componentName, this.identifier)
+
+    private data class TileWithUser(val user: UserHandle, val tile: Tile)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileModule.kt
index 83767aa..d956fde 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileModule.kt
@@ -24,6 +24,8 @@
 import com.android.systemui.qs.tiles.impl.custom.CustomTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepositoryImpl
+import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileRepository
+import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileRepositoryImpl
 import com.android.systemui.qs.tiles.impl.custom.di.bound.CustomTileBoundComponent
 import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
 import dagger.Binds
@@ -50,4 +52,6 @@
     fun bindCustomTileDefaultsRepository(
         impl: CustomTileDefaultsRepositoryImpl
     ): CustomTileDefaultsRepository
+
+    @Binds fun bindCustomTileRepository(impl: CustomTileRepositoryImpl): CustomTileRepository
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt
new file mode 100644
index 0000000..351bba5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.custom.domain.interactor
+
+import android.os.UserHandle
+import android.service.quicksettings.Tile
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.qs.external.TileServiceManager
+import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository
+import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileRepository
+import com.android.systemui.qs.tiles.impl.custom.di.bound.CustomTileBoundScope
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.firstOrNull
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+
+/** Manages updates of the [Tile] assigned for the current custom tile. */
+@CustomTileBoundScope
+class CustomTileInteractor
+@Inject
+constructor(
+    private val user: UserHandle,
+    private val defaultsRepository: CustomTileDefaultsRepository,
+    private val customTileRepository: CustomTileRepository,
+    private val tileServiceManager: TileServiceManager,
+    @CustomTileBoundScope private val boundScope: CoroutineScope,
+    @Background private val backgroundContext: CoroutineContext,
+) {
+
+    private val tileUpdates =
+        MutableSharedFlow<Tile>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
+
+    /** [Tile] updates. [updateTile] to emit a new one. */
+    val tiles: Flow<Tile>
+        get() = customTileRepository.getTiles(user)
+
+    /**
+     * Current [Tile]
+     *
+     * @throws IllegalStateException when the repository stores a tile for another user. This means
+     *   the tile hasn't been updated for the current user. Can happen when this is accessed before
+     *   [init] returns.
+     */
+    val tile: Tile
+        get() =
+            customTileRepository.getTile(user)
+                ?: throw IllegalStateException("Attempt to get a tile for a wrong user")
+
+    /**
+     * Initializes the repository for the current user. Suspends until it's safe to call [tile]
+     * which needs at least one of the following:
+     * - defaults are loaded;
+     * - receive tile update in [updateTile];
+     * - restoration happened for a persisted tile.
+     */
+    suspend fun init() {
+        launchUpdates()
+        customTileRepository.restoreForTheUserIfNeeded(user, tileServiceManager.isActiveTile)
+        // Suspend to make sure it gets the tile from one of the sources: restoration, defaults, or
+        // tile update.
+        customTileRepository.getTiles(user).firstOrNull()
+    }
+
+    private fun launchUpdates() {
+        tileUpdates
+            .onEach {
+                customTileRepository.updateWithTile(
+                    user,
+                    it,
+                    tileServiceManager.isActiveTile,
+                )
+            }
+            .flowOn(backgroundContext)
+            .launchIn(boundScope)
+        defaultsRepository
+            .defaults(user)
+            .onEach {
+                customTileRepository.updateWithDefaults(
+                    user,
+                    it,
+                    tileServiceManager.isActiveTile,
+                )
+            }
+            .flowOn(backgroundContext)
+            .launchIn(boundScope)
+    }
+
+    /** Updates current [Tile]. Emits a new event in [tiles]. */
+    fun updateTile(newTile: Tile) {
+        tileUpdates.tryEmit(newTile)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
index b2b22646..881a6bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
@@ -16,8 +16,9 @@
 
 package com.android.systemui.qs.tiles.impl.flashlight.domain
 
-import android.content.Context
+import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
 import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
@@ -26,30 +27,28 @@
 import javax.inject.Inject
 
 /** Maps [FlashlightTileModel] to [QSTileState]. */
-class FlashlightMapper @Inject constructor(private val context: Context) :
+class FlashlightMapper @Inject constructor(@Main private val resources: Resources) :
     QSTileDataToStateMapper<FlashlightTileModel> {
 
     override fun map(config: QSTileConfig, data: FlashlightTileModel): QSTileState =
-        QSTileState.build(context, config.uiConfig) {
+        QSTileState.build(resources, config.uiConfig) {
             val icon =
-                Icon.Loaded(
-                    context.resources.getDrawable(
-                        if (data.isEnabled) {
-                            R.drawable.qs_flashlight_icon_on
-                        } else {
-                            R.drawable.qs_flashlight_icon_off
-                        }
-                    ),
+                Icon.Resource(
+                    if (data.isEnabled) {
+                        R.drawable.qs_flashlight_icon_on
+                    } else {
+                        R.drawable.qs_flashlight_icon_off
+                    },
                     contentDescription = null
                 )
             this.icon = { icon }
 
             if (data.isEnabled) {
                 activationState = QSTileState.ActivationState.ACTIVE
-                secondaryLabel = context.resources.getStringArray(R.array.tile_states_flashlight)[2]
+                secondaryLabel = resources.getStringArray(R.array.tile_states_flashlight)[2]
             } else {
                 activationState = QSTileState.ActivationState.INACTIVE
-                secondaryLabel = context.resources.getStringArray(R.array.tile_states_flashlight)[1]
+                secondaryLabel = resources.getStringArray(R.array.tile_states_flashlight)[1]
             }
             contentDescription = label
             supportedActions =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
index 8e53723..7e7034d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
@@ -16,8 +16,9 @@
 
 package com.android.systemui.qs.tiles.impl.location.domain
 
-import android.content.Context
+import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
 import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
@@ -26,32 +27,30 @@
 import javax.inject.Inject
 
 /** Maps [LocationTileModel] to [QSTileState]. */
-class LocationTileMapper @Inject constructor(private val context: Context) :
+class LocationTileMapper @Inject constructor(@Main private val resources: Resources) :
     QSTileDataToStateMapper<LocationTileModel> {
 
     override fun map(config: QSTileConfig, data: LocationTileModel): QSTileState =
-        QSTileState.build(context, config.uiConfig) {
+        QSTileState.build(resources, config.uiConfig) {
             val icon =
-                Icon.Loaded(
-                    context.resources.getDrawable(
-                        if (data.isEnabled) {
-                            R.drawable.qs_location_icon_on
-                        } else {
-                            R.drawable.qs_location_icon_off
-                        }
-                    ),
+                Icon.Resource(
+                    if (data.isEnabled) {
+                        R.drawable.qs_location_icon_on
+                    } else {
+                        R.drawable.qs_location_icon_off
+                    },
                     contentDescription = null
                 )
             this.icon = { icon }
 
-            this.label = context.resources.getString(R.string.quick_settings_location_label)
+            this.label = resources.getString(R.string.quick_settings_location_label)
 
             if (data.isEnabled) {
                 activationState = QSTileState.ActivationState.ACTIVE
-                secondaryLabel = context.resources.getStringArray(R.array.tile_states_location)[2]
+                secondaryLabel = resources.getStringArray(R.array.tile_states_location)[2]
             } else {
                 activationState = QSTileState.ActivationState.INACTIVE
-                secondaryLabel = context.resources.getStringArray(R.array.tile_states_location)[1]
+                secondaryLabel = resources.getStringArray(R.array.tile_states_location)[1]
             }
             contentDescription = label
             supportedActions =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
index f9e0b16..23e0cb6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.qs.tiles.viewmodel
 
-import android.content.Context
+import android.content.res.Resources
 import android.service.quicksettings.Tile
 import android.view.View
 import android.widget.Switch
@@ -46,13 +46,13 @@
     companion object {
 
         fun build(
-            context: Context,
+            resources: Resources,
             config: QSTileUIConfig,
             build: Builder.() -> Unit
         ): QSTileState =
             build(
                 { Icon.Resource(config.iconRes, null) },
-                context.getString(config.labelRes),
+                resources.getString(config.labelRes),
                 build,
             )
 
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index f3f9c91..d42fde6 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -128,7 +128,7 @@
     private fun automaticallySwitchScenes() {
         applicationScope.launch {
             // TODO (b/308001302): Move this to a bouncer specific interactor.
-            bouncerInteractor.onImeHidden.collectLatest {
+            bouncerInteractor.onImeHiddenByUser.collectLatest {
                 if (sceneInteractor.desiredScene.value.key == SceneKey.Bouncer) {
                     sceneInteractor.changeScene(
                         scene = SceneModel(SceneKey.Lockscreen),
@@ -146,19 +146,21 @@
                     isAnySimLocked -> {
                         switchToScene(
                             targetSceneKey = SceneKey.Bouncer,
-                            loggingReason = "Need to authenticate locked sim card."
+                            loggingReason = "Need to authenticate locked SIM card."
                         )
                     }
-                    isUnlocked && !canSwipeToEnter -> {
+                    isUnlocked && canSwipeToEnter == false -> {
                         switchToScene(
                             targetSceneKey = SceneKey.Gone,
-                            loggingReason = "Sim cards are unlocked."
+                            loggingReason = "All SIM cards unlocked and device already" +
+                                " unlocked and lockscreen doesn't require a swipe to dismiss."
                         )
                     }
                     else -> {
                         switchToScene(
                             targetSceneKey = SceneKey.Lockscreen,
-                            loggingReason = "Sim cards are unlocked."
+                            loggingReason = "All SIM cards unlocked and device still locked" +
+                                " or lockscreen still requires a swipe to dismiss."
                         )
                     }
                 }
@@ -205,11 +207,17 @@
                             //    when the user is passively authenticated, the false value here
                             //    when the unlock state changes indicates this is an active
                             //    authentication attempt.
-                            if (isBypassEnabled || !canSwipeToEnter)
-                                SceneKey.Gone to
-                                    "device has been unlocked on lockscreen with either " +
-                                        "bypass enabled or using an active authentication mechanism"
-                            else null
+                            when {
+                                isBypassEnabled ->
+                                    SceneKey.Gone to
+                                        "device has been unlocked on lockscreen with bypass" +
+                                            " enabled"
+                                canSwipeToEnter == false ->
+                                    SceneKey.Gone to
+                                        "device has been unlocked on lockscreen using an active" +
+                                            " authentication mechanism"
+                                else -> null
+                            }
                         // Not on lockscreen or bouncer, so remain in the current scene.
                         else -> null
                     }
@@ -232,7 +240,7 @@
                 } else {
                     val canSwipeToEnter = deviceEntryInteractor.canSwipeToEnter.value
                     val isUnlocked = deviceEntryInteractor.isUnlocked.value
-                    if (isUnlocked && !canSwipeToEnter) {
+                    if (isUnlocked && canSwipeToEnter == false) {
                         switchToScene(
                             targetSceneKey = SceneKey.Gone,
                             loggingReason =
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
index d14ef35..dbb58a3 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
@@ -16,12 +16,14 @@
 
 package com.android.systemui.scene.shared.flag
 
+import android.content.Context
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.Flags as AConfigFlags
 import com.android.systemui.Flags.keyguardBottomAreaRefactor
 import com.android.systemui.Flags.sceneContainer
 import com.android.systemui.compose.ComposeFacade
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.flags.Flag
 import com.android.systemui.flags.Flags
@@ -29,6 +31,7 @@
 import com.android.systemui.flags.ResourceBooleanFlag
 import com.android.systemui.flags.UnreleasedFlag
 import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl
+import com.android.systemui.res.R
 import dagger.Module
 import dagger.Provides
 import dagger.assisted.Assisted
@@ -51,6 +54,7 @@
 class SceneContainerFlagsImpl
 @AssistedInject
 constructor(
+    @Application private val context: Context,
     private val featureFlagsClassic: FeatureFlagsClassic,
     @Assisted private val isComposeAvailable: Boolean,
 ) : SceneContainerFlags {
@@ -80,7 +84,11 @@
             ),
         ) +
             classicFlagTokens.map { flagToken -> FlagMustBeEnabled(flagToken) } +
-            listOf(ComposeMustBeAvailable(), CompileTimeFlagMustBeEnabled())
+            listOf(
+                ComposeMustBeAvailable(),
+                CompileTimeFlagMustBeEnabled(),
+                ResourceConfigMustBeEnabled()
+            )
 
     override fun isEnabled(): Boolean {
         // SCENE_CONTAINER_ENABLED is an explicit static flag check that helps with downstream
@@ -146,6 +154,14 @@
         }
     }
 
+    private inner class ResourceConfigMustBeEnabled : Requirement {
+        override val name: String = "R.bool.config_sceneContainerFrameworkEnabled must be true"
+
+        override fun isMet(): Boolean {
+            return context.resources.getBoolean(R.bool.config_sceneContainerFrameworkEnabled)
+        }
+    }
+
     @AssistedFactory
     interface Factory {
         fun create(isComposeAvailable: Boolean): SceneContainerFlagsImpl
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
index e7481cc..b98093e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
@@ -32,13 +32,16 @@
 import android.os.Looper;
 import android.os.ResultReceiver;
 import android.view.Gravity;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ArrayAdapter;
 import android.widget.Spinner;
 import android.widget.Switch;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
@@ -115,6 +118,17 @@
         mOptions.setOnItemClickListenerInt((parent, view, position, id) -> {
             mAudioSwitch.setChecked(true);
         });
+
+        // disable redundant Touch & Hold accessibility action for Switch Access
+        mOptions.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+            @Override
+            public void onInitializeAccessibilityNodeInfo(@NonNull View host,
+                    @NonNull AccessibilityNodeInfo info) {
+                info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
+                super.onInitializeAccessibilityNodeInfo(host, info);
+            }
+        });
+        mOptions.setLongClickable(false);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
index 9f4ea27..d13edf0 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
@@ -39,6 +39,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.res.R;
+import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 
@@ -58,18 +59,21 @@
     private final DelayableExecutor mMainExecutor;
     private final AccessibilityManagerWrapper mAccessibilityMgr;
     private Runnable mCancelTimeoutRunnable;
+    private final ShadeInteractor mShadeInteractor;
 
     @Inject
     public BrightnessDialog(
             BrightnessSliderController.Factory brightnessSliderfactory,
             BrightnessController.Factory brightnessControllerFactory,
             @Main DelayableExecutor mainExecutor,
-            AccessibilityManagerWrapper accessibilityMgr
+            AccessibilityManagerWrapper accessibilityMgr,
+            ShadeInteractor shadeInteractor
     ) {
         mToggleSliderFactory = brightnessSliderfactory;
         mBrightnessControllerFactory = brightnessControllerFactory;
         mMainExecutor = mainExecutor;
         mAccessibilityMgr = accessibilityMgr;
+        mShadeInteractor = shadeInteractor;
     }
 
 
@@ -79,6 +83,10 @@
         setWindowAttributes();
         setContentView(R.layout.brightness_mirror_container);
         setBrightnessDialogViewAttributes();
+
+        if (mShadeInteractor.isQsExpanded().getValue()) {
+            finish();
+        }
     }
 
     private void setWindowAttributes() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
index 6a9757f..31a4de4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
@@ -39,7 +39,7 @@
      * input (i.e. dragging a pointer). This will be true even if the user's input gesture had ended
      * but a transition they initiated is still animating.
      */
-    val isUserInteracting: Flow<Boolean>
+    val isUserInteracting: StateFlow<Boolean>
 
     /** Are touches allowed on the notification panel? */
     val isShadeTouchable: Flow<Boolean>
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
index d41c5a6..6defbcf 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
@@ -39,7 +39,7 @@
     override val isAnyExpanded: StateFlow<Boolean> = inactiveFlowBoolean
     override val isUserInteractingWithShade: Flow<Boolean> = inactiveFlowBoolean
     override val isUserInteractingWithQs: Flow<Boolean> = inactiveFlowBoolean
-    override val isUserInteracting: Flow<Boolean> = inactiveFlowBoolean
+    override val isUserInteracting: StateFlow<Boolean> = inactiveFlowBoolean
     override val isShadeTouchable: Flow<Boolean> = inactiveFlowBoolean
     override val isExpandToQsEnabled: Flow<Boolean> = inactiveFlowBoolean
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt
index 68600e9..7a340d2 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt
@@ -65,9 +65,10 @@
     override val isShadeFullyExpanded: Flow<Boolean> =
         baseShadeInteractor.shadeExpansion.map { it >= 1f }.distinctUntilChanged()
 
-    override val isUserInteracting: Flow<Boolean> =
+    override val isUserInteracting: StateFlow<Boolean> =
         combine(isUserInteractingWithShade, isUserInteractingWithQs) { shade, qs -> shade || qs }
             .distinctUntilChanged()
+            .stateIn(scope, SharingStarted.Eagerly, false)
 
     override val isShadeTouchable: Flow<Boolean> =
         combine(
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index 2a071de..d0da945 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -19,10 +19,16 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.media.controls.pipeline.MediaDataManager
+import com.android.systemui.media.controls.ui.MediaHierarchyManager
+import com.android.systemui.media.controls.ui.MediaHost
+import com.android.systemui.media.controls.ui.MediaHostState
+import com.android.systemui.media.dagger.MediaModule
 import com.android.systemui.qs.ui.adapter.QSSceneAdapter
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
 import javax.inject.Inject
+import javax.inject.Named
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
@@ -39,6 +45,8 @@
     val qsSceneAdapter: QSSceneAdapter,
     val shadeHeaderViewModel: ShadeHeaderViewModel,
     val notifications: NotificationsPlaceholderViewModel,
+    val mediaDataManager: MediaDataManager,
+    @Named(MediaModule.QUICK_QS_PANEL) private val mediaHost: MediaHost,
 ) {
     /** The key of the scene we should switch to when swiping up. */
     val upDestinationSceneKey: StateFlow<SceneKey> =
@@ -66,12 +74,23 @@
 
     private fun upDestinationSceneKey(
         isUnlocked: Boolean,
-        canSwipeToDismiss: Boolean,
+        canSwipeToDismiss: Boolean?,
     ): SceneKey {
         return when {
-            canSwipeToDismiss -> SceneKey.Lockscreen
+            canSwipeToDismiss == true -> SceneKey.Lockscreen
             isUnlocked -> SceneKey.Gone
             else -> SceneKey.Lockscreen
         }
     }
+
+    init {
+        mediaHost.expansion = MediaHostState.EXPANDED
+        mediaHost.showsOnlyActiveMedia = true
+        mediaHost.init(MediaHierarchyManager.LOCATION_QQS)
+    }
+
+    fun isMediaVisible(): Boolean {
+        // TODO(b/296122467): handle updates to carousel visibility while scene is still visible
+        return mediaDataManager.hasActiveMediaOrRecommendation()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index 1b096b5..909cff37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -493,11 +493,11 @@
                         Arrays.asList(
                                 Pair.create(KeyEvent.KEYCODE_SLASH, KeyEvent.META_META_ON))),
                 /* Back: go back to previous state (back button) */
-                /* Meta + Grave, Meta + backspace, Meta + left arrow */
+                /* Meta + Escape, Meta + Grave, Meta + backspace, Meta + left arrow */
                 new ShortcutKeyGroupMultiMappingInfo(
                         context.getString(R.string.group_system_go_back),
                         Arrays.asList(
-                                Pair.create(KeyEvent.KEYCODE_GRAVE, KeyEvent.META_META_ON),
+                                Pair.create(KeyEvent.KEYCODE_ESCAPE, KeyEvent.META_META_ON),
                                 Pair.create(KeyEvent.KEYCODE_DEL, KeyEvent.META_META_ON),
                                 Pair.create(KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.META_META_ON))),
                 /* Access home screen: Meta + H, Meta + Enter */
@@ -612,7 +612,7 @@
     private static KeyboardShortcutMultiMappingGroup getMultiMappingInputShortcuts(
             Context context) {
         List<ShortcutMultiMappingInfo> shortcutMultiMappingInfoList = Arrays.asList(
-                /* Switch input language (next language): Ctrl + Space or Meta + Space */
+                /* Switch input language (next language): Ctrl + Space */
                 new ShortcutMultiMappingInfo(
                         context.getString(R.string.input_switch_input_language_next),
                         null,
@@ -621,14 +621,9 @@
                                         context.getString(
                                                 R.string.input_switch_input_language_next),
                                         KeyEvent.KEYCODE_SPACE, KeyEvent.META_CTRL_ON),
-                                        null),
-                                new ShortcutKeyGroup(new KeyboardShortcutInfo(
-                                        context.getString(
-                                                R.string.input_switch_input_language_next),
-                                        KeyEvent.KEYCODE_SPACE, KeyEvent.META_META_ON),
                                         null))),
                 /* Switch input language (previous language): */
-                /* Ctrl + Shift + Space or Meta + Shift + Space */
+                /* Ctrl + Shift + Space */
                 new ShortcutMultiMappingInfo(
                         context.getString(R.string.input_switch_input_language_previous),
                         null,
@@ -638,12 +633,6 @@
                                                 R.string.input_switch_input_language_previous),
                                         KeyEvent.KEYCODE_SPACE,
                                         KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON),
-                                        null),
-                                new ShortcutKeyGroup(new KeyboardShortcutInfo(
-                                        context.getString(
-                                                R.string.input_switch_input_language_previous),
-                                        KeyEvent.KEYCODE_SPACE,
-                                        KeyEvent.META_META_ON | KeyEvent.META_SHIFT_ON),
                                         null)))
         );
         return new KeyboardShortcutMultiMappingGroup(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 0e83c78..e486457 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -530,16 +530,12 @@
                 userHandle = mCurrentUserId;
             }
             if (mUsersUsersAllowingPrivateNotifications.indexOfKey(userHandle) < 0) {
-                // TODO(b/301955929): STOP_SHIP (stop flag flip): remove this read and use a safe
-                // default value before moving to 'released'
-                Log.wtf(TAG, "Asking for redact notifs setting too early", new Throwable());
-                updateUserShowPrivateSettings(userHandle);
+                Log.i(TAG, "Asking for redact notifs setting too early", new Throwable());
+                return false;
             }
             if (mUsersDpcAllowingPrivateNotifications.indexOfKey(userHandle) < 0) {
-                // TODO(b/301955929): STOP_SHIP (stop flag flip): remove this read and use a safe
-                // default value before moving to 'released'
-                Log.wtf(TAG, "Asking for redact notifs dpm override too early", new Throwable());
-                updateDpcSettings(userHandle);
+                Log.i(TAG, "Asking for redact notifs dpm override too early", new Throwable());
+                return false;
             }
             return mUsersUsersAllowingPrivateNotifications.get(userHandle)
                     && mUsersDpcAllowingPrivateNotifications.get(userHandle);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
index 3184d5e..3616fd6d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
@@ -18,6 +18,8 @@
 
 import static android.graphics.PorterDuff.Mode.SRC_ATOP;
 
+import static com.android.systemui.Flags.notificationBackgroundTintOptimization;
+
 import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
 import android.annotation.StringRes;
@@ -313,15 +315,16 @@
         Resources.Theme theme = mContext.getTheme();
         final @ColorInt int onSurface = Utils.getColorAttrDefaultColor(mContext,
                 com.android.internal.R.attr.materialColorOnSurface);
-        final @ColorInt int scHigh = Utils.getColorAttrDefaultColor(mContext,
-                com.android.internal.R.attr.materialColorSurfaceContainerHigh);
         final Drawable clearAllBg = theme.getDrawable(R.drawable.notif_footer_btn_background);
         final Drawable manageBg = theme.getDrawable(R.drawable.notif_footer_btn_background);
-        // TODO(b/282173943): Remove redundant tinting once Resources are thread-safe
-        final ColorFilter bgColorFilter = new PorterDuffColorFilter(scHigh, SRC_ATOP);
-        if (scHigh != 0) {
-            clearAllBg.setColorFilter(bgColorFilter);
-            manageBg.setColorFilter(bgColorFilter);
+        if (!notificationBackgroundTintOptimization()) {
+            final @ColorInt int scHigh = Utils.getColorAttrDefaultColor(mContext,
+                    com.android.internal.R.attr.materialColorSurfaceContainerHigh);
+            if (scHigh != 0) {
+                final ColorFilter bgColorFilter = new PorterDuffColorFilter(scHigh, SRC_ATOP);
+                clearAllBg.setColorFilter(bgColorFilter);
+                manageBg.setColorFilter(bgColorFilter);
+            }
         }
         mClearAllButton.setBackground(clearAllBg);
         mClearAllButton.setTextColor(onSurface);
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 7c8d762..4fe05ec 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
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static com.android.systemui.Flags.notificationBackgroundTintOptimization;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
@@ -309,8 +311,7 @@
     protected void setBackgroundTintColor(int color) {
         if (color != mCurrentBackgroundTint) {
             mCurrentBackgroundTint = color;
-            // TODO(282173943): re-enable this tinting optimization when Resources are thread-safe
-            if (false && color == mNormalColor) {
+            if (notificationBackgroundTintOptimization() && color == mNormalColor) {
                 // We don't need to tint a normal notification
                 color = 0;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 64f61d9..8eda96f 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
@@ -27,7 +27,6 @@
 import android.graphics.drawable.LayerDrawable;
 import android.graphics.drawable.RippleDrawable;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 
 import androidx.annotation.NonNull;
@@ -43,11 +42,9 @@
  * A view that can be used for both the dimmed and normal background of an notification.
  */
 public class NotificationBackgroundView extends View implements Dumpable {
-    private static final String TAG = "NotificationBackgroundView";
 
     private final boolean mDontModifyCorners;
     private Drawable mBackground;
-    private Drawable mBackgroundDrawableToTint;
     private int mClipTopAmount;
     private int mClipBottomAmount;
     private int mTintColor;
@@ -134,7 +131,6 @@
             unscheduleDrawable(mBackground);
         }
         mBackground = background;
-        mBackgroundDrawableToTint = findBackgroundDrawableToTint(mBackground);
         mRippleColor = null;
         mBackground.mutate();
         if (mBackground != null) {
@@ -148,46 +144,25 @@
         invalidate();
     }
 
-    // setCustomBackground should be called from ActivatableNotificationView.initBackground
-    // with R.drawable.notification_material_bg, which is a layer-list with a lower layer
-    // for the background color (annotated with an ID so we can find it) and an upper layer
-    // to blend in the stateful @color/notification_overlay_color.
-    //
-    // If the notification is tinted, we want to set a tint list on *just that lower layer* that
-    // will replace the default materialColorSurfaceContainerHigh *without* wiping out the stateful
-    // tints in the upper layer that make the hovered and pressed states visible.
-    //
-    // This function fishes that lower layer out, or makes a fuss in logcat if it can't find it.
-    private @Nullable Drawable findBackgroundDrawableToTint(@Nullable Drawable background) {
-        if (background == null) {
-            return null;
-        }
-
-        if (!(background instanceof LayerDrawable)) {
-            Log.wtf(TAG, "background is not a LayerDrawable: " + background);
-            return background;
-        }
-
-        final Drawable backgroundColorLayer = ((LayerDrawable) background).findDrawableByLayerId(
-                R.id.notification_background_color_layer);
-
-        if (backgroundColorLayer == null) {
-            Log.wtf(TAG, "background is missing background color layer: " + background);
-            return background;
-        }
-
-        return backgroundColorLayer;
-    }
-
     public void setCustomBackground(int drawableResId) {
         final Drawable d = mContext.getDrawable(drawableResId);
         setCustomBackground(d);
     }
 
     public void setTint(int tintColor) {
-        mBackgroundDrawableToTint.setTint(tintColor);
-        mBackgroundDrawableToTint.setTintMode(PorterDuff.Mode.SRC_ATOP);
+        if (tintColor != 0) {
+            ColorStateList stateList = new ColorStateList(new int[][]{
+                    new int[]{com.android.internal.R.attr.state_pressed},
+                    new int[]{com.android.internal.R.attr.state_hovered},
+                    new int[]{}},
 
+                    new int[]{tintColor, tintColor, tintColor}
+            );
+            mBackground.setTintMode(PorterDuff.Mode.SRC_ATOP);
+            mBackground.setTintList(stateList);
+        } else {
+            mBackground.setTintList(null);
+        }
         mTintColor = tintColor;
         invalidate();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 6d8ec44..c615887 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -67,6 +67,7 @@
     private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
 
     private boolean mIsStatusBarExpanded = false;
+    private boolean mIsSceneContainerVisible = false;
     private boolean mShouldAdjustInsets = false;
     private View mNotificationShadeWindowView;
     private View mNotificationPanelView;
@@ -128,11 +129,14 @@
         });
 
         mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
-        javaAdapter.alwaysCollectFlow(shadeInteractor.isAnyExpanded(), this::onShadeOrQsExpanded);
 
         if (sceneContainerFlags.isEnabled()) {
             javaAdapter.alwaysCollectFlow(
                     sceneInteractor.get().isVisible(),
+                    this::onSceneContainerVisibilityChanged);
+        } else {
+            javaAdapter.alwaysCollectFlow(
+                    shadeInteractor.isAnyExpanded(),
                     this::onShadeOrQsExpanded);
         }
 
@@ -164,6 +168,17 @@
         }
     }
 
+    private void onSceneContainerVisibilityChanged(Boolean isVisible) {
+        if (isVisible != mIsSceneContainerVisible) {
+            mIsSceneContainerVisible = isVisible;
+            if (isVisible) {
+                // make sure our state is sensible
+                mForceCollapsedUntilLayout = false;
+            }
+            updateTouchableRegion();
+        }
+    }
+
     /**
      * Calculates the touch region needed for heads up notifications, taking into consideration
      * any existing display cutouts (notch)
@@ -267,6 +282,7 @@
         // since we don't want stray touches to go through the light reveal scrim to whatever is
         // underneath.
         return mIsStatusBarExpanded
+                || mIsSceneContainerVisible
                 || mPrimaryBouncerInteractor.isShowing().getValue()
                 || mAlternateBouncerInteractor.isVisibleState()
                 || mUnlockedScreenOffAnimationController.isAnimationPlaying();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java
index bbba19d..87df180 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureController.java
@@ -73,7 +73,11 @@
 
     /** Callback to be notified about device posture changes. */
     interface Callback {
-        /** Called when the posture changes. */
+        /**
+         * Called when the posture changes. If there are multiple active displays ("concurrent"),
+         * this will report the physical posture of the device (also known as the base device
+         * state).
+         */
         void onPostureChanged(@DevicePostureInt int posture);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java
index 8f1ac81..422aa4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java
@@ -39,8 +39,11 @@
 /** Implementation of {@link DevicePostureController} using the DeviceStateManager. */
 @SysUISingleton
 public class DevicePostureControllerImpl implements DevicePostureController {
+    /** From androidx.window.common.COMMON_STATE_USE_BASE_STATE */
+    private static final int COMMON_STATE_USE_BASE_STATE = 1000;
     private final List<Callback> mListeners = new ArrayList<>();
     private int mCurrentDevicePosture = DEVICE_POSTURE_UNKNOWN;
+    private int mCurrentBasePosture = DEVICE_POSTURE_UNKNOWN;
 
     private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
 
@@ -73,16 +76,32 @@
             mDeviceStateToPostureMap.put(deviceState, posture);
         }
 
-        deviceStateManager.registerCallback(executor, state -> {
-            Assert.isMainThread();
-            mCurrentDevicePosture =
-                    mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN);
+        deviceStateManager.registerCallback(executor, new DeviceStateManager.DeviceStateCallback() {
+            @Override
+            public void onStateChanged(int state) {
+                Assert.isMainThread();
+                mCurrentDevicePosture =
+                        mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN);
+                sendUpdatePosture();
+            }
 
-            ListenersTracing.INSTANCE.forEachTraced(mListeners, "DevicePostureControllerImpl",
+            @Override
+            public void onBaseStateChanged(int state) {
+                Assert.isMainThread();
+                mCurrentBasePosture = mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN);
+
+                if (useBaseState()) {
+                    sendUpdatePosture();
+                }
+            }
+
+            private void sendUpdatePosture() {
+                ListenersTracing.INSTANCE.forEachTraced(mListeners, "DevicePostureControllerImpl",
                     l -> {
-                        l.onPostureChanged(mCurrentDevicePosture);
+                        l.onPostureChanged(getDevicePosture());
                         return Unit.INSTANCE;
                     });
+            }
         });
     }
 
@@ -100,6 +119,14 @@
 
     @Override
     public int getDevicePosture() {
-        return mCurrentDevicePosture;
+        if (useBaseState()) {
+            return mCurrentBasePosture;
+        } else {
+            return mCurrentDevicePosture;
+        }
+    }
+
+    private boolean useBaseState() {
+        return mCurrentDevicePosture == COMMON_STATE_USE_BASE_STATE;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
index e576f36..279e5ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
@@ -16,6 +16,7 @@
 
 import com.android.systemui.Dumpable;
 import com.android.systemui.statusbar.policy.FlashlightController.FlashlightListener;
+import com.android.systemui.util.annotations.WeaklyReferencedCallback;
 
 public interface FlashlightController extends CallbackController<FlashlightListener>, Dumpable {
 
@@ -24,6 +25,7 @@
     boolean isAvailable();
     boolean isEnabled();
 
+    @WeaklyReferencedCallback
     public interface FlashlightListener {
 
         /**
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
index 8ae093a..10fc83c 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.shade.NotificationPanelUnfoldAnimationController
 import com.android.systemui.statusbar.phone.StatusBarMoveFromCenterAnimationController
+import com.android.systemui.unfold.dagger.UnfoldBg
 import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
 import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
 import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
@@ -33,10 +34,7 @@
 import javax.inject.Named
 import javax.inject.Scope
 
-@Scope
-@MustBeDocumented
-@Retention(AnnotationRetention.RUNTIME)
-annotation class SysUIUnfoldScope
+@Scope @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class SysUIUnfoldScope
 
 /**
  * Creates an injectable [SysUIUnfoldComponent] that provides objects that have been scoped with
@@ -55,20 +53,21 @@
     @Provides
     @SysUISingleton
     fun provideSysUIUnfoldComponent(
-            provider: Optional<UnfoldTransitionProgressProvider>,
-            rotationProvider: Optional<NaturalRotationUnfoldProgressProvider>,
-            @Named(UNFOLD_STATUS_BAR) scopedProvider:
-            Optional<ScopedUnfoldTransitionProgressProvider>,
-            unfoldLatencyTracker: Lazy<UnfoldLatencyTracker>,
-            factory: SysUIUnfoldComponent.Factory
+        provider: Optional<UnfoldTransitionProgressProvider>,
+        rotationProvider: Optional<NaturalRotationUnfoldProgressProvider>,
+        @Named(UNFOLD_STATUS_BAR) scopedProvider: Optional<ScopedUnfoldTransitionProgressProvider>,
+        @UnfoldBg bgProvider: Optional<UnfoldTransitionProgressProvider>,
+        unfoldLatencyTracker: Lazy<UnfoldLatencyTracker>,
+        factory: SysUIUnfoldComponent.Factory
     ): Optional<SysUIUnfoldComponent> {
         val p1 = provider.getOrNull()
         val p2 = rotationProvider.getOrNull()
         val p3 = scopedProvider.getOrNull()
-        return if (p1 == null || p2 == null || p3 == null) {
+        val p4 = bgProvider.getOrNull()
+        return if (p1 == null || p2 == null || p3 == null || p4 == null) {
             Optional.empty()
         } else {
-            Optional.of(factory.create(p1, p2, p3, unfoldLatencyTracker.get()))
+            Optional.of(factory.create(p1, p2, p3, p4, unfoldLatencyTracker.get()))
         }
     }
 }
@@ -76,13 +75,15 @@
 @SysUIUnfoldScope
 @Subcomponent
 interface SysUIUnfoldComponent {
+
     @Subcomponent.Factory
     interface Factory {
         fun create(
-                @BindsInstance p1: UnfoldTransitionProgressProvider,
-                @BindsInstance p2: NaturalRotationUnfoldProgressProvider,
-                @BindsInstance p3: ScopedUnfoldTransitionProgressProvider,
-                @BindsInstance p4: UnfoldLatencyTracker,
+            @BindsInstance p1: UnfoldTransitionProgressProvider,
+            @BindsInstance p2: NaturalRotationUnfoldProgressProvider,
+            @BindsInstance p3: ScopedUnfoldTransitionProgressProvider,
+            @BindsInstance @UnfoldBg p4: UnfoldTransitionProgressProvider,
+            @BindsInstance p5: UnfoldLatencyTracker,
         ): SysUIUnfoldComponent
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
index 36a1e8a..b72c6f1 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
@@ -35,6 +35,9 @@
 import android.view.SurfaceSession
 import android.view.WindowManager
 import android.view.WindowlessWindowManager
+import com.android.app.tracing.traceSection
+import com.android.keyguard.logging.ScrimLogger
+import com.android.systemui.Flags.unfoldAnimationBackgroundProgress
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -45,16 +48,16 @@
 import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation.AddOverlayReason.FOLD
 import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation.AddOverlayReason.UNFOLD
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.dagger.UnfoldBg
 import com.android.systemui.unfold.updates.RotationChangeProvider
 import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider.Companion.areAnimationsEnabled
 import com.android.systemui.util.concurrency.ThreadFactory
-import com.android.app.tracing.traceSection
-import com.android.keyguard.logging.ScrimLogger
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper
 import java.util.Optional
 import java.util.concurrent.Executor
 import java.util.function.Consumer
 import javax.inject.Inject
+import javax.inject.Provider
 
 @SysUIUnfoldScope
 class UnfoldLightRevealOverlayAnimation
@@ -65,11 +68,14 @@
     private val deviceStateManager: DeviceStateManager,
     private val contentResolver: ContentResolver,
     private val displayManager: DisplayManager,
-    private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
+    @UnfoldBg
+    private val unfoldTransitionBgProgressProvider: Provider<UnfoldTransitionProgressProvider>,
+    private val unfoldTransitionProgressProvider: Provider<UnfoldTransitionProgressProvider>,
     private val displayAreaHelper: Optional<DisplayAreaHelper>,
     @Main private val executor: Executor,
     private val threadFactory: ThreadFactory,
-    private val rotationChangeProvider: RotationChangeProvider,
+    @UnfoldBg private val rotationChangeProvider: RotationChangeProvider,
+    @UnfoldBg private val unfoldProgressHandler: Handler,
     private val displayTracker: DisplayTracker,
     private val scrimLogger: ScrimLogger,
 ) {
@@ -96,11 +102,15 @@
     fun init() {
         // This method will be called only on devices where this animation is enabled,
         // so normally this thread won't be created
-        bgHandler = threadFactory.buildHandlerOnNewThread(TAG)
+        bgHandler = unfoldProgressHandler
         bgExecutor = threadFactory.buildDelayableExecutorOnHandler(bgHandler)
 
         deviceStateManager.registerCallback(bgExecutor, FoldListener())
-        unfoldTransitionProgressProvider.addCallback(transitionListener)
+        if (unfoldAnimationBackgroundProgress()) {
+            unfoldTransitionBgProgressProvider.get().addCallback(transitionListener)
+        } else {
+            unfoldTransitionProgressProvider.get().addCallback(transitionListener)
+        }
         rotationChangeProvider.addCallback(rotationWatcher)
 
         val containerBuilder =
@@ -169,8 +179,13 @@
 
         overlayAddReason = reason
 
-        val newRoot = SurfaceControlViewHost(context, context.display!!, wwm,
-                "UnfoldLightRevealOverlayAnimation")
+        val newRoot =
+            SurfaceControlViewHost(
+                context,
+                context.display,
+                wwm,
+                "UnfoldLightRevealOverlayAnimation"
+            )
         val params = getLayoutParams()
         val newView =
             LightRevealScrim(
@@ -353,12 +368,13 @@
     }
 
     private fun executeInBackground(f: () -> Unit) {
-        check(Looper.myLooper() != bgHandler.looper) {
-            "Trying to execute using background handler while already running" +
-                " in the background handler"
+        // This is needed to allow progresses to be received both from the main thread (that will
+        // schedule a runnable on the bg thread), and from the bg thread directly (no reposting).
+        if (bgHandler.looper.isCurrentThread) {
+            f()
+        } else {
+            bgHandler.post(f)
         }
-        // The UiBackground executor is not used as it doesn't have a prepared looper.
-        bgHandler.post(f)
     }
 
     private fun ensureInBackground() {
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTraceLogger.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTraceLogger.kt
index 12b8845..94912bf8 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTraceLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTraceLogger.kt
@@ -21,11 +21,14 @@
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.unfold.system.DeviceStateRepository
 import com.android.systemui.unfold.updates.FoldStateRepository
 import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.plus
 
 /**
  * Logs several unfold related details in a trace. Mainly used for debugging and investigate
@@ -37,7 +40,8 @@
 constructor(
     private val context: Context,
     private val foldStateRepository: FoldStateRepository,
-    @Application private val applicationScope: CoroutineScope,
+    @Application applicationScope: CoroutineScope,
+    @Background private val coroutineContext: CoroutineContext,
     private val deviceStateRepository: DeviceStateRepository
 ) : CoreStartable {
     private val isFoldable: Boolean
@@ -46,20 +50,22 @@
                 .getIntArray(com.android.internal.R.array.config_foldedDeviceStates)
                 .isNotEmpty()
 
+    private val bgScope = applicationScope.plus(coroutineContext)
+
     override fun start() {
         if (!isFoldable) return
 
-        applicationScope.launch {
+        bgScope.launch {
             val foldUpdateLogger = TraceStateLogger("FoldUpdate")
             foldStateRepository.foldUpdate.collect { foldUpdateLogger.log(it.name) }
         }
 
-        applicationScope.launch {
+        bgScope.launch {
             foldStateRepository.hingeAngle.collect {
                 Trace.traceCounter(Trace.TRACE_TAG_APP, "hingeAngle", it.toInt())
             }
         }
-        applicationScope.launch {
+        bgScope.launch {
             val foldedStateLogger = TraceStateLogger("FoldedState")
             deviceStateRepository.isFolded.collect { isFolded ->
                 foldedStateLogger.log(
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
index 7b628f8..9689811 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -20,10 +20,13 @@
 import android.hardware.devicestate.DeviceStateManager
 import android.os.SystemProperties
 import com.android.systemui.CoreStartable
+import com.android.systemui.Flags
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.LifecycleScreenStatusProvider
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.dagger.UnfoldBgProgressFlag
+import com.android.systemui.unfold.dagger.UnfoldMain
 import com.android.systemui.unfold.data.repository.UnfoldTransitionRepository
 import com.android.systemui.unfold.data.repository.UnfoldTransitionRepositoryImpl
 import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
@@ -63,6 +66,10 @@
 
     @Provides @UnfoldTransitionATracePrefix fun tracingTagPrefix() = "systemui"
 
+    @Provides
+    @UnfoldBgProgressFlag
+    fun unfoldBgProgressFlag() = Flags.unfoldAnimationBackgroundProgress()
+
     /** A globally available FoldStateListener that allows one to query the fold state. */
     @Provides
     @Singleton
@@ -102,7 +109,7 @@
     @Singleton
     fun provideNaturalRotationProgressProvider(
         context: Context,
-        rotationChangeProvider: RotationChangeProvider,
+        @UnfoldMain rotationChangeProvider: RotationChangeProvider,
         unfoldTransitionProgressProvider: Optional<UnfoldTransitionProgressProvider>
     ): Optional<NaturalRotationUnfoldProgressProvider> =
         unfoldTransitionProgressProvider.map { provider ->
@@ -153,7 +160,8 @@
 
         return resultingProvider?.get()?.orElse(null)?.let { unfoldProgressProvider ->
             UnfoldProgressProvider(unfoldProgressProvider, foldProvider)
-        } ?: ShellUnfoldProgressProvider.NO_PROVIDER
+        }
+            ?: ShellUnfoldProgressProvider.NO_PROVIDER
     }
 
     @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
index cc9335e..472f0ae 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
@@ -14,6 +14,7 @@
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.plus
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
 
@@ -29,6 +30,14 @@
 
     @Provides
     @SysUISingleton
+    @Background
+    fun bgApplicationScope(
+            @Application applicationScope: CoroutineScope,
+            @Background coroutineContext: CoroutineContext,
+    ): CoroutineScope = applicationScope.plus(coroutineContext)
+
+    @Provides
+    @SysUISingleton
     @Main
     @Deprecated(
         "Use @Main CoroutineContext instead",
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
index 0e6df6b..e031be2 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
@@ -19,6 +19,7 @@
 import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE;
 import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE;
 
+import android.annotation.WorkerThread;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
@@ -146,7 +147,9 @@
 
     /**
      * Update the "show wallet" preference.
+     * This should not be called on the main thread.
      */
+    @WorkerThread
     public void updateWalletPreference() {
         mWalletEnabled = mQuickAccessWalletClient.isWalletServiceAvailable()
                 && mQuickAccessWalletClient.isWalletFeatureAvailable()
@@ -155,10 +158,12 @@
 
     /**
      * Query the wallet cards from {@link QuickAccessWalletClient}.
+     * This should not be called on the main thread.
      *
      * @param cardsRetriever a callback to retrieve wallet cards.
      * @param maxCards the maximum number of cards requested from the QuickAccessWallet
      */
+    @WorkerThread
     public void queryWalletCards(
             QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever, int maxCards) {
         if (mClock.elapsedRealtime() - mQawClientCreatedTimeMillis
@@ -182,9 +187,11 @@
 
     /**
      * Query the wallet cards from {@link QuickAccessWalletClient}.
+     * This should not be called on the main thread.
      *
      * @param cardsRetriever a callback to retrieve wallet cards.
      */
+    @WorkerThread
     public void queryWalletCards(
             QuickAccessWalletClient.OnWalletCardsRetrievedCallback cardsRetriever) {
         queryWalletCards(cardsRetriever, /* maxCards= */ 1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
index d8799e1..4395282 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
@@ -133,8 +133,8 @@
     }
 
     @Test
-    public void setScale() throws RemoteException {
-        mIWindowMagnificationConnection.setScale(TEST_DISPLAY, 3.0f);
+    public void setScaleForWindowMagnification() throws RemoteException {
+        mIWindowMagnificationConnection.setScaleForWindowMagnification(TEST_DISPLAY, 3.0f);
         waitForIdleSync();
 
         verify(mWindowMagnificationController).setScale(3.0f);
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 f4122d5..ea20d29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -338,6 +338,13 @@
         waitForIdleSync()
 
         assertThat(container.hasCredentialView()).isTrue()
+        assertThat(container.hasBiometricPrompt()).isFalse()
+
+        // Check credential view persists after new attachment
+        container.onAttachedToWindow()
+
+        assertThat(container.hasCredentialView()).isTrue()
+        assertThat(container.hasBiometricPrompt()).isFalse()
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
index 993dbac..54d6b53 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
@@ -95,6 +95,18 @@
         }
 
     @Test
+    fun enableDetector_isUserInteractingTrue_shouldNotPostRunnable() =
+        testComponent.runTest {
+            // GIVEN isInteracting starts true
+            shadeRepository.setLegacyShadeTracking(true)
+            runCurrent()
+            detector.enable(action)
+
+            // THEN action was not run
+            verifyZeroInteractions(action)
+        }
+
+    @Test
     fun enableDetector_shadeExpandImmediate_shouldNotPostRunnable() =
         testComponent.runTest {
             // GIVEN shade is closed and detector is enabled
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
deleted file mode 100644
index f5b6f14..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics
-
-import android.graphics.Rect
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_BP
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_OTHER
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_ENROLLING
-import android.hardware.biometrics.BiometricOverlayConstants.ShowReason
-import android.hardware.fingerprint.FingerprintManager
-import android.hardware.fingerprint.IUdfpsOverlayControllerCallback
-import android.testing.TestableLooper.RunWithLooper
-import android.view.LayoutInflater
-import android.view.MotionEvent
-import android.view.Surface
-import android.view.Surface.Rotation
-import android.view.View
-import android.view.WindowManager
-import android.view.accessibility.AccessibilityManager
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.Flags
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.animation.ActivityLaunchAnimator
-import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
-import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
-import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.LockscreenShadeTransitionController
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
-import com.android.systemui.statusbar.phone.SystemUIDialogManager
-import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController
-import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.statusbar.policy.KeyguardStateController
-import com.android.systemui.user.domain.interactor.SelectedUserInteractor
-import com.android.systemui.util.settings.SecureSettings
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.eq
-import org.mockito.Captor
-import org.mockito.Mock
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.verify
-import org.mockito.junit.MockitoJUnit
-import org.mockito.Mockito.`when` as whenever
-
-private const val REQUEST_ID = 2L
-
-// Dimensions for the current display resolution.
-private const val DISPLAY_WIDTH = 1080
-private const val DISPLAY_HEIGHT = 1920
-private const val SENSOR_WIDTH = 30
-private const val SENSOR_HEIGHT = 60
-
-@ExperimentalCoroutinesApi
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-@RunWithLooper(setAsMainLooper = true)
-class UdfpsControllerOverlayTest : SysuiTestCase() {
-
-    @JvmField @Rule var rule = MockitoJUnit.rule()
-
-    @Mock private lateinit var fingerprintManager: FingerprintManager
-    @Mock private lateinit var inflater: LayoutInflater
-    @Mock private lateinit var windowManager: WindowManager
-    @Mock private lateinit var accessibilityManager: AccessibilityManager
-    @Mock private lateinit var statusBarStateController: StatusBarStateController
-    @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
-    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
-    @Mock private lateinit var dialogManager: SystemUIDialogManager
-    @Mock private lateinit var dumpManager: DumpManager
-    @Mock private lateinit var transitionController: LockscreenShadeTransitionController
-    @Mock private lateinit var configurationController: ConfigurationController
-    @Mock private lateinit var keyguardStateController: KeyguardStateController
-    @Mock private lateinit var unlockedScreenOffAnimationController:
-            UnlockedScreenOffAnimationController
-    @Mock private lateinit var udfpsDisplayMode: UdfpsDisplayModeProvider
-    @Mock private lateinit var secureSettings: SecureSettings
-    @Mock private lateinit var controllerCallback: IUdfpsOverlayControllerCallback
-    @Mock private lateinit var udfpsController: UdfpsController
-    @Mock private lateinit var udfpsView: UdfpsView
-    @Mock private lateinit var mUdfpsKeyguardViewLegacy: UdfpsKeyguardViewLegacy
-    @Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
-    @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
-    @Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
-    @Mock private lateinit var mSelectedUserInteractor: SelectedUserInteractor
-    @Mock private lateinit var udfpsKeyguardAccessibilityDelegate:
-            UdfpsKeyguardAccessibilityDelegate
-    @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
-    @Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
-
-    private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true }
-    private var overlayParams: UdfpsOverlayParams = UdfpsOverlayParams()
-    private lateinit var controllerOverlay: UdfpsControllerOverlay
-
-    @Before
-    fun setup() {
-        whenever(inflater.inflate(R.layout.udfps_view, null, false))
-                .thenReturn(udfpsView)
-        whenever(inflater.inflate(R.layout.udfps_bp_view, null))
-                .thenReturn(mock(UdfpsBpView::class.java))
-        whenever(inflater.inflate(R.layout.udfps_keyguard_view_legacy, null))
-                .thenReturn(mUdfpsKeyguardViewLegacy)
-        whenever(inflater.inflate(R.layout.udfps_fpm_empty_view, null))
-                .thenReturn(mock(UdfpsFpmEmptyView::class.java))
-    }
-
-    private fun withReason(
-            @ShowReason reason: Int,
-            isDebuggable: Boolean = false,
-            enableDeviceEntryUdfpsRefactor: Boolean = false,
-            block: () -> Unit,
-    ) {
-        if (enableDeviceEntryUdfpsRefactor) {
-            mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
-        } else {
-            mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
-        }
-        controllerOverlay = UdfpsControllerOverlay(
-                context,
-                inflater,
-                windowManager,
-                accessibilityManager,
-                statusBarStateController,
-                statusBarKeyguardViewManager,
-                keyguardUpdateMonitor,
-                dialogManager,
-                dumpManager,
-                transitionController,
-                configurationController,
-                keyguardStateController,
-                unlockedScreenOffAnimationController,
-                udfpsDisplayMode,
-                REQUEST_ID,
-                reason,
-                controllerCallback,
-                onTouch,
-                activityLaunchAnimator,
-                primaryBouncerInteractor,
-                alternateBouncerInteractor,
-                isDebuggable,
-                udfpsKeyguardAccessibilityDelegate,
-                keyguardTransitionInteractor,
-                mSelectedUserInteractor,
-        )
-        block()
-    }
-
-    @Test
-    fun showUdfpsOverlay_bp() = withReason(REASON_AUTH_BP) { showUdfpsOverlay() }
-
-    @Test
-    fun showUdfpsOverlay_keyguard() = withReason(REASON_AUTH_KEYGUARD) {
-        showUdfpsOverlay()
-        verify(mUdfpsKeyguardViewLegacy).updateSensorLocation(eq(overlayParams.sensorBounds))
-    }
-
-    @Test
-    fun showUdfpsOverlay_other() = withReason(REASON_AUTH_OTHER) { showUdfpsOverlay() }
-
-    private fun withRotation(@Rotation rotation: Int, block: () -> Unit) {
-        // Sensor that's in the top left corner of the display in natural orientation.
-        val sensorBounds = Rect(0, 0, SENSOR_WIDTH, SENSOR_HEIGHT)
-        val overlayBounds = Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT)
-        overlayParams = UdfpsOverlayParams(
-                sensorBounds,
-                overlayBounds,
-                DISPLAY_WIDTH,
-                DISPLAY_HEIGHT,
-                scaleFactor = 1f,
-                rotation
-        )
-        block()
-    }
-
-    @Test
-    fun showUdfpsOverlay_withRotation0() = withRotation(Surface.ROTATION_0) {
-        withReason(REASON_AUTH_BP) {
-            controllerOverlay.show(udfpsController, overlayParams)
-            verify(windowManager).addView(
-                    eq(controllerOverlay.getTouchOverlay()),
-                    layoutParamsCaptor.capture()
-            )
-
-            // ROTATION_0 is the native orientation. Sensor should stay in the top left corner.
-            val lp = layoutParamsCaptor.value
-            assertThat(lp.x).isEqualTo(0)
-            assertThat(lp.y).isEqualTo(0)
-            assertThat(lp.width).isEqualTo(DISPLAY_WIDTH)
-            assertThat(lp.height).isEqualTo(DISPLAY_HEIGHT)
-        }
-    }
-
-    @Test
-    fun showUdfpsOverlay_withRotation180() = withRotation(Surface.ROTATION_180) {
-        withReason(REASON_AUTH_BP) {
-            controllerOverlay.show(udfpsController, overlayParams)
-            verify(windowManager).addView(
-                    eq(controllerOverlay.getTouchOverlay()),
-                    layoutParamsCaptor.capture()
-            )
-
-            // ROTATION_180 is not supported. Sensor should stay in the top left corner.
-            val lp = layoutParamsCaptor.value
-            assertThat(lp.x).isEqualTo(0)
-            assertThat(lp.y).isEqualTo(0)
-            assertThat(lp.width).isEqualTo(DISPLAY_WIDTH)
-            assertThat(lp.height).isEqualTo(DISPLAY_HEIGHT)
-        }
-    }
-
-    @Test
-    fun showUdfpsOverlay_withRotation90() = withRotation(Surface.ROTATION_90) {
-        withReason(REASON_AUTH_BP) {
-            controllerOverlay.show(udfpsController, overlayParams)
-            verify(windowManager).addView(
-                    eq(controllerOverlay.getTouchOverlay()),
-                    layoutParamsCaptor.capture()
-            )
-
-            // Sensor should be in the bottom left corner in ROTATION_90.
-            val lp = layoutParamsCaptor.value
-            assertThat(lp.x).isEqualTo(0)
-            assertThat(lp.y).isEqualTo(0)
-            assertThat(lp.width).isEqualTo(DISPLAY_HEIGHT)
-            assertThat(lp.height).isEqualTo(DISPLAY_WIDTH)
-        }
-    }
-
-    @Test
-    fun showUdfpsOverlay_withRotation270() = withRotation(Surface.ROTATION_270) {
-        withReason(REASON_AUTH_BP) {
-            controllerOverlay.show(udfpsController, overlayParams)
-            verify(windowManager).addView(
-                    eq(controllerOverlay.getTouchOverlay()),
-                    layoutParamsCaptor.capture()
-            )
-
-            // Sensor should be in the top right corner in ROTATION_270.
-            val lp = layoutParamsCaptor.value
-            assertThat(lp.x).isEqualTo(0)
-            assertThat(lp.y).isEqualTo(0)
-            assertThat(lp.width).isEqualTo(DISPLAY_HEIGHT)
-            assertThat(lp.height).isEqualTo(DISPLAY_WIDTH)
-        }
-    }
-
-    private fun showUdfpsOverlay() {
-        val didShow = controllerOverlay.show(udfpsController, overlayParams)
-
-        verify(windowManager).addView(eq(controllerOverlay.getTouchOverlay()), any())
-        verify(udfpsView).setUdfpsDisplayModeProvider(eq(udfpsDisplayMode))
-        verify(udfpsView).animationViewController = any()
-        verify(udfpsView).addView(any())
-
-        assertThat(didShow).isTrue()
-        assertThat(controllerOverlay.isShowing).isTrue()
-        assertThat(controllerOverlay.isHiding).isFalse()
-        assertThat(controllerOverlay.getTouchOverlay()).isNotNull()
-    }
-
-    @Test
-    fun hideUdfpsOverlay_bp() = withReason(REASON_AUTH_BP) { hideUdfpsOverlay() }
-
-    @Test
-    fun hideUdfpsOverlay_keyguard() = withReason(REASON_AUTH_KEYGUARD) { hideUdfpsOverlay() }
-
-    @Test
-    fun hideUdfpsOverlay_settings() = withReason(REASON_AUTH_SETTINGS) { hideUdfpsOverlay() }
-
-    @Test
-    fun hideUdfpsOverlay_other() = withReason(REASON_AUTH_OTHER) { hideUdfpsOverlay() }
-
-    private fun hideUdfpsOverlay() {
-        val didShow = controllerOverlay.show(udfpsController, overlayParams)
-        val view = controllerOverlay.getTouchOverlay()
-        val didHide = controllerOverlay.hide()
-
-        verify(windowManager).removeView(eq(view))
-
-        assertThat(didShow).isTrue()
-        assertThat(didHide).isTrue()
-        assertThat(controllerOverlay.getTouchOverlay()).isNull()
-        assertThat(controllerOverlay.animationViewController).isNull()
-        assertThat(controllerOverlay.isShowing).isFalse()
-        assertThat(controllerOverlay.isHiding).isTrue()
-    }
-
-    @Test
-    fun canNotHide() = withReason(REASON_AUTH_BP) {
-        assertThat(controllerOverlay.hide()).isFalse()
-    }
-
-    @Test
-    fun canNotReshow() = withReason(REASON_AUTH_BP) {
-        assertThat(controllerOverlay.show(udfpsController, overlayParams)).isTrue()
-        assertThat(controllerOverlay.show(udfpsController, overlayParams)).isFalse()
-    }
-
-    @Test
-    fun cancels() = withReason(REASON_AUTH_BP) {
-        controllerOverlay.cancel()
-        verify(controllerCallback).onUserCanceled()
-    }
-
-    @Test
-    fun unconfigureDisplayOnHide() = withReason(REASON_AUTH_BP) {
-        whenever(udfpsView.isDisplayConfigured).thenReturn(true)
-
-        controllerOverlay.show(udfpsController, overlayParams)
-        controllerOverlay.hide()
-        verify(udfpsView).unconfigureDisplay()
-    }
-
-    @Test
-    fun matchesRequestIds() = withReason(REASON_AUTH_BP) {
-        assertThat(controllerOverlay.matchesRequestId(REQUEST_ID)).isTrue()
-        assertThat(controllerOverlay.matchesRequestId(REQUEST_ID + 1)).isFalse()
-    }
-
-    @Test
-    fun smallOverlayOnEnrollmentWithA11y() = withRotation(Surface.ROTATION_0) {
-        withReason(REASON_ENROLL_ENROLLING) {
-            // When a11y enabled during enrollment
-            whenever(accessibilityManager.isTouchExplorationEnabled).thenReturn(true)
-
-            controllerOverlay.show(udfpsController, overlayParams)
-            verify(windowManager).addView(
-                    eq(controllerOverlay.getTouchOverlay()),
-                    layoutParamsCaptor.capture()
-            )
-
-            // Layout params should use sensor bounds
-            val lp = layoutParamsCaptor.value
-            assertThat(lp.width).isEqualTo(overlayParams.sensorBounds.width())
-            assertThat(lp.height).isEqualTo(overlayParams.sensorBounds.height())
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt
new file mode 100644
index 0000000..575d8bf
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysUITestComponent
+import com.android.systemui.SysUITestModule
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.TestMocksModule
+import com.android.systemui.collectLastValue
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FakeFeatureFlagsClassicModule
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.shared.model.StatusBarState
+import com.android.systemui.runCurrent
+import com.android.systemui.runTest
+import com.android.systemui.shade.data.repository.FakeShadeRepository
+import com.android.systemui.shade.domain.model.ShadeModel
+import com.android.systemui.statusbar.phone.SystemUIDialogManager
+import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+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.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class DefaultUdfpsTouchOverlayViewModelTest : SysuiTestCase() {
+    @Captor
+    private lateinit var sysuiDialogListenerCaptor: ArgumentCaptor<SystemUIDialogManager.Listener>
+    private var systemUIDialogManager: SystemUIDialogManager = mock()
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @SysUISingleton
+    @Component(
+        modules =
+            [
+                SysUITestModule::class,
+                UserDomainLayerModule::class,
+            ]
+    )
+    interface TestComponent : SysUITestComponent<DefaultUdfpsTouchOverlayViewModel> {
+        val keyguardRepository: FakeKeyguardRepository
+        val shadeRepository: FakeShadeRepository
+        @Component.Factory
+        interface Factory {
+            fun create(
+                @BindsInstance test: SysuiTestCase,
+                featureFlags: FakeFeatureFlagsClassicModule,
+                mocks: TestMocksModule,
+            ): TestComponent
+        }
+    }
+
+    private fun TestComponent.shadeExpanded(expanded: Boolean) {
+        if (expanded) {
+            shadeRepository.setShadeModel(
+                ShadeModel(
+                    expansionAmount = 1f,
+                    isExpanded = true,
+                    isUserDragging = false,
+                )
+            )
+            shadeRepository.setLegacyExpandedOrAwaitingInputTransfer(true)
+        } else {
+            keyguardRepository.setStatusBarState(StatusBarState.SHADE)
+            shadeRepository.setShadeModel(
+                ShadeModel(
+                    expansionAmount = 0f,
+                    isExpanded = false,
+                    isUserDragging = false,
+                )
+            )
+            shadeRepository.setLegacyExpandedOrAwaitingInputTransfer(false)
+        }
+    }
+
+    private val testComponent: TestComponent =
+        DaggerDefaultUdfpsTouchOverlayViewModelTest_TestComponent.factory()
+            .create(
+                test = this,
+                featureFlags =
+                    FakeFeatureFlagsClassicModule { set(Flags.FULL_SCREEN_USER_SWITCHER, true) },
+                mocks = TestMocksModule(systemUIDialogManager = systemUIDialogManager),
+            )
+
+    @Test
+    fun shadeNotExpanded_noDialogShowing_shouldHandleTouchesTrue() =
+        testComponent.runTest {
+            val shouldHandleTouches by collectLastValue(underTest.shouldHandleTouches)
+            runCurrent()
+
+            shadeExpanded(false)
+            verify(systemUIDialogManager).registerListener(sysuiDialogListenerCaptor.capture())
+            sysuiDialogListenerCaptor.value.shouldHideAffordances(false)
+            runCurrent()
+
+            assertThat(shouldHandleTouches).isTrue()
+        }
+
+    @Test
+    fun shadeNotExpanded_dialogShowing_shouldHandleTouchesFalse() =
+        testComponent.runTest {
+            val shouldHandleTouches by collectLastValue(underTest.shouldHandleTouches)
+            runCurrent()
+
+            shadeExpanded(false)
+            verify(systemUIDialogManager).registerListener(sysuiDialogListenerCaptor.capture())
+            sysuiDialogListenerCaptor.value.shouldHideAffordances(true)
+            runCurrent()
+
+            assertThat(shouldHandleTouches).isFalse()
+        }
+
+    @Test
+    fun shadeExpanded_noDialogShowing_shouldHandleTouchesFalse() =
+        testComponent.runTest {
+            val shouldHandleTouches by collectLastValue(underTest.shouldHandleTouches)
+            runCurrent()
+
+            shadeExpanded(true)
+            verify(systemUIDialogManager).registerListener(sysuiDialogListenerCaptor.capture())
+            sysuiDialogListenerCaptor.value.shouldHideAffordances(false)
+            runCurrent()
+
+            assertThat(shouldHandleTouches).isFalse()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
new file mode 100644
index 0000000..dfb18b9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysUITestComponent
+import com.android.systemui.SysUITestModule
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.TestMocksModule
+import com.android.systemui.collectLastValue
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FakeFeatureFlagsClassicModule
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.runCurrent
+import com.android.systemui.runTest
+import com.android.systemui.shade.data.repository.FakeShadeRepository
+import com.android.systemui.statusbar.phone.SystemUIDialogManager
+import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+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.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class DeviceEntryUdfpsTouchOverlayViewModelTest : SysuiTestCase() {
+    @Captor
+    private lateinit var sysuiDialogListenerCaptor: ArgumentCaptor<SystemUIDialogManager.Listener>
+    private var systemUIDialogManager: SystemUIDialogManager = mock()
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @SysUISingleton
+    @Component(
+        modules =
+            [
+                SysUITestModule::class,
+                UserDomainLayerModule::class,
+            ]
+    )
+    interface TestComponent : SysUITestComponent<DeviceEntryUdfpsTouchOverlayViewModel> {
+        val keyguardRepository: FakeKeyguardRepository
+        val shadeRepository: FakeShadeRepository
+        @Component.Factory
+        interface Factory {
+            fun create(
+                @BindsInstance test: SysuiTestCase,
+                featureFlags: FakeFeatureFlagsClassicModule,
+                mocks: TestMocksModule,
+            ): TestComponent
+        }
+    }
+
+    private val testDeviceEntryIconTransitionAlpha = MutableStateFlow(0f)
+    private val testDeviceEntryIconTransition: DeviceEntryIconTransition
+        get() =
+            object : DeviceEntryIconTransition {
+                override val deviceEntryParentViewAlpha: Flow<Float> =
+                    testDeviceEntryIconTransitionAlpha.asStateFlow()
+            }
+    private val testComponent: TestComponent =
+        DaggerDeviceEntryUdfpsTouchOverlayViewModelTest_TestComponent.factory()
+            .create(
+                test = this,
+                featureFlags =
+                    FakeFeatureFlagsClassicModule { set(Flags.FULL_SCREEN_USER_SWITCHER, true) },
+                mocks =
+                    TestMocksModule(
+                        systemUIDialogManager = systemUIDialogManager,
+                        deviceEntryIconTransitions =
+                            setOf(
+                                testDeviceEntryIconTransition,
+                            )
+                    ),
+            )
+
+    @Test
+    fun dialogShowing_shouldHandleTouchesFalse() =
+        testComponent.runTest {
+            val shouldHandleTouches by collectLastValue(underTest.shouldHandleTouches)
+            runCurrent()
+
+            testDeviceEntryIconTransitionAlpha.value = 1f
+            verify(systemUIDialogManager).registerListener(sysuiDialogListenerCaptor.capture())
+            sysuiDialogListenerCaptor.value.shouldHideAffordances(true)
+            runCurrent()
+
+            assertThat(shouldHandleTouches).isFalse()
+        }
+
+    @Test
+    fun transitionAlphaIsSmall_shouldHandleTouchesFalse() =
+        testComponent.runTest {
+            val shouldHandleTouches by collectLastValue(underTest.shouldHandleTouches)
+            runCurrent()
+
+            testDeviceEntryIconTransitionAlpha.value = .3f
+            verify(systemUIDialogManager).registerListener(sysuiDialogListenerCaptor.capture())
+            sysuiDialogListenerCaptor.value.shouldHideAffordances(false)
+            runCurrent()
+
+            assertThat(shouldHandleTouches).isFalse()
+        }
+
+    @Test
+    fun alphaFullyShowing_noDialog_shouldHandleTouchesTrue() =
+        testComponent.runTest {
+            val shouldHandleTouches by collectLastValue(underTest.shouldHandleTouches)
+            runCurrent()
+
+            testDeviceEntryIconTransitionAlpha.value = 1f
+            verify(systemUIDialogManager).registerListener(sysuiDialogListenerCaptor.capture())
+            sysuiDialogListenerCaptor.value.shouldHideAffordances(false)
+            runCurrent()
+
+            assertThat(shouldHandleTouches).isTrue()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java
index 50914c8..7133e8b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LifecycleTest.java
@@ -16,8 +16,7 @@
 
 package com.android.systemui.keyguard;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
 
 import android.testing.AndroidTestingRunner;
 
@@ -52,8 +51,7 @@
         mLifecycle.addObserver(mObj1);
 
         mLifecycle.dispatch(mDispatchedObjects::add);
-
-        assertTrue(mDispatchedObjects.contains(mObj1));
+        assertThat(mDispatchedObjects).contains(mObj1);
     }
 
     @Test
@@ -63,7 +61,7 @@
 
         mLifecycle.dispatch(mDispatchedObjects::add);
 
-        assertFalse(mDispatchedObjects.contains(mObj1));
+        assertThat(mDispatchedObjects).isEmpty();
     }
 
     @Test
@@ -73,8 +71,7 @@
 
         mLifecycle.dispatch(mDispatchedObjects::add);
 
-        assertTrue(mDispatchedObjects.contains(mObj1));
-        assertTrue(mDispatchedObjects.contains(mObj2));
+        assertThat(mDispatchedObjects).containsExactly(mObj1, mObj2);
     }
 
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
index 67c4e26..0c30d10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
@@ -51,6 +51,7 @@
 import com.android.systemui.res.R
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.FakeSharedPreferences
@@ -58,8 +59,10 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth
-import kotlin.math.max
 import kotlin.math.min
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -73,6 +76,7 @@
 import org.mockito.Mockito
 import org.mockito.MockitoAnnotations
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(JUnit4::class)
 class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@@ -85,6 +89,47 @@
     @Mock private lateinit var keyguardStateController: KeyguardStateController
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
     @Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
+    @Mock private lateinit var shadeInteractor: ShadeInteractor
+    @Mock
+    private lateinit var aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel
+    @Mock
+    private lateinit var dozingToLockscreenTransitionViewModel:
+        DozingToLockscreenTransitionViewModel
+    @Mock
+    private lateinit var dreamingHostedToLockscreenTransitionViewModel:
+        DreamingHostedToLockscreenTransitionViewModel
+    @Mock
+    private lateinit var dreamingToLockscreenTransitionViewModel:
+        DreamingToLockscreenTransitionViewModel
+    @Mock
+    private lateinit var goneToLockscreenTransitionViewModel: GoneToLockscreenTransitionViewModel
+    @Mock
+    private lateinit var occludedToLockscreenTransitionViewModel:
+        OccludedToLockscreenTransitionViewModel
+    @Mock
+    private lateinit var offToLockscreenTransitionViewModel: OffToLockscreenTransitionViewModel
+    @Mock
+    private lateinit var primaryBouncerToLockscreenTransitionViewModel:
+        PrimaryBouncerToLockscreenTransitionViewModel
+    @Mock
+    private lateinit var lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel
+    @Mock
+    private lateinit var lockscreenToDozingTransitionViewModel:
+        LockscreenToDozingTransitionViewModel
+    @Mock
+    private lateinit var lockscreenToDreamingHostedTransitionViewModel:
+        LockscreenToDreamingHostedTransitionViewModel
+    @Mock
+    private lateinit var lockscreenToDreamingTransitionViewModel:
+        LockscreenToDreamingTransitionViewModel
+    @Mock
+    private lateinit var lockscreenToGoneTransitionViewModel: LockscreenToGoneTransitionViewModel
+    @Mock
+    private lateinit var lockscreenToOccludedTransitionViewModel:
+        LockscreenToOccludedTransitionViewModel
+    @Mock
+    private lateinit var lockscreenToPrimaryBouncerTransitionViewModel:
+        LockscreenToPrimaryBouncerTransitionViewModel
 
     private lateinit var underTest: KeyguardQuickAffordancesCombinedViewModel
 
@@ -97,6 +142,10 @@
     private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
     private lateinit var keyguardInteractor: KeyguardInteractor
 
+    private val intendedAlphaMutableStateFlow: MutableStateFlow<Float> = MutableStateFlow(1f)
+    // the viewModel does a `map { 1 - it }` on this value, which is why it's different
+    private val intendedShadeAlphaMutableStateFlow: MutableStateFlow<Float> = MutableStateFlow(0f)
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
@@ -191,6 +240,31 @@
                 userHandle = UserHandle.SYSTEM,
             )
 
+        intendedAlphaMutableStateFlow.value = 1f
+        intendedShadeAlphaMutableStateFlow.value = 0f
+        whenever(aodToLockscreenTransitionViewModel.shortcutsAlpha)
+            .thenReturn(intendedAlphaMutableStateFlow)
+        whenever(dozingToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+        whenever(dreamingHostedToLockscreenTransitionViewModel.shortcutsAlpha)
+            .thenReturn(emptyFlow())
+        whenever(dreamingToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+        whenever(goneToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+        whenever(occludedToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+        whenever(offToLockscreenTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+        whenever(primaryBouncerToLockscreenTransitionViewModel.shortcutsAlpha)
+            .thenReturn(emptyFlow())
+        whenever(lockscreenToAodTransitionViewModel.shortcutsAlpha)
+            .thenReturn(intendedAlphaMutableStateFlow)
+        whenever(lockscreenToDozingTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+        whenever(lockscreenToDreamingHostedTransitionViewModel.shortcutsAlpha)
+            .thenReturn(emptyFlow())
+        whenever(lockscreenToDreamingTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+        whenever(lockscreenToGoneTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+        whenever(lockscreenToOccludedTransitionViewModel.shortcutsAlpha).thenReturn(emptyFlow())
+        whenever(lockscreenToPrimaryBouncerTransitionViewModel.shortcutsAlpha)
+            .thenReturn(emptyFlow())
+        whenever(shadeInteractor.qsExpansion).thenReturn(intendedShadeAlphaMutableStateFlow)
+
         underTest =
             KeyguardQuickAffordancesCombinedViewModel(
                 quickAffordanceInteractor =
@@ -210,7 +284,27 @@
                         backgroundDispatcher = testDispatcher,
                         appContext = mContext,
                     ),
-                keyguardInteractor = keyguardInteractor
+                keyguardInteractor = keyguardInteractor,
+                shadeInteractor = shadeInteractor,
+                aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
+                dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel,
+                dreamingHostedToLockscreenTransitionViewModel =
+                    dreamingHostedToLockscreenTransitionViewModel,
+                dreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel,
+                goneToLockscreenTransitionViewModel = goneToLockscreenTransitionViewModel,
+                occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
+                offToLockscreenTransitionViewModel = offToLockscreenTransitionViewModel,
+                primaryBouncerToLockscreenTransitionViewModel =
+                    primaryBouncerToLockscreenTransitionViewModel,
+                lockscreenToAodTransitionViewModel = lockscreenToAodTransitionViewModel,
+                lockscreenToDozingTransitionViewModel = lockscreenToDozingTransitionViewModel,
+                lockscreenToDreamingHostedTransitionViewModel =
+                    lockscreenToDreamingHostedTransitionViewModel,
+                lockscreenToDreamingTransitionViewModel = lockscreenToDreamingTransitionViewModel,
+                lockscreenToGoneTransitionViewModel = lockscreenToGoneTransitionViewModel,
+                lockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel,
+                lockscreenToPrimaryBouncerTransitionViewModel =
+                    lockscreenToPrimaryBouncerTransitionViewModel
             )
     }
 
@@ -526,15 +620,15 @@
     @Test
     fun isClickable_falseWhenAlphaBelowThreshold() =
         testScope.runTest {
+            intendedAlphaMutableStateFlow.value =
+                KeyguardQuickAffordancesCombinedViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD -
+                    .1f
+            // the viewModel does a `map { 1 - it }` on this value, which is why it's different
+            intendedShadeAlphaMutableStateFlow.value =
+                KeyguardQuickAffordancesCombinedViewModel.AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD +
+                    .1f
             repository.setKeyguardShowing(true)
             val latest = collectLastValue(underTest.startButton)
-            repository.setKeyguardAlpha(
-                max(
-                    0f,
-                    KeyguardQuickAffordancesCombinedViewModel
-                        .AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD - 0.1f
-                ),
-            )
 
             val testConfig =
                 TestConfig(
@@ -561,9 +655,10 @@
     @Test
     fun isClickable_falseWhenAlphaAtZero() =
         testScope.runTest {
+            intendedAlphaMutableStateFlow.value = 0f
+            intendedShadeAlphaMutableStateFlow.value = 1f
             repository.setKeyguardShowing(true)
             val latest = collectLastValue(underTest.startButton)
-            repository.setKeyguardAlpha(0f)
 
             val testConfig =
                 TestConfig(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index e6d6cf2..a57feda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -163,23 +163,6 @@
         }
 
     @Test
-    fun alpha_inPreviewMode_doesNotChange() =
-        testScope.runTest {
-            val value = collectLastValue(underTest.alpha)
-            underTest.enablePreviewMode()
-
-            assertThat(value()).isEqualTo(1f)
-            repository.setKeyguardAlpha(0.1f)
-            assertThat(value()).isEqualTo(1f)
-            repository.setKeyguardAlpha(0.5f)
-            assertThat(value()).isEqualTo(1f)
-            repository.setKeyguardAlpha(0.2f)
-            assertThat(value()).isEqualTo(1f)
-            repository.setKeyguardAlpha(0f)
-            assertThat(value()).isEqualTo(1f)
-        }
-
-    @Test
     fun translationAndScaleFromBurnInNotDozing() =
         testScope.runTest {
             val translationX by collectLastValue(underTest.translationX)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index d6e2e97..2f35380 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -61,7 +61,6 @@
 import com.android.internal.logging.InstanceId
 import com.android.internal.widget.CachingIconView
 import com.android.systemui.ActivityIntentHelper
-import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.bluetooth.BroadcastDialogController
 import com.android.systemui.broadcast.BroadcastSender
@@ -81,12 +80,14 @@
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
 import com.android.systemui.media.controls.pipeline.EMPTY_SMARTSPACE_MEDIA_DATA
 import com.android.systemui.media.controls.pipeline.MediaDataManager
+import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.media.controls.util.MediaUiEventLogger
 import com.android.systemui.media.dialog.MediaOutputDialogFactory
 import com.android.systemui.monet.ColorScheme
 import com.android.systemui.monet.Style
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.surfaceeffects.ripple.MultiRippleView
@@ -232,6 +233,7 @@
             this.set(Flags.UMO_TURBULENCE_NOISE, false)
         }
     @Mock private lateinit var globalSettings: GlobalSettings
+    @Mock private lateinit var mediaFlags: MediaFlags
 
     @JvmField @Rule val mockito = MockitoJUnit.rule()
 
@@ -251,6 +253,7 @@
             .thenReturn(applicationInfo)
         whenever(packageManager.getApplicationLabel(any())).thenReturn(PACKAGE)
         context.setMockPackageManager(packageManager)
+        whenever(mediaFlags.isSceneContainerEnabled()).thenReturn(false)
 
         player =
             object :
@@ -273,7 +276,8 @@
                     lockscreenUserManager,
                     broadcastDialogController,
                     fakeFeatureFlag,
-                    globalSettings
+                    globalSettings,
+                    mediaFlags,
                 ) {
                 override fun loadAnimator(
                     animId: Int,
@@ -1884,7 +1888,8 @@
     @Test
     fun bindRecommendation_listHasTooFewRecs_notDisplayed() {
         player.attachRecommendation(recommendationViewHolder)
-        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
+        val icon =
+            Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
         val data =
             smartspaceData.copy(
                 recommendations =
@@ -1911,7 +1916,8 @@
     @Test
     fun bindRecommendation_listHasTooFewRecsWithIcons_notDisplayed() {
         player.attachRecommendation(recommendationViewHolder)
-        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
+        val icon =
+            Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
         val data =
             smartspaceData.copy(
                 recommendations =
@@ -1955,7 +1961,8 @@
         val subtitle1 = "Subtitle1"
         val subtitle2 = "Subtitle2"
         val subtitle3 = "Subtitle3"
-        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
+        val icon =
+            Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
 
         val data =
             smartspaceData.copy(
@@ -1998,7 +2005,12 @@
                     listOf(
                         SmartspaceAction.Builder("id1", "")
                             .setSubtitle("fake subtitle")
-                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata))
+                            .setIcon(
+                                Icon.createWithResource(
+                                    context,
+                                    com.android.settingslib.R.drawable.ic_1x_mobiledata
+                                )
+                            )
                             .setExtras(Bundle.EMPTY)
                             .build()
                     )
@@ -2013,7 +2025,8 @@
         useRealConstraintSets()
         player.attachRecommendation(recommendationViewHolder)
 
-        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
+        val icon =
+            Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
         val data =
             smartspaceData.copy(
                 recommendations =
@@ -2047,7 +2060,8 @@
         useRealConstraintSets()
         player.attachRecommendation(recommendationViewHolder)
 
-        val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
+        val icon =
+            Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)
         val data =
             smartspaceData.copy(
                 recommendations =
@@ -2086,7 +2100,12 @@
                     listOf(
                         SmartspaceAction.Builder("id1", "title1")
                             .setSubtitle("")
-                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata))
+                            .setIcon(
+                                Icon.createWithResource(
+                                    context,
+                                    com.android.settingslib.R.drawable.ic_1x_mobiledata
+                                )
+                            )
                             .setExtras(Bundle.EMPTY)
                             .build(),
                         SmartspaceAction.Builder("id2", "title2")
@@ -2096,7 +2115,12 @@
                             .build(),
                         SmartspaceAction.Builder("id3", "title3")
                             .setSubtitle("")
-                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_3g_mobiledata))
+                            .setIcon(
+                                Icon.createWithResource(
+                                    context,
+                                    com.android.settingslib.R.drawable.ic_3g_mobiledata
+                                )
+                            )
                             .setExtras(Bundle.EMPTY)
                             .build()
                     )
@@ -2119,7 +2143,12 @@
                     listOf(
                         SmartspaceAction.Builder("id1", "")
                             .setSubtitle("subtitle1")
-                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata))
+                            .setIcon(
+                                Icon.createWithResource(
+                                    context,
+                                    com.android.settingslib.R.drawable.ic_1x_mobiledata
+                                )
+                            )
                             .setExtras(Bundle.EMPTY)
                             .build(),
                         SmartspaceAction.Builder("id2", "")
@@ -2129,7 +2158,12 @@
                             .build(),
                         SmartspaceAction.Builder("id3", "")
                             .setSubtitle("subtitle3")
-                            .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_3g_mobiledata))
+                            .setIcon(
+                                Icon.createWithResource(
+                                    context,
+                                    com.android.settingslib.R.drawable.ic_3g_mobiledata
+                                )
+                            )
                             .setExtras(Bundle.EMPTY)
                             .build()
                     )
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 db7c987..73885f4 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
@@ -32,6 +32,7 @@
 import com.android.systemui.dreams.DreamOverlayStateController
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.media.controls.pipeline.MediaDataManager
+import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.media.dream.MediaDreamComplication
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.res.R
@@ -94,6 +95,7 @@
     @Mock private lateinit var dreamOverlayStateController: DreamOverlayStateController
     @Mock private lateinit var shadeInteractor: ShadeInteractor
     @Mock lateinit var logger: MediaViewLogger
+    @Mock private lateinit var mediaFlags: MediaFlags
     @Captor
     private lateinit var wakefullnessObserver: ArgumentCaptor<(WakefulnessLifecycle.Observer)>
     @Captor
@@ -126,6 +128,7 @@
         whenever(mediaCarouselController.mediaFrame).thenReturn(mediaFrame)
         isQsBypassingShade = MutableStateFlow(false)
         whenever(shadeInteractor.isQsBypassingShade).thenReturn(isQsBypassingShade)
+        whenever(mediaFlags.isSceneContainerEnabled()).thenReturn(false)
         mediaHierarchyManager =
             MediaHierarchyManager(
                 context,
@@ -145,6 +148,7 @@
                 testScope.backgroundScope,
                 ResourcesSplitShadeStateController(),
                 logger,
+                mediaFlags,
             )
         verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
         verify(statusBarStateController).addCallback(statusBarCallback.capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt
index a9f8ea0..81d02b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt
@@ -85,7 +85,7 @@
         `when`(sharedPreferences.edit()).thenReturn(editor)
 
         tile = Tile()
-        customTileStatePersister = CustomTileStatePersister(mockContext)
+        customTileStatePersister = CustomTileStatePersisterImpl(mockContext)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt
index 3808c7e..313ccb8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt
@@ -228,16 +228,16 @@
                 showPairNewDevice = true
             )
 
-            val seeAllLayout = bluetoothTileDialog.requireViewById<View>(R.id.see_all_layout_group)
-            val pairNewLayout =
-                bluetoothTileDialog.requireViewById<View>(R.id.pair_new_device_layout_group)
+            val seeAllButton = bluetoothTileDialog.requireViewById<View>(R.id.see_all_button)
+            val pairNewButton =
+                bluetoothTileDialog.requireViewById<View>(R.id.pair_new_device_button)
             val recyclerView = bluetoothTileDialog.requireViewById<RecyclerView>(R.id.device_list)
             val adapter = recyclerView?.adapter as BluetoothTileDialog.Adapter
 
-            assertThat(seeAllLayout).isNotNull()
-            assertThat(seeAllLayout.visibility).isEqualTo(GONE)
-            assertThat(pairNewLayout).isNotNull()
-            assertThat(pairNewLayout.visibility).isEqualTo(VISIBLE)
+            assertThat(seeAllButton).isNotNull()
+            assertThat(seeAllButton.visibility).isEqualTo(GONE)
+            assertThat(pairNewButton).isNotNull()
+            assertThat(pairNewButton.visibility).isEqualTo(VISIBLE)
             assertThat(adapter.itemCount).isEqualTo(1)
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt
index fb5dd21..99993f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.time.FakeSystemClock
-import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -113,9 +112,7 @@
         testScope.runTest {
             bluetoothTileDialogViewModel.showDialog(context, null)
 
-            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
             verify(dialogLaunchAnimator, never()).showFromView(any(), any(), any(), any())
-            assertThat(bluetoothTileDialogViewModel.dialog?.isShowing).isTrue()
             verify(uiEventLogger).log(BluetoothTileDialogUiEvent.BLUETOOTH_TILE_DIALOG_SHOWN)
         }
     }
@@ -125,7 +122,6 @@
         testScope.runTest {
             bluetoothTileDialogViewModel.showDialog(mContext, LinearLayout(mContext))
 
-            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
             verify(dialogLaunchAnimator).showFromView(any(), any(), nullable(), anyBoolean())
         }
     }
@@ -136,7 +132,6 @@
             backgroundExecutor.execute {
                 bluetoothTileDialogViewModel.showDialog(mContext, LinearLayout(mContext))
 
-                assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
                 verify(dialogLaunchAnimator).showFromView(any(), any(), nullable(), anyBoolean())
             }
         }
@@ -147,7 +142,6 @@
         testScope.runTest {
             bluetoothTileDialogViewModel.showDialog(context, null)
 
-            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
             verify(deviceItemInteractor).deviceItemUpdate
         }
     }
@@ -157,7 +151,6 @@
         testScope.runTest {
             bluetoothTileDialogViewModel.showDialog(context, null)
 
-            assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
             verify(bluetoothStateInteractor).bluetoothStateUpdate
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt
index 4c173cc..e236f4a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt
@@ -220,45 +220,57 @@
 
     @Test
     fun testUpdateDeviceItemOnClick_connectedMedia_setActive() {
-        `when`(deviceItem1.type).thenReturn(DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE)
+        testScope.runTest {
+            `when`(deviceItem1.type).thenReturn(DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE)
 
-        interactor.updateDeviceItemOnClick(deviceItem1)
+            interactor.updateDeviceItemOnClick(deviceItem1)
 
-        verify(cachedDevice1).setActive()
-        verify(logger)
-            .logDeviceClick(cachedDevice1.address, DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE)
+            verify(cachedDevice1).setActive()
+            verify(logger)
+                .logDeviceClick(
+                    cachedDevice1.address,
+                    DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE
+                )
+        }
     }
 
     @Test
     fun testUpdateDeviceItemOnClick_activeMedia_disconnect() {
-        `when`(deviceItem1.type).thenReturn(DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
+        testScope.runTest {
+            `when`(deviceItem1.type).thenReturn(DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
 
-        interactor.updateDeviceItemOnClick(deviceItem1)
+            interactor.updateDeviceItemOnClick(deviceItem1)
 
-        verify(cachedDevice1).disconnect()
-        verify(logger)
-            .logDeviceClick(cachedDevice1.address, DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
+            verify(cachedDevice1).disconnect()
+            verify(logger)
+                .logDeviceClick(cachedDevice1.address, DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
+        }
     }
 
     @Test
     fun testUpdateDeviceItemOnClick_connectedOtherDevice_disconnect() {
-        `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+        testScope.runTest {
+            `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
 
-        interactor.updateDeviceItemOnClick(deviceItem1)
+            interactor.updateDeviceItemOnClick(deviceItem1)
 
-        verify(cachedDevice1).disconnect()
-        verify(logger)
-            .logDeviceClick(cachedDevice1.address, DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+            verify(cachedDevice1).disconnect()
+            verify(logger)
+                .logDeviceClick(cachedDevice1.address, DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+        }
     }
 
     @Test
     fun testUpdateDeviceItemOnClick_saved_connect() {
-        `when`(deviceItem1.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE)
+        testScope.runTest {
+            `when`(deviceItem1.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE)
 
-        interactor.updateDeviceItemOnClick(deviceItem1)
+            interactor.updateDeviceItemOnClick(deviceItem1)
 
-        verify(cachedDevice1).connect()
-        verify(logger).logDeviceClick(cachedDevice1.address, DeviceItemType.SAVED_BLUETOOTH_DEVICE)
+            verify(cachedDevice1).connect()
+            verify(logger)
+                .logDeviceClick(cachedDevice1.address, DeviceItemType.SAVED_BLUETOOTH_DEVICE)
+        }
     }
 
     private fun createFactory(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
index 5969bd8..0173c32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt
@@ -27,6 +27,7 @@
 import com.android.systemui.flags.ResourceBooleanFlag
 import com.android.systemui.flags.UnreleasedFlag
 import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl
+import com.android.systemui.res.R
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Rule
@@ -74,10 +75,15 @@
             .forEach { flagToken ->
                 setFlagsRule.enableFlags(flagToken)
                 aconfigFlags.setFlag(flagToken, testCase.areAllFlagsSet)
+                overrideResource(
+                    R.bool.config_sceneContainerFrameworkEnabled,
+                    testCase.isResourceConfigEnabled
+                )
             }
 
         underTest =
             SceneContainerFlagsImpl(
+                context = context,
                 featureFlagsClassic = featureFlags,
                 isComposeAvailable = testCase.isComposeAvailable,
             )
@@ -91,13 +97,12 @@
     internal data class TestCase(
         val isComposeAvailable: Boolean,
         val areAllFlagsSet: Boolean,
+        val isResourceConfigEnabled: Boolean,
         val expectedEnabled: Boolean,
     ) {
         override fun toString(): String {
-            return """
-                (compose=$isComposeAvailable + flags=$areAllFlagsSet) -> expected=$expectedEnabled
-            """
-                .trimIndent()
+            return "(compose=$isComposeAvailable + flags=$areAllFlagsSet) + XML" +
+                " config=$isResourceConfigEnabled -> expected=$expectedEnabled"
         }
     }
 
@@ -105,17 +110,20 @@
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
         fun testCases() = buildList {
-            repeat(4) { combination ->
-                val isComposeAvailable = combination and 0b10 != 0
-                val areAllFlagsSet = combination and 0b01 != 0
+            repeat(8) { combination ->
+                val isComposeAvailable = combination and 0b100 != 0
+                val areAllFlagsSet = combination and 0b010 != 0
+                val isResourceConfigEnabled = combination and 0b001 != 0
 
-                val expectedEnabled = isComposeAvailable && areAllFlagsSet
+                val expectedEnabled =
+                    isComposeAvailable && areAllFlagsSet && isResourceConfigEnabled
 
                 add(
                     TestCase(
                         isComposeAvailable = isComposeAvailable,
                         areAllFlagsSet = areAllFlagsSet,
                         expectedEnabled = expectedEnabled,
+                        isResourceConfigEnabled = isResourceConfigEnabled,
                     )
                 )
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
index 6e487cd..88c728f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
@@ -28,12 +28,16 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.activity.SingleActivityFactory
 import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
+import dagger.Lazy
+import kotlinx.coroutines.flow.MutableStateFlow
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
@@ -55,6 +59,8 @@
     @Mock private lateinit var brightnessControllerFactory: BrightnessController.Factory
     @Mock private lateinit var brightnessController: BrightnessController
     @Mock private lateinit var accessibilityMgr: AccessibilityManagerWrapper
+    @Mock private lateinit var shadeInteractorLazy: Lazy<ShadeInteractor>
+    @Mock private lateinit var shadeInteractor: ShadeInteractor
 
     private val clock = FakeSystemClock()
     private val mainExecutor = FakeExecutor(clock)
@@ -68,7 +74,8 @@
                     brightnessSliderControllerFactory,
                     brightnessControllerFactory,
                     mainExecutor,
-                    accessibilityMgr
+                    accessibilityMgr,
+                    shadeInteractor
                 )
             },
             /* initialTouchMode= */ false,
@@ -82,6 +89,8 @@
             .thenReturn(brightnessSliderController)
         `when`(brightnessSliderController.rootView).thenReturn(View(context))
         `when`(brightnessControllerFactory.create(any())).thenReturn(brightnessController)
+        whenever(shadeInteractorLazy.get()).thenReturn(shadeInteractor)
+        whenever(shadeInteractor.isQsExpanded).thenReturn(MutableStateFlow(false))
     }
 
     @After
@@ -175,13 +184,15 @@
         brightnessSliderControllerFactory: BrightnessSliderController.Factory,
         brightnessControllerFactory: BrightnessController.Factory,
         mainExecutor: DelayableExecutor,
-        accessibilityMgr: AccessibilityManagerWrapper
+        accessibilityMgr: AccessibilityManagerWrapper,
+        shadeInteractor: ShadeInteractor
     ) :
         BrightnessDialog(
             brightnessSliderControllerFactory,
             brightnessControllerFactory,
             mainExecutor,
-            accessibilityMgr
+            accessibilityMgr,
+            shadeInteractor
         ) {
         private var finishing = false
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
new file mode 100644
index 0000000..ce47170
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy
+
+import android.hardware.devicestate.DeviceStateManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableResources
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_FLIPPED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_HALF_OPENED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN
+import com.android.systemui.statusbar.policy.DevicePostureController.SUPPORTED_POSTURES_SIZE
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class DevicePostureControllerImplTest : SysuiTestCase() {
+    private val useBaseStateDeviceState = SUPPORTED_POSTURES_SIZE
+    private val deviceStateToPostureMapping =
+        arrayOf(
+            "$DEVICE_POSTURE_UNKNOWN:$DEVICE_POSTURE_UNKNOWN",
+            "$DEVICE_POSTURE_CLOSED:$DEVICE_POSTURE_CLOSED",
+            "$DEVICE_POSTURE_HALF_OPENED:$DEVICE_POSTURE_HALF_OPENED",
+            "$DEVICE_POSTURE_OPENED:$DEVICE_POSTURE_OPENED",
+            "$DEVICE_POSTURE_FLIPPED:$DEVICE_POSTURE_FLIPPED",
+            "$useBaseStateDeviceState:1000"
+        )
+    @Mock private lateinit var deviceStateManager: DeviceStateManager
+    @Captor
+    private lateinit var deviceStateCallback: ArgumentCaptor<DeviceStateManager.DeviceStateCallback>
+
+    private lateinit var mainExecutor: FakeExecutor
+    private lateinit var testableResources: TestableResources
+    private lateinit var underTest: DevicePostureControllerImpl
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        mainExecutor = FakeExecutor(FakeSystemClock())
+        testableResources = context.getOrCreateTestableResources()
+        testableResources.addOverride(
+            com.android.internal.R.array.config_device_state_postures,
+            deviceStateToPostureMapping
+        )
+        underTest =
+            DevicePostureControllerImpl(
+                context,
+                deviceStateManager,
+                mainExecutor,
+            )
+        verifyRegistersForDeviceStateCallback()
+    }
+
+    @Test
+    fun testPostureChanged_updates() {
+        var posture = -1
+        underTest.addCallback { posture = it }
+
+        deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_UNKNOWN)
+        assertThat(posture).isEqualTo(DEVICE_POSTURE_UNKNOWN)
+
+        deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_CLOSED)
+        assertThat(posture).isEqualTo(DEVICE_POSTURE_CLOSED)
+
+        deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_HALF_OPENED)
+        assertThat(posture).isEqualTo(DEVICE_POSTURE_HALF_OPENED)
+
+        deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_OPENED)
+        assertThat(posture).isEqualTo(DEVICE_POSTURE_OPENED)
+
+        deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_FLIPPED)
+        assertThat(posture).isEqualTo(DEVICE_POSTURE_FLIPPED)
+    }
+
+    @Test
+    fun testPostureChanged_useBaseUpdate() {
+        var posture = -1
+        underTest.addCallback { posture = it }
+
+        deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_HALF_OPENED)
+        assertThat(posture).isEqualTo(DEVICE_POSTURE_HALF_OPENED)
+
+        // base state change doesn't change the posture
+        deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_CLOSED)
+        assertThat(posture).isEqualTo(DEVICE_POSTURE_HALF_OPENED)
+
+        // WHEN the display state maps to using the base state, then posture updates
+        deviceStateCallback.value.onStateChanged(useBaseStateDeviceState)
+        assertThat(posture).isEqualTo(DEVICE_POSTURE_CLOSED)
+    }
+
+    @Test
+    fun baseStateChanges_doesNotUpdatePosture() {
+        var numPostureChanges = 0
+        underTest.addCallback { numPostureChanges++ }
+
+        deviceStateCallback.value.onStateChanged(DEVICE_POSTURE_HALF_OPENED)
+        assertThat(numPostureChanges).isEqualTo(1)
+
+        // base state changes doesn't send another posture update since the device state isn't
+        // useBaseStateDeviceState
+        deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_CLOSED)
+        deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_HALF_OPENED)
+        deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_FLIPPED)
+        deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_OPENED)
+        deviceStateCallback.value.onBaseStateChanged(DEVICE_POSTURE_UNKNOWN)
+        assertThat(numPostureChanges).isEqualTo(1)
+    }
+
+    private fun verifyRegistersForDeviceStateCallback() {
+        verify(deviceStateManager).registerCallback(eq(mainExecutor), deviceStateCallback.capture())
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
new file mode 100644
index 0000000..4e61b89
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold.progress
+
+import android.os.Looper
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.utils.os.FakeHandler
+import kotlin.test.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@RunWithLooper(setAsMainLooper = true)
+class MainThreadUnfoldTransitionProgressProviderTest : SysuiTestCase() {
+
+    private val wrappedProgressProvider = TestUnfoldTransitionProvider()
+    private val fakeHandler = FakeHandler(Looper.getMainLooper())
+    private val listener = TestUnfoldProgressListener()
+
+    private val progressProvider =
+        MainThreadUnfoldTransitionProgressProvider(fakeHandler, wrappedProgressProvider)
+
+    @Test
+    fun onTransitionStarted_propagated() {
+        progressProvider.addCallback(listener)
+
+        wrappedProgressProvider.onTransitionStarted()
+        fakeHandler.dispatchQueuedMessages()
+
+        listener.assertStarted()
+    }
+
+    @Test
+    fun onTransitionProgress_propagated() {
+        progressProvider.addCallback(listener)
+
+        wrappedProgressProvider.onTransitionStarted()
+        wrappedProgressProvider.onTransitionProgress(0.5f)
+        fakeHandler.dispatchQueuedMessages()
+
+        listener.assertLastProgress(0.5f)
+    }
+
+    @Test
+    fun onTransitionFinished_propagated() {
+        progressProvider.addCallback(listener)
+
+        wrappedProgressProvider.onTransitionStarted()
+        wrappedProgressProvider.onTransitionProgress(0.5f)
+        wrappedProgressProvider.onTransitionFinished()
+        fakeHandler.dispatchQueuedMessages()
+
+        listener.ensureTransitionFinished()
+    }
+
+    @Test
+    fun onTransitionFinishing_propagated() {
+        progressProvider.addCallback(listener)
+
+        wrappedProgressProvider.onTransitionStarted()
+        wrappedProgressProvider.onTransitionProgress(0.5f)
+        wrappedProgressProvider.onTransitionFinished()
+        fakeHandler.dispatchQueuedMessages()
+
+        listener.ensureTransitionFinished()
+    }
+
+    @Test
+    fun onTransitionStarted_afterCallbackRemoved_notPropagated() {
+        progressProvider.addCallback(listener)
+        progressProvider.removeCallback(listener)
+
+        wrappedProgressProvider.onTransitionStarted()
+        fakeHandler.dispatchQueuedMessages()
+
+        listener.assertNotStarted()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
index 9fe2f56..14fb054 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
@@ -15,9 +15,10 @@
  */
 package com.android.systemui.unfold.progress
 
+import android.os.Handler
+import android.os.HandlerThread
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import androidx.test.platform.app.InstrumentationRegistry
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider
 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
@@ -26,6 +27,8 @@
 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING
 import com.android.systemui.unfold.util.TestFoldStateProvider
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -37,16 +40,28 @@
     private val foldStateProvider: TestFoldStateProvider = TestFoldStateProvider()
     private val listener = TestUnfoldProgressListener()
     private lateinit var progressProvider: UnfoldTransitionProgressProvider
+    private val schedulerFactory =
+        mock<UnfoldFrameCallbackScheduler.Factory>().apply {
+            whenever(create()).then { UnfoldFrameCallbackScheduler() }
+        }
+    private val mockBgHandler = mock<Handler>()
+    private val fakeHandler = Handler(HandlerThread("UnfoldBg").apply { start() }.looper)
 
     @Before
     fun setUp() {
-        progressProvider = PhysicsBasedUnfoldTransitionProgressProvider(context, foldStateProvider)
+        progressProvider =
+            PhysicsBasedUnfoldTransitionProgressProvider(
+                context,
+                schedulerFactory,
+                foldStateProvider = foldStateProvider,
+                progressHandler = fakeHandler
+            )
         progressProvider.addCallback(listener)
     }
 
     @Test
     fun testUnfold_emitsIncreasingTransitionEvents() {
-        runOnMainThreadWithInterval(
+        runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
             { foldStateProvider.sendUnfoldedScreenAvailable() },
@@ -63,7 +78,7 @@
 
     @Test
     fun testUnfold_emitsFinishingEvent() {
-        runOnMainThreadWithInterval(
+        runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
             { foldStateProvider.sendUnfoldedScreenAvailable() },
@@ -77,7 +92,7 @@
 
     @Test
     fun testUnfold_screenAvailableOnlyAfterFullUnfold_emitsIncreasingTransitionEvents() {
-        runOnMainThreadWithInterval(
+        runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
             { foldStateProvider.sendHingeAngleUpdate(90f) },
@@ -94,7 +109,7 @@
 
     @Test
     fun testFold_emitsDecreasingTransitionEvents() {
-        runOnMainThreadWithInterval(
+        runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_CLOSING) },
             { foldStateProvider.sendHingeAngleUpdate(170f) },
             { foldStateProvider.sendHingeAngleUpdate(90f) },
@@ -110,7 +125,7 @@
 
     @Test
     fun testUnfoldAndStopUnfolding_finishesTheUnfoldTransition() {
-        runOnMainThreadWithInterval(
+        runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
             { foldStateProvider.sendUnfoldedScreenAvailable() },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
@@ -126,7 +141,7 @@
 
     @Test
     fun testFoldImmediatelyAfterUnfold_runsFoldAnimation() {
-        runOnMainThreadWithInterval(
+        runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
             { foldStateProvider.sendUnfoldedScreenAvailable() },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
@@ -144,9 +159,12 @@
         with(listener.ensureTransitionFinished()) { assertHasFoldAnimationAtTheEnd() }
     }
 
-    private fun runOnMainThreadWithInterval(vararg blocks: () -> Unit, intervalMillis: Long = 60) {
+    private fun runOnProgressThreadWithInterval(
+        vararg blocks: () -> Unit,
+        intervalMillis: Long = 60,
+    ) {
         blocks.forEach {
-            InstrumentationRegistry.getInstrumentation().runOnMainSync { it() }
+            fakeHandler.post(it)
             Thread.sleep(intervalMillis)
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index aa49287..552b60c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
-import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.fail
 import java.util.concurrent.Executor
@@ -105,16 +104,15 @@
 
         foldStateProvider =
             DeviceFoldStateProvider(
-                config,
-                testHingeAngleProvider,
-                screenOnStatusProvider,
-                foldProvider,
-                activityTypeProvider,
-                unfoldKeyguardVisibilityProvider,
-                rotationChangeProvider,
-                context,
-                context.mainExecutor,
-                handler
+                    config,
+                    context,
+                    screenOnStatusProvider,
+                    activityTypeProvider,
+                    unfoldKeyguardVisibilityProvider,
+                    foldProvider,
+                    testHingeAngleProvider,
+                    rotationChangeProvider,
+                    handler
             )
 
         foldStateProvider.addCallback(
@@ -151,6 +149,12 @@
             null
         }
 
+        whenever(handler.post(any<Runnable>())).then { invocationOnMock ->
+            val runnable = invocationOnMock.getArgument<Runnable>(0)
+            runnable.run()
+            null
+        }
+
         // By default, we're on launcher.
         setupForegroundActivityType(isHomeActivity = true)
         setIsLargeScreen(true)
@@ -171,7 +175,7 @@
     }
 
     @Test
-    fun testOnUnfold_hingeAngleDecreasesBeforeInnerScreenAvailable_emitsOnlyStartAndInnerScreenAvailableEvents() {
+    fun onUnfold_angleDecrBeforeInnerScrAvailable_emitsOnlyStartAndInnerScrAvailableEvents() {
         setFoldState(folded = true)
         foldUpdates.clear()
 
@@ -187,7 +191,7 @@
     }
 
     @Test
-    fun testOnUnfold_hingeAngleDecreasesAfterInnerScreenAvailable_emitsStartInnerScreenAvailableAndStartClosingEvents() {
+    fun onUnfold_angleDecrAfterInnerScrAvailable_emitsStartInnerScrAvailableAndStartClosingEvnts() {
         setFoldState(folded = true)
         foldUpdates.clear()
 
@@ -690,7 +694,7 @@
             callbacks.forEach { it.onFoldUpdated(isFolded) }
         }
 
-        fun getNumberOfCallbacks(): Int{
+        fun getNumberOfCallbacks(): Int {
             return callbacks.size
         }
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
index f57ace9..b28af46 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
@@ -29,7 +29,9 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.ScreenLifecycle
 import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.dagger.BiometricLog
 import com.android.systemui.log.dagger.BroadcastDispatcherLog
 import com.android.systemui.log.dagger.SceneFrameworkLog
 import com.android.systemui.media.controls.ui.MediaHierarchyManager
@@ -54,6 +56,7 @@
 import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController
 import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.statusbar.phone.SystemUIDialogManager
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.statusbar.policy.ZenModeController
 import com.android.systemui.statusbar.window.StatusBarWindowController
@@ -106,12 +109,16 @@
     val unfoldTransitionProgressProvider: Optional<UnfoldTransitionProgressProvider> =
         Optional.empty(),
     @get:Provides val zenModeController: ZenModeController = mock(),
+    @get:Provides val systemUIDialogManager: SystemUIDialogManager = mock(),
+    @get:Provides val deviceEntryIconTransitions: Set<DeviceEntryIconTransition> = emptySet(),
 
     // log buffers
     @get:[Provides BroadcastDispatcherLog]
     val broadcastDispatcherLogger: LogBuffer = mock(),
     @get:[Provides SceneFrameworkLog]
     val sceneLogger: LogBuffer = mock(),
+    @get:[Provides BiometricLog]
+    val biometricLogger: LogBuffer = mock(),
     @get:Provides val lsShadeTransitionLogger: LSShadeTransitionLogger = mock(),
 
     // framework mocks
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt
index 8c653a5..ce52f4b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.bouncer.data.repository.FakeBouncerDataLayerModule
 import com.android.systemui.common.ui.data.FakeCommonDataLayerModule
 import com.android.systemui.deviceentry.data.FakeDeviceEntryDataLayerModule
+import com.android.systemui.keyevent.data.repository.FakeKeyEventDataLayerModule
 import com.android.systemui.keyguard.data.FakeKeyguardDataLayerModule
 import com.android.systemui.power.data.FakePowerDataLayerModule
 import com.android.systemui.shade.data.repository.FakeShadeDataLayerModule
@@ -44,6 +45,7 @@
             FakeStatusBarDataLayerModule::class,
             FakeTelephonyDataLayerModule::class,
             FakeUserDataLayerModule::class,
+            FakeKeyEventDataLayerModule::class,
         ]
 )
 object FakeSystemUiDataLayerModule
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt
index 8ff04a63..d97cb56 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.deviceentry.data
 
 import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepositoryModule
+import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryHapticsRepositoryModule
 import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepositoryModule
 import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepositoryModule
 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepositoryModule
@@ -28,6 +29,7 @@
         [
             FakeBiometricSettingsRepositoryModule::class,
             FakeDeviceEntryRepositoryModule::class,
+            FakeDeviceEntryHapticsRepositoryModule::class,
             FakeDeviceEntryFaceAuthRepositoryModule::class,
             FakeDeviceEntryFingerprintAuthRepositoryModule::class,
             FakeFingerprintPropertyRepositoryModule::class,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryHapticsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryHapticsRepository.kt
new file mode 100644
index 0000000..b29b67d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryHapticsRepository.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.deviceentry.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/** Fake implementation of [DeviceEntryHapticsRepository] */
+@SysUISingleton
+class FakeDeviceEntryHapticsRepository @Inject constructor() : DeviceEntryHapticsRepository {
+    private var _successHapticRequest: MutableStateFlow<Boolean> = MutableStateFlow(false)
+    override val successHapticRequest: Flow<Boolean> = _successHapticRequest.asStateFlow()
+
+    private var _errorHapticRequest: MutableStateFlow<Boolean> = MutableStateFlow(false)
+    override val errorHapticRequest: Flow<Boolean> = _errorHapticRequest.asStateFlow()
+
+    override fun requestSuccessHaptic() {
+        _successHapticRequest.value = true
+    }
+
+    override fun handleSuccessHaptic() {
+        _successHapticRequest.value = false
+    }
+
+    override fun requestErrorHaptic() {
+        _errorHapticRequest.value = true
+    }
+
+    override fun handleErrorHaptic() {
+        _errorHapticRequest.value = false
+    }
+}
+
+@Module
+interface FakeDeviceEntryHapticsRepositoryModule {
+    @Binds fun bindFake(fake: FakeDeviceEntryHapticsRepository): DeviceEntryHapticsRepository
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventDataLayerModule.kt
similarity index 80%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryDataLayerModule.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventDataLayerModule.kt
index f4feee1..191bccc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryDataLayerModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventDataLayerModule.kt
@@ -13,8 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.deviceentry.data.repository
+
+package com.android.systemui.keyevent.data.repository
 
 import dagger.Module
 
-@Module(includes = [FakeDeviceEntryRepositoryModule::class]) object FakeDeviceEntryDataLayerModule
+@Module(includes = [FakeKeyEventRepositoryModule::class]) object FakeKeyEventDataLayerModule
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventRepository.kt
index 95b5316..97dab49 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyevent/data/repository/FakeKeyEventRepository.kt
@@ -16,11 +16,14 @@
 
 package com.android.systemui.keyevent.data.repository
 
+import dagger.Binds
+import dagger.Module
+import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
 
-class FakeKeyEventRepository() : KeyEventRepository {
+class FakeKeyEventRepository @Inject constructor() : KeyEventRepository {
     private val _isPowerButtonDown = MutableStateFlow(false)
     override val isPowerButtonDown: Flow<Boolean> = _isPowerButtonDown.asStateFlow()
 
@@ -28,3 +31,8 @@
         _isPowerButtonDown.value = isDown
     }
 }
+
+@Module
+interface FakeKeyEventRepositoryModule {
+    @Binds fun bindFake(fake: FakeKeyEventRepository): KeyEventRepository
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/FakeCustomTileStatePersister.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/FakeCustomTileStatePersister.kt
new file mode 100644
index 0000000..29702eb
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/external/FakeCustomTileStatePersister.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.external
+
+import android.service.quicksettings.Tile
+
+class FakeCustomTileStatePersister : CustomTileStatePersister {
+
+    private val tiles: MutableMap<TileServiceKey, Tile> = mutableMapOf()
+
+    override fun readState(key: TileServiceKey): Tile? = tiles[key]
+
+    override fun persistState(key: TileServiceKey, tile: Tile) {
+        tiles[key] = tile
+    }
+
+    override fun removeState(key: TileServiceKey) {
+        tiles.remove(key)
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/TileSubject.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/TileSubject.kt
new file mode 100644
index 0000000..d2351dc
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/TileSubject.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.custom
+
+import android.service.quicksettings.Tile
+import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat
+import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.tiles
+import com.google.common.truth.FailureMetadata
+import com.google.common.truth.Subject
+import com.google.common.truth.Subject.Factory
+import com.google.common.truth.Truth
+
+/**
+ * [Tile]-specific extension for [Truth]. Use [assertThat] or [tiles] to get an instance of this
+ * subject.
+ */
+class TileSubject private constructor(failureMetadata: FailureMetadata, subject: Tile?) :
+    Subject(failureMetadata, subject) {
+
+    private val actual: Tile? = subject
+
+    /** Asserts if the [Tile] fields are the same. */
+    fun isEqualTo(other: Tile?) {
+        if (actual == null) {
+            check("other").that(other).isNull()
+            return
+        } else {
+            check("other").that(other).isNotNull()
+            other ?: return
+        }
+
+        check("icon").that(actual.icon).isEqualTo(other.icon)
+        check("label").that(actual.label).isEqualTo(other.label)
+        check("subtitle").that(actual.subtitle).isEqualTo(other.subtitle)
+        check("contentDescription")
+            .that(actual.contentDescription)
+            .isEqualTo(other.contentDescription)
+        check("stateDescription").that(actual.stateDescription).isEqualTo(other.stateDescription)
+        check("activityLaunchForClick")
+            .that(actual.activityLaunchForClick)
+            .isEqualTo(other.activityLaunchForClick)
+        check("state").that(actual.state).isEqualTo(other.state)
+    }
+
+    companion object {
+
+        /** Returns a factory to be used with [Truth.assertAbout]. */
+        fun tiles(): Factory<TileSubject, Tile?> {
+            return Factory { failureMetadata: FailureMetadata, subject: Tile? ->
+                TileSubject(failureMetadata, subject)
+            }
+        }
+
+        /** Shortcut for `Truth.assertAbout(tiles()).that(tile)`. */
+        fun assertThat(tile: Tile?): TileSubject = Truth.assertAbout(tiles()).that(tile)
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt
index 13910fd..ccba072 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt
@@ -19,15 +19,20 @@
 import android.content.ComponentName
 import android.os.UserHandle
 import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import kotlinx.coroutines.channels.BufferOverflow
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.mapNotNull
 
 class FakeCustomTileDefaultsRepository : CustomTileDefaultsRepository {
 
     private val defaults: MutableMap<DefaultsKey, CustomTileDefaults> = mutableMapOf()
-    private val defaultsFlow = MutableSharedFlow<DefaultsRequest>()
+    private val defaultsFlow =
+        MutableSharedFlow<DefaultsRequest>(
+            replay = 1,
+            onBufferOverflow = BufferOverflow.DROP_OLDEST
+        )
 
     private val mutableDefaultsRequests: MutableList<DefaultsRequest> = mutableListOf()
     val defaultsRequests: List<DefaultsRequest> = mutableDefaultsRequests
@@ -41,7 +46,7 @@
                     old == new
                 }
             }
-            .map { defaults[DefaultsKey(it.user, it.componentName)]!! }
+            .mapNotNull { defaults[DefaultsKey(it.user, it.componentName)] }
 
     override fun requestNewDefaults(
         user: UserHandle,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt
new file mode 100644
index 0000000..ccf0391
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.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.qs.tiles.impl.custom.data.repository
+
+import android.os.UserHandle
+import android.service.quicksettings.Tile
+import com.android.systemui.qs.external.FakeCustomTileStatePersister
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.flow.Flow
+
+class FakeCustomTileRepository(
+    tileSpec: TileSpec.CustomTileSpec,
+    customTileStatePersister: FakeCustomTileStatePersister,
+    testBackgroundContext: CoroutineContext,
+) : CustomTileRepository {
+
+    private val realDelegate: CustomTileRepository =
+        CustomTileRepositoryImpl(
+            tileSpec,
+            customTileStatePersister,
+            testBackgroundContext,
+        )
+
+    override suspend fun restoreForTheUserIfNeeded(user: UserHandle, isPersistable: Boolean) =
+        realDelegate.restoreForTheUserIfNeeded(user, isPersistable)
+
+    override fun getTiles(user: UserHandle): Flow<Tile> = realDelegate.getTiles(user)
+
+    override fun getTile(user: UserHandle): Tile? = realDelegate.getTile(user)
+
+    override suspend fun updateWithTile(
+        user: UserHandle,
+        newTile: Tile,
+        isPersistable: Boolean,
+    ) = realDelegate.updateWithTile(user, newTile, isPersistable)
+
+    override suspend fun updateWithDefaults(
+        user: UserHandle,
+        defaults: CustomTileDefaults,
+        isPersistable: Boolean,
+    ) = realDelegate.updateWithDefaults(user, defaults, isPersistable)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationsKeyguardInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationsKeyguardInteractorKosmos.kt
index 61a38b8..432464e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationsKeyguardInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationsKeyguardInteractorKosmos.kt
@@ -18,11 +18,13 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.statusbar.notification.data.repository.notificationsKeyguardViewStateRepository
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
 
 val Kosmos.notificationsKeyguardInteractor by Fixture {
     NotificationsKeyguardInteractor(
         repository = notificationsKeyguardViewStateRepository,
+        backgroundDispatcher = testDispatcher,
     )
 }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt
index a639df5..2bc2db3 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt
@@ -16,9 +16,12 @@
 
 package com.android.systemui.unfold
 
+import android.os.Handler
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.dagger.UnfoldMain
 import com.android.systemui.unfold.dagger.UseReceivingFilter
 import com.android.systemui.unfold.progress.RemoteUnfoldTransitionReceiver
+import com.android.systemui.unfold.updates.RotationChangeProvider
 import com.android.systemui.unfold.util.ATraceLoggerTransitionProgressListener
 import dagger.Module
 import dagger.Provides
@@ -33,16 +36,25 @@
     @Singleton
     fun provideTransitionProvider(
         config: UnfoldTransitionConfig,
-        traceListener: ATraceLoggerTransitionProgressListener,
+        traceListener: ATraceLoggerTransitionProgressListener.Factory,
         remoteReceiverProvider: Provider<RemoteUnfoldTransitionReceiver>,
     ): Optional<RemoteUnfoldTransitionReceiver> {
         if (!config.isEnabled) {
             return Optional.empty()
         }
         val remoteReceiver = remoteReceiverProvider.get()
-        remoteReceiver.addCallback(traceListener)
+        remoteReceiver.addCallback(traceListener.create("remoteReceiver"))
         return Optional.of(remoteReceiver)
     }
 
     @Provides @UseReceivingFilter fun useReceivingFilter(): Boolean = true
+
+    @Provides
+    @UnfoldMain
+    fun provideMainRotationChangeProvider(
+        rotationChangeProviderFactory: RotationChangeProvider.Factory,
+        @UnfoldMain mainHandler: Handler,
+    ): RotationChangeProvider {
+        return rotationChangeProviderFactory.create(mainHandler)
+    }
 }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
index c3a6cf0..31b7ccc 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
@@ -22,12 +22,12 @@
 import android.hardware.display.DisplayManager
 import android.os.Handler
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.dagger.UnfoldBg
 import com.android.systemui.unfold.dagger.UnfoldMain
 import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
 import com.android.systemui.unfold.progress.RemoteUnfoldTransitionReceiver
 import com.android.systemui.unfold.updates.FoldProvider
 import com.android.systemui.unfold.updates.RotationChangeProvider
-import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
 import com.android.systemui.unfold.util.CurrentActivityTypeProvider
 import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
@@ -63,13 +63,12 @@
             @BindsInstance @UnfoldSingleThreadBg singleThreadBgExecutor: Executor,
             @BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
             @BindsInstance displayManager: DisplayManager,
-            @BindsInstance contentResolver: ContentResolver = context.contentResolver
+            @BindsInstance @UnfoldBg bgHandler: Handler,
+            @BindsInstance contentResolver: ContentResolver = context.contentResolver,
         ): UnfoldSharedComponent
     }
 
     val unfoldTransitionProvider: Optional<UnfoldTransitionProgressProvider>
-    val hingeAngleProvider: HingeAngleProvider
-    val rotationChangeProvider: RotationChangeProvider
 }
 
 /**
@@ -94,7 +93,8 @@
     }
 
     val remoteTransitionProgress: Optional<RemoteUnfoldTransitionReceiver>
-    val rotationChangeProvider: RotationChangeProvider
+
+    @UnfoldMain fun getRotationChangeProvider(): RotationChangeProvider
 }
 
 /**
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
index 7473ca6..f7fb014 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
@@ -16,14 +16,20 @@
 
 package com.android.systemui.unfold
 
+import android.os.Handler
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.dagger.UnfoldBg
+import com.android.systemui.unfold.dagger.UnfoldBgProgressFlag
+import com.android.systemui.unfold.dagger.UnfoldMain
 import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
+import com.android.systemui.unfold.progress.MainThreadUnfoldTransitionProgressProvider
 import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
 import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder
 import com.android.systemui.unfold.updates.DeviceFoldStateProvider
 import com.android.systemui.unfold.updates.FoldStateProvider
 import com.android.systemui.unfold.updates.FoldStateRepository
 import com.android.systemui.unfold.updates.FoldStateRepositoryImpl
+import com.android.systemui.unfold.updates.RotationChangeProvider
 import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider
 import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
 import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
@@ -32,22 +38,27 @@
 import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
 import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManagerImpl
 import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
+import dagger.BindsOptionalOf
 import dagger.Module
 import dagger.Provides
 import java.util.Optional
 import javax.inject.Provider
 import javax.inject.Singleton
+import kotlin.jvm.optionals.getOrDefault
 
-@Module(includes = [UnfoldSharedInternalModule::class])
+@Module(
+    includes =
+        [
+            UnfoldFlagsModule::class,
+            UnfoldSharedInternalModule::class,
+            UnfoldRotationProviderInternalModule::class,
+            HingeAngleProviderInternalModule::class,
+            FoldStateProviderModule::class,
+        ]
+)
 class UnfoldSharedModule {
     @Provides
     @Singleton
-    fun provideFoldStateProvider(
-        deviceFoldStateProvider: DeviceFoldStateProvider
-    ): FoldStateProvider = deviceFoldStateProvider
-
-    @Provides
-    @Singleton
     fun unfoldKeyguardVisibilityProvider(
         impl: UnfoldKeyguardVisibilityManagerImpl
     ): UnfoldKeyguardVisibilityProvider = impl
@@ -60,9 +71,17 @@
 
     @Provides
     @Singleton
-    fun foldStateRepository(
-            impl: FoldStateRepositoryImpl
-    ): FoldStateRepository = impl
+    fun foldStateRepository(impl: FoldStateRepositoryImpl): FoldStateRepository = impl
+}
+
+@Module
+abstract class UnfoldFlagsModule {
+    /**
+     * Users of the library can bind this boolean to notify whether the progress should be
+     * calculated only in the background (and the main thread provider is generated by posting the
+     * background events in the main handler).
+     */
+    @BindsOptionalOf @UnfoldBgProgressFlag abstract fun unfoldBgProgressFlag(): Boolean
 }
 
 /**
@@ -77,17 +96,86 @@
     fun unfoldTransitionProgressProvider(
         config: UnfoldTransitionConfig,
         scaleAwareProviderFactory: ScaleAwareTransitionProgressProvider.Factory,
+        tracingListener: ATraceLoggerTransitionProgressListener.Factory,
+        physicsBasedUnfoldTransitionProgressProvider:
+            PhysicsBasedUnfoldTransitionProgressProvider.Factory,
+        fixedTimingTransitionProgressProvider: Provider<FixedTimingTransitionProgressProvider>,
+        foldStateProvider: FoldStateProvider,
+        @UnfoldMain mainHandler: Handler,
+        mainThreadUnfoldTransitionProgressProviderFactory:
+            MainThreadUnfoldTransitionProgressProvider.Factory,
+        @UnfoldBg bgProvider: Provider<Optional<UnfoldTransitionProgressProvider>>,
+        @UnfoldBgProgressFlag unfoldBgProgressFlag: Optional<Boolean>,
+    ): Optional<UnfoldTransitionProgressProvider> {
+        if (unfoldBgProgressFlag.getOrDefault(false)) {
+            // In this case, we wrap the background progress provider
+            val mainThreadProvider: Optional<UnfoldTransitionProgressProvider> =
+                bgProvider.get().map {
+                    mainThreadUnfoldTransitionProgressProviderFactory.create(it)
+                }
+            mainThreadProvider.ifPresent {
+                it.addCallback(tracingListener.create("MainThreadFromBgProgress"))
+            }
+            return mainThreadProvider
+        } else {
+            // TODO(b/277879146): Remove this once unfold_animation_background_progress is launched.
+            return createOptionalUnfoldTransitionProgressProvider(
+                config = config,
+                scaleAwareProviderFactory = scaleAwareProviderFactory,
+                tracingListener = tracingListener.create("MainThread"),
+                physicsBasedUnfoldTransitionProgressProvider =
+                    physicsBasedUnfoldTransitionProgressProvider,
+                fixedTimingTransitionProgressProvider = fixedTimingTransitionProgressProvider,
+                foldStateProvider = foldStateProvider,
+                progressHandler = mainHandler,
+            )
+        }
+    }
+
+    @Provides
+    @Singleton
+    @UnfoldBg
+    fun unfoldBgTransitionProgressProvider(
+        config: UnfoldTransitionConfig,
+        scaleAwareProviderFactory: ScaleAwareTransitionProgressProvider.Factory,
+        tracingListener: ATraceLoggerTransitionProgressListener.Factory,
+        physicsBasedUnfoldTransitionProgressProvider:
+            PhysicsBasedUnfoldTransitionProgressProvider.Factory,
+        fixedTimingTransitionProgressProvider: Provider<FixedTimingTransitionProgressProvider>,
+        @UnfoldBg bgFoldStateProvider: FoldStateProvider,
+        @UnfoldBg bgHandler: Handler,
+    ): Optional<UnfoldTransitionProgressProvider> {
+        return createOptionalUnfoldTransitionProgressProvider(
+            config = config,
+            scaleAwareProviderFactory = scaleAwareProviderFactory,
+            tracingListener = tracingListener.create("BgThread"),
+            physicsBasedUnfoldTransitionProgressProvider =
+                physicsBasedUnfoldTransitionProgressProvider,
+            fixedTimingTransitionProgressProvider = fixedTimingTransitionProgressProvider,
+            foldStateProvider = bgFoldStateProvider,
+            progressHandler = bgHandler,
+        )
+    }
+
+    private fun createOptionalUnfoldTransitionProgressProvider(
+        config: UnfoldTransitionConfig,
+        scaleAwareProviderFactory: ScaleAwareTransitionProgressProvider.Factory,
         tracingListener: ATraceLoggerTransitionProgressListener,
         physicsBasedUnfoldTransitionProgressProvider:
-            Provider<PhysicsBasedUnfoldTransitionProgressProvider>,
+            PhysicsBasedUnfoldTransitionProgressProvider.Factory,
         fixedTimingTransitionProgressProvider: Provider<FixedTimingTransitionProgressProvider>,
+        foldStateProvider: FoldStateProvider,
+        progressHandler: Handler,
     ): Optional<UnfoldTransitionProgressProvider> {
         if (!config.isEnabled) {
             return Optional.empty()
         }
         val baseProgressProvider =
             if (config.isHingeAngleEnabled) {
-                physicsBasedUnfoldTransitionProgressProvider.get()
+                physicsBasedUnfoldTransitionProgressProvider.create(
+                    foldStateProvider,
+                    progressHandler
+                )
             } else {
                 fixedTimingTransitionProgressProvider.get()
             }
@@ -101,26 +189,105 @@
     }
 
     @Provides
+    @Singleton
+    fun provideProgressForwarder(
+        config: UnfoldTransitionConfig,
+        progressForwarder: Provider<UnfoldTransitionProgressForwarder>
+    ): Optional<UnfoldTransitionProgressForwarder> {
+        if (!config.isEnabled) {
+            return Optional.empty()
+        }
+        return Optional.of(progressForwarder.get())
+    }
+}
+
+/**
+ * Provides [FoldStateProvider]. The [UnfoldBg] annotated binding sends progress in the [UnfoldBg]
+ * handler.
+ */
+@Module
+internal class FoldStateProviderModule {
+    @Provides
+    @Singleton
+    fun provideFoldStateProvider(
+        factory: DeviceFoldStateProvider.Factory,
+        @UnfoldMain hingeAngleProvider: HingeAngleProvider,
+        @UnfoldMain rotationChangeProvider: RotationChangeProvider,
+        @UnfoldMain mainHandler: Handler,
+    ): FoldStateProvider =
+        factory.create(
+            hingeAngleProvider,
+            rotationChangeProvider,
+            progressHandler = mainHandler
+        )
+
+    @Provides
+    @Singleton
+    @UnfoldBg
+    fun provideBgFoldStateProvider(
+        factory: DeviceFoldStateProvider.Factory,
+        @UnfoldBg hingeAngleProvider: HingeAngleProvider,
+        @UnfoldBg rotationChangeProvider: RotationChangeProvider,
+        @UnfoldBg bgHandler: Handler,
+    ): FoldStateProvider =
+        factory.create(
+            hingeAngleProvider,
+            rotationChangeProvider,
+            progressHandler = bgHandler
+        )
+}
+
+/** Provides bindings for both [UnfoldMain] and [UnfoldBg] [HingeAngleProvider]. */
+@Module
+internal class HingeAngleProviderInternalModule {
+    @Provides
+    @UnfoldMain
     fun hingeAngleProvider(
         config: UnfoldTransitionConfig,
-        hingeAngleSensorProvider: Provider<HingeSensorAngleProvider>
+        @UnfoldMain handler: Handler,
+        hingeAngleSensorProvider: HingeSensorAngleProvider.Factory
     ): HingeAngleProvider {
         return if (config.isHingeAngleEnabled) {
-            hingeAngleSensorProvider.get()
+            hingeAngleSensorProvider.create(handler)
         } else {
             EmptyHingeAngleProvider
         }
     }
 
     @Provides
-    @Singleton
-    fun provideProgressForwarder(
-            config: UnfoldTransitionConfig,
-            progressForwarder: Provider<UnfoldTransitionProgressForwarder>
-    ): Optional<UnfoldTransitionProgressForwarder> {
-        if (!config.isEnabled) {
-            return Optional.empty()
+    @UnfoldBg
+    fun hingeAngleProviderBg(
+        config: UnfoldTransitionConfig,
+        @UnfoldBg handler: Handler,
+        hingeAngleSensorProvider: HingeSensorAngleProvider.Factory
+    ): HingeAngleProvider {
+        return if (config.isHingeAngleEnabled) {
+            hingeAngleSensorProvider.create(handler)
+        } else {
+            EmptyHingeAngleProvider
         }
-        return Optional.of(progressForwarder.get())
+    }
+}
+
+@Module
+internal class UnfoldRotationProviderInternalModule {
+    @Provides
+    @Singleton
+    @UnfoldMain
+    fun provideRotationChangeProvider(
+        rotationChangeProviderFactory: RotationChangeProvider.Factory,
+        @UnfoldMain mainHandler: Handler,
+    ): RotationChangeProvider {
+        return rotationChangeProviderFactory.create(mainHandler)
+    }
+
+    @Provides
+    @Singleton
+    @UnfoldBg
+    fun provideBgRotationChangeProvider(
+        rotationChangeProviderFactory: RotationChangeProvider.Factory,
+        @UnfoldBg bgHandler: Handler,
+    ): RotationChangeProvider {
+        return rotationChangeProviderFactory.create(bgHandler)
     }
 }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index 1839919..1cbaf31 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -48,6 +48,7 @@
         singleThreadBgExecutor: Executor,
         tracingTagPrefix: String,
         displayManager: DisplayManager,
+        bgHandler: Handler,
 ): UnfoldSharedComponent =
         DaggerUnfoldSharedComponent.factory()
                 .create(
@@ -62,6 +63,7 @@
                         singleThreadBgExecutor,
                         tracingTagPrefix,
                         displayManager,
+                        bgHandler,
                 )
 
 /**
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBg.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBg.kt
new file mode 100644
index 0000000..7cd4419
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBg.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.dagger
+
+import javax.inject.Qualifier
+
+/** Annotation for background computations related to unfold lib. */
+@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class UnfoldBg
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBgProgressFlag.kt
similarity index 63%
copy from packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
copy to packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBgProgressFlag.kt
index ee36989..0e371fa 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBgProgressFlag.kt
@@ -14,16 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.common
+package com.android.systemui.unfold.dagger
 
-import android.app.PendingIntent
-import android.content.Intent
+import javax.inject.Qualifier
 
-open class BaseEntry (
-    val providerId: String,
-    val entryKey: String,
-    val entrySubkey: String,
-    val pendingIntent: PendingIntent?,
-    val fillInIntent: Intent?,
-    val shouldTerminateUiUponSuccessfulProviderResult: Boolean,
-)
\ No newline at end of file
+/**
+ * Annotates the boolean representing whether we are calculating progresses in the background.
+ *
+ * Used to allow clients to provide this value, without depending on the flags directly.
+ */
+@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class UnfoldBgProgressFlag
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProvider.kt
new file mode 100644
index 0000000..9bdf3d5
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProvider.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold.progress
+
+import android.os.Handler
+import androidx.annotation.FloatRange
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.dagger.UnfoldMain
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+/**
+ * [UnfoldTransitionProgressProvider] that forwards all progress to the main thread handler.
+ *
+ * This is needed when progress are calculated in the background, but some listeners need the
+ * callbacks in the main thread.
+ */
+class MainThreadUnfoldTransitionProgressProvider
+@AssistedInject
+constructor(
+    @UnfoldMain private val mainHandler: Handler,
+    @Assisted private val rootProvider: UnfoldTransitionProgressProvider
+) : UnfoldTransitionProgressProvider {
+
+    private val listenerMap = mutableMapOf<TransitionProgressListener, TransitionProgressListener>()
+
+    override fun addCallback(listener: TransitionProgressListener) {
+        assertMainThread()
+        val proxy = TransitionProgressListerProxy(listener)
+        rootProvider.addCallback(proxy)
+        listenerMap[listener] = proxy
+    }
+
+    override fun removeCallback(listener: TransitionProgressListener) {
+        assertMainThread()
+        val proxy = listenerMap.remove(listener) ?: return
+        rootProvider.removeCallback(proxy)
+    }
+
+    private fun assertMainThread() {
+        check(mainHandler.looper.isCurrentThread) {
+            "Should be called from the main thread, but this is ${Thread.currentThread()}"
+        }
+    }
+
+    override fun destroy() {
+        rootProvider.destroy()
+    }
+
+    inner class TransitionProgressListerProxy(private val listener: TransitionProgressListener) :
+        TransitionProgressListener {
+        override fun onTransitionStarted() {
+            mainHandler.post { listener.onTransitionStarted() }
+        }
+
+        override fun onTransitionProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float) {
+            mainHandler.post { listener.onTransitionProgress(progress) }
+        }
+
+        override fun onTransitionFinishing() {
+            mainHandler.post { listener.onTransitionFinishing() }
+        }
+
+        override fun onTransitionFinished() {
+            mainHandler.post { listener.onTransitionFinished() }
+        }
+    }
+
+    @AssistedFactory
+    interface Factory {
+        /** Creates a [MainThreadUnfoldTransitionProgressProvider] that wraps the [rootProvider]. */
+        fun create(
+            rootProvider: UnfoldTransitionProgressProvider
+        ): MainThreadUnfoldTransitionProgressProvider
+    }
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
index f8f168b..907bf46 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
@@ -20,6 +20,7 @@
 import android.animation.ObjectAnimator
 import android.animation.ValueAnimator
 import android.content.Context
+import android.os.Handler
 import android.os.Trace
 import android.util.FloatProperty
 import android.util.Log
@@ -38,13 +39,25 @@
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
 import com.android.systemui.unfold.updates.name
-import javax.inject.Inject
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
 
-/** Maps fold updates to unfold transition progress using DynamicAnimation. */
+/**
+ * Maps fold updates to unfold transition progress using DynamicAnimation.
+ *
+ * Note that all variable accesses must be done in the [Handler] provided in the constructor, that
+ * might be different than [mainHandler]. When a custom handler is provided, the [SpringAnimation]
+ * uses a scheduler different than the default one.
+ */
 class PhysicsBasedUnfoldTransitionProgressProvider
-@Inject
-constructor(context: Context, private val foldStateProvider: FoldStateProvider) :
-    UnfoldTransitionProgressProvider, FoldUpdatesListener, DynamicAnimation.OnAnimationEndListener {
+@AssistedInject
+constructor(
+    context: Context,
+    private val schedulerFactory: UnfoldFrameCallbackScheduler.Factory,
+    @Assisted private val foldStateProvider: FoldStateProvider,
+    @Assisted private val progressHandler: Handler,
+) : UnfoldTransitionProgressProvider, FoldUpdatesListener, DynamicAnimation.OnAnimationEndListener {
 
     private val emphasizedInterpolator =
         loadInterpolator(context, android.R.interpolator.fast_out_extra_slow_in)
@@ -63,6 +76,7 @@
 
     private var transitionProgress: Float = 0.0f
         set(value) {
+            assertInProgressThread()
             if (isTransitionRunning) {
                 listeners.forEach { it.onTransitionProgress(value) }
             }
@@ -72,8 +86,14 @@
     private val listeners: MutableList<TransitionProgressListener> = mutableListOf()
 
     init {
-        foldStateProvider.addCallback(this)
-        foldStateProvider.start()
+        progressHandler.post {
+            // The scheduler needs to be created in the progress handler in order to get the correct
+            // choreographer and frame callbacks. This is because the choreographer can be get only
+            // as a thread local.
+            springAnimation.scheduler = schedulerFactory.create()
+            foldStateProvider.addCallback(this)
+            foldStateProvider.start()
+        }
     }
 
     override fun destroy() {
@@ -81,6 +101,8 @@
     }
 
     override fun onHingeAngleUpdate(angle: Float) {
+        assertInProgressThread()
+
         if (!isTransitionRunning || isAnimatedCancelRunning) return
         val progress = saturate(angle / FINAL_HINGE_ANGLE_POSITION)
         springAnimation.animateToFinalPosition(progress)
@@ -90,6 +112,7 @@
         if (amount < low) low else if (amount > high) high else amount
 
     override fun onFoldUpdate(@FoldUpdate update: Int) {
+        assertInProgressThread()
         when (update) {
             FOLD_UPDATE_FINISH_FULL_OPEN,
             FOLD_UPDATE_FINISH_HALF_OPEN -> {
@@ -148,6 +171,7 @@
     }
 
     private fun cancelTransition(endValue: Float, animate: Boolean) {
+        assertInProgressThread()
         if (isTransitionRunning && animate) {
             if (endValue == 1.0f && !isAnimatedCancelRunning) {
                 listeners.forEach { it.onTransitionFinishing() }
@@ -165,7 +189,6 @@
             isAnimatedCancelRunning = false
             isTransitionRunning = false
             springAnimation.cancel()
-
             cannedAnimator?.removeAllListeners()
             cannedAnimator?.cancel()
             cannedAnimator = null
@@ -182,7 +205,7 @@
         animation: DynamicAnimation<out DynamicAnimation<*>>,
         canceled: Boolean,
         value: Float,
-        velocity: Float
+        velocity: Float,
     ) {
         if (isAnimatedCancelRunning) {
             cancelTransition(value, animate = false)
@@ -202,6 +225,7 @@
     }
 
     private fun startTransition(startValue: Float) {
+        assertInProgressThread()
         if (!isTransitionRunning) onStartTransition()
 
         springAnimation.apply {
@@ -221,14 +245,16 @@
     }
 
     override fun addCallback(listener: TransitionProgressListener) {
-        listeners.add(listener)
+        progressHandler.post { listeners.add(listener) }
     }
 
     override fun removeCallback(listener: TransitionProgressListener) {
-        listeners.remove(listener)
+        progressHandler.post { listeners.remove(listener) }
     }
 
     private fun startCannedCancelAnimation() {
+        assertInProgressThread()
+
         cannedAnimator?.cancel()
         cannedAnimator = null
 
@@ -264,7 +290,7 @@
 
         override fun setValue(
             provider: PhysicsBasedUnfoldTransitionProgressProvider,
-            value: Float
+            value: Float,
         ) {
             provider.transitionProgress = value
         }
@@ -272,6 +298,25 @@
         override fun get(provider: PhysicsBasedUnfoldTransitionProgressProvider): Float =
             provider.transitionProgress
     }
+
+    private fun assertInProgressThread() {
+        check(progressHandler.looper.isCurrentThread) {
+            val progressThread = progressHandler.looper.thread
+            val thisThread = Thread.currentThread()
+            """should be called from the progress thread.
+                progressThread=$progressThread tid=${progressThread.id}
+                Thread.currentThread()=$thisThread tid=${thisThread.id}"""
+                .trimMargin()
+        }
+    }
+
+    @AssistedFactory
+    interface Factory {
+        fun create(
+            foldStateProvider: FoldStateProvider,
+            handler: Handler,
+        ): PhysicsBasedUnfoldTransitionProgressProvider
+    }
 }
 
 private const val TAG = "PhysicsBasedUnfoldTransitionProgressProvider"
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldFrameCallbackScheduler.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldFrameCallbackScheduler.kt
new file mode 100644
index 0000000..1dffd84
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldFrameCallbackScheduler.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.unfold.progress
+
+import android.os.Looper
+import android.view.Choreographer
+import androidx.dynamicanimation.animation.FrameCallbackScheduler
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+/**
+ * Scheduler that posts animation progresses on a thread different than the ui one.
+ *
+ * The following is taken from [AnimationHandler.FrameCallbackScheduler16]. It is extracted here as
+ * there are no guarantees which implementation the [DynamicAnimation] class would use otherwise.
+ * This allows classes using [DynamicAnimation] to be created in any thread, but still use the
+ * scheduler for a specific thread.
+ *
+ * Technically the [AssistedInject] is not needed: it's just to have a nicer factory with a
+ * documentation snippet instead of using a plain dagger provider.
+ */
+class UnfoldFrameCallbackScheduler @AssistedInject constructor() : FrameCallbackScheduler {
+
+    private val choreographer = Choreographer.getInstance()
+    private val looper =
+        Looper.myLooper() ?: error("This should be created in a thread with a looper.")
+
+    override fun postFrameCallback(frameCallback: Runnable) {
+        choreographer.postFrameCallback { frameCallback.run() }
+    }
+
+    override fun isCurrentThread(): Boolean {
+        return looper.isCurrentThread
+    }
+
+    @AssistedFactory
+    interface Factory {
+        /**
+         * Creates a [FrameCallbackScheduler] that uses [Choreographer] to post frame callbacks.
+         *
+         * Note that the choreographer used depends on the thread this [create] is called on, as it
+         * is get from a thread static attribute.
+         */
+        fun create(): UnfoldFrameCallbackScheduler
+    }
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index 003013e..77f637b 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -23,37 +23,34 @@
 import androidx.core.util.Consumer
 import com.android.systemui.unfold.compat.INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
-import com.android.systemui.unfold.dagger.UnfoldMain
-import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
-import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
-import com.android.systemui.unfold.updates.RotationChangeProvider.RotationListener
 import com.android.systemui.unfold.updates.hinge.FULLY_CLOSED_DEGREES
 import com.android.systemui.unfold.updates.hinge.FULLY_OPEN_DEGREES
 import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
 import com.android.systemui.unfold.util.CurrentActivityTypeProvider
 import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.util.concurrent.CopyOnWriteArrayList
 import java.util.concurrent.Executor
-import javax.inject.Inject
 
 class DeviceFoldStateProvider
-@Inject
+@AssistedInject
 constructor(
     config: UnfoldTransitionConfig,
-    private val hingeAngleProvider: HingeAngleProvider,
+    private val context: Context,
     private val screenStatusProvider: ScreenStatusProvider,
-    private val foldProvider: FoldProvider,
     private val activityTypeProvider: CurrentActivityTypeProvider,
     private val unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider,
-    private val rotationChangeProvider: RotationChangeProvider,
-    private val context: Context,
-    @UnfoldMain private val mainExecutor: Executor,
-    @UnfoldMain private val handler: Handler
+    private val foldProvider: FoldProvider,
+    @Assisted private val hingeAngleProvider: HingeAngleProvider,
+    @Assisted private val rotationChangeProvider: RotationChangeProvider,
+    @Assisted private val progressHandler: Handler,
 ) : FoldStateProvider {
+    private val outputListeners = CopyOnWriteArrayList<FoldStateProvider.FoldUpdatesListener>()
 
-    private val outputListeners: MutableList<FoldUpdatesListener> = mutableListOf()
-
-    @FoldUpdate private var lastFoldUpdate: Int? = null
+    @FoldStateProvider.FoldUpdate private var lastFoldUpdate: Int? = null
 
     @FloatRange(from = 0.0, to = 180.0) private var lastHingeAngle: Float = 0f
     @FloatRange(from = 0.0, to = 180.0) private var lastHingeAngleBeforeTransition: Float = 0f
@@ -61,11 +58,9 @@
     private val hingeAngleListener = HingeAngleListener()
     private val screenListener = ScreenStatusListener()
     private val foldStateListener = FoldStateListener()
-    private val mainLooper = handler.looper
     private val timeoutRunnable = Runnable { cancelAnimation() }
-    private val rotationListener = RotationListener {
-        if (isTransitionInProgress) cancelAnimation()
-    }
+    private val rotationListener = FoldRotationListener()
+    private val progressExecutor = Executor { progressHandler.post(it) }
 
     /**
      * Time after which [FOLD_UPDATE_FINISH_HALF_OPEN] is emitted following a
@@ -80,9 +75,9 @@
     private var isStarted = false
 
     override fun start() {
-        assertMainThread()
         if (isStarted) return
-        foldProvider.registerCallback(foldStateListener, mainExecutor)
+        foldProvider.registerCallback(foldStateListener, progressExecutor)
+        // TODO(b/277879146): get callbacks in the background
         screenStatusProvider.addCallback(screenListener)
         hingeAngleProvider.addCallback(hingeAngleListener)
         rotationChangeProvider.addCallback(rotationListener)
@@ -91,7 +86,6 @@
     }
 
     override fun stop() {
-        assertMainThread()
         screenStatusProvider.removeCallback(screenListener)
         foldProvider.unregisterCallback(foldStateListener)
         hingeAngleProvider.removeCallback(hingeAngleListener)
@@ -101,11 +95,11 @@
         isStarted = false
     }
 
-    override fun addCallback(listener: FoldUpdatesListener) {
+    override fun addCallback(listener: FoldStateProvider.FoldUpdatesListener) {
         outputListeners.add(listener)
     }
 
-    override fun removeCallback(listener: FoldUpdatesListener) {
+    override fun removeCallback(listener: FoldStateProvider.FoldUpdatesListener) {
         outputListeners.remove(listener)
     }
 
@@ -121,6 +115,7 @@
                 lastFoldUpdate == FOLD_UPDATE_START_CLOSING
 
     private fun onHingeAngle(angle: Float) {
+        assertInProgressThread()
         if (DEBUG) {
             Log.d(
                 TAG,
@@ -131,14 +126,14 @@
         }
 
         val currentDirection =
-                if (angle < lastHingeAngle) FOLD_UPDATE_START_CLOSING else FOLD_UPDATE_START_OPENING
+            if (angle < lastHingeAngle) FOLD_UPDATE_START_CLOSING else FOLD_UPDATE_START_OPENING
         if (isTransitionInProgress && currentDirection != lastFoldUpdate) {
             lastHingeAngleBeforeTransition = lastHingeAngle
         }
 
         val isClosing = angle < lastHingeAngleBeforeTransition
         val transitionUpdate =
-                if (isClosing) FOLD_UPDATE_START_CLOSING else FOLD_UPDATE_START_OPENING
+            if (isClosing) FOLD_UPDATE_START_CLOSING else FOLD_UPDATE_START_OPENING
         val angleChangeSurpassedThreshold =
             Math.abs(angle - lastHingeAngleBeforeTransition) > HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES
         val isFullyOpened = FULLY_OPEN_DEGREES - angle < FULLY_OPEN_THRESHOLD_DEGREES
@@ -150,12 +145,12 @@
             angleChangeSurpassedThreshold && // Do not react immediately to small changes in angle
                 eventNotAlreadyDispatched && // we haven't sent transition event already
                 !isFullyOpened && // do not send transition event if we are in fully opened hinge
-                                  // angle range as closing threshold could overlap this range
+                // angle range as closing threshold could overlap this range
                 screenAvailableEventSent && // do not send transition event if we are still in the
-                                            // process of turning on the inner display
+                // process of turning on the inner display
                 isClosingThresholdMet(angle) && // hinge angle is below certain threshold.
                 isOnLargeScreen // Avoids sending closing event when on small screen.
-                                // Start event is sent regardless due to hall sensor.
+        // Start event is sent regardless due to hall sensor.
         ) {
             notifyFoldUpdate(transitionUpdate, lastHingeAngle)
         }
@@ -202,6 +197,7 @@
 
     private inner class FoldStateListener : FoldProvider.FoldCallback {
         override fun onFoldUpdated(isFolded: Boolean) {
+            assertInProgressThread()
             this@DeviceFoldStateProvider.isFolded = isFolded
             lastHingeAngle = FULLY_CLOSED_DEGREES
 
@@ -218,7 +214,14 @@
         }
     }
 
-    private fun notifyFoldUpdate(@FoldUpdate update: Int, angle: Float) {
+    private inner class FoldRotationListener : RotationChangeProvider.RotationListener {
+        override fun onRotationChanged(newRotation: Int) {
+            assertInProgressThread()
+            if (isTransitionInProgress) cancelAnimation()
+        }
+    }
+
+    private fun notifyFoldUpdate(@FoldStateProvider.FoldUpdate update: Int, angle: Float) {
         if (DEBUG) {
             Log.d(TAG, update.name())
         }
@@ -236,11 +239,11 @@
         if (isTransitionInProgress) {
             cancelTimeout()
         }
-        handler.postDelayed(timeoutRunnable, halfOpenedTimeoutMillis.toLong())
+        progressHandler.postDelayed(timeoutRunnable, halfOpenedTimeoutMillis.toLong())
     }
 
     private fun cancelTimeout() {
-        handler.removeCallbacks(timeoutRunnable)
+        progressHandler.removeCallbacks(timeoutRunnable)
     }
 
     private fun cancelAnimation(): Unit =
@@ -249,42 +252,61 @@
     private inner class ScreenStatusListener : ScreenStatusProvider.ScreenListener {
 
         override fun onScreenTurnedOn() {
-            // Trigger this event only if we are unfolded and this is the first screen
-            // turned on event since unfold started. This prevents running the animation when
-            // turning on the internal display using the power button.
-            // Initially isUnfoldHandled is true so it will be reset to false *only* when we
-            // receive 'folded' event. If SystemUI started when device is already folded it will
-            // still receive 'folded' event on startup.
-            if (!isFolded && !isUnfoldHandled) {
-                outputListeners.forEach { it.onUnfoldedScreenAvailable() }
-                isUnfoldHandled = true
+            executeInProgressThread {
+                // Trigger this event only if we are unfolded and this is the first screen
+                // turned on event since unfold started. This prevents running the animation when
+                // turning on the internal display using the power button.
+                // Initially isUnfoldHandled is true so it will be reset to false *only* when we
+                // receive 'folded' event. If SystemUI started when device is already folded it will
+                // still receive 'folded' event on startup.
+                if (!isFolded && !isUnfoldHandled) {
+                    outputListeners.forEach { it.onUnfoldedScreenAvailable() }
+                    isUnfoldHandled = true
+                }
             }
         }
 
         override fun markScreenAsTurnedOn() {
-            if (!isFolded) {
-                isUnfoldHandled = true
+            executeInProgressThread {
+                if (!isFolded) {
+                    isUnfoldHandled = true
+                }
             }
         }
 
         override fun onScreenTurningOn() {
-            isScreenOn = true
-            updateHingeAngleProviderState()
+            executeInProgressThread {
+                isScreenOn = true
+                updateHingeAngleProviderState()
+            }
         }
 
         override fun onScreenTurningOff() {
-            isScreenOn = false
-            updateHingeAngleProviderState()
+            executeInProgressThread {
+                isScreenOn = false
+                updateHingeAngleProviderState()
+            }
+        }
+
+        /**
+         * Needed just for compatibility while not all data sources are providing data in the
+         * background.
+         *
+         * TODO(b/277879146): Remove once ScreeStatusProvider provides in the background.
+         */
+        private fun executeInProgressThread(f: () -> Unit) {
+            progressHandler.post { f() }
         }
     }
 
     private fun isOnLargeScreen(): Boolean {
-      return context.resources.configuration.smallestScreenWidthDp >
-          INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP
+        return context.resources.configuration.smallestScreenWidthDp >
+            INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP
     }
 
     /** While the screen is off or the device is folded, hinge angle updates are not needed. */
     private fun updateHingeAngleProviderState() {
+        assertInProgressThread()
         if (isScreenOn && !isFolded) {
             hingeAngleProvider.start()
         } else {
@@ -294,20 +316,34 @@
 
     private inner class HingeAngleListener : Consumer<Float> {
         override fun accept(angle: Float) {
+            assertInProgressThread()
             onHingeAngle(angle)
         }
     }
 
-    private fun assertMainThread() {
-        check(mainLooper.isCurrentThread) {
-            ("should be called from the main thread." +
-                    " sMainLooper.threadName=" + mainLooper.thread.name +
-                    " Thread.currentThread()=" + Thread.currentThread().name)
+    private fun assertInProgressThread() {
+        check(progressHandler.looper.isCurrentThread) {
+            val progressThread = progressHandler.looper.thread
+            val thisThread = Thread.currentThread()
+            """should be called from the progress thread.
+                progressThread=$progressThread tid=${progressThread.id}
+                Thread.currentThread()=$thisThread tid=${thisThread.id}"""
+                .trimMargin()
         }
     }
+
+    @AssistedFactory
+    interface Factory {
+        /** Creates a [DeviceFoldStateProvider] using the provided dependencies. */
+        fun create(
+            hingeAngleProvider: HingeAngleProvider,
+            rotationChangeProvider: RotationChangeProvider,
+            progressHandler: Handler,
+        ): DeviceFoldStateProvider
+    }
 }
 
-fun @receiver:FoldUpdate Int.name() =
+fun @receiver:FoldStateProvider.FoldUpdate Int.name() =
     when (this) {
         FOLD_UPDATE_START_OPENING -> "START_OPENING"
         FOLD_UPDATE_START_CLOSING -> "START_CLOSING"
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
index ce8f1a1..82ea362 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
@@ -20,20 +20,21 @@
 import android.hardware.display.DisplayManager
 import android.os.Handler
 import android.os.RemoteException
-import com.android.systemui.unfold.dagger.UnfoldMain
 import com.android.systemui.unfold.util.CallbackController
-import javax.inject.Inject
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
 
 /**
- * Allows to subscribe to rotation changes. Updates are provided for the display associated
- * to [context].
+ * Allows to subscribe to rotation changes. Updates are provided for the display associated to
+ * [context].
  */
 class RotationChangeProvider
-@Inject
+@AssistedInject
 constructor(
     private val displayManager: DisplayManager,
     private val context: Context,
-    @UnfoldMain private val mainHandler: Handler,
+    @Assisted private val handler: Handler,
 ) : CallbackController<RotationChangeProvider.RotationListener> {
 
     private val listeners = mutableListOf<RotationListener>()
@@ -42,7 +43,7 @@
     private var lastRotation: Int? = null
 
     override fun addCallback(listener: RotationListener) {
-        mainHandler.post {
+        handler.post {
             if (listeners.isEmpty()) {
                 subscribeToRotation()
             }
@@ -51,7 +52,7 @@
     }
 
     override fun removeCallback(listener: RotationListener) {
-        mainHandler.post {
+        handler.post {
             listeners -= listener
             if (listeners.isEmpty()) {
                 unsubscribeToRotation()
@@ -62,7 +63,7 @@
 
     private fun subscribeToRotation() {
         try {
-            displayManager.registerDisplayListener(displayListener, mainHandler)
+            displayManager.registerDisplayListener(displayListener, handler)
         } catch (e: RemoteException) {
             throw e.rethrowFromSystemServer()
         }
@@ -100,4 +101,10 @@
 
         override fun onDisplayRemoved(displayId: Int) {}
     }
+
+    @AssistedFactory
+    interface Factory {
+        /** Creates a new [RotationChangeProvider] that provides updated using [handler]. */
+        fun create(handler: Handler): RotationChangeProvider
+    }
 }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
index 89fb12e..14c4cc0 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
@@ -18,21 +18,26 @@
 import android.hardware.SensorEvent
 import android.hardware.SensorEventListener
 import android.hardware.SensorManager
+import android.os.Handler
 import android.os.Trace
 import androidx.core.util.Consumer
 import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.util.concurrent.CopyOnWriteArrayList
 import java.util.concurrent.Executor
-import javax.inject.Inject
 
 internal class HingeSensorAngleProvider
-@Inject
+@AssistedInject
 constructor(
     private val sensorManager: SensorManager,
-    @UnfoldSingleThreadBg private val singleThreadBgExecutor: Executor
+    @UnfoldSingleThreadBg private val singleThreadBgExecutor: Executor,
+    @Assisted private val listenerHandler: Handler,
 ) : HingeAngleProvider {
 
     private val sensorListener = HingeAngleSensorListener()
-    private val listeners: MutableList<Consumer<Float>> = arrayListOf()
+    private val listeners: MutableList<Consumer<Float>> = CopyOnWriteArrayList()
     var started = false
 
     override fun start() {
@@ -43,7 +48,8 @@
             sensorManager.registerListener(
                 sensorListener,
                 sensor,
-                SensorManager.SENSOR_DELAY_FASTEST
+                SensorManager.SENSOR_DELAY_FASTEST,
+                listenerHandler
             )
             Trace.endSection()
 
@@ -75,4 +81,10 @@
             listeners.forEach { it.accept(event.values[0]) }
         }
     }
+
+    @AssistedFactory
+    interface Factory {
+        /** Creates an [HingeSensorAngleProvider] that sends updates using [handler]. */
+        fun create(handler: Handler): HingeSensorAngleProvider
+    }
 }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
index d8bc018..a31896a 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
@@ -16,7 +16,9 @@
 
 import android.os.Trace
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
-import javax.inject.Inject
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
 import javax.inject.Qualifier
 
 /**
@@ -26,11 +28,11 @@
  * for each fold/unfold: in (1) systemui and (2) launcher process.
  */
 class ATraceLoggerTransitionProgressListener
-@Inject
-internal constructor(@UnfoldTransitionATracePrefix tracePrefix: String) :
+@AssistedInject
+internal constructor(@UnfoldTransitionATracePrefix tracePrefix: String, @Assisted details: String) :
     TransitionProgressListener {
 
-    private val traceName = "$tracePrefix#$UNFOLD_TRANSITION_TRACE_NAME"
+    private val traceName = "$tracePrefix$details#$UNFOLD_TRANSITION_TRACE_NAME"
 
     override fun onTransitionStarted() {
         Trace.beginAsyncSection(traceName, /* cookie= */ 0)
@@ -43,6 +45,12 @@
     override fun onTransitionProgress(progress: Float) {
         Trace.setCounter(traceName, (progress * 100).toLong())
     }
+
+    @AssistedFactory
+    interface Factory {
+        /** Creates an [ATraceLoggerTransitionProgressListener] with [details] in the track name. */
+        fun create(details: String): ATraceLoggerTransitionProgressListener
+    }
 }
 
 private const val UNFOLD_TRANSITION_TRACE_NAME = "FoldUnfoldTransitionInProgress"
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values-sw600dp/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values-sw600dp/config.xml
new file mode 100644
index 0000000..be1f081
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values-sw600dp/config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+    <!-- If true, attach the navigation bar to the app during app transition -->
+    <bool name="config_attachNavBarToAppDuringTransition">false</bool>
+</resources>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values-sw600dp/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values-sw600dp/config.xml
new file mode 100644
index 0000000..be1f081
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values-sw600dp/config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+    <!-- If true, attach the navigation bar to the app during app transition -->
+    <bool name="config_attachNavBarToAppDuringTransition">false</bool>
+</resources>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values-sw600dp/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values-sw600dp/config.xml
new file mode 100644
index 0000000..be1f081
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values-sw600dp/config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+    <!-- If true, attach the navigation bar to the app during app transition -->
+    <bool name="config_attachNavBarToAppDuringTransition">false</bool>
+</resources>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values-sw600dp/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values-sw600dp/config.xml
new file mode 100644
index 0000000..be1f081
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values-sw600dp/config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+    <!-- If true, attach the navigation bar to the app during app transition -->
+    <bool name="config_attachNavBarToAppDuringTransition">false</bool>
+</resources>
diff --git a/ravenwood/OWNERS b/ravenwood/OWNERS
index c06b3b9..41fd68e 100644
--- a/ravenwood/OWNERS
+++ b/ravenwood/OWNERS
@@ -1,3 +1,5 @@
+set noparent
+
 jsharkey@google.com
 omakoto@google.com
 jaggies@google.com
diff --git a/ravenwood/README.md b/ravenwood/README.md
new file mode 100644
index 0000000..9c4fda7
--- /dev/null
+++ b/ravenwood/README.md
@@ -0,0 +1,28 @@
+# Ravenwood
+
+Ravenwood is an officially-supported lightweight unit testing environment for Android platform code that runs on the host.
+
+Ravenwood’s focus on Android platform use-cases, improved maintainability, and device consistency distinguishes it from Robolectric, which remains a popular choice for app testing.
+
+## Background
+
+Executing tests on a typical Android device has substantial overhead, such as flashing the build, waiting for the boot to complete, and retrying tests that fail due to general flakiness.
+
+In contrast, defining a lightweight unit testing environment mitigates these issues by running directly from build artifacts (no flashing required), runs immediately (no booting required), and runs in an isolated environment (less flakiness).
+
+## Guiding principles
+Here’s a summary of the guiding principles for Ravenwood, aimed at addressing Robolectric design concerns and better supporting Android platform developers:
+
+* **API support for Ravenwood is opt-in.**  Teams that own APIs decide exactly what, and how, they support their API functionality being available to tests.  When an API hasn’t opted-in, the API signatures remain available for tests to compile against and/or mock, but they throw when called under a Ravenwood environment.
+    * _Contrasted with Robolectric which attempts to run API implementations as-is, causing maintenance pains as teams maintain or redesign their API internals._
+* **API support and customizations for Ravenwood appear directly inline with relevant code.** This improves maintenance of APIs by providing awareness of what code runs under Ravenwood, including the ability to replace code at a per-method level when Ravenwood-specific customization is needed.
+    * _Contrasted with Robolectric which maintains customized behavior in separate “Shadow” classes that are difficult for maintainers to be aware of._
+* **APIs supported under Ravenwood are tested to remain consistent with physical devices.**  As teams progressively opt-in supporting APIs under Ravenwood, we’re requiring they bring along “bivalent” tests (such as the relevant CTS) to validate that Ravenwood behaves just like a physical device.
+    * _Contrasted with Robolectric, which has limited (and forked) testing of their environment, increasing their risk of accidental divergence over time and misleading “passing” signals._
+* **Ravenwood aims to support more “real” code.**  As API owners progressively opt-in their code, they have the freedom to provide either a limited “fake” that is a faithful emulation of how a device behaves, or they can bring more “real” code that runs on physical devices.
+    * _Contrasted with Robolectric, where support for “real” code ends at the app process boundary, such as a call into `system_server`._
+
+## More details
+
+* [Ravenwood for Test Authors](test-authors.md)
+* [Ravenwood for API Maintainers](api-maintainers.md)
diff --git a/ravenwood/api-maintainers.md b/ravenwood/api-maintainers.md
new file mode 100644
index 0000000..30e899c
--- /dev/null
+++ b/ravenwood/api-maintainers.md
@@ -0,0 +1,73 @@
+# Ravenwood for API Maintainers
+
+By default, Android APIs aren’t opted-in to Ravenwood, and they default to throwing when called under the Ravenwood environment.
+
+To opt-in to supporting an API under Ravenwood, you can use the inline annotations documented below to customize your API behavior when running under Ravenwood.  Because these annotations are inline in the relevant platform source code, they serve as valuable reminders to future API maintainers of Ravenwood support expectations.
+
+> **Note:** to ensure that API teams are well-supported during early Ravenwood onboarding, the Ravenwood team is manually maintaining an allow-list of classes that are able to use Ravenwood annotations.  Please reach out to ravenwood@ so we can offer design advice and allow-list your APIs.
+
+These Ravenwood-specific annotations have no bearing on the status of an API being public, `@SystemApi`, `@TestApi`, `@hide`, etc.  Ravenwood annotations are an orthogonal concept that are only consumed by the internal `hoststubgen` tool during a post-processing step that generates the Ravenwood runtime environment.  Teams that own APIs can continue to refactor opted-in `@hide` implementation details, as long as the test-visible behavior continues passing.
+
+As described in our Guiding Principles, when a team opts-in an API, we’re requiring that they bring along “bivalent” tests (such as the relevant CTS) to validate that Ravenwood behaves just like a physical device.  At the moment this means adding the bivalent tests to relevant `TEST_MAPPING` files to ensure they remain consistently passing over time.  These bivalent tests are important because they progressively provide the foundation on which higher-level unit tests place their trust.
+
+## Opt-in to supporting a single method while other methods remained opt-out
+
+```
+@RavenwoodKeepPartialClass
+public class MyManager {
+    @RavenwoodKeep
+    public static String modeToString(int mode) {
+        // This method implementation runs as-is on both devices and Ravenwood
+    }
+
+    public static void doComplex() {
+        // This method implementation runs as-is on devices, but because there
+        // is no method-level annotation, and the class-level default is
+        // “keep partial”, this method is not supported under Ravenwood and
+        // will throw
+    }
+}
+```
+
+## Opt-in an entire class with opt-out of specific methods
+
+```
+@RavenwoodKeepWholeClass
+public class MyStruct {
+    public void doSimple() {
+        // This method implementation runs as-is on both devices and Ravenwood,
+        // implicitly inheriting the class-level annotation
+    }
+
+    @RavenwoodThrow
+    public void doComplex() {
+        // This method implementation runs as-is on devices, but the
+        // method-level annotation overrides the class-level annotation, so
+        // this method is not supported under Ravenwood and will throw
+    }
+}
+```
+
+## Replace a complex method when under Ravenwood
+
+```
+@RavenwoodKeepWholeClass
+public class MyStruct {
+    @RavenwoodReplace
+    public void doComplex() {
+        // This method implementation runs as-is on devices, but the
+        // implementation is replaced/substituted by the
+        // doComplex$ravenwood() method implementation under Ravenwood
+    }
+
+    public void doComplex$ravenwood() {
+        // This method implementation only runs under Ravenwood
+    }
+}
+```
+
+## General strategies for side-stepping tricky dependencies
+
+The “replace” strategy described above is quite powerful, and can be used in creative ways to sidestep tricky underlying dependencies that aren’t ready yet.
+
+For example, consider a constructor or static initializer that relies on unsupported functionality from another team.  By factoring the unsupported logic into a dedicated method, that method can then be replaced under Ravenwood to offer baseline functionality.
diff --git a/ravenwood/framework-minus-apex-ravenwood-policies.txt b/ravenwood/framework-minus-apex-ravenwood-policies.txt
index c70c171..96cfa48 100644
--- a/ravenwood/framework-minus-apex-ravenwood-policies.txt
+++ b/ravenwood/framework-minus-apex-ravenwood-policies.txt
@@ -1,5 +1,8 @@
 # Ravenwood "policy" file for framework-minus-apex.
 
+# Keep all AIDL interfaces
+class :aidl stubclass
+
 # Collections
 class android.util.ArrayMap stubclass
 class android.util.ArraySet stubclass
@@ -131,6 +134,8 @@
 class android.net.Uri stubclass
 class android.net.UriCodec stubclass
 
-# Context: just enough to support wrapper, no further functionality
+# Just enough to support mocking, no further functionality
 class android.content.Context stub
     method <init> ()V stub
+class android.content.pm.PackageManager stub
+    method <init> ()V stub
diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt
index 07c2cd7c..eba6e0b 100644
--- a/ravenwood/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/ravenwood-annotation-allowed-classes.txt
@@ -2,16 +2,20 @@
 
 com.android.internal.util.ArrayUtils
 
+android.util.AtomicFile
 android.util.DataUnit
 android.util.EventLog
 android.util.IntArray
 android.util.LongArray
+android.util.LruCache
 android.util.Slog
 android.util.TimeUtils
 android.util.Xml
 
 android.os.Binder
 android.os.Binder$IdentitySupplier
+android.os.FileUtils
+android.os.FileUtils$MemoryPipe
 android.os.Handler
 android.os.HandlerExecutor
 android.os.HandlerThread
@@ -30,6 +34,7 @@
 android.content.ComponentName
 android.content.ContentUris
 android.content.ContentValues
+android.content.ContextWrapper
 android.content.Intent
 android.content.IntentFilter
 android.content.UriMatcher
diff --git a/ravenwood/ravenwood-standard-options.txt b/ravenwood/ravenwood-standard-options.txt
index 8ad21fa..f64f26d 100644
--- a/ravenwood/ravenwood-standard-options.txt
+++ b/ravenwood/ravenwood-standard-options.txt
@@ -1,6 +1,6 @@
 # File containing standard options to HostStubGen for Ravenwood
 
---debug
+# --debug # To enable debug log on consone
 
 # Keep all classes / methods / fields, but make the methods throw.
 --default-throw
diff --git a/ravenwood/test-authors.md b/ravenwood/test-authors.md
new file mode 100644
index 0000000..2b5bd908
--- /dev/null
+++ b/ravenwood/test-authors.md
@@ -0,0 +1,132 @@
+# Ravenwood for Test Authors
+
+The Ravenwood testing environment runs inside a single Java process on the host side, and provides a limited yet growing set of Android API functionality.
+
+Ravenwood explicitly does not support “large” integration tests that expect a fully booted Android OS.  Instead, it’s more suited for “small” and “medium” tests where your code-under-test has been factored to remove dependencies on a fully booted device.
+
+When writing tests under Ravenwood, all Android API symbols associated with your declared `sdk_version` are available to link against using, but unsupported APIs will throw an exception.  This design choice enables mocking of unsupported APIs, and supports sharing of test code to build “bivalent” test suites that run against either Ravenwood or a traditional device.
+
+## Typical test structure
+
+Below are the typical steps needed to add a straightforward “small” unit test:
+
+* Define an `android_ravenwood_test` rule in your `Android.bp` file:
+
+```
+android_ravenwood_test {
+    name: "MyTestsRavenwood",
+    static_libs: [
+        "androidx.annotation_annotation",
+        "androidx.test.rules",
+    ],
+    srcs: [
+        "src/com/example/MyCode.java",
+        "tests/src/com/example/MyCodeTest.java",
+    ],
+    sdk_version: "test_current",
+    auto_gen_config: true,
+}
+```
+
+* Write your unit test just like you would for an Android device:
+
+```
+@RunWith(AndroidJUnit4.class)
+public class MyCodeTest {
+    @Test
+    public void testSimple() {
+        // ...
+    }
+}
+```
+
+* APIs available under Ravenwood are stateless by default.  If your test requires explicit states (such as defining the UID you’re running under, or requiring a main `Looper` thread), add a `RavenwoodRule` to declare that:
+
+```
+@RunWith(AndroidJUnit4.class)
+public class MyCodeTest {
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
+            .setProcessApp()
+            .setProvideMainThread(true)
+            .build();
+```
+
+Once you’ve defined your test, you can use typical commands to execute it locally:
+
+```
+$ atest MyTestsRavenwood
+```
+
+> **Note:** There's a known bug where `atest` currently requires a connected device to run Ravenwood tests, but that device isn't used for testing.
+
+You can also run your new tests automatically via `TEST_MAPPING` rules like this:
+
+```
+{
+  "ravenwood-presubmit": [
+    {
+      "name": "MyTestsRavenwood",
+      "host": true
+    }
+  ]
+}
+```
+
+## Strategies for migration/bivalent tests
+
+Ravenwood aims to support tests that are written in a “bivalent” way, where the same test code can run on both a real Android device and under a Ravenwood environment.
+
+In situations where a test method depends on API functionality not yet available under Ravenwood, we provide an annotation to quietly “ignore” that test under Ravenwood, while continuing to validate that test on real devices.  Please note that your test must declare a `RavenwoodRule` for the annotation to take effect.
+
+Test authors are encouraged to provide a `blockedBy` or `reason` argument to help future maintainers understand why a test is being ignored, and under what conditions it might be supported in the future.
+
+```
+@RunWith(AndroidJUnit4.class)
+public class MyCodeTest {
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule();
+
+    @Test
+    public void testSimple() {
+        // Simple test that runs on both devices and Ravenwood
+    }
+
+    @Test
+    @IgnoreUnderRavenwood(blockedBy = PackageManager.class)
+    public void testComplex() {
+        // Complex test that runs on devices, but is ignored under Ravenwood
+    }
+}
+```
+
+## Strategies for unsupported APIs
+
+As you write tests against Ravenwood, you’ll likely discover API dependencies that aren’t supported yet.  Here’s a few strategies that can help you make progress:
+
+* Your code-under-test may benefit from subtle dependency refactoring to reduce coupling.  (For example, providing a specific `File` argument instead of deriving it internally from a `Context`.)
+* Although mocking code that your team doesn’t own is a generally discouraged testing practice, it can be a valuable pressure relief valve when a dependency isn’t yet supported.
+
+## Strategies for debugging test development
+
+When writing tests you may encounter odd or hard to debug behaviors.  One good place to start is at the beginning of the logs stored by atest:
+
+```
+$ atest MyTestsRavenwood
+...
+Test Logs have saved in /tmp/atest_result/20231128_094010_0e90t8v8/log
+Run 'atest --history' to review test result history.
+```
+
+The most useful logs are in the `isolated-java-logs` text file, which can typically be tab-completed by copy-pasting the logs path mentioned in the atest output:
+
+```
+$ less /tmp/atest_result/20231128_133105_h9al__79/log/i*/i*/isolated-java-logs*
+```
+
+Here are some common known issues and recommended workarounds:
+
+* Some code may unconditionally interact with unsupported APIs, such as via static initializers.  One strategy is to shift the logic into `@Before` methods and make it conditional by testing `RavenwoodRule.isUnderRavenwood()`.
+* Some code may reference API symbols not yet present in the Ravenwood runtime, such as ART or ICU internals, or APIs from Mainline modules.  One strategy is to refactor to avoid these internal dependencies, but Ravenwood aims to better support them soon.
+    * This may also manifest as very odd behavior, such as test not being executed at all, tracked by bug #312517322
+    * This may also manifest as an obscure Mockito error claiming “Mockito can only mock non-private & non-final classes”
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 74538ac..6cac6a4 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -668,7 +668,7 @@
             final Context uiContext = displayContext.createWindowContext(
                     TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, null /* options */);
             magnificationGestureHandler = new WindowMagnificationGestureHandler(uiContext,
-                    mAms.getWindowMagnificationMgr(), mAms.getTraceManager(),
+                    mAms.getMagnificationConnectionManager(), mAms.getTraceManager(),
                     mAms.getMagnificationController(),
                     detectControlGestures,
                     detectTwoFingerTripleTap,
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index b5e8c84..2eecb4d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -158,10 +158,10 @@
 import com.android.server.AccessibilityManagerInternal;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.accessibility.magnification.MagnificationConnectionManager;
 import com.android.server.accessibility.magnification.MagnificationController;
 import com.android.server.accessibility.magnification.MagnificationProcessor;
 import com.android.server.accessibility.magnification.MagnificationScaleProvider;
-import com.android.server.accessibility.magnification.WindowMagnificationManager;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.policy.WindowManagerPolicy;
@@ -3442,7 +3442,7 @@
                 && (userState.getMagnificationCapabilitiesLocked()
                 != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN)
                 || userHasMagnificationServicesLocked(userState);
-        getWindowMagnificationMgr().requestConnection(connect);
+        getMagnificationConnectionManager().requestConnection(connect);
     }
 
     /**
@@ -4122,17 +4122,17 @@
         mSecurityPolicy.enforceCallingOrSelfPermission(
                 android.Manifest.permission.STATUS_BAR_SERVICE);
 
-        getWindowMagnificationMgr().setConnection(connection);
+        getMagnificationConnectionManager().setConnection(connection);
     }
 
     /**
-     * Getter of {@link WindowMagnificationManager}.
+     * Getter of {@link MagnificationConnectionManager}.
      *
-     * @return WindowMagnificationManager
+     * @return MagnificationManager
      */
-    public WindowMagnificationManager getWindowMagnificationMgr() {
+    public MagnificationConnectionManager getMagnificationConnectionManager() {
         synchronized (mLock) {
-            return mMagnificationController.getWindowMagnificationMgr();
+            return mMagnificationController.getMagnificationConnectionManager();
         }
     }
 
@@ -4423,7 +4423,7 @@
                 pw.println();
             }
             pw.append("hasWindowMagnificationConnection=").append(
-                    String.valueOf(getWindowMagnificationMgr().isConnected()));
+                    String.valueOf(getMagnificationConnectionManager().isConnected()));
             pw.println();
             mMagnificationProcessor.dump(pw, getValidDisplayList());
             final int userCount = mUserStates.size();
@@ -5144,7 +5144,7 @@
 
             for (int i = 0; i < displays.size(); i++) {
                 final int displayId = displays.get(i).getDisplayId();
-                getWindowMagnificationMgr().removeMagnificationButton(displayId);
+                getMagnificationConnectionManager().removeMagnificationButton(displayId);
             }
         }
     }
@@ -5580,6 +5580,8 @@
 
     @Override
     public void injectInputEventToInputFilter(InputEvent event) {
+        mSecurityPolicy.enforceCallingPermission(Manifest.permission.INJECT_EVENTS,
+                "injectInputEventToInputFilter");
         synchronized (mLock) {
             final long endMillis =
                     SystemClock.uptimeMillis() + WAIT_INPUT_FILTER_INSTALL_TIMEOUT_MS;
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index d31b1ef..e3797c9 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -258,6 +258,11 @@
                 public void logMagnificationTripleTap(boolean enabled) {
                     AccessibilityStatsLogUtils.logMagnificationTripleTap(enabled);
                 }
+
+                @Override
+                public void logMagnificationTwoFingerTripleTap(boolean enabled) {
+                    AccessibilityStatsLogUtils.logMagnificationTwoFingerTripleTap(enabled);
+                }
             };
         }
 
@@ -419,6 +424,7 @@
     /** An interface that allows testing magnification log events. */
     interface MagnificationLogger {
         void logMagnificationTripleTap(boolean enabled);
+        void logMagnificationTwoFingerTripleTap(boolean enabled);
     }
 
     interface State {
@@ -987,12 +993,14 @@
                             mDisplayId, event.getX(), event.getY())) {
                         transitionToDelegatingStateAndClear();
 
+                    } else if (isMultiFingerMultiTapTriggered(/* targetTapCount= */ 3, event)) {
+                        // Placing multiple fingers before a single finger, because achieving a
+                        // multi finger multi tap also means achieving a single finger triple tap
+                        onTripleTap(event);
+
                     } else if (isMultiTapTriggered(3 /* taps */)) {
                         onTripleTap(/* up */ event);
 
-                    } else if (isMultiFingerMultiTapTriggered(/* targetTapCount= */ 3, event)) {
-                        onTripleTap(event);
-
                     } else if (
                             // Possible to be false on: 3tap&drag -> scale -> PTR_UP -> UP
                             isFingerDown()
@@ -1026,6 +1034,11 @@
                 mCompletedTapCount++;
                 mIsTwoFingerCountReached = false;
             }
+
+            if (mDetectTwoFingerTripleTap && mCompletedTapCount > 2) {
+                final boolean enabled = !isActivated();
+                mMagnificationLogger.logMagnificationTwoFingerTripleTap(enabled);
+            }
             return mDetectTwoFingerTripleTap && mCompletedTapCount == targetTapCount;
         }
 
@@ -1037,6 +1050,29 @@
             mFirstPointerDownLocation.set(Float.NaN, Float.NaN);
             mSecondPointerDownLocation.set(Float.NaN, Float.NaN);
         }
+
+        void transitionToViewportDraggingStateAndClear(MotionEvent down) {
+
+            if (DEBUG_DETECTING) Slog.i(mLogTag, "onTripleTapAndHold()");
+            final boolean shortcutTriggered = mShortcutTriggered;
+
+            // Only log the 3tap and hold event
+            if (!shortcutTriggered) {
+                final boolean enabled = !isActivated();
+                if (mCompletedTapCount == 2) {
+                    // Two finger triple tap and hold
+                    mMagnificationLogger.logMagnificationTwoFingerTripleTap(enabled);
+                } else {
+                    // Triple tap and hold also belongs to triple tap event
+                    mMagnificationLogger.logMagnificationTripleTap(enabled);
+                }
+            }
+            clear();
+
+            mViewportDraggingState.prepareForZoomInTemporary(shortcutTriggered);
+            zoomInTemporary(down.getX(), down.getY(), shortcutTriggered);
+            transitionTo(mViewportDraggingState);
+        }
     }
 
     /**
@@ -1416,8 +1452,6 @@
 
             // Only log the 3tap and hold event
             if (!shortcutTriggered) {
-                // TODO:(b/309534286): Add metrics for two-finger triple-tap and fix
-                //  the log two-finger bug before enabling the flag
                 // Triple tap and hold also belongs to triple tap event
                 final boolean enabled = !isActivated();
                 mMagnificationLogger.logMagnificationTripleTap(enabled);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
similarity index 94%
rename from services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
rename to services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
index 3ea805b..5a3c070 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
@@ -60,19 +60,19 @@
 import java.util.concurrent.atomic.AtomicLongFieldUpdater;
 
 /**
- * A class to manipulate window magnification through {@link MagnificationConnectionWrapper}
+ * A class to manipulate magnification through {@link MagnificationConnectionWrapper}
  * create by {@link #setConnection(IWindowMagnificationConnection)}. To set the connection with
  * SysUI, call {@code StatusBarManagerInternal#requestWindowMagnificationConnection(boolean)}.
  * The applied magnification scale is constrained by
  * {@link MagnificationScaleProvider#constrainScale(float)}
  */
-public class WindowMagnificationManager implements
+public class MagnificationConnectionManager implements
         PanningScalingHandler.MagnificationDelegate,
         WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks {
 
     private static final boolean DBG = false;
 
-    private static final String TAG = "WindowMagnificationMgr";
+    private static final String TAG = "MagnificationConnectionManager";
 
     /**
      * Indicate that the magnification window is at the magnification center.
@@ -208,7 +208,7 @@
     private final AccessibilityTraceManager mTrace;
     private final MagnificationScaleProvider mScaleProvider;
 
-    public WindowMagnificationManager(Context context, Object lock, @NonNull Callback callback,
+    public MagnificationConnectionManager(Context context, Object lock, @NonNull Callback callback,
             AccessibilityTraceManager trace, MagnificationScaleProvider scaleProvider) {
         mContext = context;
         mLock = lock;
@@ -1040,7 +1040,7 @@
         private float mScale = MagnificationScaleProvider.MIN_SCALE;
         private boolean mEnabled;
 
-        private final WindowMagnificationManager mWindowMagnificationManager;
+        private final MagnificationConnectionManager mMagnificationConnectionManager;
         // Records the bounds of window magnification.
         private final Rect mBounds = new Rect();
         // The magnified bounds on the screen.
@@ -1058,11 +1058,15 @@
                         "mTrackingTypingFocusSumTime");
         private volatile long mTrackingTypingFocusSumTime = 0;
 
-        WindowMagnifier(int displayId, WindowMagnificationManager windowMagnificationManager) {
+        WindowMagnifier(int displayId,
+                MagnificationConnectionManager magnificationConnectionManager) {
             mDisplayId = displayId;
-            mWindowMagnificationManager = windowMagnificationManager;
+            mMagnificationConnectionManager = magnificationConnectionManager;
         }
 
+        // TODO(b/312324808): Investigating whether
+        //  mMagnificationConnectionManager#enableWindowMagnificationInternal requires a sync lock
+        @SuppressWarnings("GuardedBy")
         boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY,
                 @Nullable MagnificationAnimationCallback animationCallback,
                 @WindowPosition int windowPosition, int id) {
@@ -1072,8 +1076,8 @@
             }
             final float normScale = MagnificationScaleProvider.constrainScale(scale);
             setMagnificationFrameOffsetRatioByWindowPosition(windowPosition);
-            if (mWindowMagnificationManager.enableWindowMagnificationInternal(mDisplayId, normScale,
-                    centerX, centerY, mMagnificationFrameOffsetRatio.x,
+            if (mMagnificationConnectionManager.enableWindowMagnificationInternal(mDisplayId,
+                    normScale, centerX, centerY, mMagnificationFrameOffsetRatio.x,
                     mMagnificationFrameOffsetRatio.y, animationCallback)) {
                 mScale = normScale;
                 mEnabled = true;
@@ -1096,12 +1100,15 @@
             }
         }
 
+        // TODO(b/312324808): Investigating whether
+        //  mMagnificationConnectionManager#disableWindowMagnificationInternal requires a sync lock
+        @SuppressWarnings("GuardedBy")
         boolean disableWindowMagnificationInternal(
                 @Nullable MagnificationAnimationCallback animationResultCallback) {
             if (!mEnabled) {
                 return false;
             }
-            if (mWindowMagnificationManager.disableWindowMagnificationInternal(
+            if (mMagnificationConnectionManager.disableWindowMagnificationInternal(
                     mDisplayId, animationResultCallback)) {
                 mEnabled = false;
                 mIdOfLastServiceToControl = INVALID_SERVICE_ID;
@@ -1112,6 +1119,10 @@
             return false;
         }
 
+        // ErrorProne says the access of mMagnificationConnectionManager#setScaleInternal should
+        // be guarded by 'this.mMagnificationConnectionManager.mLock' which is the same one as
+        // 'mLock'. Therefore, we'll put @SuppressWarnings here.
+        @SuppressWarnings("GuardedBy")
         @GuardedBy("mLock")
         void setScale(float scale) {
             if (!mEnabled) {
@@ -1119,7 +1130,8 @@
             }
             final float normScale = MagnificationScaleProvider.constrainScale(scale);
             if (Float.compare(mScale, normScale) != 0
-                    && mWindowMagnificationManager.setScaleInternal(mDisplayId, scale)) {
+                    && mMagnificationConnectionManager
+                        .setScaleForWindowMagnificationInternal(mDisplayId, scale)) {
                 mScale = normScale;
             }
         }
@@ -1159,8 +1171,8 @@
         }
 
         void setTrackingTypingFocusEnabled(boolean trackingTypingFocusEnabled) {
-            if (mWindowMagnificationManager.isWindowMagnifierEnabled(mDisplayId)
-                    && mWindowMagnificationManager.isImeVisible(mDisplayId)
+            if (mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId)
+                    && mMagnificationConnectionManager.isImeVisible(mDisplayId)
                     && trackingTypingFocusEnabled) {
                 startTrackingTypingFocusRecord();
             }
@@ -1206,7 +1218,7 @@
                     Slog.d(TAG, "stop and log: session duration = " + duration
                             + ", elapsed = " + elapsed);
                 }
-                mWindowMagnificationManager.logTrackingTypingFocus(duration);
+                mMagnificationConnectionManager.logTrackingTypingFocus(duration);
                 mTrackingTypingFocusStartTime = 0;
                 mTrackingTypingFocusSumTime = 0;
             }
@@ -1216,9 +1228,14 @@
             return mEnabled;
         }
 
+        // ErrorProne says the access of mMagnificationConnectionManager#moveWindowMagnifierInternal
+        // should be guarded by 'this.mMagnificationConnectionManager.mLock' which is the same one
+        // as 'mLock'. Therefore, we'll put @SuppressWarnings here.
+        @SuppressWarnings("GuardedBy")
         @GuardedBy("mLock")
         void move(float offsetX, float offsetY) {
-            mWindowMagnificationManager.moveWindowMagnifierInternal(mDisplayId, offsetX, offsetY);
+            mMagnificationConnectionManager.moveWindowMagnifierInternal(
+                    mDisplayId, offsetX, offsetY);
         }
 
         @GuardedBy("mLock")
@@ -1270,8 +1287,10 @@
                 animationCallback);
     }
 
-    private boolean setScaleInternal(int displayId, float scale) {
-        return mConnectionWrapper != null && mConnectionWrapper.setScale(displayId, scale);
+    @GuardedBy("mLock")
+    private boolean setScaleForWindowMagnificationInternal(int displayId, float scale) {
+        return mConnectionWrapper != null
+                && mConnectionWrapper.setScaleForWindowMagnification(displayId, scale);
     }
 
     @GuardedBy("mLock")
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java
index f0c44d6..20538f1 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java
@@ -82,16 +82,16 @@
         return true;
     }
 
-    boolean setScale(int displayId, float scale) {
+    boolean setScaleForWindowMagnification(int displayId, float scale) {
         if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
             mTrace.logTrace(TAG + ".setScale", FLAGS_WINDOW_MAGNIFICATION_CONNECTION,
                     "displayId=" + displayId + ";scale=" + scale);
         }
         try {
-            mConnection.setScale(displayId, scale);
+            mConnection.setScaleForWindowMagnification(displayId, scale);
         } catch (RemoteException e) {
             if (DBG) {
-                Slog.e(TAG, "Error calling setScale()", e);
+                Slog.e(TAG, "Error calling setScaleForWindowMagnification()", e);
             }
             return false;
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index effd873..52e123a 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -77,7 +77,7 @@
  *  <b>Note</b> Updates magnification switch UI when magnification mode transition
  *  is done and before invoking {@link TransitionCallBack#onResult}.
  */
-public class MagnificationController implements WindowMagnificationManager.Callback,
+public class MagnificationController implements MagnificationConnectionManager.Callback,
         MagnificationGestureHandler.Callback,
         FullScreenMagnificationController.MagnificationInfoChangedCallback,
         WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks {
@@ -96,7 +96,7 @@
     private final AlwaysOnMagnificationFeatureFlag mAlwaysOnMagnificationFeatureFlag;
     private final MagnificationScaleProvider mScaleProvider;
     private FullScreenMagnificationController mFullScreenMagnificationController;
-    private WindowMagnificationManager mWindowMagnificationMgr;
+    private MagnificationConnectionManager mMagnificationConnectionManager;
     private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
     /** Whether the platform supports window magnification feature. */
     private final boolean mSupportWindowMagnification;
@@ -164,11 +164,11 @@
     @VisibleForTesting
     public MagnificationController(AccessibilityManagerService ams, Object lock,
             Context context, FullScreenMagnificationController fullScreenMagnificationController,
-            WindowMagnificationManager windowMagnificationManager,
+            MagnificationConnectionManager magnificationConnectionManager,
             MagnificationScaleProvider scaleProvider, Executor backgroundExecutor) {
         this(ams, lock, context, scaleProvider, backgroundExecutor);
         mFullScreenMagnificationController = fullScreenMagnificationController;
-        mWindowMagnificationMgr = windowMagnificationManager;
+        mMagnificationConnectionManager = magnificationConnectionManager;
     }
 
     @Override
@@ -179,10 +179,10 @@
             if (updatePersistence) {
                 getFullScreenMagnificationController().persistScale(displayId);
             }
-        } else if (getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId)) {
-            getWindowMagnificationMgr().setScale(displayId, scale);
+        } else if (getMagnificationConnectionManager().isWindowMagnifierEnabled(displayId)) {
+            getMagnificationConnectionManager().setScale(displayId, scale);
             if (updatePersistence) {
-                getWindowMagnificationMgr().persistScale(displayId);
+                getMagnificationConnectionManager().persistScale(displayId);
             }
         }
     }
@@ -222,15 +222,15 @@
         }
 
         if (showModeSwitchButton) {
-            getWindowMagnificationMgr().showMagnificationButton(displayId, mode);
+            getMagnificationConnectionManager().showMagnificationButton(displayId, mode);
         } else {
-            getWindowMagnificationMgr().removeMagnificationButton(displayId);
+            getMagnificationConnectionManager().removeMagnificationButton(displayId);
         }
 
         if (!enableSettingsPanel) {
             // Whether the settings panel needs to be shown is controlled in system UI.
             // Here, we only guarantee that the settings panel is closed when it is not needed.
-            getWindowMagnificationMgr().removeMagnificationSettingsPanel(displayId);
+            getMagnificationConnectionManager().removeMagnificationSettingsPanel(displayId);
         }
     }
 
@@ -284,7 +284,8 @@
 
         final FullScreenMagnificationController screenMagnificationController =
                 getFullScreenMagnificationController();
-        final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr();
+        final MagnificationConnectionManager magnificationConnectionManager =
+                getMagnificationConnectionManager();
         final float scale = getTargetModeScaleFromCurrentMagnification(displayId, targetMode);
         final DisableMagnificationCallback animationEndCallback =
                 new DisableMagnificationCallback(transitionCallBack, displayId, targetMode,
@@ -295,7 +296,7 @@
         if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
             screenMagnificationController.reset(displayId, animationEndCallback);
         } else {
-            windowMagnificationMgr.disableWindowMagnification(displayId, false,
+            magnificationConnectionManager.disableWindowMagnification(displayId, false,
                     animationEndCallback);
         }
     }
@@ -340,7 +341,8 @@
             }
             final FullScreenMagnificationController screenMagnificationController =
                     getFullScreenMagnificationController();
-            final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr();
+            final MagnificationConnectionManager magnificationConnectionManager =
+                    getMagnificationConnectionManager();
             final float targetScale = Float.isNaN(config.getScale())
                     ? getTargetModeScaleFromCurrentMagnification(displayId, targetMode)
                     : config.getScale();
@@ -353,14 +355,15 @@
                 if (targetMode == MAGNIFICATION_MODE_WINDOW) {
                     screenMagnificationController.reset(displayId, false);
                     if (targetActivated) {
-                        windowMagnificationMgr.enableWindowMagnification(displayId,
+                        magnificationConnectionManager.enableWindowMagnification(displayId,
                                 targetScale, magnificationCenter.x, magnificationCenter.y,
                                 magnificationAnimationCallback, id);
                     } else {
-                        windowMagnificationMgr.disableWindowMagnification(displayId, false);
+                        magnificationConnectionManager.disableWindowMagnification(displayId, false);
                     }
                 } else if (targetMode == MAGNIFICATION_MODE_FULLSCREEN) {
-                    windowMagnificationMgr.disableWindowMagnification(displayId, false, null);
+                    magnificationConnectionManager.disableWindowMagnification(
+                            displayId, false, null);
                     if (targetActivated) {
                         if (!screenMagnificationController.isRegistered(displayId)) {
                             screenMagnificationController.register(displayId);
@@ -409,7 +412,7 @@
         if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
             return getFullScreenMagnificationController().getScale(displayId);
         } else {
-            return getWindowMagnificationMgr().getScale(displayId);
+            return getMagnificationConnectionManager().getScale(displayId);
         }
     }
 
@@ -441,7 +444,8 @@
             mAccessibilityCallbacksDelegateArray.put(displayId,
                     getFullScreenMagnificationController());
         } else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
-            mAccessibilityCallbacksDelegateArray.put(displayId, getWindowMagnificationMgr());
+            mAccessibilityCallbacksDelegateArray.put(
+                    displayId, getMagnificationConnectionManager());
         } else {
             mAccessibilityCallbacksDelegateArray.delete(displayId);
         }
@@ -462,13 +466,13 @@
 
     @Override
     public void onRequestMagnificationSpec(int displayId, int serviceId) {
-        final WindowMagnificationManager windowMagnificationManager;
+        final MagnificationConnectionManager magnificationConnectionManager;
         synchronized (mLock) {
             updateMagnificationUIControls(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-            windowMagnificationManager = mWindowMagnificationMgr;
+            magnificationConnectionManager = mMagnificationConnectionManager;
         }
-        if (windowMagnificationManager != null) {
-            mWindowMagnificationMgr.disableWindowMagnification(displayId, false);
+        if (magnificationConnectionManager != null) {
+            mMagnificationConnectionManager.disableWindowMagnification(displayId, false);
         }
     }
 
@@ -491,7 +495,7 @@
                 setCurrentMagnificationModeAndSwitchDelegate(displayId,
                         ACCESSIBILITY_MAGNIFICATION_MODE_NONE);
                 duration = SystemClock.uptimeMillis() - mWindowModeEnabledTimeArray.get(displayId);
-                scale = mWindowMagnificationMgr.getLastActivatedScale(displayId);
+                scale = mMagnificationConnectionManager.getLastActivatedScale(displayId);
             }
             logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, duration, scale);
         }
@@ -507,13 +511,14 @@
     public void onSourceBoundsChanged(int displayId, Rect bounds) {
         if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_WINDOW)) {
             // notify sysui the magnification scale changed on window magnifier
-            mWindowMagnificationMgr.onUserMagnificationScaleChanged(
-                    mUserId, displayId, getWindowMagnificationMgr().getScale(displayId));
+            mMagnificationConnectionManager.onUserMagnificationScaleChanged(
+                    mUserId, displayId, getMagnificationConnectionManager().getScale(displayId));
 
             final MagnificationConfig config = new MagnificationConfig.Builder()
                     .setMode(MAGNIFICATION_MODE_WINDOW)
-                    .setActivated(getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId))
-                    .setScale(getWindowMagnificationMgr().getScale(displayId))
+                    .setActivated(
+                            getMagnificationConnectionManager().isWindowMagnifierEnabled(displayId))
+                    .setScale(getMagnificationConnectionManager().getScale(displayId))
                     .setCenterX(bounds.exactCenterX())
                     .setCenterY(bounds.exactCenterY()).build();
             mAms.notifyMagnificationChanged(displayId, new Region(bounds), config);
@@ -525,7 +530,7 @@
             @NonNull MagnificationConfig config) {
         if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_FULLSCREEN)) {
             // notify sysui the magnification scale changed on fullscreen magnifier
-            mWindowMagnificationMgr.onUserMagnificationScaleChanged(
+            mMagnificationConnectionManager.onUserMagnificationScaleChanged(
                     mUserId, displayId, config.getScale());
 
             mAms.notifyMagnificationChanged(displayId, region, config);
@@ -548,8 +553,8 @@
         synchronized (mLock) {
             final boolean fullScreenActivated = mFullScreenMagnificationController != null
                     && mFullScreenMagnificationController.isActivated(displayId);
-            final boolean windowEnabled = mWindowMagnificationMgr != null
-                    && mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId);
+            final boolean windowEnabled = mMagnificationConnectionManager != null
+                    && mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId);
             final Integer transitionMode = mTransitionModes.get(displayId);
             if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenActivated)
                     || (changeMode == MAGNIFICATION_MODE_WINDOW && windowEnabled))
@@ -608,10 +613,10 @@
     }
 
     private void disableWindowMagnificationIfNeeded(int displayId) {
-        final WindowMagnificationManager windowMagnificationManager =
-                getWindowMagnificationMgr();
+        final MagnificationConnectionManager magnificationConnectionManager =
+                getMagnificationConnectionManager();
         if (isActivated(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)) {
-            windowMagnificationManager.disableWindowMagnification(displayId, false);
+            magnificationConnectionManager.disableWindowMagnification(displayId, false);
         }
     }
 
@@ -620,7 +625,7 @@
         synchronized (mLock) {
             mIsImeVisibleArray.put(displayId, shown);
         }
-        getWindowMagnificationMgr().onImeWindowVisibilityChanged(displayId, shown);
+        getMagnificationConnectionManager().onImeWindowVisibilityChanged(displayId, shown);
         logMagnificationModeWithImeOnIfNeeded(displayId);
     }
 
@@ -661,7 +666,7 @@
 
     /**
      * Updates the active user ID of {@link FullScreenMagnificationController} and {@link
-     * WindowMagnificationManager}.
+     * MagnificationConnectionManager}.
      *
      * @param userId the currently active user ID
      */
@@ -671,10 +676,10 @@
         }
         mUserId = userId;
         final FullScreenMagnificationController fullMagnificationController;
-        final WindowMagnificationManager windowMagnificationManager;
+        final MagnificationConnectionManager magnificationConnectionManager;
         synchronized (mLock) {
             fullMagnificationController = mFullScreenMagnificationController;
-            windowMagnificationManager = mWindowMagnificationMgr;
+            magnificationConnectionManager = mMagnificationConnectionManager;
             mAccessibilityCallbacksDelegateArray.clear();
             mCurrentMagnificationModeArray.clear();
             mLastMagnificationActivatedModeArray.clear();
@@ -685,8 +690,8 @@
         if (fullMagnificationController != null) {
             fullMagnificationController.resetAllIfNeeded(false);
         }
-        if (windowMagnificationManager != null) {
-            windowMagnificationManager.disableAllWindowMagnifiers();
+        if (magnificationConnectionManager != null) {
+            magnificationConnectionManager.disableAllWindowMagnifiers();
         }
     }
 
@@ -700,8 +705,8 @@
             if (mFullScreenMagnificationController != null) {
                 mFullScreenMagnificationController.onDisplayRemoved(displayId);
             }
-            if (mWindowMagnificationMgr != null) {
-                mWindowMagnificationMgr.onDisplayRemoved(displayId);
+            if (mMagnificationConnectionManager != null) {
+                mMagnificationConnectionManager.onDisplayRemoved(displayId);
             }
             mAccessibilityCallbacksDelegateArray.delete(displayId);
             mCurrentMagnificationModeArray.delete(displayId);
@@ -728,7 +733,7 @@
      * @param enabled Enable the following typing focus feature
      */
     public void setMagnificationFollowTypingEnabled(boolean enabled) {
-        getWindowMagnificationMgr().setMagnificationFollowTypingEnabled(enabled);
+        getMagnificationConnectionManager().setMagnificationFollowTypingEnabled(enabled);
         getFullScreenMagnificationController().setMagnificationFollowTypingEnabled(enabled);
     }
 
@@ -805,29 +810,29 @@
     }
 
     /**
-     * Getter of {@link WindowMagnificationManager}.
+     * Getter of {@link MagnificationConnectionManager}.
      *
-     * @return {@link WindowMagnificationManager}.
+     * @return {@link MagnificationConnectionManager}.
      */
-    public WindowMagnificationManager getWindowMagnificationMgr() {
+    public MagnificationConnectionManager getMagnificationConnectionManager() {
         synchronized (mLock) {
-            if (mWindowMagnificationMgr == null) {
-                mWindowMagnificationMgr = new WindowMagnificationManager(mContext,
+            if (mMagnificationConnectionManager == null) {
+                mMagnificationConnectionManager = new MagnificationConnectionManager(mContext,
                         mLock, this, mAms.getTraceManager(),
                         mScaleProvider);
             }
-            return mWindowMagnificationMgr;
+            return mMagnificationConnectionManager;
         }
     }
 
     private @Nullable PointF getCurrentMagnificationCenterLocked(int displayId, int targetMode) {
         if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
-            if (mWindowMagnificationMgr == null
-                    || !mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId)) {
+            if (mMagnificationConnectionManager == null
+                    || !mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId)) {
                 return null;
             }
-            mTempPoint.set(mWindowMagnificationMgr.getCenterX(displayId),
-                    mWindowMagnificationMgr.getCenterY(displayId));
+            mTempPoint.set(mMagnificationConnectionManager.getCenterX(displayId),
+                    mMagnificationConnectionManager.getCenterY(displayId));
         } else {
             if (mFullScreenMagnificationController == null
                     || !mFullScreenMagnificationController.isActivated(displayId)) {
@@ -858,10 +863,10 @@
             }
         } else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
             synchronized (mLock) {
-                if (mWindowMagnificationMgr == null) {
+                if (mMagnificationConnectionManager == null) {
                     return false;
                 }
-                isActivated = mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId);
+                isActivated = mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId);
             }
         }
         return isActivated;
@@ -980,7 +985,7 @@
                         mCurrentCenter.x, mCurrentCenter.y, mAnimate,
                         MAGNIFICATION_GESTURE_HANDLER_ID);
             } else {
-                getWindowMagnificationMgr().enableWindowMagnification(mDisplayId,
+                getMagnificationConnectionManager().enableWindowMagnification(mDisplayId,
                         mCurrentScale, mCurrentCenter.x,
                         mCurrentCenter.y, mAnimate ? STUB_ANIMATION_CALLBACK : null,
                         MAGNIFICATION_GESTURE_HANDLER_ID);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java
index 5cf2a63..ed8f1ab 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java
@@ -84,13 +84,13 @@
                     .setCenterX(fullScreenMagnificationController.getCenterX(displayId))
                     .setCenterY(fullScreenMagnificationController.getCenterY(displayId));
         } else if (mode == MAGNIFICATION_MODE_WINDOW) {
-            final WindowMagnificationManager windowMagnificationManager =
-                    mController.getWindowMagnificationMgr();
+            final MagnificationConnectionManager magnificationConnectionManager =
+                    mController.getMagnificationConnectionManager();
             builder.setMode(mode)
                     .setActivated(mController.isActivated(displayId, MAGNIFICATION_MODE_WINDOW))
-                    .setScale(windowMagnificationManager.getScale(displayId))
-                    .setCenterX(windowMagnificationManager.getCenterX(displayId))
-                    .setCenterY(windowMagnificationManager.getCenterY(displayId));
+                    .setScale(magnificationConnectionManager.getScale(displayId))
+                    .setCenterX(magnificationConnectionManager.getCenterX(displayId))
+                    .setCenterY(magnificationConnectionManager.getCenterY(displayId));
         } else {
             // For undefined mode, set enabled to false
             builder.setActivated(false);
@@ -135,12 +135,12 @@
             }
         } else if (configMode == MAGNIFICATION_MODE_WINDOW) {
             if (configActivated) {
-                return mController.getWindowMagnificationMgr().enableWindowMagnification(displayId,
-                        config.getScale(), config.getCenterX(), config.getCenterY(),
+                return mController.getMagnificationConnectionManager().enableWindowMagnification(
+                        displayId, config.getScale(), config.getCenterX(), config.getCenterY(),
                         animate ? STUB_ANIMATION_CALLBACK : null,
                         id);
             } else {
-                return mController.getWindowMagnificationMgr()
+                return mController.getMagnificationConnectionManager()
                         .disableWindowMagnification(displayId, false);
             }
         }
@@ -256,7 +256,7 @@
         if (currentMode == MAGNIFICATION_MODE_FULLSCREEN) {
             getFullscreenMagnificationRegion(displayId, outRegion, canControlMagnification);
         } else if (currentMode == MAGNIFICATION_MODE_WINDOW) {
-            mController.getWindowMagnificationMgr().getMagnificationSourceBounds(displayId,
+            mController.getMagnificationConnectionManager().getMagnificationSourceBounds(displayId,
                     outRegion);
         }
     }
@@ -297,8 +297,8 @@
         if (mode == MAGNIFICATION_MODE_FULLSCREEN) {
             return mController.getFullScreenMagnificationController().reset(displayId, animate);
         } else if (mode == MAGNIFICATION_MODE_WINDOW) {
-            return mController.getWindowMagnificationMgr().disableWindowMagnification(displayId,
-                    false, animate ? STUB_ANIMATION_CALLBACK : null);
+            return mController.getMagnificationConnectionManager().disableWindowMagnification(
+                    displayId, false, animate ? STUB_ANIMATION_CALLBACK : null);
         }
         return false;
     }
@@ -325,19 +325,20 @@
      */
     public void resetAllIfNeeded(int connectionId) {
         mController.getFullScreenMagnificationController().resetAllIfNeeded(connectionId);
-        mController.getWindowMagnificationMgr().resetAllIfNeeded(connectionId);
+        mController.getMagnificationConnectionManager().resetAllIfNeeded(connectionId);
     }
 
     /**
      * {@link FullScreenMagnificationController#isActivated(int)}
-     * {@link WindowMagnificationManager#isWindowMagnifierEnabled(int)}
+     * {@link MagnificationConnectionManager#isWindowMagnifierEnabled(int)}
      */
     public boolean isMagnifying(int displayId) {
         int mode = getControllingMode(displayId);
         if (mode == MAGNIFICATION_MODE_FULLSCREEN) {
             return mController.getFullScreenMagnificationController().isActivated(displayId);
         } else if (mode == MAGNIFICATION_MODE_WINDOW) {
-            return mController.getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId);
+            return mController.getMagnificationConnectionManager().isWindowMagnifierEnabled(
+                    displayId);
         }
         return false;
     }
@@ -416,22 +417,23 @@
         pw.append("    SupportWindowMagnification="
                 + mController.supportWindowMagnification()).println();
         pw.append("    WindowMagnificationConnectionState="
-                + mController.getWindowMagnificationMgr().getConnectionState()).println();
+                + mController.getMagnificationConnectionManager().getConnectionState()).println();
     }
 
     private int getIdOfLastServiceToMagnify(int mode, int displayId) {
         return (mode == MAGNIFICATION_MODE_FULLSCREEN)
                 ? mController.getFullScreenMagnificationController()
                 .getIdOfLastServiceToMagnify(displayId)
-                : mController.getWindowMagnificationMgr().getIdOfLastServiceToMagnify(
+                : mController.getMagnificationConnectionManager().getIdOfLastServiceToMagnify(
                         displayId);
     }
 
     private void dumpTrackingTypingFocusEnabledState(final PrintWriter pw, int displayId,
             int mode) {
         if (mode == MAGNIFICATION_MODE_WINDOW) {
-            pw.append("    TrackingTypingFocusEnabled="  + mController
-                            .getWindowMagnificationMgr().isTrackingTypingFocusEnabled(displayId))
+            pw.append("    TrackingTypingFocusEnabled="
+                            + mController.getMagnificationConnectionManager()
+                                .isTrackingTypingFocusEnabled(displayId))
                     .println();
         }
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
index 9455628..6b48d2b 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
@@ -45,6 +45,7 @@
     private static final String TAG = "PanningScalingHandler";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
+    // TODO(b/312372035): Revisit the scope of usage of the interface
     interface MagnificationDelegate {
         boolean processScroll(int displayId, float distanceX, float distanceY);
         void setScale(int displayId, float scale);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
index 36e75118..73c267a 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
@@ -79,7 +79,7 @@
     private static final float MIN_SCALE = 1.0f;
     private static final float MAX_SCALE = MagnificationScaleProvider.MAX_SCALE;
 
-    private final WindowMagnificationManager mWindowMagnificationMgr;
+    private final MagnificationConnectionManager mMagnificationConnectionManager;
     @VisibleForTesting
     final DelegatingState mDelegatingState;
     @VisibleForTesting
@@ -101,7 +101,7 @@
     private long mTripleTapAndHoldStartedTime = 0;
 
     public WindowMagnificationGestureHandler(@UiContext Context context,
-            WindowMagnificationManager windowMagnificationMgr,
+            MagnificationConnectionManager magnificationConnectionManager,
             AccessibilityTraceManager trace,
             Callback callback,
             boolean detectSingleFingerTripleTap,
@@ -115,7 +115,7 @@
                     "WindowMagnificationGestureHandler() , displayId = " + displayId + ")");
         }
         mContext = context;
-        mWindowMagnificationMgr = windowMagnificationMgr;
+        mMagnificationConnectionManager = magnificationConnectionManager;
         mMotionEventDispatcherDelegate = new MotionEventDispatcherDelegate(context,
                 (event, rawEvent, policyFlags) -> dispatchTransformedEvent(event, rawEvent,
                         policyFlags));
@@ -128,18 +128,18 @@
                             @Override
                             public boolean processScroll(int displayId, float distanceX,
                                     float distanceY) {
-                                return mWindowMagnificationMgr.processScroll(displayId, distanceX,
-                                        distanceY);
+                                return mMagnificationConnectionManager.processScroll(
+                                        displayId, distanceX, distanceY);
                             }
 
                             @Override
                             public void setScale(int displayId, float scale) {
-                                mWindowMagnificationMgr.setScale(displayId, scale);
+                                mMagnificationConnectionManager.setScale(displayId, scale);
                             }
 
                             @Override
                             public float getScale(int displayId) {
-                                return mWindowMagnificationMgr.getScale(displayId);
+                                return mMagnificationConnectionManager.getScale(displayId);
                             }
                         }));
 
@@ -167,7 +167,7 @@
             Slog.i(mLogTag, "onDestroy(); delayed = "
                     + mDetectingState.toString());
         }
-        mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, true);
+        mMagnificationConnectionManager.disableWindowMagnification(mDisplayId, true);
         resetToDetectState();
     }
 
@@ -176,7 +176,7 @@
         final Point screenSize = mTempPoint;
         getScreenSize(mTempPoint);
         toggleMagnification(screenSize.x / 2.0f, screenSize.y / 2.0f,
-                WindowMagnificationManager.WINDOW_POSITION_AT_CENTER);
+                MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER);
     }
 
     private  void getScreenSize(Point outSize) {
@@ -190,28 +190,29 @@
     }
 
     private void enableWindowMagnifier(float centerX, float centerY,
-            @WindowMagnificationManager.WindowPosition int windowPosition) {
+            @MagnificationConnectionManager.WindowPosition int windowPosition) {
         if (DEBUG_ALL) {
             Slog.i(mLogTag, "enableWindowMagnifier :"
                     + centerX + ", " + centerY + ", " + windowPosition);
         }
 
         final float scale = MathUtils.constrain(
-                mWindowMagnificationMgr.getPersistedScale(mDisplayId), MIN_SCALE, MAX_SCALE);
-        mWindowMagnificationMgr.enableWindowMagnification(mDisplayId, scale, centerX, centerY,
-                windowPosition);
+                mMagnificationConnectionManager.getPersistedScale(mDisplayId),
+                MIN_SCALE, MAX_SCALE);
+        mMagnificationConnectionManager.enableWindowMagnification(
+                mDisplayId, scale, centerX, centerY, windowPosition);
     }
 
     private void disableWindowMagnifier() {
         if (DEBUG_ALL) {
             Slog.i(mLogTag, "disableWindowMagnifier()");
         }
-        mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, false);
+        mMagnificationConnectionManager.disableWindowMagnification(mDisplayId, false);
     }
 
     private void toggleMagnification(float centerX, float centerY,
-            @WindowMagnificationManager.WindowPosition int windowPosition) {
-        if (mWindowMagnificationMgr.isWindowMagnifierEnabled(mDisplayId)) {
+            @MagnificationConnectionManager.WindowPosition int windowPosition) {
+        if (mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId)) {
             disableWindowMagnifier();
         } else {
             enableWindowMagnifier(centerX, centerY, windowPosition);
@@ -223,7 +224,7 @@
             Slog.i(mLogTag, "onTripleTap()");
         }
         toggleMagnification(up.getX(), up.getY(),
-                WindowMagnificationManager.WINDOW_POSITION_AT_CENTER);
+                MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER);
     }
 
     @VisibleForTesting
@@ -232,9 +233,9 @@
             Slog.i(mLogTag, "onTripleTapAndHold()");
         }
         mViewportDraggingState.mEnabledBeforeDrag =
-                mWindowMagnificationMgr.isWindowMagnifierEnabled(mDisplayId);
+                mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId);
         enableWindowMagnifier(up.getX(), up.getY(),
-                WindowMagnificationManager.WINDOW_POSITION_AT_TOP_LEFT);
+                MagnificationConnectionManager.WINDOW_POSITION_AT_TOP_LEFT);
         mTripleTapAndHoldStartedTime = SystemClock.uptimeMillis();
         transitionTo(mViewportDraggingState);
     }
@@ -242,7 +243,7 @@
     @VisibleForTesting
     void releaseTripleTapAndHold() {
         if (!mViewportDraggingState.mEnabledBeforeDrag) {
-            mWindowMagnificationMgr.disableWindowMagnification(mDisplayId, true);
+            mMagnificationConnectionManager.disableWindowMagnification(mDisplayId, true);
         }
         transitionTo(mDetectingState);
         if (mTripleTapAndHoldStartedTime != 0) {
@@ -331,7 +332,7 @@
         @Override
         public void onExit() {
             mPanningScalingHandler.setEnabled(false);
-            mWindowMagnificationMgr.persistScale(mDisplayId);
+            mMagnificationConnectionManager.persistScale(mDisplayId);
             clear();
         }
 
@@ -404,7 +405,7 @@
                     if (!Float.isNaN(mLastX) && !Float.isNaN(mLastY)) {
                         float offsetX = event.getX() - mLastX;
                         float offsetY = event.getY() - mLastY;
-                        mWindowMagnificationMgr.moveWindowMagnification(mDisplayId, offsetX,
+                        mMagnificationConnectionManager.moveWindowMagnification(mDisplayId, offsetX,
                                 offsetY);
                     }
                     mLastX = event.getX();
@@ -522,7 +523,7 @@
 
         @Override
         public boolean shouldStopDetection(MotionEvent motionEvent) {
-            return !mWindowMagnificationMgr.isWindowMagnifierEnabled(mDisplayId)
+            return !mMagnificationConnectionManager.isWindowMagnifierEnabled(mDisplayId)
                     && !mDetectSingleFingerTripleTap
                     && !(mDetectTwoFingerTripleTap
                     && Flags.enableMagnificationMultipleFingerMultipleTapGesture());
@@ -540,7 +541,8 @@
                         "onGestureDetected : delayedEventQueue = " + delayedEventQueue);
             }
             if (gestureId == MagnificationGestureMatcher.GESTURE_TWO_FINGERS_DOWN_OR_SWIPE
-                    && mWindowMagnificationMgr.pointersInWindow(mDisplayId, motionEvent) > 0) {
+                    && mMagnificationConnectionManager
+                        .pointersInWindow(mDisplayId, motionEvent) > 0) {
                 transitionTo(mObservePanningScalingState);
             } else if (gestureId == MagnificationGestureMatcher.GESTURE_TRIPLE_TAP) {
                 onTripleTap(motionEvent);
@@ -584,7 +586,7 @@
                 + ", mMagnifiedInteractionState=" + mObservePanningScalingState
                 + ", mCurrentState=" + State.nameOf(mCurrentState)
                 + ", mPreviousState=" + State.nameOf(mPreviousState)
-                + ", mWindowMagnificationMgr=" + mWindowMagnificationMgr
+                + ", mMagnificationConnectionManager=" + mMagnificationConnectionManager
                 + ", mDisplayId=" + mDisplayId
                 + '}';
     }
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 96a873e..316a16d 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -32,7 +32,6 @@
 import android.annotation.Nullable;
 import android.app.ApplicationThreadConstants;
 import android.app.IBackupAgent;
-import android.app.backup.BackupAnnotations;
 import android.app.backup.BackupDataInput;
 import android.app.backup.BackupDataOutput;
 import android.app.backup.BackupManagerMonitor;
@@ -183,8 +182,7 @@
         mUserId = 0;
         mBackupEligibilityRules = null;
         this.backupManagerService = backupManagerService;
-        mBackupManagerMonitorEventSender =
-                new BackupManagerMonitorEventSender(/*monitor*/null);
+        mBackupManagerMonitorEventSender = new BackupManagerMonitorEventSender(/* monitor= */ null);
     }
 
     // This task can assume that the wakelock is properly held for it and doesn't have to worry
@@ -212,8 +210,7 @@
 
         mTransportConnection = transportConnection;
         mObserver = observer;
-        mBackupManagerMonitorEventSender =
-                new BackupManagerMonitorEventSender(monitor);
+        mBackupManagerMonitorEventSender = new BackupManagerMonitorEventSender(monitor);
         mToken = restoreSetToken;
         mPmToken = pmToken;
         mTargetPackage = targetPackage;
@@ -221,9 +218,10 @@
         mFinished = false;
         mDidLaunch = false;
         mListener = listener;
-        mAgentTimeoutParameters = Objects.requireNonNull(
-                backupManagerService.getAgentTimeoutParameters(),
-                "Timeout parameters cannot be null");
+        mAgentTimeoutParameters =
+                Objects.requireNonNull(
+                        backupManagerService.getAgentTimeoutParameters(),
+                        "Timeout parameters cannot be null");
         mBackupEligibilityRules = backupEligibilityRules;
 
         if (targetPackage != null) {
@@ -236,7 +234,8 @@
                 // We want everything and a pony
                 List<PackageInfo> apps =
                         PackageManagerBackupAgent.getStorableApplications(
-                                backupManagerService.getPackageManager(), mUserId,
+                                backupManagerService.getPackageManager(),
+                                mUserId,
                                 backupEligibilityRules);
                 filterSet = packagesToNames(apps);
                 if (DEBUG) {
@@ -264,11 +263,11 @@
                         continue;
                     }
 
-
                     ApplicationInfo applicationInfo = info.applicationInfo;
                     if (backupEligibilityRules.appIsEligibleForBackup(applicationInfo)) {
                         if (Flags.enableSkippingRestoreLaunchedApps()
-                            && !backupEligibilityRules.isAppEligibleForRestore(applicationInfo)) {
+                                && !backupEligibilityRules.isAppEligibleForRestore(
+                                        applicationInfo)) {
                             continue;
                         }
 
@@ -280,16 +279,21 @@
             }
             if (hasSystem) {
                 try {
-                    mAcceptSet.add(0, backupManagerService.getPackageManager().getPackageInfoAsUser(
-                                    PLATFORM_PACKAGE_NAME, 0, mUserId));
+                    mAcceptSet.add(
+                            0,
+                            backupManagerService
+                                    .getPackageManager()
+                                    .getPackageInfoAsUser(PLATFORM_PACKAGE_NAME, 0, mUserId));
                 } catch (NameNotFoundException e) {
                     // won't happen; we know a priori that it's valid
                 }
             }
             if (hasSettings) {
                 try {
-                    mAcceptSet.add(backupManagerService.getPackageManager().getPackageInfoAsUser(
-                            SETTINGS_PACKAGE, 0, mUserId));
+                    mAcceptSet.add(
+                            backupManagerService
+                                    .getPackageManager()
+                                    .getPackageInfoAsUser(SETTINGS_PACKAGE, 0, mUserId));
                 } catch (NameNotFoundException e) {
                     // this one is always valid too
                 }
@@ -402,15 +406,15 @@
         // If we're starting a full-system restore, set up to begin widget ID remapping
         if (mIsSystemRestore) {
             AppWidgetBackupBridge.systemRestoreStarting(mUserId);
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
                     BackupManagerMonitor.LOG_EVENT_ID_START_SYSTEM_RESTORE,
                     null,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                     monitoringExtras);
         } else {
-            //We are either performing RestoreAtInstall or Bmgr.
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            // We are either performing RestoreAtInstall or Bmgr.
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
                     BackupManagerMonitor.LOG_EVENT_ID_START_RESTORE_AT_INSTALL,
                     null,
@@ -443,7 +447,7 @@
             mStatus = transport.startRestore(mToken, packages);
             if (mStatus != BackupTransport.TRANSPORT_OK) {
                 Slog.e(TAG, "Transport error " + mStatus + "; no restore possible");
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_DURING_START_RESTORE,
                         mCurrentPackage,
@@ -457,7 +461,7 @@
             RestoreDescription desc = transport.nextRestorePackage();
             if (desc == null) {
                 Slog.e(TAG, "No restore metadata available; halting");
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_NO_RESTORE_METADATA_AVAILABLE,
                         mCurrentPackage,
@@ -467,11 +471,9 @@
                 executeNextState(UnifiedRestoreState.FINAL);
                 return;
             }
-            if (!PACKAGE_MANAGER_SENTINEL.equals(
-                    desc.getPackageName())) {
-                Slog.e(TAG, "Required package metadata but got "
-                        + desc.getPackageName());
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            if (!PACKAGE_MANAGER_SENTINEL.equals(desc.getPackageName())) {
+                Slog.e(TAG, "Required package metadata but got " + desc.getPackageName());
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_NO_PM_METADATA_RECEIVED,
                         mCurrentPackage,
@@ -500,26 +502,27 @@
             // message and jump straight to the FINAL state.  Because this was
             // synchronous we also know that we should cancel the pending timeout
             // message.
-            backupManagerService.getBackupHandler().removeMessages(
-                    MSG_RESTORE_OPERATION_TIMEOUT);
+            backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_OPERATION_TIMEOUT);
 
             // Verify that the backup set includes metadata.  If not, we can't do
             // signature/version verification etc, so we simply do not proceed with
             // the restore operation.
             if (!mPmAgent.hasMetadata()) {
                 Slog.e(TAG, "PM agent has no metadata, so not restoring");
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_PM_AGENT_HAS_NO_METADATA,
                         mCurrentPackage,
                         BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                         monitoringExtras);
-                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
+                EventLog.writeEvent(
+                        EventLogTags.RESTORE_AGENT_FAILURE,
                         PACKAGE_MANAGER_SENTINEL,
                         "Package manager restore metadata missing");
                 mStatus = BackupTransport.TRANSPORT_ERROR;
-                backupManagerService.getBackupHandler().removeMessages(
-                        MSG_BACKUP_RESTORE_STEP, this);
+                backupManagerService
+                        .getBackupHandler()
+                        .removeMessages(MSG_BACKUP_RESTORE_STEP, this);
                 executeNextState(UnifiedRestoreState.FINAL);
                 return;
             }
@@ -530,15 +533,14 @@
         } catch (Exception e) {
             // If we lost the transport at any time, halt
             Slog.e(TAG, "Unable to contact transport for restore: " + e.getMessage());
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
                     BackupManagerMonitor.LOG_EVENT_ID_LOST_TRANSPORT,
                     null,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
                     monitoringExtras);
             mStatus = BackupTransport.TRANSPORT_ERROR;
-            backupManagerService.getBackupHandler().removeMessages(
-                    MSG_BACKUP_RESTORE_STEP, this);
+            backupManagerService.getBackupHandler().removeMessages(MSG_BACKUP_RESTORE_STEP, this);
             executeNextState(UnifiedRestoreState.FINAL);
             return;
         }
@@ -553,10 +555,10 @@
                     mTransportConnection.connectOrThrow(
                             "PerformUnifiedRestoreTask.dispatchNextRestore()");
             mRestoreDescription = transport.nextRestorePackage();
-            final String pkgName = (mRestoreDescription != null)
-                    ? mRestoreDescription.getPackageName() : null;
+            final String pkgName =
+                    (mRestoreDescription != null) ? mRestoreDescription.getPackageName() : null;
             if (pkgName == null) {
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_CANNOT_GET_NEXT_PKG_NAME,
                         null,
@@ -586,23 +588,26 @@
             if (metaInfo == null) {
                 PackageInfo pkgInfo = new PackageInfo();
                 pkgInfo.packageName = pkgName;
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_PM_AGENT_HAS_NO_METADATA,
                         pkgInfo,
                         BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                         monitoringExtras);
                 Slog.e(TAG, "No metadata for " + pkgName);
-                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName,
-                        "Package metadata missing");
+                EventLog.writeEvent(
+                        EventLogTags.RESTORE_AGENT_FAILURE, pkgName, "Package metadata missing");
                 nextState = UnifiedRestoreState.RUNNING_QUEUE;
                 return;
             }
 
             try {
-                mCurrentPackage = backupManagerService.getPackageManager().getPackageInfoAsUser(
-                        pkgName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                mCurrentPackage =
+                        backupManagerService
+                                .getPackageManager()
+                                .getPackageInfoAsUser(
+                                        pkgName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_START_PACKAGE_RESTORE,
                         mCurrentPackage,
@@ -613,14 +618,14 @@
                 // Whoops, we thought we could restore this package but it
                 // turns out not to be present.  Skip it.
                 Slog.e(TAG, "Package not present: " + pkgName);
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_NOT_PRESENT,
                         mCurrentPackage,
                         BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                         monitoringExtras);
-                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName,
-                        "Package missing on device");
+                EventLog.writeEvent(
+                        EventLogTags.RESTORE_AGENT_FAILURE, pkgName, "Package missing on device");
                 nextState = UnifiedRestoreState.RUNNING_QUEUE;
                 return;
             }
@@ -630,40 +635,53 @@
                 // installed.  If the app has not declared that it is prepared to
                 // handle this case, we do not attempt the restore.
                 if ((mCurrentPackage.applicationInfo.flags
-                        & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) == 0) {
-                    String message = "Source version " + metaInfo.versionCode
-                            + " > installed version " + mCurrentPackage.getLongVersionCode();
+                                & ApplicationInfo.FLAG_RESTORE_ANY_VERSION)
+                        == 0) {
+                    String message =
+                            "Source version "
+                                    + metaInfo.versionCode
+                                    + " > installed version "
+                                    + mCurrentPackage.getLongVersionCode();
                     Slog.w(TAG, "Package " + pkgName + ": " + message);
-                    Bundle monitoringExtras = mBackupManagerMonitorEventSender.putMonitoringExtra(
-                            null,
-                            BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
-                            metaInfo.versionCode);
-                    monitoringExtras = mBackupManagerMonitorEventSender.putMonitoringExtra(
-                            monitoringExtras,
-                            BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY, false);
+                    Bundle monitoringExtras =
+                            mBackupManagerMonitorEventSender.putMonitoringExtra(
+                                    null,
+                                    BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
+                                    metaInfo.versionCode);
+                    monitoringExtras =
+                            mBackupManagerMonitorEventSender.putMonitoringExtra(
+                                    monitoringExtras,
+                                    BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY,
+                                    false);
                     monitoringExtras = addRestoreOperationTypeToEvent(monitoringExtras);
                     mBackupManagerMonitorEventSender.monitorEvent(
                             BackupManagerMonitor.LOG_EVENT_ID_RESTORE_VERSION_HIGHER,
                             mCurrentPackage,
                             BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                             monitoringExtras);
-                    EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
-                            pkgName, message);
+                    EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName, message);
                     nextState = UnifiedRestoreState.RUNNING_QUEUE;
                     return;
                 } else {
                     if (DEBUG) {
-                        Slog.v(TAG, "Source version " + metaInfo.versionCode
-                                + " > installed version " + mCurrentPackage.getLongVersionCode()
-                                + " but restoreAnyVersion");
+                        Slog.v(
+                                TAG,
+                                "Source version "
+                                        + metaInfo.versionCode
+                                        + " > installed version "
+                                        + mCurrentPackage.getLongVersionCode()
+                                        + " but restoreAnyVersion");
                     }
-                    Bundle monitoringExtras = mBackupManagerMonitorEventSender.putMonitoringExtra(
-                            null,
-                            BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
-                            metaInfo.versionCode);
-                    monitoringExtras = mBackupManagerMonitorEventSender.putMonitoringExtra(
-                            monitoringExtras,
-                            BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY, true);
+                    Bundle monitoringExtras =
+                            mBackupManagerMonitorEventSender.putMonitoringExtra(
+                                    null,
+                                    BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
+                                    metaInfo.versionCode);
+                    monitoringExtras =
+                            mBackupManagerMonitorEventSender.putMonitoringExtra(
+                                    monitoringExtras,
+                                    BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY,
+                                    true);
                     monitoringExtras = addRestoreOperationTypeToEvent(monitoringExtras);
                     mBackupManagerMonitorEventSender.monitorEvent(
                             BackupManagerMonitor.LOG_EVENT_ID_RESTORE_VERSION_HIGHER,
@@ -674,10 +692,15 @@
             }
 
             if (MORE_DEBUG) {
-                Slog.v(TAG, "Package " + pkgName
-                        + " restore version [" + metaInfo.versionCode
-                        + "] is compatible with installed version ["
-                        + mCurrentPackage.getLongVersionCode() + "]");
+                Slog.v(
+                        TAG,
+                        "Package "
+                                + pkgName
+                                + " restore version ["
+                                + metaInfo.versionCode
+                                + "] is compatible with installed version ["
+                                + mCurrentPackage.getLongVersionCode()
+                                + "]");
             }
 
             // Reset per-package preconditions and fire the appropriate next state
@@ -690,19 +713,17 @@
             } else {
                 // Unknown restore type; ignore this package and move on
                 Slog.e(TAG, "Unrecognized restore type " + type);
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);;
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_RESTORE_TYPE,
                         mCurrentPackage,
                         BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                         monitoringExtras);
                 nextState = UnifiedRestoreState.RUNNING_QUEUE;
-                return;
             }
         } catch (Exception e) {
-            Slog.e(TAG, "Can't get next restore target from transport; halting: "
-                    + e.getMessage());
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);;
+            Slog.e(TAG, "Can't get next restore target from transport; halting: " + e.getMessage());
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
                     BackupManagerMonitor.LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET,
                     mCurrentPackage,
@@ -710,7 +731,6 @@
                     monitoringExtras);
             EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
             nextState = UnifiedRestoreState.FINAL;
-            return;
         } finally {
             executeNextState(nextState);
         }
@@ -725,21 +745,25 @@
         // Validate some semantic requirements that apply in this way
         // only to the key/value restore API flow
         mBackupManagerMonitorEventSender.monitorEvent(
-                BackupManagerMonitor.LOG_EVENT_ID_KV_RESTORE, mCurrentPackage,
+                BackupManagerMonitor.LOG_EVENT_ID_KV_RESTORE,
+                mCurrentPackage,
                 BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                /*monitoringExtras*/ addRestoreOperationTypeToEvent(/*extras*/null));
+                /* extras= */ addRestoreOperationTypeToEvent(/* extras= */ null));
         if (mCurrentPackage.applicationInfo.backupAgentName == null
                 || "".equals(mCurrentPackage.applicationInfo.backupAgentName)) {
             if (MORE_DEBUG) {
-                Slog.i(TAG, "Data exists for package " + packageName
-                        + " but app has no agent; skipping");
+                Slog.i(
+                        TAG,
+                        "Data exists for package "
+                                + packageName
+                                + " but app has no agent; skipping");
             }
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
                     BackupManagerMonitor.LOG_EVENT_ID_APP_HAS_NO_AGENT, mCurrentPackage,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, monitoringExtras);
-            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
-                    "Package has no agent");
+            EventLog.writeEvent(
+                    EventLogTags.RESTORE_AGENT_FAILURE, packageName, "Package has no agent");
             executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
             return;
         }
@@ -748,31 +772,34 @@
         PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
         if (!BackupUtils.signaturesMatch(metaInfo.sigHashes, mCurrentPackage, pmi)) {
             Slog.w(TAG, "Signature mismatch restoring " + packageName);
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
-                    BackupManagerMonitor.LOG_EVENT_ID_SIGNATURE_MISMATCH, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_ID_SIGNATURE_MISMATCH,
+                    mCurrentPackage,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                     monitoringExtras);
-            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
-                    "Signature mismatch");
+            EventLog.writeEvent(
+                    EventLogTags.RESTORE_AGENT_FAILURE, packageName, "Signature mismatch");
             executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
             return;
         }
 
         // Good to go!  Set up and bind the agent...
-        mAgent = backupManagerService.bindToAgentSynchronous(
-                mCurrentPackage.applicationInfo,
-                ApplicationThreadConstants.BACKUP_MODE_RESTORE,
-                mBackupEligibilityRules.getBackupDestination());
+        mAgent =
+                backupManagerService.bindToAgentSynchronous(
+                        mCurrentPackage.applicationInfo,
+                        ApplicationThreadConstants.BACKUP_MODE_RESTORE,
+                        mBackupEligibilityRules.getBackupDestination());
         if (mAgent == null) {
             Slog.w(TAG, "Can't find backup agent for " + packageName);
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
-                    BackupManagerMonitor.LOG_EVENT_ID_CANT_FIND_AGENT, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_ID_CANT_FIND_AGENT,
+                    mCurrentPackage,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                     monitoringExtras);
-            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName,
-                    "Restore agent missing");
+            EventLog.writeEvent(
+                    EventLogTags.RESTORE_AGENT_FAILURE, packageName, "Restore agent missing");
             executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
             return;
         }
@@ -786,9 +813,10 @@
             ++mCount;
         } catch (Exception e) {
             Slog.e(TAG, "Error when attempting restore: " + e.toString());
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
-                    BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR,
+                    mCurrentPackage,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
                     monitoringExtras);
             keyValueAgentErrorCleanup(false);
@@ -820,16 +848,18 @@
                             "PerformUnifiedRestoreTask.initiateOneRestore()");
 
             // Run the transport's restore pass
-            stage = ParcelFileDescriptor.open(downloadFile,
-                    ParcelFileDescriptor.MODE_READ_WRITE |
-                            ParcelFileDescriptor.MODE_CREATE |
-                            ParcelFileDescriptor.MODE_TRUNCATE);
+            stage =
+                    ParcelFileDescriptor.open(
+                            downloadFile,
+                            ParcelFileDescriptor.MODE_READ_WRITE
+                                    | ParcelFileDescriptor.MODE_CREATE
+                                    | ParcelFileDescriptor.MODE_TRUNCATE);
 
             if (transport.getRestoreData(stage) != BackupTransport.TRANSPORT_OK) {
                 // Transport-level failure. This failure could be specific to package currently in
                 // restore.
                 Slog.e(TAG, "Error getting restore data for " + packageName);
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_KV_RESTORE,
                         mCurrentPackage,
@@ -840,7 +870,7 @@
                 downloadFile.delete();
                 UnifiedRestoreState nextState =
                         BackupAndRestoreFeatureFlags
-                                .getUnifiedRestoreContinueAfterTransportFailureInKvRestore()
+                                        .getUnifiedRestoreContinueAfterTransportFailureInKvRestore()
                                 ? UnifiedRestoreState.RUNNING_QUEUE
                                 : UnifiedRestoreState.FINAL;
                 executeNextState(nextState);
@@ -852,13 +882,16 @@
             // if appropriate
             if (staging) {
                 stage.close();
-                stage = ParcelFileDescriptor.open(downloadFile,
-                        ParcelFileDescriptor.MODE_READ_ONLY);
+                stage =
+                        ParcelFileDescriptor.open(
+                                downloadFile, ParcelFileDescriptor.MODE_READ_ONLY);
 
-                mBackupData = ParcelFileDescriptor.open(mBackupDataName,
-                        ParcelFileDescriptor.MODE_READ_WRITE |
-                                ParcelFileDescriptor.MODE_CREATE |
-                                ParcelFileDescriptor.MODE_TRUNCATE);
+                mBackupData =
+                        ParcelFileDescriptor.open(
+                                mBackupDataName,
+                                ParcelFileDescriptor.MODE_READ_WRITE
+                                        | ParcelFileDescriptor.MODE_CREATE
+                                        | ParcelFileDescriptor.MODE_TRUNCATE);
 
                 BackupDataInput in = new BackupDataInput(stage.getFileDescriptor());
                 BackupDataOutput out = new BackupDataOutput(mBackupData.getFileDescriptor());
@@ -870,34 +903,40 @@
             // Okay, we have the data.  Now have the agent do the restore.
             stage.close();
 
-            mBackupData = ParcelFileDescriptor.open(mBackupDataName,
-                    ParcelFileDescriptor.MODE_READ_ONLY);
+            mBackupData =
+                    ParcelFileDescriptor.open(mBackupDataName, ParcelFileDescriptor.MODE_READ_ONLY);
 
-            mNewState = ParcelFileDescriptor.open(mNewStateName,
-                    ParcelFileDescriptor.MODE_READ_WRITE |
-                            ParcelFileDescriptor.MODE_CREATE |
-                            ParcelFileDescriptor.MODE_TRUNCATE);
+            mNewState =
+                    ParcelFileDescriptor.open(
+                            mNewStateName,
+                            ParcelFileDescriptor.MODE_READ_WRITE
+                                    | ParcelFileDescriptor.MODE_CREATE
+                                    | ParcelFileDescriptor.MODE_TRUNCATE);
 
             // Kick off the restore, checking for hung agents.  The timeout or
             // the operationComplete() callback will schedule the next step,
             // so we do not do that here.
-            long restoreAgentTimeoutMillis = mAgentTimeoutParameters.getRestoreAgentTimeoutMillis(
-                    app.applicationInfo.uid);
+            long restoreAgentTimeoutMillis =
+                    mAgentTimeoutParameters.getRestoreAgentTimeoutMillis(app.applicationInfo.uid);
             backupManagerService.prepareOperationTimeout(
                     mEphemeralOpToken, restoreAgentTimeoutMillis, this, OpType.RESTORE_WAIT);
             startedAgentRestore = true;
-            mAgent.doRestoreWithExcludedKeys(mBackupData, appVersionCode, mNewState,
-                    mEphemeralOpToken, backupManagerService.getBackupManagerBinder(),
+            mAgent.doRestoreWithExcludedKeys(
+                    mBackupData,
+                    appVersionCode,
+                    mNewState,
+                    mEphemeralOpToken,
+                    backupManagerService.getBackupManagerBinder(),
                     new ArrayList<>(getExcludedKeysForPackage(packageName)));
         } catch (Exception e) {
             Slog.e(TAG, "Unable to call app for restore: " + packageName, e);
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
-                    BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR,
+                    mCurrentPackage,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
                     monitoringExtras);
-            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
-                    packageName, e.toString());
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName, e.toString());
             // Clears any pending timeout messages as well.
             keyValueAgentErrorCleanup(startedAgentRestore);
 
@@ -915,8 +954,8 @@
         // 2. Widget metadata needs to be separated from the rest to be handled separately
         // But 'android' package doesn't contain widget metadata so we want to skip staging for it
         // when there are no keys to be excluded either.
-        return !packageName.equals(PLATFORM_PACKAGE_NAME) ||
-                !getExcludedKeysForPackage(PLATFORM_PACKAGE_NAME).isEmpty();
+        return !packageName.equals(PLATFORM_PACKAGE_NAME)
+                || !getExcludedKeysForPackage(PLATFORM_PACKAGE_NAME).isEmpty();
     }
 
     @VisibleForTesting
@@ -970,14 +1009,16 @@
         // When finished, StreamFeederThread executes next state as appropriate on the
         // backup looper, and the overall unified restore task resumes
         mBackupManagerMonitorEventSender.monitorEvent(
-                BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE, mCurrentPackage,
+                BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE,
+                mCurrentPackage,
                 BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                /*monitoringExtras*/ addRestoreOperationTypeToEvent(/*extras*/null));
+                /* extras= */ addRestoreOperationTypeToEvent(/* extras= */ null));
         try {
             StreamFeederThread feeder = new StreamFeederThread();
             if (MORE_DEBUG) {
-                Slog.i(TAG, "Spinning threads for stream restore of "
-                        + mCurrentPackage.packageName);
+                Slog.i(
+                        TAG,
+                        "Spinning threads for stream restore of " + mCurrentPackage.packageName);
             }
             new Thread(feeder, "unified-stream-feeder").start();
 
@@ -988,9 +1029,10 @@
             // current target.  We haven't asked the transport for data yet, though,
             // so we can do that simply by going back to running the restore queue.
             Slog.e(TAG, "Unable to construct pipes for stream restore!");
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
-                    BackupManagerMonitor.LOG_EVENT_ID_NO_FEEDER_THREAD, mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_ID_NO_FEEDER_THREAD,
+                    mCurrentPackage,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                     monitoringExtras);
             executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
@@ -1005,24 +1047,24 @@
         try {
             long restoreAgentFinishedTimeoutMillis =
                     mAgentTimeoutParameters.getRestoreAgentFinishedTimeoutMillis();
-            backupManagerService
-                    .prepareOperationTimeout(mEphemeralOpToken,
-                            restoreAgentFinishedTimeoutMillis, this,
-                            OpType.RESTORE_WAIT);
-            mAgent.doRestoreFinished(mEphemeralOpToken,
-                    backupManagerService.getBackupManagerBinder());
+            backupManagerService.prepareOperationTimeout(
+                    mEphemeralOpToken,
+                    restoreAgentFinishedTimeoutMillis,
+                    this,
+                    OpType.RESTORE_WAIT);
+            mAgent.doRestoreFinished(
+                    mEphemeralOpToken, backupManagerService.getBackupManagerBinder());
 
             // If we get this far, the callback or timeout will schedule the
             // next restore state, so we're done
         } catch (Exception e) {
             final String packageName = mCurrentPackage.packageName;
             Slog.e(TAG, "Unable to finalize restore of " + packageName);
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
                     BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE, mCurrentPackage,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, monitoringExtras);
-            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
-                    packageName, e.toString());
+            EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName, e.toString());
             keyValueAgentErrorCleanup(true);
             executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
         }
@@ -1054,13 +1096,20 @@
             UnifiedRestoreState nextState = UnifiedRestoreState.RUNNING_QUEUE;
             int status = BackupTransport.TRANSPORT_OK;
 
-            EventLog.writeEvent(EventLogTags.FULL_RESTORE_PACKAGE,
-                    mCurrentPackage.packageName);
+            EventLog.writeEvent(EventLogTags.FULL_RESTORE_PACKAGE, mCurrentPackage.packageName);
 
-            mEngine = new FullRestoreEngine(backupManagerService, mOperationStorage,
-                    this, null, mBackupManagerMonitorEventSender.getMonitor(),
-                    mCurrentPackage, false, mEphemeralOpToken, false,
-                    mBackupEligibilityRules);
+            mEngine =
+                    new FullRestoreEngine(
+                            backupManagerService,
+                            mOperationStorage,
+                            /* monitorTask= */ this,
+                            /* observer= */ null,
+                            mBackupManagerMonitorEventSender.getMonitor(),
+                            mCurrentPackage,
+                            /* allowApks= */ false,
+                            mEphemeralOpToken,
+                            /* isAdbRestore= */ false,
+                            mBackupEligibilityRules);
             mEngineThread = new FullRestoreEngineThread(mEngine, mEnginePipes[0]);
 
             ParcelFileDescriptor eWriteEnd = mEnginePipes[1];
@@ -1077,8 +1126,8 @@
 
             String callerLogString = "PerformUnifiedRestoreTask$StreamFeederThread.run()";
             try {
-                BackupTransportClient transport = mTransportConnection.connectOrThrow(
-                        callerLogString);
+                BackupTransportClient transport =
+                        mTransportConnection.connectOrThrow(callerLogString);
                 while (status == BackupTransport.TRANSPORT_OK) {
                     // have the transport write some of the restoring data to us
                     int result = transport.getNextFullRestoreDataChunk(tWriteEnd);
@@ -1104,17 +1153,24 @@
                     } else if (result == BackupTransport.NO_MORE_DATA) {
                         // Clean finish.  Wind up and we're done!
                         if (MORE_DEBUG) {
-                            Slog.i(TAG, "Got clean full-restore EOF for "
-                                    + mCurrentPackage.packageName);
+                            Slog.i(
+                                    TAG,
+                                    "Got clean full-restore EOF for "
+                                            + mCurrentPackage.packageName);
                         }
                         status = BackupTransport.TRANSPORT_OK;
                         break;
                     } else {
                         // Transport reported some sort of failure; the fall-through
                         // handling will deal properly with that.
-                        Slog.e(TAG, "Error " + result + " streaming restore for "
-                                + mCurrentPackage.packageName);
-                        Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                        Slog.e(
+                                TAG,
+                                "Error "
+                                        + result
+                                        + " streaming restore for "
+                                        + mCurrentPackage.packageName);
+                        Bundle monitoringExtras =
+                                addRestoreOperationTypeToEvent(/* extras= */ null);
                         mBackupManagerMonitorEventSender.monitorEvent(
                                 BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE,
                                 mCurrentPackage,
@@ -1132,21 +1188,23 @@
                 // but potentially recoverable; abandon this package's restore but
                 // carry on with the next restore target.
                 Slog.e(TAG, "Unable to route data for restore");
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_FULL_AGENT_ERROR,
                         mCurrentPackage,
                         BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
                         monitoringExtras);
-                EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
-                        mCurrentPackage.packageName, "I/O error on pipes");
+                EventLog.writeEvent(
+                        EventLogTags.RESTORE_AGENT_FAILURE,
+                        mCurrentPackage.packageName,
+                        "I/O error on pipes");
                 status = BackupTransport.AGENT_ERROR;
             } catch (Exception e) {
                 // The transport threw; terminate the whole operation.  Closing
                 // the sockets will wake up the engine and it will then tidy up the
                 // remote end.
                 Slog.e(TAG, "Transport failed during restore: " + e.getMessage());
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE,
                         mCurrentPackage,
@@ -1218,10 +1276,14 @@
         // BackupRestoreTask interface, specifically for timeout handling
 
         @Override
-        public void execute() { /* intentionally empty */ }
+        public void execute() {
+            // intentionally empty
+        }
 
         @Override
-        public void operationComplete(long result) { /* intentionally empty */ }
+        public void operationComplete(long result) {
+            // intentionally empty
+        }
 
         // The app has timed out handling a restoring file
         @Override
@@ -1230,10 +1292,11 @@
             if (DEBUG) {
                 Slog.w(TAG, "Full-data restore target timed out; shutting down");
             }
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
                     BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_TIMEOUT,
-                    mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+                    mCurrentPackage,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
                     monitoringExtras);
             mEngineThread.handleTimeout();
 
@@ -1252,8 +1315,7 @@
 
         String callerLogString = "PerformUnifiedRestoreTask.finalizeRestore()";
         try {
-            BackupTransportClient transport =
-                    mTransportConnection.connectOrThrow(callerLogString);
+            BackupTransportClient transport = mTransportConnection.connectOrThrow(callerLogString);
             transport.finishRestore();
         } catch (Exception e) {
             Slog.e(TAG, "Error finishing restore", e);
@@ -1278,17 +1340,21 @@
                 Slog.v(TAG, "finishing PM token " + mPmToken);
             }
             try {
-                backupManagerService.getPackageManagerBinder().finishPackageInstall(mPmToken,
-                        mDidLaunch);
-            } catch (RemoteException e) { /* can't happen */ }
+                backupManagerService
+                        .getPackageManagerBinder()
+                        .finishPackageInstall(mPmToken, mDidLaunch);
+            } catch (RemoteException e) {
+                // can't happen
+            }
         } else {
             // We were invoked via an active restore session, not by the Package
             // Manager, so start up the session timeout again.
             long restoreAgentTimeoutMillis =
                     mAgentTimeoutParameters.getRestoreSessionTimeoutMillis();
-            backupManagerService.getBackupHandler().sendEmptyMessageDelayed(
-                    MSG_RESTORE_SESSION_TIMEOUT,
-                    restoreAgentTimeoutMillis);
+            backupManagerService
+                    .getBackupHandler()
+                    .sendEmptyMessageDelayed(
+                            MSG_RESTORE_SESSION_TIMEOUT, restoreAgentTimeoutMillis);
         }
 
         if (mIsSystemRestore) {
@@ -1312,9 +1378,12 @@
                     Slog.d(TAG, "Starting next pending restore.");
                 }
                 PerformUnifiedRestoreTask task = backupManagerService.getPendingRestores().remove();
-                backupManagerService.getBackupHandler().sendMessage(
-                        backupManagerService.getBackupHandler().obtainMessage(
-                                MSG_BACKUP_RESTORE_STEP, task));
+                backupManagerService
+                        .getBackupHandler()
+                        .sendMessage(
+                                backupManagerService
+                                        .getBackupHandler()
+                                        .obtainMessage(MSG_BACKUP_RESTORE_STEP, task));
 
             } else {
                 backupManagerService.setRestoreInProgress(false);
@@ -1325,7 +1394,7 @@
         }
 
         Slog.i(TAG, "Restore complete.");
-        Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+        Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
         mBackupManagerMonitorEventSender.monitorEvent(
                 BackupManagerMonitor.LOG_EVENT_ID_RESTORE_COMPLETE,
                 null,
@@ -1381,14 +1450,15 @@
         // migration to the newly-restored device's dataset, we will change
         // the following from a discard of the newly-written state to the
         // "correct" operation of renaming into the canonical state blob.
-        mNewStateName.delete();                      // TODO: remove; see above comment
+        mNewStateName.delete(); // TODO: remove; see above comment
 
         // If this wasn't the PM pseudopackage, tear down the agent side
         if (mCurrentPackage.applicationInfo != null) {
             // unbind and tidy up even on timeout or failure
             try {
-                backupManagerService.getActivityManager().unbindBackupAgent(
-                        mCurrentPackage.applicationInfo);
+                backupManagerService
+                        .getActivityManager()
+                        .unbindBackupAgent(mCurrentPackage.applicationInfo);
 
                 // The agent was probably running with a stub Application object,
                 // which isn't a valid run mode for the main app logic.  Shut
@@ -1407,17 +1477,22 @@
                 final boolean killAfterRestore =
                         !UserHandle.isCore(mCurrentPackage.applicationInfo.uid)
                                 && ((mRestoreDescription.getDataType()
-                                == RestoreDescription.TYPE_FULL_STREAM)
-                                || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0));
+                                                == RestoreDescription.TYPE_FULL_STREAM)
+                                        || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE)
+                                                != 0));
 
                 if (mTargetPackage == null && killAfterRestore) {
                     if (DEBUG) {
-                        Slog.d(TAG, "Restore complete, killing host process of "
-                                + mCurrentPackage.applicationInfo.processName);
+                        Slog.d(
+                                TAG,
+                                "Restore complete, killing host process of "
+                                        + mCurrentPackage.applicationInfo.processName);
                     }
-                    backupManagerService.getActivityManager().killApplicationProcess(
-                            mCurrentPackage.applicationInfo.processName,
-                            mCurrentPackage.applicationInfo.uid);
+                    backupManagerService
+                            .getActivityManager()
+                            .killApplicationProcess(
+                                    mCurrentPackage.applicationInfo.processName,
+                                    mCurrentPackage.applicationInfo.uid);
                 }
             } catch (RemoteException e) {
                 // can't happen; we run in the same process as the activity manager
@@ -1434,9 +1509,12 @@
         mOperationStorage.removeOperation(mEphemeralOpToken);
 
         if (MORE_DEBUG) {
-            Slog.i(TAG, "operationComplete() during restore: target="
-                    + mCurrentPackage.packageName
-                    + " state=" + mState);
+            Slog.i(
+                    TAG,
+                    "operationComplete() during restore: target="
+                            + mCurrentPackage.packageName
+                            + " state="
+                            + mState);
         }
 
         final UnifiedRestoreState nextState;
@@ -1449,30 +1527,31 @@
                 break;
 
             case RESTORE_KEYVALUE:
-            case RESTORE_FULL: {
+            case RESTORE_FULL:
                 // Okay, we've just heard back from the agent that it's done with
                 // the restore itself.  We now have to send the same agent its
                 // doRestoreFinished() callback, so roll into that state.
                 nextState = UnifiedRestoreState.RESTORE_FINISHED;
                 break;
-            }
 
-            case RESTORE_FINISHED: {
+            case RESTORE_FINISHED:
                 // Okay, we're done with this package.  Tidy up and go on to the next
                 // app in the queue.
                 int size = (int) mBackupDataName.length();
-                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
-                        BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED, mCurrentPackage,
+                        BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED,
+                        mCurrentPackage,
                         BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                         monitoringExtras);
-                EventLog.writeEvent(EventLogTags.RESTORE_PACKAGE,
-                        mCurrentPackage.packageName, size);
+                EventLog.writeEvent(
+                        EventLogTags.RESTORE_PACKAGE, mCurrentPackage.packageName, size);
 
-                // Ask the agent for logs after doRestoreFinished() has completed executing to allow
+                // Ask the agent for logs after doRestoreFinished() has completed executing to
+                // allow
                 // it to finalize its logs.
-                mBackupManagerMonitorEventSender.monitorAgentLoggingResults(mCurrentPackage,
-                        mAgent);
+                mBackupManagerMonitorEventSender.monitorAgentLoggingResults(
+                        mCurrentPackage, mAgent);
 
                 // Just go back to running the restore queue
                 keyValueAgentCleanup();
@@ -1481,22 +1560,20 @@
                 // incorporate it into current bookeeping and then pass that along to
                 // the app as part of the restore-time work.
                 if (mWidgetData != null) {
-                    backupManagerService.restoreWidgetData(mCurrentPackage.packageName,
-                            mWidgetData);
+                    backupManagerService.restoreWidgetData(
+                            mCurrentPackage.packageName, mWidgetData);
                 }
 
                 nextState = UnifiedRestoreState.RUNNING_QUEUE;
                 break;
-            }
 
-            default: {
+            default:
                 // Some kind of horrible semantic error; we're in an unexpected state.
                 // Back off hard and wind up.
                 Slog.e(TAG, "Unexpected restore callback into state " + mState);
                 keyValueAgentErrorCleanup(true);
                 nextState = UnifiedRestoreState.FINAL;
                 break;
-            }
         }
 
         executeNextState(nextState);
@@ -1507,12 +1584,14 @@
     public void handleCancel(boolean cancelAll) {
         mOperationStorage.removeOperation(mEphemeralOpToken);
         Slog.e(TAG, "Timeout restoring application " + mCurrentPackage.packageName);
-        Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);
+        Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
         mBackupManagerMonitorEventSender.monitorEvent(
                 BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_RESTORE_TIMEOUT,
-                mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, monitoringExtras);
-        EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
-                mCurrentPackage.packageName, "restore timeout");
+                mCurrentPackage,
+                BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+                monitoringExtras);
+        EventLog.writeEvent(
+                EventLogTags.RESTORE_AGENT_FAILURE, mCurrentPackage.packageName, "restore timeout");
         // Handle like an agent that threw on invocation: wipe it and go on to the next
         keyValueAgentErrorCleanup(true);
         executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
@@ -1521,12 +1600,13 @@
     @VisibleForTesting
     void executeNextState(UnifiedRestoreState nextState) {
         if (MORE_DEBUG) {
-            Slog.i(TAG, " => executing next step on "
-                    + this + " nextState=" + nextState);
+            Slog.i(TAG, " => executing next step on " + this + " nextState=" + nextState);
         }
         mState = nextState;
-        Message msg = backupManagerService.getBackupHandler().obtainMessage(
-                MSG_BACKUP_RESTORE_STEP, this);
+        Message msg =
+                backupManagerService
+                        .getBackupHandler()
+                        .obtainMessage(MSG_BACKUP_RESTORE_STEP, this);
         backupManagerService.getBackupHandler().sendMessage(msg);
     }
 
@@ -1584,9 +1664,8 @@
         }
     }
 
-    private Bundle addRestoreOperationTypeToEvent (@Nullable Bundle extra) {
+    private Bundle addRestoreOperationTypeToEvent(@Nullable Bundle extras) {
         return mBackupManagerMonitorEventSender.putMonitoringExtra(
-                extra,
-                BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE, RESTORE);
+                extras, BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE, RESTORE);
     }
 }
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 71a1f01..cce596b 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -833,6 +833,13 @@
         }
 
         @Override
+        public boolean isPermissionTransferUserConsented(String packageName, int userId,
+                int associationId) {
+            return mSystemDataTransferProcessor.isPermissionTransferUserConsented(packageName,
+                    userId, associationId);
+        }
+
+        @Override
         public void startSystemDataTransfer(String packageName, int userId, int associationId,
                 ISystemDataTransferCallback callback) {
             mSystemDataTransferProcessor.startSystemDataTransfer(packageName, userId,
diff --git a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
index e5c847a..bd646fa 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
@@ -120,7 +120,8 @@
      * Resolve the requested association, throwing if the caller doesn't have
      * adequate permissions.
      */
-    private @NonNull AssociationInfo resolveAssociation(String packageName, int userId,
+    @NonNull
+    private AssociationInfo resolveAssociation(String packageName, int userId,
             int associationId) {
         AssociationInfo association = mAssociationStore.getAssociationById(associationId);
         association = PermissionsUtils.sanitizeWithCallerChecks(mContext, association);
@@ -133,6 +134,20 @@
     }
 
     /**
+     * Return whether the user has consented to the permission transfer for the association.
+     */
+    public boolean isPermissionTransferUserConsented(String packageName, @UserIdInt int userId,
+            int associationId) {
+        resolveAssociation(packageName, userId, associationId);
+
+        PermissionSyncRequest request = getPermissionSyncRequest(associationId);
+        if (request == null) {
+            return false;
+        }
+        return request.isUserConsented();
+    }
+
+    /**
      * Build a PendingIntent of permission sync user consent dialog
      */
     public PendingIntent buildPermissionTransferUserConsentIntent(String packageName,
diff --git a/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING b/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING
index 3583a78..a159a5e 100644
--- a/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING
+++ b/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING
@@ -55,5 +55,15 @@
         }
       ]
     }
+  ],
+  "postsubmit": [
+    {
+      "name": "CtsVirtualDevicesCameraTestCases",
+      "options": [
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    }
   ]
 }
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index e6bfeb7..45d7314 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -39,7 +39,6 @@
 import android.app.ActivityOptions;
 import android.app.PendingIntent;
 import android.app.admin.DevicePolicyManager;
-import android.app.compat.CompatChanges;
 import android.companion.AssociationInfo;
 import android.companion.virtual.IVirtualDevice;
 import android.companion.virtual.IVirtualDeviceActivityListener;
@@ -55,8 +54,6 @@
 import android.companion.virtual.flags.Flags;
 import android.companion.virtual.sensor.VirtualSensor;
 import android.companion.virtual.sensor.VirtualSensorEvent;
-import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledAfter;
 import android.content.AttributionSource;
 import android.content.ComponentName;
 import android.content.Context;
@@ -81,7 +78,6 @@
 import android.hardware.input.VirtualTouchEvent;
 import android.hardware.input.VirtualTouchscreenConfig;
 import android.os.Binder;
-import android.os.Build;
 import android.os.IBinder;
 import android.os.LocaleList;
 import android.os.Looper;
@@ -122,22 +118,6 @@
 
     private static final String TAG = "VirtualDeviceImpl";
 
-    /**
-     * Virtual displays created by a {@code VirtualDeviceManager.VirtualDevice} are more consistent
-     * with virtual displays created via {@link android.hardware.display.DisplayManager} and allow
-     * for the creation of private, auto-mirror, and fixed orientation displays since
-     * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}.
-     *
-     * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC
-     * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
-     * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
-     * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT
-     */
-    @ChangeId
-    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final long MAKE_VIRTUAL_DISPLAY_FLAGS_CONSISTENT_WITH_DISPLAY_MANAGER =
-            294837146L;
-
     private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS =
             DisplayManager.VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED
                     | DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL
@@ -365,8 +345,7 @@
         }
 
         int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS;
-        if (!CompatChanges.isChangeEnabled(
-                MAKE_VIRTUAL_DISPLAY_FLAGS_CONSISTENT_WITH_DISPLAY_MANAGER, mOwnerUid)) {
+        if (!Flags.consistentDisplayFlags()) {
             flags |= DEFAULT_VIRTUAL_DISPLAY_FLAGS_PRE_VIC;
         }
         if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) {
@@ -960,7 +939,7 @@
         if (mVirtualCameraController == null) {
             throw new UnsupportedOperationException("Virtual camera controller is not available");
         }
-        mVirtualCameraController.registerCamera(Objects.requireNonNull(cameraConfig));
+        mVirtualCameraController.registerCamera(cameraConfig);
     }
 
     @Override // Binder call
@@ -972,7 +951,19 @@
         if (mVirtualCameraController == null) {
             throw new UnsupportedOperationException("Virtual camera controller is not available");
         }
-        mVirtualCameraController.unregisterCamera(Objects.requireNonNull(cameraConfig));
+        mVirtualCameraController.unregisterCamera(cameraConfig);
+    }
+
+    @Override // Binder call
+    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    public int getVirtualCameraId(@NonNull VirtualCameraConfig cameraConfig)
+            throws RemoteException {
+        super.getVirtualCameraId_enforcePermission();
+        Objects.requireNonNull(cameraConfig);
+        if (mVirtualCameraController == null) {
+            throw new UnsupportedOperationException("Virtual camera controller is not available");
+        }
+        return mVirtualCameraController.getCameraId(cameraConfig);
     }
 
     @Override
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index d194bb2..9b78ed4 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -460,11 +460,11 @@
 
             synchronized (mVirtualDeviceManagerLock) {
                 if (!Flags.persistentDeviceIdApi() && mVirtualDevices.size() == 0) {
-                    final long callindId = Binder.clearCallingIdentity();
+                    final long callingId = Binder.clearCallingIdentity();
                     try {
                         registerCdmAssociationListener();
                     } finally {
-                        Binder.restoreCallingIdentity(callindId);
+                        Binder.restoreCallingIdentity(callingId);
                     }
                 }
                 mVirtualDevices.put(deviceId, virtualDevice);
@@ -498,13 +498,16 @@
             synchronized (mVirtualDeviceManagerLock) {
                 virtualDeviceImpl = mVirtualDevices.get(virtualDevice.getDeviceId());
                 if (virtualDeviceImpl == null) {
-                    throw new SecurityException("Invalid VirtualDevice");
+                    throw new SecurityException(
+                            "Invalid VirtualDevice (deviceId = " + virtualDevice.getDeviceId()
+                                    + ")");
                 }
             }
             if (virtualDeviceImpl.getOwnerUid() != callingUid) {
                 throw new SecurityException(
                         "uid " + callingUid
-                                + " is not the owner of the supplied VirtualDevice");
+                                + " is not the owner of the supplied VirtualDevice (deviceId = "
+                                + virtualDevice.getDeviceId() + ")");
             }
 
             return virtualDeviceImpl.createVirtualDisplay(
@@ -851,6 +854,11 @@
         }
 
         @Override
+        public int getDeviceIdForDisplayId(int displayId) {
+            return mImpl.getDeviceIdForDisplayId(displayId);
+        }
+
+        @Override
         public @Nullable String getPersistentIdForDevice(int deviceId) {
             if (deviceId == Context.DEVICE_ID_DEFAULT) {
                 return VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;
diff --git a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java
index 06be3f3..d089b05 100644
--- a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java
+++ b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java
@@ -27,14 +27,14 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.util.ArraySet;
+import android.util.ArrayMap;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
-import java.util.Set;
+import java.util.Map;
 
 /**
  * Manages the registration and removal of virtual camera from the server side.
@@ -47,10 +47,13 @@
     private static final String VIRTUAL_CAMERA_SERVICE_NAME = "virtual_camera";
     private static final String TAG = "VirtualCameraController";
 
+    private final Object mServiceLock = new Object();
+
+    @GuardedBy("mServiceLock")
     @Nullable private IVirtualCameraService mVirtualCameraService;
 
     @GuardedBy("mCameras")
-    private final Set<VirtualCameraConfig> mCameras = new ArraySet<>();
+    private final Map<IBinder, CameraDescriptor> mCameras = new ArrayMap<>();
 
     public VirtualCameraController() {
         connectVirtualCameraService();
@@ -67,19 +70,16 @@
      * @param cameraConfig The {@link VirtualCameraConfig} sent by the client.
      */
     public void registerCamera(@NonNull VirtualCameraConfig cameraConfig) {
-        // Try to connect to service if not connected already.
-        if (mVirtualCameraService == null) {
-            connectVirtualCameraService();
-        }
-        // Throw exception if we are unable to connect to service.
-        if (mVirtualCameraService == null) {
-            throw new IllegalStateException("Virtual camera service is not connected.");
-        }
+        connectVirtualCameraServiceIfNeeded();
 
         try {
             if (registerCameraWithService(cameraConfig)) {
+                CameraDescriptor cameraDescriptor =
+                        new CameraDescriptor(cameraConfig);
+                IBinder binder = cameraConfig.getCallback().asBinder();
+                binder.linkToDeath(cameraDescriptor, 0 /* flags */);
                 synchronized (mCameras) {
-                    mCameras.add(cameraConfig);
+                    mCameras.put(binder, cameraDescriptor);
                 }
             } else {
                 // TODO(b/310857519): Revisit this to find a better way of indicating failure.
@@ -96,24 +96,44 @@
      * @param cameraConfig The {@link VirtualCameraConfig} sent by the client.
      */
     public void unregisterCamera(@NonNull VirtualCameraConfig cameraConfig) {
-        try {
-            if (mVirtualCameraService == null) {
-                Slog.w(TAG, "Virtual camera service is not connected.");
+        synchronized (mCameras) {
+            IBinder binder = cameraConfig.getCallback().asBinder();
+            if (!mCameras.containsKey(binder)) {
+                Slog.w(TAG, "Virtual camera was not registered.");
             } else {
-                mVirtualCameraService.unregisterCamera(cameraConfig.getCallback().asBinder());
+                connectVirtualCameraServiceIfNeeded();
+
+                try {
+                    synchronized (mServiceLock) {
+                        mVirtualCameraService.unregisterCamera(binder);
+                    }
+                    mCameras.remove(binder);
+                } catch (RemoteException e) {
+                    e.rethrowFromSystemServer();
+                }
             }
-            synchronized (mCameras) {
-                mCameras.remove(cameraConfig);
+        }
+    }
+
+    /** Return the id of the virtual camera with the given config. */
+    public int getCameraId(@NonNull VirtualCameraConfig cameraConfig) {
+        connectVirtualCameraServiceIfNeeded();
+
+        try {
+            synchronized (mServiceLock) {
+                return mVirtualCameraService.getCameraId(cameraConfig.getCallback().asBinder());
             }
         } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
+            throw e.rethrowFromSystemServer();
         }
     }
 
     @Override
     public void binderDied() {
         Slog.d(TAG, "Virtual camera service died.");
-        mVirtualCameraService = null;
+        synchronized (mServiceLock) {
+            mVirtualCameraService = null;
+        }
         synchronized (mCameras) {
             mCameras.clear();
         }
@@ -122,32 +142,48 @@
     /** Release resources associated with this controller. */
     public void close() {
         synchronized (mCameras) {
-            if (mVirtualCameraService == null) {
-                Slog.w(TAG, "Virtual camera service is not connected.");
-            } else {
-                for (VirtualCameraConfig config : mCameras) {
-                    try {
-                        mVirtualCameraService.unregisterCamera(config.getCallback().asBinder());
-                    } catch (RemoteException e) {
-                        Slog.w(TAG, "close(): Camera failed to be removed on camera "
-                                + "service.", e);
+            if (!mCameras.isEmpty()) {
+                connectVirtualCameraServiceIfNeeded();
+
+                synchronized (mServiceLock) {
+                    for (IBinder binder : mCameras.keySet()) {
+                        try {
+                            mVirtualCameraService.unregisterCamera(binder);
+                        } catch (RemoteException e) {
+                            Slog.w(TAG, "close(): Camera failed to be removed on camera "
+                                    + "service.", e);
+                        }
                     }
                 }
+                mCameras.clear();
             }
-            mCameras.clear();
         }
-        mVirtualCameraService = null;
+        synchronized (mServiceLock) {
+            mVirtualCameraService = null;
+        }
     }
 
     /** Dumps information about this {@link VirtualCameraController} for debugging purposes. */
     public void dump(PrintWriter fout, String indent) {
         fout.println(indent + "VirtualCameraController:");
         indent += indent;
-        fout.printf("%sService:%s\n", indent, mVirtualCameraService);
         synchronized (mCameras) {
             fout.printf("%sRegistered cameras:%d%n\n", indent, mCameras.size());
-            for (VirtualCameraConfig config : mCameras) {
-                fout.printf("%s token: %s\n", indent, config);
+            for (CameraDescriptor descriptor : mCameras.values()) {
+                fout.printf("%s token: %s\n", indent, descriptor.mConfig);
+            }
+        }
+    }
+
+    private void connectVirtualCameraServiceIfNeeded() {
+        synchronized (mServiceLock) {
+            // Try to connect to service if not connected already.
+            if (mVirtualCameraService == null) {
+                connectVirtualCameraService();
+            }
+            // Throw exception if we are unable to connect to service.
+            if (mVirtualCameraService == null) {
+                throw new IllegalStateException("Virtual camera service is not connected.");
             }
         }
     }
@@ -173,7 +209,24 @@
 
     private boolean registerCameraWithService(VirtualCameraConfig config) throws RemoteException {
         VirtualCameraConfiguration serviceConfiguration = getServiceCameraConfiguration(config);
-        return mVirtualCameraService.registerCamera(config.getCallback().asBinder(),
-                serviceConfiguration);
+        synchronized (mServiceLock) {
+            return mVirtualCameraService.registerCamera(config.getCallback().asBinder(),
+                    serviceConfiguration);
+        }
+    }
+
+    private final class CameraDescriptor implements IBinder.DeathRecipient {
+
+        private final VirtualCameraConfig mConfig;
+
+        CameraDescriptor(VirtualCameraConfig config) {
+            mConfig = config;
+        }
+
+        @Override
+        public void binderDied() {
+            Slog.d(TAG, "Virtual camera binder died");
+            unregisterCamera(mConfig);
+        }
     }
 }
diff --git a/services/core/java/android/app/usage/UsageStatsManagerInternal.java b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
index fc56511..23c008e 100644
--- a/services/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -27,6 +27,7 @@
 import android.content.LocusId;
 import android.content.res.Configuration;
 import android.os.IBinder;
+import android.os.PersistableBundle;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -134,6 +135,18 @@
             @Nullable LocusId locusId, @NonNull IBinder appToken);
 
     /**
+     * Report a user interaction event to UsageStatsManager
+     *
+     * @param pkgName The package for which this user interaction event occurred.
+     * @param userId The user id to which component belongs to.
+     * @param extras The extra details about this user interaction event.
+     * {@link UsageEvents.Event#USER_INTERACTION}
+     * {@link UsageStatsManager#reportUserInteraction(String, int, PersistableBundle)}
+     */
+    public abstract void reportUserInteractionEvent(@NonNull String pkgName, @UserIdInt int userId,
+            @NonNull PersistableBundle extras);
+
+    /**
      * Prepares the UsageStatsService for shutdown.
      */
     public abstract void prepareShutdown();
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 77b6d583..eb3ec24 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -1466,8 +1466,11 @@
         if (android.security.Flags.binaryTransparencySepolicyHash()) {
             byte[] sepolicyHash = PackageUtils.computeSha256DigestForLargeFileAsBytes(
                     "/sys/fs/selinux/policy", PackageUtils.createLargeFileBuffer());
-            String sepolicyHashEncoded = HexEncoding.encodeToString(sepolicyHash, false);
-            Slog.d(TAG, "sepolicy hash: " + sepolicyHashEncoded);
+            String sepolicyHashEncoded = null;
+            if (sepolicyHash != null) {
+                sepolicyHashEncoded = HexEncoding.encodeToString(sepolicyHash, false);
+                Slog.d(TAG, "sepolicy hash: " + sepolicyHashEncoded);
+            }
             FrameworkStatsLog.write(FrameworkStatsLog.BOOT_INTEGRITY_INFO_REPORTED,
                     sepolicyHashEncoded, mVbmetaDigest);
         }
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 987507f..c258370 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -1,5 +1,5 @@
-# BootReceiver
-per-file BootReceiver.java = gaillard@google.com
+# BootReceiver / Watchdog
+per-file BootReceiver.java,Watchdog.java = gaillard@google.com
 
 # Connectivity / Networking
 per-file ConnectivityService.java,ConnectivityServiceInitializer.java,NetworkManagementService.java,NsdService.java,VpnManagerService.java = file:/services/core/java/com/android/server/net/OWNERS
@@ -35,7 +35,7 @@
 per-file MmsServiceBroker.java = file:/telephony/OWNERS
 per-file NetIdManager.java = file:/services/core/java/com/android/server/net/OWNERS
 per-file PackageWatchdog.java, RescueParty.java = file:/services/core/java/com/android/server/rollback/OWNERS
-per-file PinnerService.java = file:/apct-tests/perftests/OWNERS
+per-file PinnerService.java = file:/core/java/android/app/pinner/OWNERS
 per-file RescueParty.java = shuc@google.com, ancr@google.com, harshitmahajan@google.com
 per-file SystemClockTime.java = file:/services/core/java/com/android/server/timedetector/OWNERS
 per-file SystemTimeZone.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 0e7b4aa..c5c2b0b 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 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.
@@ -20,6 +20,9 @@
 import static android.app.ActivityManager.UID_OBSERVER_GONE;
 import static android.os.Process.SYSTEM_UID;
 
+import static com.android.server.flags.Flags.pinWebview;
+
+import android.annotation.EnforcePermission;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -28,6 +31,8 @@
 import android.app.IActivityManager;
 import android.app.SearchManager;
 import android.app.UidObserver;
+import android.app.pinner.IPinnerService;
+import android.app.pinner.PinnedFileStat;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -48,6 +53,7 @@
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.DeviceConfig;
@@ -83,6 +89,8 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -111,16 +119,15 @@
     private static final int KEY_ASSISTANT = 2;
 
     // Pin using pinlist.meta when pinning apps.
-    private static boolean PROP_PIN_PINLIST = SystemProperties.getBoolean(
-            "pinner.use_pinlist", true);
-    // Pin the whole odex/vdex/etc file when pinning apps.
-    private static boolean PROP_PIN_ODEX = SystemProperties.getBoolean(
-            "pinner.whole_odex", true);
+    private static boolean PROP_PIN_PINLIST =
+            SystemProperties.getBoolean("pinner.use_pinlist", true);
 
     private static final int MAX_CAMERA_PIN_SIZE = 80 * (1 << 20); // 80MB max for camera app.
     private static final int MAX_HOME_PIN_SIZE = 6 * (1 << 20); // 6MB max for home app.
     private static final int MAX_ASSISTANT_PIN_SIZE = 60 * (1 << 20); // 60MB max for assistant app.
 
+    public static final String ANON_REGION_STAT_NAME = "[anon]";
+
     @IntDef({KEY_CAMERA, KEY_HOME, KEY_ASSISTANT})
     @Retention(RetentionPolicy.SOURCE)
     public @interface AppKey {}
@@ -135,8 +142,7 @@
     private SearchManager mSearchManager;
 
     /** The list of the statically pinned files. */
-    @GuardedBy("this")
-    private final ArrayList<PinnedFile> mPinnedFiles = new ArrayList<>();
+    @GuardedBy("this") private final ArrayMap<String, PinnedFile> mPinnedFiles = new ArrayMap<>();
 
     /** The list of the pinned apps. This is a map from {@link AppKey} to a pinned app. */
     @GuardedBy("this")
@@ -175,6 +181,7 @@
     private final boolean mConfiguredToPinCamera;
     private final boolean mConfiguredToPinHome;
     private final boolean mConfiguredToPinAssistant;
+    private final int mConfiguredWebviewPinBytes;
 
     private BinderService mBinderService;
     private PinnerHandler mPinnerHandler = null;
@@ -214,6 +221,11 @@
         protected void publishBinderService(PinnerService service, Binder binderService) {
             service.publishBinderService("pinner", binderService);
         }
+
+        protected PinnedFile pinFileInternal(String fileToPin,
+                int maxBytesToPin, boolean attemptPinIntrospection) {
+            return PinnerService.pinFileInternal(fileToPin, maxBytesToPin, attemptPinIntrospection);
+        }
     }
 
     public PinnerService(Context context) {
@@ -233,6 +245,8 @@
                 com.android.internal.R.bool.config_pinnerHomeApp);
         mConfiguredToPinAssistant = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_pinnerAssistantApp);
+        mConfiguredWebviewPinBytes = context.getResources().getInteger(
+                com.android.internal.R.integer.config_pinnerWebviewPinBytes);
         mPinKeys = createPinKeys();
         mPinnerHandler = new PinnerHandler(BackgroundThread.get().getLooper());
 
@@ -322,7 +336,7 @@
     public List<PinnedFileStats> dumpDataForStatsd() {
         List<PinnedFileStats> pinnedFileStats = new ArrayList<>();
         synchronized (PinnerService.this) {
-            for (PinnedFile pinnedFile : mPinnedFiles) {
+            for (PinnedFile pinnedFile : mPinnedFiles.values()) {
                 pinnedFileStats.add(new PinnedFileStats(SYSTEM_UID, pinnedFile));
             }
 
@@ -358,39 +372,17 @@
             com.android.internal.R.array.config_defaultPinnerServiceFiles);
         // Continue trying to pin each file even if we fail to pin some of them
         for (String fileToPin : filesToPin) {
-            PinnedFile pf = pinFile(fileToPin,
-                                    Integer.MAX_VALUE,
-                                    /*attemptPinIntrospection=*/false);
+            PinnedFile pf = mInjector.pinFileInternal(fileToPin, Integer.MAX_VALUE,
+                    /*attemptPinIntrospection=*/false);
             if (pf == null) {
                 Slog.e(TAG, "Failed to pin file = " + fileToPin);
                 continue;
             }
             synchronized (this) {
-                mPinnedFiles.add(pf);
+                mPinnedFiles.put(pf.fileName, pf);
             }
-            if (fileToPin.endsWith(".jar") | fileToPin.endsWith(".apk")) {
-                // Check whether the runtime has compilation artifacts to pin.
-                String arch = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
-                String[] files = null;
-                try {
-                    files = DexFile.getDexFileOutputPaths(fileToPin, arch);
-                } catch (IOException ioe) { }
-                if (files == null) {
-                    continue;
-                }
-                for (String file : files) {
-                    PinnedFile df = pinFile(file,
-                                            Integer.MAX_VALUE,
-                                            /*attemptPinIntrospection=*/false);
-                    if (df == null) {
-                        Slog.i(TAG, "Failed to pin ART file = " + file);
-                        continue;
-                    }
-                    synchronized (this) {
-                        mPinnedFiles.add(df);
-                    }
-                }
-            }
+            pf.groupName = "system";
+            pinOptimizedDexDependencies(pf, Integer.MAX_VALUE, null);
         }
 
         refreshPinAnonConfig();
@@ -487,7 +479,7 @@
             pinnedAppFiles = new ArrayList<>(app.mFiles);
         }
         for (PinnedFile pinnedFile : pinnedAppFiles) {
-            pinnedFile.close();
+            unpinFile(pinnedFile.fileName);
         }
     }
 
@@ -495,6 +487,19 @@
         return ResolverActivity.class.getName().equals(info.name);
     }
 
+    public int getWebviewPinQuota() {
+        if (!pinWebview()) {
+            return 0;
+        }
+        int quota = mConfiguredWebviewPinBytes;
+        int overrideQuota = SystemProperties.getInt("pinner.pin_webview_size", -1);
+        if (overrideQuota != -1) {
+            // Quota was overridden
+            quota = overrideQuota;
+        }
+        return quota;
+    }
+
     private ApplicationInfo getCameraInfo(int userHandle) {
         Intent cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
         ApplicationInfo info = getApplicationInfoForIntent(cameraIntent, userHandle,
@@ -728,7 +733,7 @@
             case KEY_ASSISTANT:
                 return "Assistant";
             default:
-                return null;
+                return "";
         }
     }
 
@@ -868,11 +873,12 @@
                 continue;
             }
 
-            PinnedFile pf = pinFile(apk, apkPinSizeLimit, /*attemptPinIntrospection=*/true);
+            PinnedFile pf = mInjector.pinFileInternal(apk, apkPinSizeLimit, /*attemptPinIntrospection=*/true);
             if (pf == null) {
                 Slog.e(TAG, "Failed to pin " + apk);
                 continue;
             }
+            pf.groupName = getNameForKey(key);
 
             if (DEBUG) {
                 Slog.i(TAG, "Pinned " + pf.fileName);
@@ -882,40 +888,118 @@
             }
 
             apkPinSizeLimit -= pf.bytesPinned;
+            if (apk.equals(appInfo.sourceDir)) {
+                pinOptimizedDexDependencies(pf, apkPinSizeLimit, appInfo);
+            }
         }
+    }
 
-        // determine the ABI from either ApplicationInfo or Build
-        String abi = appInfo.primaryCpuAbi != null ? appInfo.primaryCpuAbi :
-                Build.SUPPORTED_ABIS[0];
-        String arch = VMRuntime.getInstructionSet(abi);
-        // get the path to the odex or oat file
-        String baseCodePath = appInfo.getBaseCodePath();
-        String[] files = null;
-        try {
-            files = DexFile.getDexFileOutputPaths(baseCodePath, arch);
-        } catch (IOException ioe) {}
-        if (files == null) {
-            return;
+    /**
+     * Pin file or apk to memory.
+     *
+     * Prefer to use this method instead of {@link #pinFileInternal(String, int, boolean)} as it
+     * takes care of accounting and if pinning an apk, it also pins any extra optimized art files
+     * that related to the file but not within itself.
+     *
+     * @param fileToPin File to pin
+     * @param maxBytesToPin maximum quota allowed for pinning
+     * @return total bytes that were pinned.
+     */
+    public int pinFile(String fileToPin, int maxBytesToPin, @Nullable ApplicationInfo appInfo,
+            @Nullable String groupName) {
+        PinnedFile existingPin;
+        synchronized(this) {
+            existingPin = mPinnedFiles.get(fileToPin);
         }
-
-        //not pinning the oat/odex is not a fatal error
-        for (String file : files) {
-            PinnedFile pf = pinFile(file, pinSizeLimit, /*attemptPinIntrospection=*/false);
-            if (pf != null) {
-                synchronized (this) {
-                    if (PROP_PIN_ODEX) {
-                      pinnedApp.mFiles.add(pf);
-                    }
-                }
+        if (existingPin != null) {
+            if (existingPin.bytesPinned == maxBytesToPin) {
+                // Duplicate pin requesting same amount of bytes, lets just bail out.
+                return 0;
+            } else {
+                // User decided to pin a different amount of bytes than currently pinned
+                // so this is a valid pin request. Unpin the previous version before repining.
                 if (DEBUG) {
-                    if (PROP_PIN_ODEX) {
-                        Slog.i(TAG, "Pinned " + pf.fileName);
-                    } else {
-                        Slog.i(TAG, "Pinned [skip] " + pf.fileName);
-                    }
+                    Slog.d(TAG, "Unpinning file prior to repin: " + fileToPin);
+                }
+                unpinFile(fileToPin);
+            }
+        }
+
+        boolean isApk = fileToPin.endsWith(".apk");
+        int bytesPinned = 0;
+        PinnedFile pf = mInjector.pinFileInternal(fileToPin, maxBytesToPin,
+                /*attemptPinIntrospection=*/isApk);
+        if (pf == null) {
+            Slog.e(TAG, "Failed to pin file = " + fileToPin);
+            return 0;
+        }
+        pf.groupName = groupName != null ? groupName : "";
+
+        maxBytesToPin -= bytesPinned;
+        bytesPinned += pf.bytesPinned;
+
+        synchronized (this) {
+            mPinnedFiles.put(pf.fileName, pf);
+        }
+        if (maxBytesToPin > 0) {
+            pinOptimizedDexDependencies(pf, maxBytesToPin, appInfo);
+        }
+        return bytesPinned;
+    }
+
+    /**
+     * Pin any dependency optimized files generated by ART.
+     * @param pinnedFile An already pinned file whose dependencies we want pinned.
+     * @param maxBytesToPin Maximum amount of bytes to pin.
+     * @param appInfo Used to determine the ABI in case the application has one custom set, when set
+     *                to null it will use the default supported ABI by the device.
+     * @return total bytes pinned.
+     */
+    private int pinOptimizedDexDependencies(
+            PinnedFile pinnedFile, int maxBytesToPin, @Nullable ApplicationInfo appInfo) {
+        if (pinnedFile == null) {
+            return 0;
+        }
+
+        int bytesPinned = 0;
+        if (pinnedFile.fileName.endsWith(".jar") | pinnedFile.fileName.endsWith(".apk")) {
+            String abi = null;
+            if (appInfo != null) {
+                abi = appInfo.primaryCpuAbi;
+            }
+            if (abi == null) {
+                abi = Build.SUPPORTED_ABIS[0];
+            }
+            // Check whether the runtime has compilation artifacts to pin.
+            String arch = VMRuntime.getInstructionSet(abi);
+            String[] files = null;
+            try {
+                files = DexFile.getDexFileOutputPaths(pinnedFile.fileName, arch);
+            } catch (IOException ioe) {
+            }
+            if (files == null) {
+                return bytesPinned;
+            }
+            for (String file : files) {
+                // Unpin if it was already pinned prior to re-pinning.
+                unpinFile(file);
+
+                PinnedFile df = mInjector.pinFileInternal(file, Integer.MAX_VALUE,
+                        /*attemptPinIntrospection=*/false);
+                if (df == null) {
+                    Slog.i(TAG, "Failed to pin ART file = " + file);
+                    return bytesPinned;
+                }
+                df.groupName = pinnedFile.groupName;
+                pinnedFile.pinnedDeps.add(df);
+                maxBytesToPin -= df.bytesPinned;
+                bytesPinned += df.bytesPinned;
+                synchronized (this) {
+                    mPinnedFiles.put(df.fileName, df);
                 }
             }
         }
+        return bytesPinned;
     }
 
     /** mlock length bytes of fileToPin in memory
@@ -955,9 +1039,11 @@
      *   zip in order to extract the
      * @return Pinned memory resource owner thing or null on error
      */
-    private static PinnedFile pinFile(String fileToPin,
-                                      int maxBytesToPin,
-                                      boolean attemptPinIntrospection) {
+    private static PinnedFile pinFileInternal(
+            String fileToPin, int maxBytesToPin, boolean attemptPinIntrospection) {
+        if (DEBUG) {
+            Slog.d(TAG, "pin file: " + fileToPin + " use-pinlist: " + attemptPinIntrospection);
+        }
         ZipFile fileAsZip = null;
         InputStream pinRangeStream = null;
         try {
@@ -968,13 +1054,15 @@
             if (fileAsZip != null) {
                 pinRangeStream = maybeOpenPinMetaInZip(fileAsZip, fileToPin);
             }
-
-            Slog.d(TAG, "pinRangeStream: " + pinRangeStream);
-
-            PinRangeSource pinRangeSource = (pinRangeStream != null)
-                ? new PinRangeSourceStream(pinRangeStream)
-                : new PinRangeSourceStatic(0, Integer.MAX_VALUE /* will be clipped */);
-            return pinFileRanges(fileToPin, maxBytesToPin, pinRangeSource);
+            boolean use_pinlist = (pinRangeStream != null);
+            PinRangeSource pinRangeSource = use_pinlist
+                    ? new PinRangeSourceStream(pinRangeStream)
+                    : new PinRangeSourceStatic(0, Integer.MAX_VALUE /* will be clipped */);
+            PinnedFile pinnedFile = pinFileRanges(fileToPin, maxBytesToPin, pinRangeSource);
+            if (pinnedFile != null) {
+                pinnedFile.used_pinlist = use_pinlist;
+            }
+            return pinnedFile;
         } finally {
             safeClose(pinRangeStream);
             safeClose(fileAsZip);  // Also closes any streams we've opened
@@ -1013,9 +1101,23 @@
             return null;
         }
 
+        // Looking at root directory is the old behavior but still some apps rely on it so keeping
+        // for backward compatibility. As doing a single item lookup is cheap in the root.
         ZipEntry pinMetaEntry = zipFile.getEntry(PIN_META_FILENAME);
+
+        if (pinMetaEntry == null) {
+            // It is usually within an apk's control to include files in assets/ directory
+            // so this would be the expected point to have the pinlist.meta coming from.
+            // we explicitly avoid doing an exhaustive search because it may be expensive so
+            // prefer to have a good known location to retrieve the file.
+            pinMetaEntry = zipFile.getEntry("assets/" + PIN_META_FILENAME);
+        }
+
         InputStream pinMetaStream = null;
         if (pinMetaEntry != null) {
+            if (DEBUG) {
+                Slog.d(TAG, "Found pinlist.meta for " + fileName);
+            }
             try {
                 pinMetaStream = zipFile.getInputStream(pinMetaEntry);
             } catch (IOException ex) {
@@ -1024,6 +1126,10 @@
                                      fileName),
                        ex);
             }
+        } else {
+            Slog.w(TAG,
+                    String.format(
+                            "Could not find pinlist.meta for \"%s\": pinning as blob", fileName));
         }
         return pinMetaStream;
     }
@@ -1160,6 +1266,49 @@
             }
         }
     }
+    private List<PinnedFile> getAllPinsForGroup(String group) {
+        List<PinnedFile> filesInGroup;
+        synchronized (this) {
+            filesInGroup = mPinnedFiles.values()
+                                   .stream()
+                                   .filter(pf -> pf.groupName.equals(group))
+                                   .toList();
+        }
+        return filesInGroup;
+    }
+    public void unpinGroup(String group) {
+        List<PinnedFile> pinnedFiles = getAllPinsForGroup(group);
+        for (PinnedFile pf : pinnedFiles) {
+            unpinFile(pf.fileName);
+        }
+    }
+
+    public void unpinFile(String filename) {
+        PinnedFile pinnedFile;
+        synchronized (this) {
+            pinnedFile = mPinnedFiles.get(filename);
+        }
+        if (pinnedFile == null) {
+            // File not pinned, nothing to do.
+            return;
+        }
+        pinnedFile.close();
+        synchronized (this) {
+            if (DEBUG) {
+                Slog.d(TAG, "Unpinned file: " + filename);
+            }
+            mPinnedFiles.remove(pinnedFile.fileName);
+            for (PinnedFile dep : pinnedFile.pinnedDeps) {
+                if (dep == null) {
+                    continue;
+                }
+                mPinnedFiles.remove(dep.fileName);
+                if (DEBUG) {
+                    Slog.d(TAG, "Unpinned dependency: " + dep.fileName);
+                }
+            }
+        }
+    }
 
     private static int clamp(int min, int value, int max) {
         return Math.max(min, Math.min(value, max));
@@ -1205,17 +1354,44 @@
         }
     }
 
-    private final class BinderService extends Binder {
+    public List<PinnedFileStat> getPinnerStats() {
+        ArrayList<PinnedFileStat> stats = new ArrayList<>();
+        Collection<PinnedApp> pinnedApps;
+        synchronized(this) {
+            pinnedApps = mPinnedApps.values();
+        }
+        for (PinnedApp pinnedApp : pinnedApps) {
+            for (PinnedFile pf : pinnedApp.mFiles) {
+                PinnedFileStat stat =
+                        new PinnedFileStat(pf.fileName, pf.bytesPinned, pf.groupName);
+                stats.add(stat);
+            }
+        }
+
+        Collection<PinnedFile> pinnedFiles;
+        synchronized(this) {
+            pinnedFiles = mPinnedFiles.values();
+        }
+        for (PinnedFile pf : pinnedFiles) {
+            PinnedFileStat stat = new PinnedFileStat(pf.fileName, pf.bytesPinned, pf.groupName);
+            stats.add(stat);
+        }
+        if (mCurrentlyPinnedAnonSize > 0) {
+            stats.add(new PinnedFileStat(ANON_REGION_STAT_NAME,
+                        mCurrentlyPinnedAnonSize, ANON_REGION_STAT_NAME));
+        }
+        return stats;
+    }
+
+    public final class BinderService extends IPinnerService.Stub {
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+            HashSet<PinnedFile> shownPins = new HashSet<>();
+            HashSet<String> groups = new HashSet<>();
+            final int bytesPerMB = 1024 * 1024;
             synchronized (PinnerService.this) {
                 long totalSize = 0;
-                for (PinnedFile pinnedFile : mPinnedFiles) {
-                    pw.format("%s %s\n", pinnedFile.fileName, pinnedFile.bytesPinned);
-                    totalSize += pinnedFile.bytesPinned;
-                }
-                pw.println();
                 for (int key : mPinnedApps.keySet()) {
                     PinnedApp app = mPinnedApps.get(key);
                     pw.print(getNameForKey(key));
@@ -1223,14 +1399,53 @@
                     pw.print(" active="); pw.print(app.active);
                     pw.println();
                     for (PinnedFile pf : mPinnedApps.get(key).mFiles) {
-                        pw.print("  "); pw.format("%s %s\n", pf.fileName, pf.bytesPinned);
+                        pw.print("  ");
+                        pw.format("%s pinned:%d bytes (%d MB) pinlist:%b\n", pf.fileName,
+                                pf.bytesPinned, pf.bytesPinned / bytesPerMB, pf.used_pinlist);
                         totalSize += pf.bytesPinned;
+                        shownPins.add(pf);
+                        for (PinnedFile dep : pf.pinnedDeps) {
+                            pw.print("  ");
+                            pw.format("%s pinned:%d bytes (%d MB) pinlist:%b (Dependency)\n", dep.fileName,
+                                    dep.bytesPinned, dep.bytesPinned / bytesPerMB, dep.used_pinlist);
+                            totalSize += dep.bytesPinned;
+                            shownPins.add(dep);
+                        }
                     }
                 }
-                if (mPinAnonAddress != 0) {
-                    pw.format("Pinned anon region: %s\n", mCurrentlyPinnedAnonSize);
+                pw.println();
+                for (PinnedFile pinnedFile : mPinnedFiles.values()) {
+                    if (!groups.contains(pinnedFile.groupName)) {
+                        groups.add(pinnedFile.groupName);
+                    }
                 }
-                pw.format("Total size: %s\n", totalSize);
+                boolean firstPinInGroup = true;
+                for (String group : groups) {
+                    List<PinnedFile> groupPins = getAllPinsForGroup(group);
+                    for (PinnedFile pinnedFile : groupPins) {
+                        if (shownPins.contains(pinnedFile)) {
+                            // Already showed in the dump and accounted for, skip.
+                            continue;
+                        }
+                        if (firstPinInGroup) {
+                            firstPinInGroup = false;
+                            // Ensure we only print when there are pins for groups not yet shown
+                            // in the pinned app section.
+                            pw.print("Group:" + group);
+                            pw.println();
+                        }
+                        pw.format("  %s pinned:%d bytes (%d MB) pinlist:%b\n", pinnedFile.fileName,
+                                pinnedFile.bytesPinned, pinnedFile.bytesPinned / bytesPerMB,
+                                pinnedFile.used_pinlist);
+                        totalSize += pinnedFile.bytesPinned;
+                    }
+                }
+                pw.println();
+                if (mPinAnonAddress != 0) {
+                    pw.format("Pinned anon region: %d (%d MB)\n", mCurrentlyPinnedAnonSize, mCurrentlyPinnedAnonSize / bytesPerMB);
+                    totalSize += mCurrentlyPinnedAnonSize;
+                }
+                pw.format("Total pinned: %s bytes (%s MB)\n", totalSize, totalSize / bytesPerMB);
                 pw.println();
                 if (!mPendingRepin.isEmpty()) {
                     pw.print("Pending repin: ");
@@ -1277,14 +1492,29 @@
 
             resultReceiver.send(0, null);
         }
+
+        @EnforcePermission(android.Manifest.permission.DUMP)
+        @Override
+        public List<PinnedFileStat> getPinnerStats() {
+            getPinnerStats_enforcePermission();
+            return PinnerService.this.getPinnerStats();
+        }
     }
 
-    private static final class PinnedFile implements AutoCloseable {
+    @VisibleForTesting
+    public static final class PinnedFile implements AutoCloseable {
         private long mAddress;
         final int mapSize;
         final String fileName;
         final int bytesPinned;
 
+        // Whether this file was pinned using a pinlist
+        boolean used_pinlist;
+
+        // User defined group name for pinner accounting
+        String groupName = "";
+        ArrayList<PinnedFile> pinnedDeps = new ArrayList<>();
+
         PinnedFile(long address, int mapSize, String fileName, int bytesPinned) {
              mAddress = address;
              this.mapSize = mapSize;
@@ -1298,6 +1528,11 @@
                 safeMunmap(mAddress, mapSize);
                 mAddress = -1;
             }
+            for (PinnedFile dep : pinnedDeps) {
+                if (dep != null) {
+                    dep.close();
+                }
+            }
         }
 
         @Override
@@ -1355,5 +1590,4 @@
             }
         }
     }
-
 }
diff --git a/services/core/java/com/android/server/SecurityStateManagerService.java b/services/core/java/com/android/server/SecurityStateManagerService.java
new file mode 100644
index 0000000..98039be
--- /dev/null
+++ b/services/core/java/com/android/server/SecurityStateManagerService.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static android.os.SecurityStateManager.KEY_KERNEL_VERSION;
+import static android.os.SecurityStateManager.KEY_SYSTEM_SPL;
+import static android.os.SecurityStateManager.KEY_VENDOR_SPL;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.ISecurityStateManager;
+import android.os.SystemProperties;
+import android.os.VintfRuntimeInfo;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.webkit.WebViewProviderInfo;
+import android.webkit.WebViewUpdateService;
+
+import com.android.internal.R;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SecurityStateManagerService extends ISecurityStateManager.Stub {
+
+    private static final String TAG = "SecurityStateManagerService";
+
+    static final String VENDOR_SECURITY_PATCH_PROPERTY_KEY = "ro.vendor.build"
+            + ".security_patch";
+    static final Pattern KERNEL_RELEASE_PATTERN = Pattern.compile("(\\d+\\.\\d+\\.\\d+)("
+            + ".*)");
+
+    private final Context mContext;
+    private final PackageManager mPackageManager;
+
+    public SecurityStateManagerService(Context context) {
+        mContext = context;
+        mPackageManager = context.getPackageManager();
+    }
+
+    @Override
+    public Bundle getGlobalSecurityState() {
+        Bundle globalSecurityState = new Bundle();
+        globalSecurityState.putString(KEY_SYSTEM_SPL, Build.VERSION.SECURITY_PATCH);
+        globalSecurityState.putString(KEY_VENDOR_SPL,
+                SystemProperties.get(VENDOR_SECURITY_PATCH_PROPERTY_KEY, ""));
+        String moduleMetadataProviderPackageName =
+                mContext.getString(R.string.config_defaultModuleMetadataProvider);
+        if (!moduleMetadataProviderPackageName.isEmpty()) {
+            globalSecurityState.putString(moduleMetadataProviderPackageName,
+                    getSpl(moduleMetadataProviderPackageName));
+        }
+        globalSecurityState.putString(KEY_KERNEL_VERSION, getKernelVersion());
+        addWebViewPackages(globalSecurityState);
+        addSecurityStatePackages(globalSecurityState);
+        return globalSecurityState;
+    }
+
+    private String getSpl(String packageName) {
+        if (!TextUtils.isEmpty(packageName)) {
+            try {
+                return mPackageManager.getPackageInfo(packageName, 0 /* flags */).versionName;
+            } catch (PackageManager.NameNotFoundException e) {
+                Slog.e(TAG, TextUtils.formatSimple("Failed to get SPL for package %s.",
+                        packageName), e);
+            }
+        }
+        return "";
+    }
+
+    private String getKernelVersion() {
+        Matcher matcher = KERNEL_RELEASE_PATTERN.matcher(VintfRuntimeInfo.getKernelVersion());
+        if (matcher.matches()) {
+            return matcher.group(1);
+        }
+        return "";
+    }
+
+    private void addWebViewPackages(Bundle bundle) {
+        for (WebViewProviderInfo info : WebViewUpdateService.getAllWebViewPackages()) {
+            String packageName = info.packageName;
+            bundle.putString(packageName, getSpl(packageName));
+        }
+    }
+
+    private void addSecurityStatePackages(Bundle bundle) {
+        String[] packageNames;
+        packageNames = mContext.getResources().getStringArray(R.array.config_securityStatePackages);
+        for (String packageName : packageNames) {
+            bundle.putString(packageName, getSpl(packageName));
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index f6835fe..39b8643 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -215,7 +215,7 @@
     public static final int FAILED_MOUNT_RESET_TIMEOUT_SECONDS = 10;
 
     /** Extended timeout for the system server watchdog. */
-    private static final int SLOW_OPERATION_WATCHDOG_TIMEOUT_MS = 60 * 1000;
+    private static final int SLOW_OPERATION_WATCHDOG_TIMEOUT_MS = 20 * 1000;
 
     /** Extended timeout for the system server watchdog for vold#partition operation. */
     private static final int PARTITION_OPERATION_WATCHDOG_TIMEOUT_MS = 3 * 60 * 1000;
@@ -1235,11 +1235,16 @@
         }
     }
 
+    private void extendWatchdogTimeout(String reason) {
+        Watchdog w = Watchdog.getInstance();
+        w.pauseWatchingMonitorsFor(SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, reason);
+        w.pauseWatchingCurrentThreadFor(SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, reason);
+    }
+
     private void onUserStopped(int userId) {
         Slog.d(TAG, "onUserStopped " + userId);
 
-        Watchdog.getInstance().pauseWatchingMonitorsFor(
-                SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#onUserStopped might be slow");
+        extendWatchdogTimeout("#onUserStopped might be slow");
         try {
             mVold.onUserStopped(userId);
             mStoraged.onUserStopped(userId);
@@ -1322,8 +1327,7 @@
                 unlockedUsers.add(userId);
             }
         }
-        Watchdog.getInstance().pauseWatchingMonitorsFor(
-                SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#onUserStopped might be slow");
+        extendWatchdogTimeout("#onUserStopped might be slow");
         for (Integer userId : unlockedUsers) {
             try {
                 mVold.onUserStopped(userId);
@@ -2343,8 +2347,7 @@
         try {
             // TODO(b/135341433): Remove cautious logging when FUSE is stable
             Slog.i(TAG, "Mounting volume " + vol);
-            Watchdog.getInstance().pauseWatchingMonitorsFor(
-                    SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#mount might be slow");
+            extendWatchdogTimeout("#mount might be slow");
             mVold.mount(vol.id, vol.mountFlags, vol.mountUserId, new IVoldMountCallback.Stub() {
                 @Override
                 public boolean onVolumeChecking(FileDescriptor fd, String path,
@@ -2474,8 +2477,7 @@
 
         final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
 
-        Watchdog.getInstance().pauseWatchingMonitorsFor(
-                PARTITION_OPERATION_WATCHDOG_TIMEOUT_MS, "#partition might be very slow");
+        extendWatchdogTimeout("#partition might be slow");
         try {
             mVold.partition(diskId, IVold.PARTITION_TYPE_PUBLIC, -1);
             waitForLatch(latch, "partitionPublic", 3 * DateUtils.MINUTE_IN_MILLIS);
@@ -2493,8 +2495,7 @@
 
         final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
 
-        Watchdog.getInstance().pauseWatchingMonitorsFor(
-                PARTITION_OPERATION_WATCHDOG_TIMEOUT_MS, "#partition might be very slow");
+        extendWatchdogTimeout("#partition might be slow");
         try {
             mVold.partition(diskId, IVold.PARTITION_TYPE_PRIVATE, -1);
             waitForLatch(latch, "partitionPrivate", 3 * DateUtils.MINUTE_IN_MILLIS);
@@ -2512,8 +2513,7 @@
 
         final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
 
-        Watchdog.getInstance().pauseWatchingMonitorsFor(
-                PARTITION_OPERATION_WATCHDOG_TIMEOUT_MS, "#partition might be very slow");
+        extendWatchdogTimeout("#partition might be slow");
         try {
             mVold.partition(diskId, IVold.PARTITION_TYPE_MIXED, ratio);
             waitForLatch(latch, "partitionMixed", 3 * DateUtils.MINUTE_IN_MILLIS);
@@ -3622,8 +3622,7 @@
 
         @Override
         public ParcelFileDescriptor open() throws AppFuseMountException {
-            Watchdog.getInstance().pauseWatchingMonitorsFor(
-                SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#open might be slow");
+            extendWatchdogTimeout("#open might be slow");
             try {
                 final FileDescriptor fd = mVold.mountAppFuse(uid, mountId);
                 mMounted = true;
@@ -3636,8 +3635,7 @@
         @Override
         public ParcelFileDescriptor openFile(int mountId, int fileId, int flags)
                 throws AppFuseMountException {
-            Watchdog.getInstance().pauseWatchingMonitorsFor(
-                SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#openFile might be slow");
+            extendWatchdogTimeout("#openFile might be slow");
             try {
                 return new ParcelFileDescriptor(
                         mVold.openAppFuseFile(uid, mountId, fileId, flags));
@@ -3648,8 +3646,7 @@
 
         @Override
         public void close() throws Exception {
-            Watchdog.getInstance().pauseWatchingMonitorsFor(
-                SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#close might be slow");
+            extendWatchdogTimeout("#close might be slow");
             if (mMounted) {
                 BackgroundThread.getHandler().post(() -> {
                     try {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index c718d39..9eb35fd 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2096,14 +2096,48 @@
     /**
      * Send a notification to registrants about the data activity state.
      *
+     * @param subId the subscriptionId for the data connection
+     * @param state indicates the latest data activity type
+     * e.g.,{@link TelephonyManager#DATA_ACTIVITY_IN}
+     *
+     */
+
+    public void notifyDataActivityForSubscriber(int subId, int state) {
+        if (!checkNotifyPermission("notifyDataActivity()")) {
+            return;
+        }
+        int phoneId = getPhoneIdFromSubId(subId);
+        synchronized (mRecords) {
+            if (validatePhoneId(phoneId)) {
+                mDataActivity[phoneId] = state;
+                for (Record r : mRecords) {
+                    // Notify by correct subId.
+                    if (r.matchTelephonyCallbackEvent(
+                            TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED)
+                            && idMatch(r, subId, phoneId)) {
+                        try {
+                            r.callback.onDataActivity(state);
+                        } catch (RemoteException ex) {
+                            mRemoveList.add(r.binder);
+                        }
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+    }
+
+    /**
+     * Send a notification to registrants about the data activity state.
+     *
      * @param phoneId the phoneId carrying the data connection
      * @param subId the subscriptionId for the data connection
      * @param state indicates the latest data activity type
      * e.g.,{@link TelephonyManager#DATA_ACTIVITY_IN}
      *
      */
-    public void notifyDataActivityForSubscriber(int phoneId, int subId, int state) {
-        if (!checkNotifyPermission("notifyDataActivity()" )) {
+    public void notifyDataActivityForSubscriberWithSlot(int phoneId, int subId, int state) {
+        if (!checkNotifyPermission("notifyDataActivityWithSlot()")) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 003046a..382ee6e 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -69,6 +69,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.time.Clock;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -98,11 +99,17 @@
     //         applications may not work with a debug build. CTS will fail.
     private static final long DEFAULT_TIMEOUT = DB ? 10 * 1000 : 60 * 1000;
 
+    // This ratio is used to compute the pre-watchdog timeout (2 means that the pre-watchdog timeout
+    // will be half the full timeout).
+    //
+    // The pre-watchdog event is similar to a full watchdog except it does not crash system server.
+    private static final int PRE_WATCHDOG_TIMEOUT_RATIO = 3;
+
     // These are temporally ordered: larger values as lateness increases
-    private static final int COMPLETED = 0;
-    private static final int WAITING = 1;
-    private static final int WAITED_HALF = 2;
-    private static final int OVERDUE = 3;
+    static final int COMPLETED = 0;
+    static final int WAITING = 1;
+    static final int WAITED_UNTIL_PRE_WATCHDOG = 2;
+    static final int OVERDUE = 3;
 
     // Track watchdog timeout history and break the crash loop if there is.
     private static final String TIMEOUT_HISTORY_FILE = "/data/system/watchdog-timeout-history.txt";
@@ -237,10 +244,8 @@
         }
     }
 
-    /**
-     * Used for checking status of handle threads and scheduling monitor callbacks.
-     */
-    public final class HandlerChecker implements Runnable {
+    /** Used for checking status of handle threads and scheduling monitor callbacks. */
+    public static class HandlerChecker implements Runnable {
         private final Handler mHandler;
         private final String mName;
         private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
@@ -251,11 +256,19 @@
         private long mStartTimeMillis;
         private int mPauseCount;
         private long mPauseEndTimeMillis;
+        private Clock mClock;
+        private Object mLock;
 
-        HandlerChecker(Handler handler, String name) {
+        HandlerChecker(Handler handler, String name, Object lock, Clock clock) {
             mHandler = handler;
             mName = name;
+            mLock = lock;
             mCompleted = true;
+            mClock = clock;
+        }
+
+        HandlerChecker(Handler handler, String name, Object lock) {
+            this(handler, name, lock, SystemClock.uptimeClock());
         }
 
         void addMonitorLocked(Monitor monitor) {
@@ -278,11 +291,9 @@
                 mMonitorQueue.clear();
             }
 
-            long nowMillis = SystemClock.uptimeMillis();
-            boolean isPaused = mPauseCount > 0
-                    || (mPauseEndTimeMillis > 0 && mPauseEndTimeMillis < nowMillis);
-            if ((mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling())
-                    || isPaused) {
+            long nowMillis = mClock.millis();
+            boolean isPaused = mPauseCount > 0 || mPauseEndTimeMillis > nowMillis;
+            if ((mMonitors.size() == 0 && isHandlerPolling()) || isPaused) {
                 // Don't schedule until after resume OR
                 // If the target looper has recently been polling, then
                 // there is no reason to enqueue our checker on it since that
@@ -305,15 +316,19 @@
             mHandler.postAtFrontOfQueue(this);
         }
 
+        boolean isHandlerPolling() {
+            return mHandler.getLooper().getQueue().isPolling();
+        }
+
         public int getCompletionStateLocked() {
             if (mCompleted) {
                 return COMPLETED;
             } else {
-                long latency = SystemClock.uptimeMillis() - mStartTimeMillis;
-                if (latency < mWaitMaxMillis / 2) {
+                long latency = mClock.millis() - mStartTimeMillis;
+                if (latency < mWaitMaxMillis / PRE_WATCHDOG_TIMEOUT_RATIO) {
                     return WAITING;
                 } else if (latency < mWaitMaxMillis) {
-                    return WAITED_HALF;
+                    return WAITED_UNTIL_PRE_WATCHDOG;
                 }
             }
             return OVERDUE;
@@ -334,7 +349,7 @@
             } else {
                 prefix =  "Blocked in monitor " + mCurrentMonitor.getClass().getName();
             }
-            long latencySeconds = (SystemClock.uptimeMillis() - mStartTimeMillis) / 1000;
+            long latencySeconds = (mClock.millis() - mStartTimeMillis) / 1000;
             return prefix + " on " + mName + " (" + getThread().getName() + ")"
                 + " for " + latencySeconds + "s";
         }
@@ -366,10 +381,11 @@
          * the given time.
          */
         public void pauseForLocked(int pauseMillis, String reason) {
-            mPauseEndTimeMillis = SystemClock.uptimeMillis() + pauseMillis;
+            mPauseEndTimeMillis = mClock.millis() + pauseMillis;
             // Mark as completed, because there's a chance we called this after the watchog
-            // thread loop called Object#wait after 'WAITED_HALF'. In that case we want to ensure
-            // the next call to #getCompletionStateLocked for this checker returns 'COMPLETED'
+            // thread loop called Object#wait after 'WAITED_UNTIL_PRE_WATCHDOG'. In that case we
+            // want to ensure the next call to #getCompletionStateLocked for this checker returns
+            // 'COMPLETED'
             mCompleted = true;
             Slog.i(TAG, "Pausing of HandlerChecker: " + mName + " for reason: "
                     + reason + ". Pause end time: " + mPauseEndTimeMillis);
@@ -379,8 +395,9 @@
         public void pauseLocked(String reason) {
             mPauseCount++;
             // Mark as completed, because there's a chance we called this after the watchog
-            // thread loop called Object#wait after 'WAITED_HALF'. In that case we want to ensure
-            // the next call to #getCompletionStateLocked for this checker returns 'COMPLETED'
+            // thread loop called Object#wait after 'WAITED_UNTIL_PRE_WATCHDOG'. In that case we
+            // want to ensure the next call to #getCompletionStateLocked for this checker returns
+            // 'COMPLETED'
             mCompleted = true;
             Slog.i(TAG, "Pausing HandlerChecker: " + mName + " for reason: "
                     + reason + ". Pause count: " + mPauseCount);
@@ -396,6 +413,11 @@
                 Slog.wtf(TAG, "Already resumed HandlerChecker: " + mName);
             }
         }
+
+        @Override
+        public String toString() {
+            return "CheckerHandler for " + mName;
+        }
     }
 
     final class RebootRequestReceiver extends BroadcastReceiver {
@@ -445,31 +467,40 @@
         ServiceThread t = new ServiceThread("watchdog.monitor",
                 android.os.Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
         t.start();
-        mMonitorChecker = new HandlerChecker(new Handler(t.getLooper()), "monitor thread");
+        mMonitorChecker = new HandlerChecker(new Handler(t.getLooper()), "monitor thread", mLock);
         mHandlerCheckers.add(withDefaultTimeout(mMonitorChecker));
 
-        mHandlerCheckers.add(withDefaultTimeout(
-                new HandlerChecker(FgThread.getHandler(), "foreground thread")));
+        mHandlerCheckers.add(
+                withDefaultTimeout(
+                        new HandlerChecker(FgThread.getHandler(), "foreground thread", mLock)));
         // Add checker for main thread.  We only do a quick check since there
         // can be UI running on the thread.
-        mHandlerCheckers.add(withDefaultTimeout(
-                new HandlerChecker(new Handler(Looper.getMainLooper()), "main thread")));
+        mHandlerCheckers.add(
+                withDefaultTimeout(
+                        new HandlerChecker(
+                                new Handler(Looper.getMainLooper()), "main thread", mLock)));
         // Add checker for shared UI thread.
-        mHandlerCheckers.add(withDefaultTimeout(
-                new HandlerChecker(UiThread.getHandler(), "ui thread")));
+        mHandlerCheckers.add(
+                withDefaultTimeout(new HandlerChecker(UiThread.getHandler(), "ui thread", mLock)));
         // And also check IO thread.
-        mHandlerCheckers.add(withDefaultTimeout(
-                new HandlerChecker(IoThread.getHandler(), "i/o thread")));
+        mHandlerCheckers.add(
+                withDefaultTimeout(new HandlerChecker(IoThread.getHandler(), "i/o thread", mLock)));
         // And the display thread.
-        mHandlerCheckers.add(withDefaultTimeout(
-                new HandlerChecker(DisplayThread.getHandler(), "display thread")));
+        mHandlerCheckers.add(
+                withDefaultTimeout(
+                        new HandlerChecker(DisplayThread.getHandler(), "display thread", mLock)));
         // And the animation thread.
-        mHandlerCheckers.add(withDefaultTimeout(
-                 new HandlerChecker(AnimationThread.getHandler(), "animation thread")));
+        mHandlerCheckers.add(
+                withDefaultTimeout(
+                        new HandlerChecker(
+                                AnimationThread.getHandler(), "animation thread", mLock)));
         // And the surface animation thread.
-        mHandlerCheckers.add(withDefaultTimeout(
-                new HandlerChecker(SurfaceAnimationThread.getHandler(),
-                    "surface animation thread")));
+        mHandlerCheckers.add(
+                withDefaultTimeout(
+                        new HandlerChecker(
+                                SurfaceAnimationThread.getHandler(),
+                                "surface animation thread",
+                                mLock)));
         // Initialize monitor for Binder threads.
         addMonitor(new BinderThreadMonitor());
 
@@ -609,7 +640,7 @@
     public void addThread(Handler thread) {
         synchronized (mLock) {
             final String name = thread.getLooper().getThread().getName();
-            mHandlerCheckers.add(withDefaultTimeout(new HandlerChecker(thread, name)));
+            mHandlerCheckers.add(withDefaultTimeout(new HandlerChecker(thread, name, mLock)));
         }
     }
 
@@ -617,7 +648,7 @@
         synchronized (mLock) {
             final String name = thread.getLooper().getThread().getName();
             mHandlerCheckers.add(
-                    withCustomTimeout(new HandlerChecker(thread, name), timeoutMillis));
+                    withCustomTimeout(new HandlerChecker(thread, name, mLock), timeoutMillis));
         }
     }
 
@@ -797,11 +828,11 @@
             String subject = "";
             boolean allowRestart = true;
             int debuggerWasConnected = 0;
-            boolean doWaitedHalfDump = false;
+            boolean doWaitedPreDump = false;
             // The value of mWatchdogTimeoutMillis might change while we are executing the loop.
             // We store the current value to use a consistent value for all handlers.
             final long watchdogTimeoutMillis = mWatchdogTimeoutMillis;
-            final long checkIntervalMillis = watchdogTimeoutMillis / 2;
+            final long checkIntervalMillis = watchdogTimeoutMillis / PRE_WATCHDOG_TIMEOUT_RATIO;
             final ArrayList<Integer> pids;
             synchronized (mLock) {
                 long timeout = checkIntervalMillis;
@@ -848,15 +879,16 @@
                 } else if (waitState == WAITING) {
                     // still waiting but within their configured intervals; back off and recheck
                     continue;
-                } else if (waitState == WAITED_HALF) {
+                } else if (waitState == WAITED_UNTIL_PRE_WATCHDOG) {
                     if (!waitedHalf) {
-                        Slog.i(TAG, "WAITED_HALF");
+                        Slog.i(TAG, "WAITED_UNTIL_PRE_WATCHDOG");
                         waitedHalf = true;
-                        // We've waited half, but we'd need to do the stack trace dump w/o the lock.
-                        blockedCheckers = getCheckersWithStateLocked(WAITED_HALF);
+                        // We've waited until the pre-watchdog, but we'd need to do the stack trace
+                        // dump w/o the lock.
+                        blockedCheckers = getCheckersWithStateLocked(WAITED_UNTIL_PRE_WATCHDOG);
                         subject = describeCheckersLocked(blockedCheckers);
                         pids = new ArrayList<>(mInterestingJavaPids);
-                        doWaitedHalfDump = true;
+                        doWaitedPreDump = true;
                     } else {
                         continue;
                     }
@@ -874,12 +906,12 @@
             // First collect stack traces from all threads of the system process.
             //
             // Then, if we reached the full timeout, kill this process so that the system will
-            // restart. If we reached half of the timeout, just log some information and continue.
-            logWatchog(doWaitedHalfDump, subject, pids);
+            // restart. If we reached pre-watchdog timeout, just log some information and continue.
+            logWatchog(doWaitedPreDump, subject, pids);
 
-            if (doWaitedHalfDump) {
-                // We have waited for only half of the timeout, we continue to wait for the duration
-                // of the full timeout before killing the process.
+            if (doWaitedPreDump) {
+                // We have waited for only pre-watchdog timeout, we continue to wait for the
+                // duration of the full timeout before killing the process.
                 continue;
             }
 
@@ -928,8 +960,8 @@
         }
     }
 
-    private void logWatchog(boolean halfWatchdog, String subject, ArrayList<Integer> pids) {
-        // Get critical event log before logging the half watchdog so that it doesn't
+    private void logWatchog(boolean preWatchdog, String subject, ArrayList<Integer> pids) {
+        // Get critical event log before logging the pre-watchdog so that it doesn't
         // occur in the log.
         String criticalEvents =
                 CriticalEventLog.getInstance().logLinesForSystemServerTraceFile();
@@ -941,7 +973,7 @@
         }
 
         final String dropboxTag;
-        if (halfWatchdog) {
+        if (preWatchdog) {
             dropboxTag = "pre_watchdog";
             CriticalEventLog.getInstance().logHalfWatchdog(subject);
             FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED);
@@ -971,7 +1003,7 @@
         report.append(processCpuTracker.printCurrentState(anrTime, 10));
         report.append(tracesFileException.getBuffer());
 
-        if (!halfWatchdog) {
+        if (!preWatchdog) {
             // Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the
             // kernel log
             doSysRq('w');
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index 6794f75..3280afdf 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -1797,8 +1797,13 @@
                 mFingerprints);
 
         try {
-            dump.write("user_keys", AdbDebuggingManagerProto.USER_KEYS,
-                    FileUtils.readTextFile(new File("/data/misc/adb/adb_keys"), 0, null));
+            File userKeys = new File("/data/misc/adb/adb_keys");
+            if (userKeys.exists()) {
+                dump.write("user_keys", AdbDebuggingManagerProto.USER_KEYS,
+                           FileUtils.readTextFile(userKeys, 0, null));
+            } else {
+                Slog.i(TAG, "No user keys on this device");
+            }
         } catch (IOException e) {
             Slog.i(TAG, "Cannot read user keys", e);
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 54c8ed3..b87d02d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -79,7 +79,6 @@
 import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION;
 import static android.os.PowerExemptionManager.REASON_BOOT_COMPLETED;
 import static android.os.PowerExemptionManager.REASON_COMPANION_DEVICE_MANAGER;
-import static android.os.PowerExemptionManager.REASON_DENIED;
 import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
 import static android.os.PowerExemptionManager.REASON_LOCKED_BOOT_COMPLETED;
 import static android.os.PowerExemptionManager.REASON_PROC_STATE_BTOP;
@@ -5051,7 +5050,7 @@
                     REASON_LOCKED_BOOT_COMPLETED);
         }
         // Send BOOT_COMPLETED if the user is unlocked
-        if (StorageManager.isUserKeyUnlocked(app.userId)) {
+        if (StorageManager.isCeStorageUnlocked(app.userId)) {
             sendBootBroadcastToAppLocked(app, new Intent(Intent.ACTION_BOOT_COMPLETED),
                     REASON_BOOT_COMPLETED);
         }
@@ -14150,7 +14149,8 @@
                                 || action.startsWith("android.intent.action.PACKAGE_")
                                 || action.startsWith("android.intent.action.UID_")
                                 || action.startsWith("android.intent.action.EXTERNAL_")
-                                || action.startsWith("android.bluetooth.")) {
+                                || action.startsWith("android.bluetooth.")
+                                || action.equals(Intent.ACTION_SHUTDOWN)) {
                             if (DEBUG_BROADCAST) {
                                 Slog.wtf(TAG,
                                         "System internals registering for " + filter.toLongString()
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 36356bd..f2d9759 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -120,12 +120,15 @@
 import com.android.server.power.optimization.Flags;
 import com.android.server.power.stats.AggregatedPowerStatsConfig;
 import com.android.server.power.stats.BatteryExternalStatsWorker;
+import com.android.server.power.stats.BatteryStatsDumpHelperImpl;
 import com.android.server.power.stats.BatteryStatsImpl;
 import com.android.server.power.stats.BatteryUsageStatsProvider;
 import com.android.server.power.stats.CpuAggregatedPowerStatsProcessor;
 import com.android.server.power.stats.PowerStatsAggregator;
+import com.android.server.power.stats.PowerStatsExporter;
 import com.android.server.power.stats.PowerStatsScheduler;
 import com.android.server.power.stats.PowerStatsStore;
+import com.android.server.power.stats.PowerStatsUidResolver;
 import com.android.server.power.stats.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes;
 import com.android.server.power.stats.wakeups.CpuWakeupStats;
 
@@ -181,6 +184,8 @@
     private final BatteryExternalStatsWorker mWorker;
     private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;
     private final AtomicFile mConfigFile;
+    private final BatteryStats.BatteryStatsDumpHelper mDumpHelper;
+    private final PowerStatsUidResolver mPowerStatsUidResolver;
 
     private volatile boolean mMonitorEnabled = true;
 
@@ -408,9 +413,10 @@
                         .setResetOnUnplugAfterSignificantCharge(resetOnUnplugAfterSignificantCharge)
                         .setPowerStatsThrottlePeriodCpu(powerStatsThrottlePeriodCpu)
                         .build();
+        mPowerStatsUidResolver = new PowerStatsUidResolver();
         mStats = new BatteryStatsImpl(mBatteryStatsConfig, Clock.SYSTEM_CLOCK, mMonotonicClock,
                 systemDir, handler, this, this, mUserManagerUserInfoProvider, mPowerProfile,
-                mCpuScalingPolicies);
+                mCpuScalingPolicies, mPowerStatsUidResolver);
         mWorker = new BatteryExternalStatsWorker(context, mStats);
         mStats.setExternalStatsSyncLocked(mWorker);
         mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
@@ -419,8 +425,6 @@
 
         AggregatedPowerStatsConfig aggregatedPowerStatsConfig = getAggregatedPowerStatsConfig();
         mPowerStatsStore = new PowerStatsStore(systemDir, mHandler, aggregatedPowerStatsConfig);
-        mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mStats,
-                mPowerStatsStore);
         mPowerStatsAggregator = new PowerStatsAggregator(aggregatedPowerStatsConfig,
                 mStats.getHistory());
         final long aggregatedPowerStatsSpanDuration = context.getResources().getInteger(
@@ -429,7 +433,14 @@
                 com.android.internal.R.integer.config_powerStatsAggregationPeriod);
         mPowerStatsScheduler = new PowerStatsScheduler(context, mPowerStatsAggregator,
                 aggregatedPowerStatsSpanDuration, powerStatsAggregationPeriod, mPowerStatsStore,
-                Clock.SYSTEM_CLOCK, mMonotonicClock, mHandler, mStats, mBatteryUsageStatsProvider);
+                Clock.SYSTEM_CLOCK, mMonotonicClock, mHandler, mStats);
+        PowerStatsExporter powerStatsExporter =
+                new PowerStatsExporter(mPowerStatsStore, mPowerStatsAggregator);
+        mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context,
+                powerStatsExporter, mPowerProfile, mCpuScalingPolicies,
+                mPowerStatsStore, Clock.SYSTEM_CLOCK);
+        mStats.saveBatteryUsageStatsOnReset(mBatteryUsageStatsProvider, mPowerStatsStore);
+        mDumpHelper = new BatteryStatsDumpHelperImpl(mBatteryUsageStatsProvider);
         mCpuWakeupStats = new CpuWakeupStats(context, R.xml.irq_device_map, mHandler);
         mConfigFile = new AtomicFile(new File(systemDir, "battery_usage_stats_config"));
     }
@@ -469,9 +480,11 @@
     }
 
     public void systemServicesReady() {
+        mStats.setPowerStatsCollectorEnabled(Flags.streamlinedBatteryStats());
+        mBatteryUsageStatsProvider.setPowerStatsExporterEnabled(Flags.streamlinedBatteryStats());
+        mWorker.systemServicesReady();
         mStats.systemServicesReady(mContext);
         mCpuWakeupStats.systemServicesReady();
-        mWorker.systemServicesReady();
         final INetworkManagementService nms = INetworkManagementService.Stub.asInterface(
                 ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
         final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
@@ -775,25 +788,15 @@
     }
 
     void addIsolatedUid(final int isolatedUid, final int appUid) {
-        synchronized (mLock) {
-            final long elapsedRealtime = SystemClock.elapsedRealtime();
-            final long uptime = SystemClock.uptimeMillis();
-            mHandler.post(() -> {
-                synchronized (mStats) {
-                    mStats.addIsolatedUidLocked(isolatedUid, appUid, elapsedRealtime, uptime);
-                }
-            });
-        }
+        mPowerStatsUidResolver.noteIsolatedUidAdded(isolatedUid, appUid);
+        FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, appUid, isolatedUid,
+                FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
     }
 
     void removeIsolatedUid(final int isolatedUid, final int appUid) {
-        synchronized (mLock) {
-            mHandler.post(() -> {
-                synchronized (mStats) {
-                    mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid);
-                }
-            });
-        }
+        mPowerStatsUidResolver.noteIsolatedUidRemoved(isolatedUid, appUid);
+        FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, -1, isolatedUid,
+                FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__REMOVED);
     }
 
     void noteProcessStart(final String name, final int uid) {
@@ -877,12 +880,15 @@
 
         awaitCompletion();
 
-        if (mBatteryUsageStatsProvider.shouldUpdateStats(queries,
+        if (BatteryUsageStatsProvider.shouldUpdateStats(queries,
+                SystemClock.elapsedRealtime(),
                 mWorker.getLastCollectionTimeStamp())) {
             syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
         }
 
-        return mBatteryUsageStatsProvider.getBatteryUsageStats(queries);
+        synchronized (mStats) {
+            return mBatteryUsageStatsProvider.getBatteryUsageStats(mStats, queries);
+        }
     }
 
     /** Register callbacks for statsd pulled atoms. */
@@ -2643,7 +2649,9 @@
         pw.println("     --proto: output as a binary protobuffer");
         pw.println("     --model power-profile: use the power profile model"
                 + " even if measured energy is available");
-        pw.println("  --sample: collect and dump a sample of stats for debugging purpose");
+        if (Flags.streamlinedBatteryStats()) {
+            pw.println("  --sample: collect and dump a sample of stats for debugging purpose");
+        }
         pw.println("  <package.name>: optional name of package to filter output by.");
         pw.println("  -h: print this help text.");
         pw.println("Battery stats (batterystats) commands:");
@@ -2723,7 +2731,7 @@
         synchronized (mStats) {
             mStats.prepareForDumpLocked();
             BatteryUsageStats batteryUsageStats =
-                    mBatteryUsageStatsProvider.getBatteryUsageStats(query);
+                    mBatteryUsageStatsProvider.getBatteryUsageStats(mStats, query);
             if (proto) {
                 batteryUsageStats.dumpToProto(fd);
             } else {
@@ -2933,10 +2941,10 @@
                     mCpuWakeupStats.dump(new IndentingPrintWriter(pw, "  "),
                             SystemClock.elapsedRealtime());
                     return;
-                } else if ("--sample".equals(arg)) {
+                } else if (Flags.streamlinedBatteryStats() && "--sample".equals(arg)) {
                     dumpStatsSample(pw);
                     return;
-                } else if ("--aggregated".equals(arg)) {
+                } else if (Flags.streamlinedBatteryStats() && "--aggregated".equals(arg)) {
                     dumpAggregatedStats(pw);
                     return;
                 } else if ("--store".equals(arg)) {
@@ -3008,11 +3016,11 @@
                                         mBatteryStatsConfig, Clock.SYSTEM_CLOCK, mMonotonicClock,
                                         null, mStats.mHandler, null, null,
                                         mUserManagerUserInfoProvider, mPowerProfile,
-                                        mCpuScalingPolicies);
+                                        mCpuScalingPolicies, new PowerStatsUidResolver());
                                 checkinStats.readSummaryFromParcel(in);
                                 in.recycle();
-                                checkinStats.dumpProtoLocked(
-                                        mContext, fd, apps, flags, historyStart);
+                                checkinStats.dumpProtoLocked(mContext, fd, apps, flags,
+                                        historyStart, mDumpHelper);
                                 mStats.mCheckinFile.delete();
                                 return;
                             }
@@ -3026,7 +3034,7 @@
             if (DBG) Slog.d(TAG, "begin dumpProtoLocked from UID " + Binder.getCallingUid());
             awaitCompletion();
             synchronized (mStats) {
-                mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart);
+                mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart, mDumpHelper);
                 if (writeData) {
                     mStats.writeAsyncLocked();
                 }
@@ -3050,11 +3058,11 @@
                                         mBatteryStatsConfig, Clock.SYSTEM_CLOCK, mMonotonicClock,
                                         null, mStats.mHandler, null, null,
                                         mUserManagerUserInfoProvider, mPowerProfile,
-                                        mCpuScalingPolicies);
+                                        mCpuScalingPolicies, new PowerStatsUidResolver());
                                 checkinStats.readSummaryFromParcel(in);
                                 in.recycle();
                                 checkinStats.dumpCheckin(mContext, pw, apps, flags,
-                                        historyStart);
+                                        historyStart, mDumpHelper);
                                 mStats.mCheckinFile.delete();
                                 return;
                             }
@@ -3067,7 +3075,7 @@
             }
             if (DBG) Slog.d(TAG, "begin dumpCheckin from UID " + Binder.getCallingUid());
             awaitCompletion();
-            mStats.dumpCheckin(mContext, pw, apps, flags, historyStart);
+            mStats.dumpCheckin(mContext, pw, apps, flags, historyStart, mDumpHelper);
             if (writeData) {
                 mStats.writeAsyncLocked();
             }
@@ -3076,7 +3084,7 @@
             if (DBG) Slog.d(TAG, "begin dump from UID " + Binder.getCallingUid());
             awaitCompletion();
 
-            mStats.dump(mContext, pw, flags, reqUid, historyStart);
+            mStats.dump(mContext, pw, flags, reqUid, historyStart, mDumpHelper);
             if (writeData) {
                 mStats.writeAsyncLocked();
             }
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 3ce92bc..0b56146 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -361,7 +361,8 @@
                     && (record.userId == testRecord.userId)
                     && record.intent.filterEquals(testRecord.intent)
                     && isReceiverEquals(receiver, testReceiver)
-                    && testRecord.allReceiversPending()) {
+                    && testRecord.allReceiversPending()
+                    && record.isMatchingRecord(testRecord)) {
                 // Exact match found; perform in-place swap
                 args.arg1 = record;
                 args.argi1 = recordIndex;
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index e07631c..ad49991 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -230,6 +230,14 @@
             new AtomicReference<>();
 
     /**
+     * Container for holding the set of broadcast records that matches an enqueueing record.
+     * @see BroadcastRecord#isMatchingRecord(BroadcastRecord)
+     */
+    @GuardedBy("mService")
+    private final AtomicReference<ArrayMap<BroadcastRecord, Boolean>> mMatchingRecordsCache =
+            new AtomicReference<>();
+
+    /**
      * Map from UID to its last known "foreground" state. A UID is considered to be in
      * "foreground" state when it's procState is {@link ActivityManager#PROCESS_STATE_TOP}.
      * <p>
@@ -747,6 +755,12 @@
         if (replacedBroadcasts == null) {
             replacedBroadcasts = new ArraySet<>();
         }
+        ArrayMap<BroadcastRecord, Boolean> matchingBroadcasts =
+                mMatchingRecordsCache.getAndSet(null);
+        if (matchingBroadcasts == null) {
+            matchingBroadcasts = new ArrayMap<>();
+        }
+        r.setMatchingRecordsCache(matchingBroadcasts);
         boolean enqueuedBroadcast = false;
 
         for (int i = 0; i < r.receivers.size(); i++) {
@@ -780,6 +794,9 @@
         skipAndCancelReplacedBroadcasts(replacedBroadcasts);
         replacedBroadcasts.clear();
         mReplacedBroadcastsCache.compareAndSet(null, replacedBroadcasts);
+        matchingBroadcasts.clear();
+        r.clearMatchingRecordsCache();
+        mMatchingRecordsCache.compareAndSet(null, matchingBroadcasts);
 
         // If nothing to dispatch, send any pending result immediately
         if (r.receivers.isEmpty() || !enqueuedBroadcast) {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 198adcb..99b91ff 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -61,6 +61,7 @@
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.PrintWriterPrinter;
 import android.util.SparseArray;
 import android.util.TimeUtils;
@@ -164,6 +165,11 @@
     @Nullable
     final BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver;
 
+    // Cache of records that are "matching" this. Only used at the time of enqueuing this record
+    // into the queue.
+    @Nullable
+    private ArrayMap<BroadcastRecord, Boolean> mMatchingRecordsCache;
+
     private @Nullable String mCachedToString;
     private @Nullable String mCachedToShortString;
 
@@ -1250,6 +1256,33 @@
         return (terminalCount == 0 && dispatchTime <= 0);
     }
 
+    boolean isMatchingRecord(@NonNull BroadcastRecord record) {
+        final int idx = mMatchingRecordsCache.indexOfKey(record);
+        if (idx > 0) {
+            return mMatchingRecordsCache.valueAt(idx);
+        }
+        // Consider a record to be matching if has the same receivers in the same order.
+        boolean matches = (receivers.size() == record.receivers.size());
+        if (matches) {
+            for (int i = receivers.size() - 1; i >= 0; --i) {
+                if (!isReceiverEquals(receivers.get(i), record.receivers.get(i))) {
+                    matches = false;
+                    break;
+                }
+            }
+        }
+        mMatchingRecordsCache.put(record, matches);
+        return matches;
+    }
+
+    void setMatchingRecordsCache(@NonNull ArrayMap<BroadcastRecord, Boolean> matchingRecordsCache) {
+        mMatchingRecordsCache = matchingRecordsCache;
+    }
+
+    void clearMatchingRecordsCache() {
+        mMatchingRecordsCache = null;
+    }
+
     @Override
     public String toString() {
         if (mCachedToString == null) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index cb2b5fb..4ff34b1 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -34,7 +34,7 @@
 import static android.os.Process.getTotalMemory;
 import static android.os.Process.killProcessQuiet;
 import static android.os.Process.startWebView;
-import static android.system.OsConstants.*;
+import static android.system.OsConstants.EAGAIN;
 
 import static com.android.sdksandbox.flags.Flags.selinuxSdkSandboxAudit;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
@@ -133,7 +133,6 @@
 import com.android.internal.app.ProcessMap;
 import com.android.internal.os.Zygote;
 import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.MemInfoReader;
 import com.android.server.AppStateTracker;
 import com.android.server.LocalServices;
@@ -3299,8 +3298,6 @@
             // about the process state of the isolated UID *before* it is registered with the
             // owning application.
             mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
-            FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
-                    FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
         }
         final ProcessRecord r = new ProcessRecord(mService, info, proc, uid,
                 sdkSandboxClientAppPackage,
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 192fd6f..b500ff1 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -120,7 +120,6 @@
     static final String[] sDeviceConfigAconfigScopes = new String[] {
         "accessibility",
         "android_core_networking",
-        "angle",
         "app_widgets",
         "arc_next",
         "avic",
@@ -142,7 +141,9 @@
         "core_experiments_team_internal",
         "core_graphics",
         "dck_framework",
+        "devoptions_settings",
         "game",
+        "gpu",
         "haptics",
         "hardware_backed_security_mainline",
         "input",
@@ -152,11 +153,13 @@
         "mainline_sdk",
         "media_audio",
         "media_drm",
+        "media_reliability",
         "media_tv",
         "media_solutions",
         "nfc",
         "pdf_viewer",
         "pixel_audio_android",
+        "pixel_bluetooth",
         "pixel_system_sw_touch",
         "pixel_watch",
         "platform_security",
diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java
index 0ee7d9c..0916967 100644
--- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java
@@ -20,6 +20,7 @@
 import static android.app.AppOpsManager.MODE_FOREGROUND;
 import static android.app.AppOpsManager.OP_SCHEDULE_EXACT_ALARM;
 import static android.app.AppOpsManager.OP_USE_FULL_SCREEN_INTENT;
+import static android.companion.virtual.VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
@@ -150,7 +151,7 @@
     }
 
     @Override
-    public SparseIntArray getNonDefaultUidModes(int uid) {
+    public SparseIntArray getNonDefaultUidModes(int uid, String persistentDeviceId) {
         synchronized (mLock) {
             SparseIntArray opModes = mUidModes.get(uid, null);
             if (opModes == null) {
@@ -176,7 +177,7 @@
     }
 
     @Override
-    public int getUidMode(int uid, int op) {
+    public int getUidMode(int uid, String persistentDeviceId, int op) {
         synchronized (mLock) {
             SparseIntArray opModes = mUidModes.get(uid, null);
             if (opModes == null) {
@@ -187,7 +188,7 @@
     }
 
     @Override
-    public boolean setUidMode(int uid, int op, int mode) {
+    public boolean setUidMode(int uid, String persistentDeviceId, int op, int mode) {
         final int defaultMode = AppOpsManager.opToDefaultMode(op);
         List<AppOpsModeChangedListener> listenersCopy;
         synchronized (mLock) {
@@ -329,7 +330,7 @@
     }
 
     @Override
-    public SparseBooleanArray getForegroundOps(int uid) {
+    public SparseBooleanArray getForegroundOps(int uid, String persistentDeviceId) {
         SparseBooleanArray result = new SparseBooleanArray();
         synchronized (mLock) {
             SparseIntArray modes = mUidModes.get(uid);
@@ -606,9 +607,17 @@
         for (final String pkg : packagesDeclaringPermission) {
             for (int userId : userIds) {
                 final int uid = pmi.getPackageUid(pkg, 0, userId);
-                final int oldMode = getUidMode(uid, OP_SCHEDULE_EXACT_ALARM);
+                final int oldMode =
+                        getUidMode(
+                                uid,
+                                PERSISTENT_DEVICE_ID_DEFAULT,
+                                OP_SCHEDULE_EXACT_ALARM);
                 if (oldMode == AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM)) {
-                    setUidMode(uid, OP_SCHEDULE_EXACT_ALARM, MODE_ALLOWED);
+                    setUidMode(
+                            uid,
+                            PERSISTENT_DEVICE_ID_DEFAULT,
+                            OP_SCHEDULE_EXACT_ALARM,
+                            MODE_ALLOWED);
                 }
             }
             // This appop is meant to be controlled at a uid level. So we leave package modes as
@@ -641,7 +650,10 @@
                 final int flags = permissionManager.getPermissionFlags(pkg, permissionName,
                         UserHandle.of(userId));
                 if ((flags & PackageManager.FLAG_PERMISSION_USER_SET) == 0) {
-                    setUidMode(uid, OP_USE_FULL_SCREEN_INTENT,
+                    setUidMode(
+                            uid,
+                            PERSISTENT_DEVICE_ID_DEFAULT,
+                            OP_USE_FULL_SCREEN_INTENT,
                             AppOpsManager.opToDefaultMode(OP_USE_FULL_SCREEN_INTENT));
                 }
             }
diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java
index f6e6bc0..f056f6b 100644
--- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java
+++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java
@@ -59,8 +59,9 @@
      * Returns a copy of non-default app-ops with op as keys and their modes as values for a uid.
      * Returns an empty SparseIntArray if nothing is set.
      * @param uid for which we need the app-ops and their modes.
+     * @param persistentDeviceId device for which we need the app-ops and their modes
      */
-    SparseIntArray getNonDefaultUidModes(int uid);
+    SparseIntArray getNonDefaultUidModes(int uid, String persistentDeviceId);
 
     /**
      * Returns a copy of non-default app-ops with op as keys and their modes as values for a package
@@ -75,20 +76,22 @@
      * Returns the app-op mode for a particular app-op of a uid.
      * Returns default op mode if the op mode for particular uid and op is not set.
      * @param uid user id for which we need the mode.
+     * @param persistentDeviceId device for which we need the mode
      * @param op app-op for which we need the mode.
      * @return mode of the app-op.
      */
-    int getUidMode(int uid, int op);
+    int getUidMode(int uid, String persistentDeviceId, int op);
 
     /**
      * Set the app-op mode for a particular uid and op.
      * The mode is not set if the mode is the same as the default mode for the op.
      * @param uid user id for which we want to set the mode.
+     * @param persistentDeviceId device for which we want to set the mode.
      * @param op app-op for which we want to set the mode.
      * @param mode mode for the app-op.
      * @return true if op mode is changed.
      */
-    boolean setUidMode(int uid, int op, @Mode int mode);
+    boolean setUidMode(int uid, String persistentDeviceId, int op, @Mode int mode);
 
     /**
      * Gets the app-op mode for a particular package.
@@ -130,10 +133,11 @@
 
     /**
      * @param uid UID to query foreground ops for.
+     * @param persistentDeviceId device to query foreground ops for
      * @return SparseBooleanArray where the keys are the op codes for which their modes are
      * MODE_FOREGROUND for the passed UID.
      */
-    SparseBooleanArray getForegroundOps(int uid);
+    SparseBooleanArray getForegroundOps(int uid, String persistentDeviceId);
 
     /**
      *
diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java
index ccdf3a5..f6da166 100644
--- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java
+++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java
@@ -60,9 +60,9 @@
     }
 
     @Override
-    public SparseIntArray getNonDefaultUidModes(int uid) {
+    public SparseIntArray getNonDefaultUidModes(int uid, String persistentDeviceId) {
         Log.i(LOG_TAG, "getNonDefaultUidModes(uid = " + uid + ")");
-        return mService.getNonDefaultUidModes(uid);
+        return mService.getNonDefaultUidModes(uid, persistentDeviceId);
     }
 
     @Override
@@ -73,15 +73,15 @@
     }
 
     @Override
-    public int getUidMode(int uid, int op) {
+    public int getUidMode(int uid, String persistentDeviceId, int op) {
         Log.i(LOG_TAG, "getUidMode(uid = " + uid + ", op = " + op + ")");
-        return mService.getUidMode(uid, op);
+        return mService.getUidMode(uid, persistentDeviceId, op);
     }
 
     @Override
-    public boolean setUidMode(int uid, int op, int mode) {
+    public boolean setUidMode(int uid, String persistentDeviceId, int op, int mode) {
         Log.i(LOG_TAG, "setUidMode(uid = " + uid + ", op = " + op + ", mode = " + mode + ")");
-        return mService.setUidMode(uid, op, mode);
+        return mService.setUidMode(uid, persistentDeviceId, op, mode);
     }
 
     @Override
@@ -117,9 +117,9 @@
     }
 
     @Override
-    public SparseBooleanArray getForegroundOps(int uid) {
+    public SparseBooleanArray getForegroundOps(int uid, String persistentDeviceId) {
         Log.i(LOG_TAG, "getForegroundOps(uid = " + uid + ")");
-        return mService.getForegroundOps(uid);
+        return mService.getForegroundOps(uid, persistentDeviceId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java
index c3a02a8..55cf7ed 100644
--- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java
+++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java
@@ -81,11 +81,11 @@
     }
 
     @Override
-    public SparseIntArray getNonDefaultUidModes(int uid) {
+    public SparseIntArray getNonDefaultUidModes(int uid, String persistentDeviceId) {
         Trace.traceBegin(TRACE_TAG,
                 "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getNonDefaultUidModes");
         try {
-            return mService.getNonDefaultUidModes(uid);
+            return mService.getNonDefaultUidModes(uid, persistentDeviceId);
         } finally {
             Trace.traceEnd(TRACE_TAG);
         }
@@ -103,20 +103,21 @@
     }
 
     @Override
-    public int getUidMode(int uid, int op) {
+    public int getUidMode(int uid, String persistentDeviceId, int op) {
         Trace.traceBegin(TRACE_TAG, "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getUidMode");
         try {
-            return mService.getUidMode(uid, op);
+            return mService.getUidMode(uid, persistentDeviceId, op);
         } finally {
             Trace.traceEnd(TRACE_TAG);
         }
     }
 
     @Override
-    public boolean setUidMode(int uid, int op, @AppOpsManager.Mode int mode) {
+    public boolean setUidMode(
+            int uid, String persistentDeviceId, int op, @AppOpsManager.Mode int mode) {
         Trace.traceBegin(TRACE_TAG, "TaggedTracingAppOpsCheckingServiceInterfaceImpl#setUidMode");
         try {
-            return mService.setUidMode(uid, op, mode);
+            return mService.setUidMode(uid, persistentDeviceId, op, mode);
         } finally {
             Trace.traceEnd(TRACE_TAG);
         }
@@ -179,11 +180,11 @@
     }
 
     @Override
-    public SparseBooleanArray getForegroundOps(int uid) {
+    public SparseBooleanArray getForegroundOps(int uid, String persistentDeviceId) {
         Trace.traceBegin(TRACE_TAG,
                 "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getForegroundOps");
         try {
-            return mService.getForegroundOps(uid);
+            return mService.getForegroundOps(uid, persistentDeviceId);
         } finally {
             Trace.traceEnd(TRACE_TAG);
         }
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 14aab13..3446737 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -63,6 +63,7 @@
 import static android.app.AppOpsManager.opRestrictsRead;
 import static android.app.AppOpsManager.opToName;
 import static android.app.AppOpsManager.opToPublicName;
+import static android.companion.virtual.VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;
 import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
 import static android.content.pm.PermissionInfo.PROTECTION_FLAG_APPOP;
 
@@ -1349,7 +1350,10 @@
 
                 SparseBooleanArray foregroundOps = new SparseBooleanArray();
 
-                SparseBooleanArray uidForegroundOps = mAppOpsCheckingService.getForegroundOps(uid);
+                // TODO(b/299330771): Check uidForegroundOps for all devices.
+                SparseBooleanArray uidForegroundOps =
+                        mAppOpsCheckingService.getForegroundOps(
+                                uid, PERSISTENT_DEVICE_ID_DEFAULT);
                 for (int i = 0; i < uidForegroundOps.size(); i++) {
                     foregroundOps.put(uidForegroundOps.keyAt(i), true);
                 }
@@ -1369,10 +1373,16 @@
                         continue;
                     }
                     final int code = foregroundOps.keyAt(fgi);
-
-                    if (mAppOpsCheckingService.getUidMode(uidState.uid, code)
+                    // TODO(b/299330771): Notify op changes for all relevant devices.
+                    if (mAppOpsCheckingService.getUidMode(
+                                            uidState.uid,
+                                            PERSISTENT_DEVICE_ID_DEFAULT,
+                                            code)
                                     != AppOpsManager.opToDefaultMode(code)
-                            && mAppOpsCheckingService.getUidMode(uidState.uid, code)
+                            && mAppOpsCheckingService.getUidMode(
+                                            uidState.uid,
+                                            PERSISTENT_DEVICE_ID_DEFAULT,
+                                            code)
                                     == AppOpsManager.MODE_FOREGROUND) {
                         mHandler.sendMessage(PooledLambda.obtainMessage(
                                 AppOpsService::notifyOpChangedForAllPkgsInUid,
@@ -1489,7 +1499,11 @@
     @Nullable
     private ArrayList<AppOpsManager.OpEntry> collectUidOps(@NonNull UidState uidState,
             @Nullable int[] ops) {
-        final SparseIntArray opModes = mAppOpsCheckingService.getNonDefaultUidModes(uidState.uid);
+        // TODO(b/299330771): Make this methods device-aware, currently it represents only the
+        // primary device.
+        final SparseIntArray opModes =
+                mAppOpsCheckingService.getNonDefaultUidModes(
+                        uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT);
         if (opModes == null) {
             return null;
         }
@@ -1844,16 +1858,22 @@
                 uidState = new UidState(uid);
                 mUidStates.put(uid, uidState);
             }
-            if (mAppOpsCheckingService.getUidMode(uidState.uid, code)
+            // TODO(b/266164193): Ensure this behavior is device-aware after uid op mode for runtime
+            //  permissions is deprecated.
+            if (mAppOpsCheckingService.getUidMode(
+                            uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code)
                     != AppOpsManager.opToDefaultMode(code)) {
-                previousMode = mAppOpsCheckingService.getUidMode(uidState.uid, code);
+                previousMode =
+                        mAppOpsCheckingService.getUidMode(
+                                uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code);
             } else {
                 // doesn't look right but is legacy behavior.
                 previousMode = MODE_DEFAULT;
             }
 
             mIgnoredCallback = permissionPolicyCallback;
-            if (!mAppOpsCheckingService.setUidMode(uidState.uid, code, mode)) {
+            if (!mAppOpsCheckingService.setUidMode(
+                    uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code, mode)) {
                 return;
             }
             if (mode != MODE_ERRORED && mode != previousMode) {
@@ -2275,8 +2295,10 @@
             boolean changed = false;
             for (int i = mUidStates.size() - 1; i >= 0; i--) {
                 UidState uidState = mUidStates.valueAt(i);
-
-                SparseIntArray opModes = mAppOpsCheckingService.getNonDefaultUidModes(uidState.uid);
+                // TODO(b/299330771): Check non default modes for all devices.
+                SparseIntArray opModes =
+                        mAppOpsCheckingService.getNonDefaultUidModes(
+                                uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT);
                 if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) {
                     final int uidOpCount = opModes.size();
                     for (int j = uidOpCount - 1; j >= 0; j--) {
@@ -2285,7 +2307,12 @@
                             int previousMode = opModes.valueAt(j);
                             int newMode = isUidOpGrantedByRole(uidState.uid, code) ? MODE_ALLOWED :
                                     AppOpsManager.opToDefaultMode(code);
-                            mAppOpsCheckingService.setUidMode(uidState.uid, code, newMode);
+                            // TODO(b/299330771): Set mode for all necessary devices.
+                            mAppOpsCheckingService.setUidMode(
+                                    uidState.uid,
+                                    PERSISTENT_DEVICE_ID_DEFAULT,
+                                    code,
+                                    newMode);
                             for (String packageName : getPackagesForUid(uidState.uid)) {
                                 callbacks = addCallbacks(callbacks, code, uidState.uid, packageName,
                                         previousMode, mOpModeWatchers.get(code));
@@ -2601,10 +2628,14 @@
             }
             code = AppOpsManager.opToSwitch(code);
             UidState uidState = getUidStateLocked(uid, false);
+            // TODO(b/299330771): Check mode for the relevant device.
             if (uidState != null
-                    && mAppOpsCheckingService.getUidMode(uidState.uid, code)
+                    && mAppOpsCheckingService.getUidMode(
+                                    uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code)
                             != AppOpsManager.opToDefaultMode(code)) {
-                final int rawMode = mAppOpsCheckingService.getUidMode(uidState.uid, code);
+                final int rawMode =
+                        mAppOpsCheckingService.getUidMode(
+                                uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code);
                 return raw ? rawMode : uidState.evalMode(code, rawMode);
             }
             Op op = getOpLocked(code, uid, packageName, null, false, pvr.bypass, /* edit */ false);
@@ -2851,13 +2882,19 @@
                 return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, attributionTag,
                         packageName);
             }
+            // TODO(b/299330771): Check mode for the relevant device.
             // If there is a non-default per UID policy (we set UID op mode only if
             // non-default) it takes over, otherwise use the per package policy.
-            if (mAppOpsCheckingService.getUidMode(uidState.uid, switchCode)
+            if (mAppOpsCheckingService.getUidMode(
+                            uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, switchCode)
                     != AppOpsManager.opToDefaultMode(switchCode)) {
                 final int uidMode =
                         uidState.evalMode(
-                                code, mAppOpsCheckingService.getUidMode(uidState.uid, switchCode));
+                                code,
+                                mAppOpsCheckingService.getUidMode(
+                                        uidState.uid,
+                                        PERSISTENT_DEVICE_ID_DEFAULT,
+                                        switchCode));
                 if (uidMode != AppOpsManager.MODE_ALLOWED) {
                     if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
@@ -3396,13 +3433,19 @@
             isRestricted = isOpRestrictedLocked(uid, code, packageName, attributionTag, pvr.bypass,
                     false);
             final int switchCode = AppOpsManager.opToSwitch(code);
+            // TODO(b/299330771): Check mode for the relevant device.
             // If there is a non-default per UID policy (we set UID op mode only if
             // non-default) it takes over, otherwise use the per package policy.
-            if (mAppOpsCheckingService.getUidMode(uidState.uid, switchCode)
+            if (mAppOpsCheckingService.getUidMode(
+                            uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, switchCode)
                     != AppOpsManager.opToDefaultMode(switchCode)) {
                 final int uidMode =
                         uidState.evalMode(
-                                code, mAppOpsCheckingService.getUidMode(uidState.uid, switchCode));
+                                code,
+                                mAppOpsCheckingService.getUidMode(
+                                        uidState.uid,
+                                        PERSISTENT_DEVICE_ID_DEFAULT,
+                                        switchCode));
                 if (!shouldStartForMode(uidMode, startIfModeDefault)) {
                     if (DEBUG) {
                         Slog.d(TAG, "startOperation: uid reject #" + uidMode + " for code "
@@ -3511,13 +3554,19 @@
             isRestricted = isOpRestrictedLocked(uid, code, packageName, attributionTag, pvr.bypass,
                     false);
             final int switchCode = AppOpsManager.opToSwitch(code);
+            // TODO(b/299330771): Check mode for the relevant device.
             // If there is a non-default mode per UID policy (we set UID op mode only if
             // non-default) it takes over, otherwise use the per package policy.
-            if (mAppOpsCheckingService.getUidMode(uidState.uid, switchCode)
+            if (mAppOpsCheckingService.getUidMode(
+                            uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, switchCode)
                     != AppOpsManager.opToDefaultMode(switchCode)) {
                 final int uidMode =
                         uidState.evalMode(
-                                code, mAppOpsCheckingService.getUidMode(uidState.uid, switchCode));
+                                code,
+                                mAppOpsCheckingService.getUidMode(
+                                        uidState.uid,
+                                        PERSISTENT_DEVICE_ID_DEFAULT,
+                                        switchCode));
                 if (!shouldStartForMode(uidMode, startIfModeDefault)) {
                     if (DEBUG) {
                         Slog.d(TAG, "startOperation: uid reject #" + uidMode + " for code "
@@ -5664,8 +5713,10 @@
             }
             for (int i=0; i<mUidStates.size(); i++) {
                 UidState uidState = mUidStates.valueAt(i);
+                // TODO(b/299330771): Get modes for all devices.
                 final SparseIntArray opModes =
-                        mAppOpsCheckingService.getNonDefaultUidModes(uidState.uid);
+                        mAppOpsCheckingService.getNonDefaultUidModes(
+                                uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT);
                 final ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
 
                 if (dumpWatchers || dumpHistory) {
diff --git a/services/core/java/com/android/server/appop/AppOpsServiceTestingShim.java b/services/core/java/com/android/server/appop/AppOpsServiceTestingShim.java
index 98e6476..c9fa9e6 100644
--- a/services/core/java/com/android/server/appop/AppOpsServiceTestingShim.java
+++ b/services/core/java/com/android/server/appop/AppOpsServiceTestingShim.java
@@ -65,9 +65,9 @@
     }
 
     @Override
-    public SparseIntArray getNonDefaultUidModes(int uid) {
-        SparseIntArray oldVal = mOldImplementation.getNonDefaultUidModes(uid);
-        SparseIntArray newVal = mNewImplementation.getNonDefaultUidModes(uid);
+    public SparseIntArray getNonDefaultUidModes(int uid, String persistentDeviceId) {
+        SparseIntArray oldVal = mOldImplementation.getNonDefaultUidModes(uid, persistentDeviceId);
+        SparseIntArray newVal = mNewImplementation.getNonDefaultUidModes(uid, persistentDeviceId);
 
         if (!Objects.equals(oldVal, newVal)) {
             signalImplDifference("getNonDefaultUidModes");
@@ -89,9 +89,9 @@
     }
 
     @Override
-    public int getUidMode(int uid, int op) {
-        int oldVal = mOldImplementation.getUidMode(uid, op);
-        int newVal = mNewImplementation.getUidMode(uid, op);
+    public int getUidMode(int uid, String persistentDeviceId, int op) {
+        int oldVal = mOldImplementation.getUidMode(uid, persistentDeviceId, op);
+        int newVal = mNewImplementation.getUidMode(uid, persistentDeviceId, op);
 
         if (oldVal != newVal) {
             signalImplDifference("getUidMode");
@@ -101,9 +101,9 @@
     }
 
     @Override
-    public boolean setUidMode(int uid, int op, int mode) {
-        boolean oldVal = mOldImplementation.setUidMode(uid, op, mode);
-        boolean newVal = mNewImplementation.setUidMode(uid, op, mode);
+    public boolean setUidMode(int uid, String persistentDeviceId, int op, int mode) {
+        boolean oldVal = mOldImplementation.setUidMode(uid, persistentDeviceId, op, mode);
+        boolean newVal = mNewImplementation.setUidMode(uid, persistentDeviceId, op, mode);
 
         if (oldVal != newVal) {
             signalImplDifference("setUidMode");
@@ -155,9 +155,9 @@
     }
 
     @Override
-    public SparseBooleanArray getForegroundOps(int uid) {
-        SparseBooleanArray oldVal = mOldImplementation.getForegroundOps(uid);
-        SparseBooleanArray newVal = mNewImplementation.getForegroundOps(uid);
+    public SparseBooleanArray getForegroundOps(int uid, String persistentDeviceId) {
+        SparseBooleanArray oldVal = mOldImplementation.getForegroundOps(uid, persistentDeviceId);
+        SparseBooleanArray newVal = mNewImplementation.getForegroundOps(uid, persistentDeviceId);
 
         if (!Objects.equals(oldVal, newVal)) {
             signalImplDifference("getForegroundOps");
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index d4b72c1..4f6c6d6 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -38,6 +38,7 @@
 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
 
+import static com.android.media.audio.Flags.alarmMinVolumeZero;
 import static com.android.media.audio.Flags.bluetoothMacAddressAnonymization;
 import static com.android.media.audio.Flags.disablePrescaleAbsoluteVolume;
 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE;
@@ -94,6 +95,7 @@
 import android.hidl.manager.V1_0.IServiceManager;
 import android.media.AudioAttributes;
 import android.media.AudioAttributes.AttributeSystemUsage;
+import android.media.AudioDescriptor;
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceInfo;
 import android.media.AudioDeviceVolumeManager;
@@ -106,6 +108,7 @@
 import android.media.AudioManagerInternal;
 import android.media.AudioMixerAttributes;
 import android.media.AudioPlaybackConfiguration;
+import android.media.AudioProfile;
 import android.media.AudioRecordingConfiguration;
 import android.media.AudioRoutesInfo;
 import android.media.AudioSystem;
@@ -233,6 +236,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -1191,6 +1195,19 @@
             MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
         }
 
+        if (alarmMinVolumeZero()) {
+            try {
+                int minAlarmVolume = mContext.getResources().getInteger(
+                        com.android.internal.R.integer.config_audio_alarm_min_vol);
+                if (minAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
+                    MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = minAlarmVolume;
+                } else {
+                    Log.e(TAG, "Error min alarm volume greater than max alarm volume");
+                }
+            } catch (Resources.NotFoundException e) {
+                Log.e(TAG, "Error querying for alarm min volume ", e);
+            }
+        }
         int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
         if (defaultAlarmVolume != -1 &&
                 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
@@ -4600,7 +4617,7 @@
     }
 
     private void setStreamVolume(int streamType, int index, int flags,
-            @NonNull AudioDeviceAttributes ada,
+            @Nullable AudioDeviceAttributes ada,
             String callingPackage, String caller, String attributionTag, int uid,
             boolean hasModifyAudioSettings,
             boolean canChangeMuteAndUpdateController) {
@@ -4618,7 +4635,9 @@
         int streamTypeAlias = mStreamVolumeAlias[streamType];
         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
 
-        final int device = ada.getInternalType();
+        final int device = (ada == null)
+                ? getDeviceForStream(streamType)
+                : ada.getInternalType();
         int oldIndex;
 
         // skip a2dp absolute volume control request when the device
@@ -7671,6 +7690,13 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface ConnectionState {}
 
+    /**
+     * Default SAD for a TV using ARC, used when the Amplifier didn't report any SADs.
+     * Represents 2-channel LPCM including all defined sample rates and bit depths.
+     * For the format definition, see Table 34 in the CEA standard CEA-861-D.
+     */
+    private static final byte[] DEFAULT_ARC_AUDIO_DESCRIPTOR = new byte[]{0x09, 0x7f, 0x07};
+
     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     /**
      * see AudioManager.setWiredDeviceConnectionState()
@@ -7682,6 +7708,27 @@
 
         attributes = retrieveBluetoothAddress(attributes);
 
+        // When using ARC, a TV should use default 2 channel LPCM if the Amplifier didn't
+        // report any SADs. See section 13.15.3 of the HDMI-CEC spec version 1.4b.
+        if (attributes.getType() == AudioDeviceInfo.TYPE_HDMI_ARC
+                && attributes.getRole() == AudioDeviceAttributes.ROLE_OUTPUT
+                && attributes.getAudioDescriptors().isEmpty()) {
+            attributes = new AudioDeviceAttributes(
+                    attributes.getRole(),
+                    attributes.getType(),
+                    attributes.getAddress(),
+                    attributes.getName(),
+                    attributes.getAudioProfiles(),
+                    new ArrayList<AudioDescriptor>(Collections.singletonList(
+                            new AudioDescriptor(
+                                    AudioDescriptor.STANDARD_EDID,
+                                    AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE,
+                                    DEFAULT_ARC_AUDIO_DESCRIPTOR
+                            )
+                    ))
+            );
+        }
+
         if (state != CONNECTION_STATE_CONNECTED
                 && state != CONNECTION_STATE_DISCONNECTED) {
             throw new IllegalArgumentException("Invalid state " + state);
@@ -10665,8 +10712,8 @@
 
     /** @see LoudnessCodecConfigurator#addMediaCodec(MediaCodec) */
     @Override
-    public void addLoudnessCodecInfo(int piid, LoudnessCodecInfo codecInfo) {
-        mLoudnessCodecHelper.addLoudnessCodecInfo(piid, codecInfo);
+    public void addLoudnessCodecInfo(int piid, int mediaCodecHash, LoudnessCodecInfo codecInfo) {
+        mLoudnessCodecHelper.addLoudnessCodecInfo(piid, mediaCodecHash, codecInfo);
     }
 
     /** @see LoudnessCodecConfigurator#removeMediaCodec(MediaCodec) */
@@ -11370,6 +11417,8 @@
     static final int LOG_NB_EVENTS_SPATIAL = 30;
     static final int LOG_NB_EVENTS_SOUND_DOSE = 30;
 
+    static final int LOG_NB_EVENTS_LOUDNESS_CODEC = 30;
+
     static final EventLogger
             sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE,
             "audio services lifecycle");
@@ -11569,6 +11618,10 @@
         mSpatializerHelper.dump(pw);
         sSpatialLogger.dump(pw);
 
+        pw.println("\n");
+        pw.println("\nLoudness alignment:");
+        mLoudnessCodecHelper.dump(pw);
+
         mAudioSystem.dump(pw);
     }
 
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index f69b9f6..de89011 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -622,6 +622,55 @@
         }
     }
 
+    static final class LoudnessEvent extends EventLogger.Event {
+        static final int START_PIID = 0;
+
+        static final int STOP_PIID = 1;
+
+        static final int CLIENT_DIED = 2;
+
+        final int mEventType;
+        final int mIntValue1;
+        final int mIntValue2;
+
+        private LoudnessEvent(int event, int i1, int i2) {
+            mEventType = event;
+            mIntValue1 = i1;
+            mIntValue2 = i2;
+        }
+
+        static LoudnessEvent getStartPiid(int piid, int pid) {
+            return new LoudnessEvent(START_PIID, piid, pid);
+        }
+
+        static LoudnessEvent getStopPiid(int piid, int pid) {
+            return new LoudnessEvent(STOP_PIID, piid, pid);
+        }
+
+        static LoudnessEvent getClientDied(int pid) {
+            return new LoudnessEvent(CLIENT_DIED, 0 /* ignored */, pid);
+        }
+
+
+        @Override
+        public String eventToString() {
+            switch (mEventType) {
+                case START_PIID:
+                    return String.format(
+                            "Start loudness updates for piid %d for client pid %d",
+                            mIntValue1, mIntValue2);
+                case STOP_PIID:
+                    return String.format(
+                            "Stop loudness updates for piid %d for client pid %d",
+                            mIntValue1, mIntValue2);
+                case CLIENT_DIED:
+                    return String.format("Loudness client with pid %d died", mIntValue2);
+
+            }
+            return new StringBuilder("FIXME invalid event type:").append(mEventType).toString();
+        }
+    }
+
     /**
      * Class to log stream type mute/unmute events
      */
diff --git a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java
index 3c67e9d..bbe819f 100644
--- a/services/core/java/com/android/server/audio/LoudnessCodecHelper.java
+++ b/services/core/java/com/android/server/audio/LoudnessCodecHelper.java
@@ -21,6 +21,11 @@
 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEARING_AID;
 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_WATCH;
 import static android.media.AudioPlaybackConfiguration.PLAYER_DEVICEID_INVALID;
+import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_4;
+import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_D;
+import static android.media.MediaFormat.KEY_AAC_DRC_EFFECT_TYPE;
+import static android.media.MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION;
+import static android.media.MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -41,7 +46,11 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.audio.AudioServiceEvents.LoudnessEvent;
+import com.android.server.utils.EventLogger;
 
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -50,6 +59,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Class to handle the updates in loudness parameters and responsible to generate parameters that
@@ -70,10 +80,14 @@
     private static final String SYSTEM_PROPERTY_SPEAKER_SPL_RANGE_SIZE =
             "audio.loudness.builtin-speaker-spl-range-size";
 
-    private static final int SPL_RANGE_UNKNOWN = 0;
-    private static final int SPL_RANGE_SMALL = 1;
-    private static final int SPL_RANGE_MEDIUM = 2;
-    private static final int SPL_RANGE_LARGE = 3;
+    @VisibleForTesting
+    static final int SPL_RANGE_UNKNOWN = 0;
+    @VisibleForTesting
+    static final int SPL_RANGE_SMALL = 1;
+    @VisibleForTesting
+    static final int SPL_RANGE_MEDIUM = 2;
+    @VisibleForTesting
+    static final int SPL_RANGE_LARGE = 3;
 
     /** The possible transducer SPL ranges as defined in CTA2075 */
     @IntDef({
@@ -99,12 +113,19 @@
                 pid = (Integer) cookie;
             }
             if (pid != null) {
-                mLoudnessCodecHelper.removePid(pid);
+                if (DEBUG) {
+                    Log.d(TAG, "Client with pid " + pid + " died, removing from receiving updates");
+                }
+                sLogger.enqueue(LoudnessEvent.getClientDied(pid));
+                mLoudnessCodecHelper.onClientPidDied(pid);
             }
             super.onCallbackDied(callback, cookie);
         }
     }
 
+    private static final EventLogger sLogger = new EventLogger(
+            AudioService.LOG_NB_EVENTS_LOUDNESS_CODEC, "Loudness updates");
+
     private final LoudnessRemoteCallbackList mLoudnessUpdateDispatchers =
             new LoudnessRemoteCallbackList(this);
 
@@ -125,7 +146,8 @@
     private final AudioService mAudioService;
 
     /** Contains the properties necessary to compute the codec loudness related parameters. */
-    private static final class LoudnessCodecInputProperties {
+    @VisibleForTesting
+    static final class LoudnessCodecInputProperties {
         private final int mMetadataType;
 
         private final boolean mIsDownmixing;
@@ -200,10 +222,53 @@
         }
 
         PersistableBundle createLoudnessParameters() {
-            // TODO: create bundle with new parameters
-            return new PersistableBundle();
-        }
+            PersistableBundle loudnessParams = new PersistableBundle();
 
+            switch (mDeviceSplRange) {
+                case SPL_RANGE_LARGE:
+                    // corresponds to -31dB attenuation
+                    loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 124);
+                    if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+                        loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, 0);
+                    } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+                        // general compression
+                        loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6);
+                    }
+                    break;
+                case SPL_RANGE_MEDIUM:
+                    // corresponds to -24dB attenuation
+                    loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 96);
+                    if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+                        loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, mIsDownmixing ? 1 : 0);
+                    } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+                        // general compression
+                        loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6);
+                    }
+                    break;
+                case SPL_RANGE_SMALL:
+                    // corresponds to -16dB attenuation
+                    loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 64);
+                    if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+                        loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, 1);
+                    } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+                        // limited playback range compression
+                        loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 3);
+                    }
+                    break;
+                default:
+                    // corresponds to -24dB attenuation
+                    loudnessParams.putInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, 96);
+                    if (mMetadataType == CODEC_METADATA_TYPE_MPEG_4) {
+                        loudnessParams.putInt(KEY_AAC_DRC_HEAVY_COMPRESSION, mIsDownmixing ? 1 : 0);
+                    } else if (mMetadataType == CODEC_METADATA_TYPE_MPEG_D) {
+                        // general compression
+                        loudnessParams.putInt(KEY_AAC_DRC_EFFECT_TYPE, 6);
+                    }
+                    break;
+            }
+
+            return loudnessParams;
+        }
     }
 
     @GuardedBy("mLock")
@@ -227,22 +292,25 @@
         if (DEBUG) {
             Log.d(TAG, "startLoudnessCodecUpdates: piid " + piid + " codecInfos " + codecInfoList);
         }
-        Set<LoudnessCodecInfo> infoSet;
+
         synchronized (mLock) {
             if (mStartedPiids.contains(piid)) {
                 Log.w(TAG, "Already started loudness updates for piid " + piid);
                 return;
             }
-            infoSet = new HashSet<>(codecInfoList);
+            Set<LoudnessCodecInfo> infoSet = new HashSet<>(codecInfoList);
             mStartedPiids.put(piid, infoSet);
 
-            mPiidToPidCache.put(piid, Binder.getCallingPid());
+            int pid = Binder.getCallingPid();
+            mPiidToPidCache.put(piid, pid);
+
+            sLogger.enqueue(LoudnessEvent.getStartPiid(piid, pid));
         }
 
         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
             mAudioService.getActivePlaybackConfigurations().stream().filter(
                     conf -> conf.getPlayerInterfaceId() == piid).findFirst().ifPresent(
-                            apc -> updateCodecParametersForConfiguration(apc, infoSet));
+                    this::updateCodecParametersForConfiguration);
         }
     }
 
@@ -250,20 +318,24 @@
         if (DEBUG) {
             Log.d(TAG, "stopLoudnessCodecUpdates: piid " + piid);
         }
+
         synchronized (mLock) {
             if (!mStartedPiids.contains(piid)) {
                 Log.w(TAG, "Loudness updates are already stopped for piid " + piid);
                 return;
             }
             mStartedPiids.remove(piid);
+
+            sLogger.enqueue(LoudnessEvent.getStopPiid(piid, mPiidToPidCache.get(piid, -1)));
             mPiidToDeviceIdCache.delete(piid);
             mPiidToPidCache.delete(piid);
         }
     }
 
-    void addLoudnessCodecInfo(int piid, LoudnessCodecInfo info) {
+    void addLoudnessCodecInfo(int piid, int mediaCodecHash, LoudnessCodecInfo info) {
         if (DEBUG) {
-            Log.d(TAG, "addLoudnessCodecInfo: piid " + piid + " info " + info);
+            Log.d(TAG, "addLoudnessCodecInfo: piid " + piid + " mcHash " + mediaCodecHash + " info "
+                    + info);
         }
 
         Set<LoudnessCodecInfo> infoSet;
@@ -280,7 +352,20 @@
         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
             mAudioService.getActivePlaybackConfigurations().stream().filter(
                     conf -> conf.getPlayerInterfaceId() == piid).findFirst().ifPresent(
-                            apc -> updateCodecParametersForConfiguration(apc, Set.of(info)));
+                            apc -> {
+                                final AudioDeviceInfo deviceInfo = apc.getAudioDeviceInfo();
+                                if (deviceInfo != null) {
+                                    PersistableBundle updateBundle = new PersistableBundle();
+                                    synchronized (mLock) {
+                                        updateBundle.putPersistableBundle(
+                                                Integer.toString(mediaCodecHash),
+                                                getCodecBundle_l(deviceInfo, info));
+                                    }
+                                    if (!updateBundle.isDefinitelyEmpty()) {
+                                        dispatchNewLoudnessParameters(piid, updateBundle);
+                                    }
+                                }
+                            });
         }
     }
 
@@ -298,24 +383,6 @@
         }
     }
 
-    void removePid(int pid) {
-        if (DEBUG) {
-            Log.d(TAG, "Removing pid " + pid + " from receiving updates");
-        }
-        synchronized (mLock) {
-            for (int i = 0; i < mPiidToPidCache.size(); ++i) {
-                int piid = mPiidToPidCache.keyAt(i);
-                if (mPiidToPidCache.get(piid) == pid) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Removing piid  " + piid);
-                    }
-                    mStartedPiids.delete(piid);
-                    mPiidToDeviceIdCache.delete(piid);
-                }
-            }
-        }
-    }
-
     PersistableBundle getLoudnessParams(int piid, LoudnessCodecInfo codecInfo) {
         if (DEBUG) {
             Log.d(TAG, "getLoudnessParams: piid " + piid + " codecInfo " + codecInfo);
@@ -381,48 +448,77 @@
             }
         }
 
-        updateApcList.forEach(apc -> updateCodecParametersForConfiguration(apc, null));
+        updateApcList.forEach(apc -> updateCodecParametersForConfiguration(apc));
     }
 
-    /** Updates and dispatches the new loudness parameters for the {@code codecInfos} set.
+    /** Updates and dispatches the new loudness parameters for all its registered codecs. */
+    void dump(PrintWriter pw) {
+        // Registered clients
+        pw.println("\nRegistered clients:\n");
+        synchronized (mLock) {
+            for (int i = 0; i < mStartedPiids.size(); ++i) {
+                int piid = mStartedPiids.keyAt(i);
+                int pid = mPiidToPidCache.get(piid, -1);
+                final Set<LoudnessCodecInfo> codecInfos = mStartedPiids.get(piid);
+                pw.println(String.format("Player piid %d pid %d active codec types %s\n", piid,
+                        pid, codecInfos.stream().map(Object::toString).collect(
+                                Collectors.joining(", "))));
+            }
+            pw.println();
+        }
+
+        sLogger.dump(pw);
+        pw.println();
+    }
+
+    private void onClientPidDied(int pid) {
+        synchronized (mLock) {
+            for (int i = 0; i < mPiidToPidCache.size(); ++i) {
+                int piid = mPiidToPidCache.keyAt(i);
+                if (mPiidToPidCache.get(piid) == pid) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Removing piid  " + piid);
+                    }
+                    mStartedPiids.delete(piid);
+                    mPiidToDeviceIdCache.delete(piid);
+                }
+            }
+        }
+    }
+
+    /**
+     * Updates and dispatches the new loudness parameters for the {@code codecInfos} set.
      *
      * @param apc the player configuration for which the loudness parameters are updated.
-     * @param codecInfos the codec info for which the parameters are updated. If {@code null},
-     *                   send updates for all the started codecs assigned to {@code apc}
      */
-    private void updateCodecParametersForConfiguration(AudioPlaybackConfiguration apc,
-            Set<LoudnessCodecInfo> codecInfos) {
+    private void updateCodecParametersForConfiguration(AudioPlaybackConfiguration apc) {
         if (DEBUG) {
-            Log.d(TAG, "updateCodecParametersForConfiguration apc:" + apc + " codecInfos: "
-                    + codecInfos);
+            Log.d(TAG, "updateCodecParametersForConfiguration apc:" + apc);
         }
+
         final PersistableBundle allBundles = new PersistableBundle();
         final int piid = apc.getPlayerInterfaceId();
+
         synchronized (mLock) {
-            if (codecInfos == null) {
-                codecInfos = mStartedPiids.get(piid);
-            }
+            final Set<LoudnessCodecInfo> codecInfos = mStartedPiids.get(piid);
 
             final AudioDeviceInfo deviceInfo = apc.getAudioDeviceInfo();
             if (codecInfos != null && deviceInfo != null) {
                 for (LoudnessCodecInfo info : codecInfos) {
-                    allBundles.putPersistableBundle(Integer.toString(info.mediaCodecHashCode),
+                    allBundles.putPersistableBundle(Integer.toString(info.hashCode()),
                             getCodecBundle_l(deviceInfo, info));
                 }
             }
         }
 
         if (!allBundles.isDefinitelyEmpty()) {
-            if (DEBUG) {
-                Log.d(TAG, "Dispatching for piid: " + piid + " bundle: " + allBundles);
-            }
             dispatchNewLoudnessParameters(piid, allBundles);
         }
     }
 
     private void dispatchNewLoudnessParameters(int piid, PersistableBundle bundle) {
         if (DEBUG) {
-            Log.d(TAG, "dispatchNewLoudnessParameters: piid " + piid);
+            Log.d(TAG, "dispatchNewLoudnessParameters: piid " + piid + " bundle: " + bundle);
         }
         final int nbDispatchers = mLoudnessUpdateDispatchers.beginBroadcast();
         for (int i = 0; i < nbDispatchers; ++i) {
diff --git a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
index be78ea2..cecde55 100644
--- a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
+++ b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
@@ -149,6 +149,14 @@
     public abstract @NonNull ArraySet<Integer> getDisplayIdsForDevice(int deviceId);
 
     /**
+     * Returns the ID of the device which owns the display with the given ID.
+     *
+     * <p>In case the virtual display ID is invalid or doesn't belong to a virtual device, then
+     * {@link android.content.Context#DEVICE_ID_DEFAULT} is returned.</p>
+     */
+    public abstract int getDeviceIdForDisplayId(int displayId);
+
+    /**
      * Gets the persistent ID for the VirtualDevice with the given device ID.
      *
      * @param deviceId which device we're asking about
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index debf828..d848f4b 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -121,6 +121,7 @@
 
         // Display independent, mode dependent values
         float[] brightnessLevelsNits;
+        float[] brightnessLevels = null;
         float[] luxLevels;
         if (isForIdleMode) {
             brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
@@ -130,11 +131,21 @@
         } else {
             brightnessLevelsNits = displayDeviceConfig.getAutoBrightnessBrighteningLevelsNits();
             luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux();
+
+            brightnessLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevels();
+            if (brightnessLevels == null || brightnessLevels.length == 0) {
+                // Load the old configuration in the range [0, 255]. The values need to be
+                // normalized to the range [0, 1].
+                int[] brightnessLevelsInt = resources.getIntArray(
+                        com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
+                brightnessLevels = new float[brightnessLevelsInt.length];
+                for (int i = 0; i < brightnessLevels.length; i++) {
+                    brightnessLevels[i] = normalizeAbsoluteBrightness(brightnessLevelsInt[i]);
+                }
+            }
         }
 
         // Display independent, mode independent values
-        int[] brightnessLevelsBacklight = resources.getIntArray(
-                com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
         float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
                 com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
                 1, 1);
@@ -155,8 +166,8 @@
             builder.setShortTermModelUpperLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO);
             return new PhysicalMappingStrategy(builder.build(), nitsRange, brightnessRange,
                     autoBrightnessAdjustmentMaxGamma, isForIdleMode, displayWhiteBalanceController);
-        } else if (isValidMapping(luxLevels, brightnessLevelsBacklight) && !isForIdleMode) {
-            return new SimpleMappingStrategy(luxLevels, brightnessLevelsBacklight,
+        } else if (isValidMapping(luxLevels, brightnessLevels)) {
+            return new SimpleMappingStrategy(luxLevels, brightnessLevels,
                     autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout);
         } else {
             return null;
@@ -620,7 +631,7 @@
         private float mUserBrightness;
         private long mShortTermModelTimeout;
 
-        private SimpleMappingStrategy(float[] lux, int[] brightness, float maxGamma,
+        private SimpleMappingStrategy(float[] lux, float[] brightness, float maxGamma,
                 long timeout) {
             Preconditions.checkArgument(lux.length != 0 && brightness.length != 0,
                     "Lux and brightness arrays must not be empty!");
@@ -635,7 +646,7 @@
             mBrightness = new float[N];
             for (int i = 0; i < N; i++) {
                 mLux[i] = lux[i];
-                mBrightness[i] = normalizeAbsoluteBrightness(brightness[i]);
+                mBrightness[i] = brightness[i];
             }
 
             mMaxGamma = maxGamma;
diff --git a/services/core/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java
index 70d4ad2..c26118e 100644
--- a/services/core/java/com/android/server/display/DisplayAdapter.java
+++ b/services/core/java/com/android/server/display/DisplayAdapter.java
@@ -20,6 +20,8 @@
 import android.os.Handler;
 import android.view.Display;
 
+import com.android.server.display.feature.DisplayManagerFlags;
+
 import java.io.PrintWriter;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -39,6 +41,7 @@
     private final Handler mHandler;
     private final Listener mListener;
     private final String mName;
+    private final DisplayManagerFlags mFeatureFlags;
 
     public static final int DISPLAY_DEVICE_EVENT_ADDED = 1;
     public static final int DISPLAY_DEVICE_EVENT_CHANGED = 2;
@@ -50,13 +53,14 @@
     private static final AtomicInteger NEXT_DISPLAY_MODE_ID = new AtomicInteger(1);  // 0 = no mode.
 
     // Called with SyncRoot lock held.
-    public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
-            Context context, Handler handler, Listener listener, String name) {
+    DisplayAdapter(DisplayManagerService.SyncRoot syncRoot, Context context, Handler handler,
+            Listener listener, String name, DisplayManagerFlags featureFlags) {
         mSyncRoot = syncRoot;
         mContext = context;
         mHandler = handler;
         mListener = listener;
         mName = name;
+        mFeatureFlags = featureFlags;
     }
 
     /**
@@ -88,6 +92,10 @@
         return mName;
     }
 
+    public final DisplayManagerFlags getFeatureFlags() {
+        return mFeatureFlags;
+    }
+
     /**
      * Registers the display adapter with the display manager.
      *
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 2fdf90d..3b05b47 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -400,6 +400,7 @@
     }
 
     private DisplayDeviceConfig loadDisplayDeviceConfig() {
-        return DisplayDeviceConfig.create(mContext, false);
+        return DisplayDeviceConfig.create(mContext, /* useConfigXml= */ false,
+                mDisplayAdapter.getFeatureFlags());
     }
 }
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index b99de5c..d97127c 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -57,6 +57,7 @@
 import com.android.server.display.config.HighBrightnessMode;
 import com.android.server.display.config.IntegerArray;
 import com.android.server.display.config.LuxThrottling;
+import com.android.server.display.config.LuxToBrightnessMapping;
 import com.android.server.display.config.NitsMap;
 import com.android.server.display.config.NonNegativeFloatToFloatPoint;
 import com.android.server.display.config.Point;
@@ -77,6 +78,7 @@
 import com.android.server.display.config.ThresholdPoint;
 import com.android.server.display.config.UsiVersion;
 import com.android.server.display.config.XmlParser;
+import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.display.utils.DebugUtils;
 
 import org.xmlpull.v1.XmlPullParserException;
@@ -310,16 +312,18 @@
  *          <darkeningLightDebounceIdleMillis>
  *              1000
  *          </darkeningLightDebounceIdleMillis>
- *          <displayBrightnessMapping>
- *              <displayBrightnessPoint>
- *                  <lux>50</lux>
- *                  <nits>45.32</nits>
- *              </displayBrightnessPoint>
- *              <displayBrightnessPoint>
- *                  <lux>80</lux>
- *                  <nits>75.43</nits>
- *              </displayBrightnessPoint>
- *          </displayBrightnessMapping>
+ *          <luxToBrightnessMapping>
+ *            <map>
+ *              <point>
+ *                <first>0</first>
+ *                <second>0.2</second>
+ *              </point>
+ *              <point>
+ *                <first>80</first>
+ *                <second>0.3</second>
+ *              </point>
+ *            </map>
+ *          </luxToBrightnessMapping>
  *      </autoBrightness>
  *
  *      <screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease>
@@ -528,6 +532,7 @@
  *         <majorVersion>2</majorVersion>
  *         <minorVersion>0</minorVersion>
  *     </usiVersion>
+ *     <screenBrightnessCapForWearBedtimeMode>0.1</screenBrightnessCapForWearBedtimeMode>
  *    </displayConfiguration>
  *  }
  *  </pre>
@@ -629,7 +634,6 @@
     // for the corresponding values above
     private float[] mBrightness;
 
-
     /**
      * Array of desired screen brightness in nits corresponding to the lux values
      * in the mBrightnessLevelsLux array. The display brightness is defined as the
@@ -639,20 +643,25 @@
     private float[] mBrightnessLevelsNits;
 
     /**
-     * Array of light sensor lux values to define our levels for auto backlight
-     * brightness support.
+     * Array of desired screen brightness corresponding to the lux values
+     * in the mBrightnessLevelsLux array. The brightness values must be non-negative and
+     * non-decreasing. They must be between {@link PowerManager.BRIGHTNESS_MIN} and
+     * {@link PowerManager.BRIGHTNESS_MAX}. This must be overridden in platform specific overlays
+     */
+    private float[] mBrightnessLevels;
+
+    /**
+     * Array of light sensor lux values to define our levels for auto-brightness support.
      *
-     * The N + 1 entries of this array define N control points defined in mBrightnessLevelsNits,
-     * with first value always being 0 lux
+     * The first lux value is always 0.
      *
-     * The control points must be strictly increasing.  Each control point
-     * corresponds to an entry in the brightness backlight values arrays.
-     * For example, if lux == level[1] (second element of the levels array)
-     * then the brightness will be determined by value[0] (first element
-     * of the brightness values array).
+     * The control points must be strictly increasing. Each control point corresponds to an entry
+     * in the brightness values arrays. For example, if lux == luxLevels[1] (second element
+     * of the levels array) then the brightness will be determined by brightnessLevels[1] (second
+     * element of the brightness values array).
      *
-     * Spline interpolation is used to determine the auto-brightness
-     * backlight values for lux levels between these control points.
+     * Spline interpolation is used to determine the auto-brightness values for lux levels between
+     * these control points.
      */
     private float[] mBrightnessLevelsLux;
 
@@ -843,9 +852,17 @@
     @Nullable
     private HdrBrightnessData mHdrBrightnessData;
 
+    /**
+     * Maximum screen brightness setting when screen brightness capped in Wear Bedtime mode.
+     */
+    private float mBrightnessCapForWearBedtimeMode;
+
+    private final DisplayManagerFlags mFlags;
+
     @VisibleForTesting
-    DisplayDeviceConfig(Context context) {
+    DisplayDeviceConfig(Context context, DisplayManagerFlags flags) {
         mContext = context;
+        mFlags = flags;
     }
 
     /**
@@ -861,9 +878,9 @@
      * @return A configuration instance for the specified display.
      */
     public static DisplayDeviceConfig create(Context context, long physicalDisplayId,
-            boolean isFirstDisplay) {
+            boolean isFirstDisplay, DisplayManagerFlags flags) {
         final DisplayDeviceConfig config = createWithoutDefaultValues(context, physicalDisplayId,
-                isFirstDisplay);
+                isFirstDisplay, flags);
 
         config.copyUninitializedValuesFromSecondaryConfig(loadDefaultConfigurationXml(context));
         return config;
@@ -878,28 +895,29 @@
      *                     or the default values.
      * @return A configuration instance.
      */
-    public static DisplayDeviceConfig create(Context context, boolean useConfigXml) {
+    public static DisplayDeviceConfig create(Context context, boolean useConfigXml,
+            DisplayManagerFlags flags) {
         final DisplayDeviceConfig config;
         if (useConfigXml) {
-            config = getConfigFromGlobalXml(context);
+            config = getConfigFromGlobalXml(context, flags);
         } else {
-            config = getConfigFromPmValues(context);
+            config = getConfigFromPmValues(context, flags);
         }
         return config;
     }
 
     private static DisplayDeviceConfig createWithoutDefaultValues(Context context,
-            long physicalDisplayId, boolean isFirstDisplay) {
+            long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) {
         DisplayDeviceConfig config;
 
         config = loadConfigFromDirectory(context, Environment.getProductDirectory(),
-                physicalDisplayId);
+                physicalDisplayId, flags);
         if (config != null) {
             return config;
         }
 
         config = loadConfigFromDirectory(context, Environment.getVendorDirectory(),
-                physicalDisplayId);
+                physicalDisplayId, flags);
         if (config != null) {
             return config;
         }
@@ -907,7 +925,7 @@
         // If no config can be loaded from any ddc xml at all,
         // prepare a whole config using the global config.xml.
         // Guaranteed not null
-        return create(context, isFirstDisplay);
+        return create(context, isFirstDisplay, flags);
     }
 
     private static DisplayConfiguration loadDefaultConfigurationXml(Context context) {
@@ -960,18 +978,19 @@
     }
 
     private static DisplayDeviceConfig loadConfigFromDirectory(Context context,
-            File baseDirectory, long physicalDisplayId) {
+            File baseDirectory, long physicalDisplayId, DisplayManagerFlags flags) {
         DisplayDeviceConfig config;
         // Create config using filename from physical ID (including "stable" bit).
         config = getConfigFromSuffix(context, baseDirectory, STABLE_ID_SUFFIX_FORMAT,
-                physicalDisplayId);
+                physicalDisplayId, flags);
         if (config != null) {
             return config;
         }
 
         // Create config using filename from physical ID (excluding "stable" bit).
         final long withoutStableFlag = physicalDisplayId & ~STABLE_FLAG;
-        config = getConfigFromSuffix(context, baseDirectory, NO_SUFFIX_FORMAT, withoutStableFlag);
+        config = getConfigFromSuffix(context, baseDirectory, NO_SUFFIX_FORMAT, withoutStableFlag,
+                flags);
         if (config != null) {
             return config;
         }
@@ -980,7 +999,7 @@
         final DisplayAddress.Physical physicalAddress =
                 DisplayAddress.fromPhysicalDisplayId(physicalDisplayId);
         int port = physicalAddress.getPort();
-        config = getConfigFromSuffix(context, baseDirectory, PORT_SUFFIX_FORMAT, port);
+        config = getConfigFromSuffix(context, baseDirectory, PORT_SUFFIX_FORMAT, port, flags);
         return config;
     }
 
@@ -1599,6 +1618,13 @@
     }
 
     /**
+     * @return Auto brightness brightening levels
+     */
+    public float[] getAutoBrightnessBrighteningLevels() {
+        return mBrightnessLevels;
+    }
+
+    /**
      * @return Default peak refresh rate of the associated display
      */
     public int getDefaultPeakRefreshRate() {
@@ -1741,6 +1767,13 @@
         return mHostUsiVersion;
     }
 
+    /**
+     * @return Maximum screen brightness setting when screen brightness capped in Wear Bedtime mode.
+     */
+    public float getBrightnessCapForWearBedtimeMode() {
+        return mBrightnessCapForWearBedtimeMode;
+    }
+
     @Override
     public String toString() {
         return "DisplayDeviceConfig{"
@@ -1844,6 +1877,7 @@
                 + mAutoBrightnessDarkeningLightDebounceIdle
                 + ", mBrightnessLevelsLux= " + Arrays.toString(mBrightnessLevelsLux)
                 + ", mBrightnessLevelsNits= " + Arrays.toString(mBrightnessLevelsNits)
+                + ", mBrightnessLevels= " + Arrays.toString(mBrightnessLevels)
                 + ", mDdcAutoBrightnessAvailable= " + mDdcAutoBrightnessAvailable
                 + ", mAutoBrightnessAvailable= " + mAutoBrightnessAvailable
                 + "\n"
@@ -1867,36 +1901,39 @@
                 + ", mHighAmbientBrightnessThresholds= "
                 + Arrays.toString(mHighAmbientBrightnessThresholds)
                 + "\n"
-                + "mScreenOffBrightnessSensorValueToLux=" + Arrays.toString(
+                + "mScreenOffBrightnessSensorValueToLux= " + Arrays.toString(
                 mScreenOffBrightnessSensorValueToLux)
                 + "\n"
                 + "mUsiVersion= " + mHostUsiVersion + "\n"
-                + "mHdrBrightnessData" + mHdrBrightnessData
+                + "mHdrBrightnessData= " + mHdrBrightnessData + "\n"
+                + "mBrightnessCapForWearBedtimeMode= " + mBrightnessCapForWearBedtimeMode
                 + "}";
     }
 
     private static DisplayDeviceConfig getConfigFromSuffix(Context context, File baseDirectory,
-            String suffixFormat, long idNumber) {
+            String suffixFormat, long idNumber, DisplayManagerFlags flags) {
 
         final String suffix = String.format(Locale.ROOT, suffixFormat, idNumber);
         final String filename = String.format(Locale.ROOT, CONFIG_FILE_FORMAT, suffix);
         final File filePath = Environment.buildPath(
                 baseDirectory, ETC_DIR, DISPLAY_CONFIG_DIR, filename);
-        final DisplayDeviceConfig config = new DisplayDeviceConfig(context);
+        final DisplayDeviceConfig config = new DisplayDeviceConfig(context, flags);
         if (config.initFromFile(filePath)) {
             return config;
         }
         return null;
     }
 
-    private static DisplayDeviceConfig getConfigFromGlobalXml(Context context) {
-        DisplayDeviceConfig config = new DisplayDeviceConfig(context);
+    private static DisplayDeviceConfig getConfigFromGlobalXml(Context context,
+            DisplayManagerFlags flags) {
+        DisplayDeviceConfig config = new DisplayDeviceConfig(context, flags);
         config.initFromGlobalXml();
         return config;
     }
 
-    private static DisplayDeviceConfig getConfigFromPmValues(Context context) {
-        DisplayDeviceConfig config = new DisplayDeviceConfig(context);
+    private static DisplayDeviceConfig getConfigFromPmValues(Context context,
+            DisplayManagerFlags flags) {
+        DisplayDeviceConfig config = new DisplayDeviceConfig(context, flags);
         config.initFromDefaultValues();
         return config;
     }
@@ -1938,6 +1975,7 @@
                 loadScreenOffBrightnessSensorValueToLuxFromDdc(config);
                 loadUsiVersion(config);
                 mHdrBrightnessData = HdrBrightnessData.loadConfig(config);
+                loadBrightnessCapForWearBedtimeMode(config);
             } else {
                 Slog.w(TAG, "DisplayDeviceConfig file is null");
             }
@@ -1961,6 +1999,7 @@
         loadAutoBrightnessConfigsFromConfigXml();
         loadAutoBrightnessAvailableFromConfigXml();
         loadRefreshRateSetting(null);
+        loadBrightnessCapForWearBedtimeModeFromConfigXml();
         mLoadedFrom = "<config.xml>";
     }
 
@@ -2599,8 +2638,23 @@
      * loading the value from the display config, and if not present, falls back to config.xml.
      */
     private void loadAutoBrightnessDisplayBrightnessMapping(AutoBrightness autoBrightnessConfig) {
-        if (autoBrightnessConfig == null
-                || autoBrightnessConfig.getDisplayBrightnessMapping() == null) {
+        if (mFlags.areAutoBrightnessModesEnabled() && autoBrightnessConfig != null
+                && autoBrightnessConfig.getLuxToBrightnessMapping() != null) {
+            LuxToBrightnessMapping mapping = autoBrightnessConfig.getLuxToBrightnessMapping();
+            final int size = mapping.getMap().getPoint().size();
+            mBrightnessLevels = new float[size];
+            mBrightnessLevelsLux = new float[size];
+            for (int i = 0; i < size; i++) {
+                float backlight = mapping.getMap().getPoint().get(i).getSecond().floatValue();
+                mBrightnessLevels[i] = mBacklightToBrightnessSpline.interpolate(backlight);
+                mBrightnessLevelsLux[i] = mapping.getMap().getPoint().get(i).getFirst()
+                        .floatValue();
+            }
+            if (size > 0 && mBrightnessLevelsLux[0] != 0) {
+                throw new IllegalArgumentException(
+                        "The first lux value in the display brightness mapping must be 0");
+            }
+        } else {
             mBrightnessLevelsNits = getFloatArray(mContext.getResources()
                     .obtainTypedArray(com.android.internal.R.array
                             .config_autoBrightnessDisplayValuesNits), PowerManager
@@ -2608,18 +2662,6 @@
             mBrightnessLevelsLux = getLuxLevels(mContext.getResources()
                     .getIntArray(com.android.internal.R.array
                             .config_autoBrightnessLevels));
-        } else {
-            final int size = autoBrightnessConfig.getDisplayBrightnessMapping()
-                    .getDisplayBrightnessPoint().size();
-            mBrightnessLevelsNits = new float[size];
-            // The first control point is implicit and always at 0 lux.
-            mBrightnessLevelsLux = new float[size + 1];
-            for (int i = 0; i < size; i++) {
-                mBrightnessLevelsNits[i] = autoBrightnessConfig.getDisplayBrightnessMapping()
-                        .getDisplayBrightnessPoint().get(i).getNits().floatValue();
-                mBrightnessLevelsLux[i + 1] = autoBrightnessConfig.getDisplayBrightnessMapping()
-                        .getDisplayBrightnessPoint().get(i).getLux().floatValue();
-            }
         }
     }
 
@@ -3350,6 +3392,23 @@
                 : null;
     }
 
+    private void loadBrightnessCapForWearBedtimeMode(DisplayConfiguration config) {
+        if (config != null) {
+            BigDecimal configBrightnessCap = config.getScreenBrightnessCapForWearBedtimeMode();
+            if (configBrightnessCap != null) {
+                mBrightnessCapForWearBedtimeMode = configBrightnessCap.floatValue();
+            } else {
+                loadBrightnessCapForWearBedtimeModeFromConfigXml();
+            }
+        }
+    }
+
+    private void loadBrightnessCapForWearBedtimeModeFromConfigXml() {
+        mBrightnessCapForWearBedtimeMode = BrightnessSynchronizer.brightnessIntToFloat(
+                mContext.getResources().getInteger(com.android.internal.R.integer
+                        .config_screenBrightnessCapForWearBedtimeMode));
+    }
+
     /**
      * Container for high brightness mode configuration data.
      */
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 6a7c17d..2ab15e6 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1853,7 +1853,7 @@
             // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
             // the virtual display inside VR before any VR-specific apps even run.
             mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
-                    mHandler, mDisplayDeviceRepo);
+                    mHandler, mDisplayDeviceRepo, mFlags);
             if (mVirtualDisplayAdapter != null) {
                 registerDisplayAdapterLocked(mVirtualDisplayAdapter);
             }
@@ -1871,7 +1871,7 @@
 
     private void registerOverlayDisplayAdapterLocked() {
         registerDisplayAdapterLocked(new OverlayDisplayAdapter(
-                mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mUiHandler));
+                mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mUiHandler, mFlags));
     }
 
     private void registerWifiDisplayAdapterLocked() {
@@ -1880,7 +1880,7 @@
                 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
             mWifiDisplayAdapter = new WifiDisplayAdapter(
                     mSyncRoot, mContext, mHandler, mDisplayDeviceRepo,
-                    mPersistentDataStore);
+                    mPersistentDataStore, mFlags);
             registerDisplayAdapterLocked(mWifiDisplayAdapter);
         }
     }
@@ -3288,8 +3288,10 @@
     @VisibleForTesting
     static class Injector {
         VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
-                Handler handler, DisplayAdapter.Listener displayAdapterListener) {
-            return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
+                Handler handler, DisplayAdapter.Listener displayAdapterListener,
+                DisplayManagerFlags flags) {
+            return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener,
+                    flags);
         }
 
         LocalDisplayAdapter getLocalDisplayAdapter(SyncRoot syncRoot, Context context,
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index ff9a1ab..22898a6 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -84,8 +84,6 @@
 
     private final boolean mIsBootDisplayModeSupported;
 
-    private final DisplayManagerFlags mFlags;
-
     private final DisplayNotificationManager mDisplayNotificationManager;
 
     private Context mOverlayContext;
@@ -103,12 +101,11 @@
             Listener listener, DisplayManagerFlags flags,
             DisplayNotificationManager displayNotificationManager,
             Injector injector) {
-        super(syncRoot, context, handler, listener, TAG);
+        super(syncRoot, context, handler, listener, TAG, flags);
         mDisplayNotificationManager = displayNotificationManager;
         mInjector = injector;
         mSurfaceControlProxy = mInjector.getSurfaceControlProxy();
         mIsBootDisplayModeSupported = mSurfaceControlProxy.getBootDisplayModeSupport();
-        mFlags = flags;
     }
 
     @Override
@@ -510,7 +507,7 @@
             // Load display device config
             final Context context = getOverlayContext();
             mDisplayDeviceConfig = mInjector.createDisplayDeviceConfig(context, mPhysicalDisplayId,
-                    mIsFirstDisplay);
+                    mIsFirstDisplay, getFeatureFlags());
 
             // Load brightness HWC quirk
             mBacklightAdapter.setForceSurfaceControl(mDisplayDeviceConfig.hasQuirk(
@@ -831,7 +828,8 @@
                                     + ", state=" + Display.stateToString(state) + ")");
                         }
 
-                        boolean isDisplayOffloadEnabled = mFlags.isDisplayOffloadEnabled();
+                        boolean isDisplayOffloadEnabled =
+                                getFeatureFlags().isDisplayOffloadEnabled();
 
                         // We must tell sidekick/displayoffload to stop controlling the display
                         // before we can change its power mode, so do that first.
@@ -1377,8 +1375,8 @@
         }
 
         public DisplayDeviceConfig createDisplayDeviceConfig(Context context,
-                long physicalDisplayId, boolean isFirstDisplay) {
-            return DisplayDeviceConfig.create(context, physicalDisplayId, isFirstDisplay);
+                long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) {
+            return DisplayDeviceConfig.create(context, physicalDisplayId, isFirstDisplay, flags);
         }
     }
 
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index 2ce7690..22ff2d0 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -36,6 +36,7 @@
 
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.display.mode.DisplayModeDirector;
 
 import java.io.PrintWriter;
@@ -134,8 +135,9 @@
 
     // Called with SyncRoot lock held.
     public OverlayDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
-            Context context, Handler handler, Listener listener, Handler uiHandler) {
-        super(syncRoot, context, handler, listener, TAG);
+            Context context, Handler handler, Listener listener, Handler uiHandler,
+            DisplayManagerFlags featureFlags) {
+        super(syncRoot, context, handler, listener, TAG, featureFlags);
         mUiHandler = uiHandler;
     }
 
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index edbd424..ec5ad7d 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -61,6 +61,7 @@
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.feature.DisplayManagerFlags;
 
 import java.io.PrintWriter;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -88,7 +89,7 @@
 
     // Called with SyncRoot lock held.
     public VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
-            Context context, Handler handler, Listener listener) {
+            Context context, Handler handler, Listener listener, DisplayManagerFlags featureFlags) {
         this(syncRoot, context, handler, listener, new SurfaceControlDisplayFactory() {
             @Override
             public IBinder createDisplay(String name, boolean secure, float requestedRefreshRate) {
@@ -99,14 +100,15 @@
             public void destroyDisplay(IBinder displayToken) {
                 DisplayControl.destroyDisplay(displayToken);
             }
-        });
+        }, featureFlags);
     }
 
     @VisibleForTesting
     VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
             Context context, Handler handler, Listener listener,
-            SurfaceControlDisplayFactory surfaceControlDisplayFactory) {
-        super(syncRoot, context, handler, listener, TAG);
+            SurfaceControlDisplayFactory surfaceControlDisplayFactory,
+            DisplayManagerFlags featureFlags) {
+        super(syncRoot, context, handler, listener, TAG, featureFlags);
         mHandler = handler;
         mSurfaceControlDisplayFactory = surfaceControlDisplayFactory;
     }
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index 7660cf8..aa98cd8 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -41,6 +41,7 @@
 
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.display.utils.DebugUtils;
 
 import java.io.PrintWriter;
@@ -99,8 +100,8 @@
     // Called with SyncRoot lock held.
     public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
             Context context, Handler handler, Listener listener,
-            PersistentDataStore persistentDataStore) {
-        super(syncRoot, context, handler, listener, TAG);
+            PersistentDataStore persistentDataStore, DisplayManagerFlags featureFlags) {
+        super(syncRoot, context, handler, listener, TAG, featureFlags);
 
         if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
             throw new RuntimeException("WiFi display was requested, "
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java
index dfcda40..42ebc40 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamper.java
@@ -17,6 +17,7 @@
 package com.android.server.display.brightness.clamper;
 
 import android.annotation.NonNull;
+import android.os.Handler;
 import android.os.PowerManager;
 
 import com.android.server.display.DisplayBrightnessState;
@@ -24,13 +25,25 @@
 import java.io.PrintWriter;
 
 /**
- * Provides max allowed brightness
+ * Provides brightness range constraints
  */
 abstract class BrightnessClamper<T> {
 
     protected float mBrightnessCap = PowerManager.BRIGHTNESS_MAX;
     protected boolean mIsActive = false;
 
+    @NonNull
+    protected final Handler mHandler;
+
+    @NonNull
+    protected final BrightnessClamperController.ClamperChangeListener mChangeListener;
+
+    BrightnessClamper(Handler handler,
+            BrightnessClamperController.ClamperChangeListener changeListener) {
+        mHandler = handler;
+        mChangeListener = changeListener;
+    }
+
     float getBrightnessCap() {
         return mBrightnessCap;
     }
@@ -60,6 +73,8 @@
 
     protected enum Type {
         THERMAL,
-        POWER
+        POWER,
+        BEDTIME_MODE,
+        LUX,
     }
 }
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
index b574919..01694dd 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
@@ -68,14 +68,14 @@
     private boolean mClamperApplied = false;
 
     public BrightnessClamperController(Handler handler,
-            ClamperChangeListener clamperChangeListener, DisplayDeviceData data,  Context context,
+            ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
             DisplayManagerFlags flags) {
         this(new Injector(), handler, clamperChangeListener, data, context, flags);
     }
 
     @VisibleForTesting
     BrightnessClamperController(Injector injector, Handler handler,
-            ClamperChangeListener clamperChangeListener, DisplayDeviceData data,  Context context,
+            ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
             DisplayManagerFlags flags) {
         mDeviceConfigParameterProvider = injector.getDeviceConfigParameterProvider();
         mHandler = handler;
@@ -90,7 +90,8 @@
             }
         };
 
-        mClampers = injector.getClampers(handler, clamperChangeListenerInternal, data, flags);
+        mClampers = injector.getClampers(handler, clamperChangeListenerInternal, data, flags,
+                context);
         mModifiers = injector.getModifiers(context);
         mOnPropertiesChangedListener =
                 properties -> mClampers.forEach(BrightnessClamper::onDeviceConfigChanged);
@@ -146,7 +147,8 @@
      * Should be moved to DisplayBrightnessState OR derived from DisplayBrightnessState
      * TODO: b/263362199
      */
-    @BrightnessInfo.BrightnessMaxReason public int getBrightnessMaxReason() {
+    @BrightnessInfo.BrightnessMaxReason
+    public int getBrightnessMaxReason() {
         if (mClamperType == null) {
             return BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
         } else if (mClamperType == Type.THERMAL) {
@@ -234,13 +236,20 @@
 
         List<BrightnessClamper<? super DisplayDeviceData>> getClampers(Handler handler,
                 ClamperChangeListener clamperChangeListener, DisplayDeviceData data,
-                DisplayManagerFlags flags) {
+                DisplayManagerFlags flags, Context context) {
             List<BrightnessClamper<? super DisplayDeviceData>> clampers = new ArrayList<>();
             clampers.add(
                     new BrightnessThermalClamper(handler, clamperChangeListener, data));
             if (flags.isPowerThrottlingClamperEnabled()) {
                 clampers.add(new BrightnessPowerClamper(handler, clamperChangeListener,
-                            data));
+                        data));
+            }
+            if (flags.isBrightnessWearBedtimeModeClamperEnabled()) {
+                clampers.add(new BrightnessWearBedtimeModeClamper(handler, context,
+                        clamperChangeListener, data));
+            }
+            if (flags.isEvenDimmerEnabled()) {
+                clampers.add(new BrightnessMinClamper(handler, clamperChangeListener, context));
             }
             return clampers;
         }
@@ -257,7 +266,8 @@
      * Config Data for clampers
      */
     public static class DisplayDeviceData implements BrightnessThermalClamper.ThermalData,
-                BrightnessPowerClamper.PowerData {
+                BrightnessPowerClamper.PowerData,
+            BrightnessWearBedtimeModeClamper.WearBedtimeModeData {
         @NonNull
         private final String mUniqueDisplayId;
         @NonNull
@@ -315,5 +325,10 @@
         public PowerThrottlingConfigData getPowerThrottlingConfigData() {
             return mDisplayDeviceConfig.getPowerThrottlingConfigData();
         }
+
+        @Override
+        public float getBrightnessWearBedtimeModeCap() {
+            return mDisplayDeviceConfig.getBrightnessCapForWearBedtimeMode();
+        }
     }
 }
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessMinClamper.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessMinClamper.java
new file mode 100644
index 0000000..71efca1
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessMinClamper.java
@@ -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.server.display.brightness.clamper;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.utils.DebugUtils;
+
+import java.io.PrintWriter;
+
+/**
+ * Class used to prevent the screen brightness dipping below a certain value, based on current
+ * lux conditions.
+ */
+public class BrightnessMinClamper extends BrightnessClamper {
+
+    // To enable these logs, run:
+    // 'adb shell setprop persist.log.tag.BrightnessMinClamper DEBUG && adb reboot'
+    private static final String TAG = "BrightnessMinClamper";
+    private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
+
+    private final SettingsObserver mSettingsObserver;
+
+    ContentResolver mContentResolver;
+    private float mNitsLowerBound;
+
+    @VisibleForTesting
+    BrightnessMinClamper(Handler handler,
+            BrightnessClamperController.ClamperChangeListener listener, Context context) {
+        super(handler, listener);
+
+        mContentResolver = context.getContentResolver();
+        mSettingsObserver = new SettingsObserver(mHandler);
+        mHandler.post(() -> {
+            start();
+        });
+    }
+
+    private void recalculateLowerBound() {
+        final int userId = UserHandle.USER_CURRENT;
+        float settingNitsLowerBound = Settings.Secure.getFloatForUser(
+                mContentResolver, Settings.Secure.EVEN_DIMMER_MIN_NITS,
+                /* def= */ PowerManager.BRIGHTNESS_MIN, userId);
+
+        boolean isActive = Settings.Secure.getIntForUser(mContentResolver,
+                Settings.Secure.EVEN_DIMMER_ACTIVATED,
+                /* def= */ 0, userId) == 1;
+
+        // TODO: luxBasedNitsLowerBound = mMinNitsToLuxSpline(currentLux);
+        float luxBasedNitsLowerBound = PowerManager.BRIGHTNESS_MIN;
+        final float nitsLowerBound = Math.max(settingNitsLowerBound, luxBasedNitsLowerBound);
+
+        if (mNitsLowerBound != nitsLowerBound || mIsActive != isActive) {
+            mIsActive = isActive;
+            mNitsLowerBound = nitsLowerBound;
+            if (DEBUG) {
+                Slog.i(TAG, "mIsActive: " + mIsActive);
+            }
+            // TODO: mBrightnessCap = nitsToBrightnessSpline(mNitsLowerBound);
+            mChangeListener.onChanged();
+        }
+    }
+
+    void start() {
+        recalculateLowerBound();
+    }
+
+
+    @Override
+    Type getType() {
+        return Type.LUX;
+    }
+
+    @Override
+    void onDeviceConfigChanged() {
+        // TODO
+    }
+
+    @Override
+    void onDisplayChanged(Object displayData) {
+
+    }
+
+    @Override
+    void stop() {
+        mContentResolver.unregisterContentObserver(mSettingsObserver);
+    }
+
+    @Override
+    void dump(PrintWriter pw) {
+        pw.println("BrightnessMinClamper:");
+        pw.println("  mBrightnessCap=" + mBrightnessCap);
+        pw.println("  mIsActive=" + mIsActive);
+        pw.println("  mNitsLowerBound=" + mNitsLowerBound);
+        super.dump(pw);
+    }
+
+    private final class SettingsObserver extends ContentObserver {
+        SettingsObserver(Handler handler) {
+            super(handler);
+            mContentResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.EVEN_DIMMER_MIN_NITS),
+                    false, this);
+            mContentResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.EVEN_DIMMER_ACTIVATED),
+                    false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            recalculateLowerBound();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessPowerClamper.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessPowerClamper.java
index 339b589..790322d 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessPowerClamper.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessPowerClamper.java
@@ -49,10 +49,6 @@
     private final Injector mInjector;
     @NonNull
     private final DeviceConfigParameterProvider mConfigParameterProvider;
-    @NonNull
-    private final Handler mHandler;
-    @NonNull
-    private final ClamperChangeListener mChangeListener;
     @Nullable
     private PmicMonitor mPmicMonitor;
     // data from DeviceConfig, for all displays, for all dataSets
@@ -99,10 +95,9 @@
     @VisibleForTesting
     BrightnessPowerClamper(Injector injector, Handler handler, ClamperChangeListener listener,
             PowerData powerData) {
+        super(handler, listener);
         mInjector = injector;
         mConfigParameterProvider = injector.getDeviceConfigParameterProvider();
-        mHandler = handler;
-        mChangeListener = listener;
 
         mHandler.post(() -> {
             setDisplayData(powerData);
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java
index 8ae962b..944a8a6 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java
@@ -54,10 +54,6 @@
     private final IThermalService mThermalService;
     @NonNull
     private final DeviceConfigParameterProvider mConfigParameterProvider;
-    @NonNull
-    private final Handler mHandler;
-    @NonNull
-    private final ClamperChangeListener mChangelistener;
     // data from DeviceConfig, for all displays, for all dataSets
     // mapOf(uniqueDisplayId to mapOf(dataSetId to ThermalBrightnessThrottlingData))
     @NonNull
@@ -108,10 +104,9 @@
     @VisibleForTesting
     BrightnessThermalClamper(Injector injector, Handler handler,
             ClamperChangeListener listener, ThermalData thermalData) {
+        super(handler, listener);
         mThermalService = injector.getThermalService();
         mConfigParameterProvider = injector.getDeviceConfigParameterProvider();
-        mHandler = handler;
-        mChangelistener = listener;
         mHandler.post(() -> {
             setDisplayData(thermalData);
             loadOverrideData();
@@ -220,7 +215,7 @@
         if (brightnessCap  != mBrightnessCap || mIsActive != isActive) {
             mBrightnessCap = brightnessCap;
             mIsActive = isActive;
-            mChangelistener.onChanged();
+            mChangeListener.onChanged();
         }
     }
 
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessWearBedtimeModeClamper.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessWearBedtimeModeClamper.java
new file mode 100644
index 0000000..7e853bf
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessWearBedtimeModeClamper.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.brightness.clamper;
+
+import android.annotation.NonNull;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+public class BrightnessWearBedtimeModeClamper extends
+        BrightnessClamper<BrightnessWearBedtimeModeClamper.WearBedtimeModeData> {
+
+    public static final int BEDTIME_MODE_OFF = 0;
+    public static final int BEDTIME_MODE_ON = 1;
+
+    private final Context mContext;
+
+    private final ContentObserver mSettingsObserver;
+
+    BrightnessWearBedtimeModeClamper(Handler handler, Context context,
+            BrightnessClamperController.ClamperChangeListener listener, WearBedtimeModeData data) {
+        this(new Injector(), handler, context, listener, data);
+    }
+
+    @VisibleForTesting
+    BrightnessWearBedtimeModeClamper(Injector injector, Handler handler, Context context,
+            BrightnessClamperController.ClamperChangeListener listener, WearBedtimeModeData data) {
+        super(handler, listener);
+        mContext = context;
+        mBrightnessCap = data.getBrightnessWearBedtimeModeCap();
+        mSettingsObserver = new ContentObserver(mHandler) {
+            @Override
+            public void onChange(boolean selfChange) {
+                final int bedtimeModeSetting = Settings.Global.getInt(
+                        mContext.getContentResolver(),
+                        Settings.Global.Wearable.BEDTIME_MODE,
+                        BEDTIME_MODE_OFF);
+                mIsActive = bedtimeModeSetting == BEDTIME_MODE_ON;
+                mChangeListener.onChanged();
+            }
+        };
+        injector.registerBedtimeModeObserver(context.getContentResolver(), mSettingsObserver);
+    }
+
+    @NonNull
+    @Override
+    Type getType() {
+        return Type.BEDTIME_MODE;
+    }
+
+    @Override
+    void onDeviceConfigChanged() {}
+
+    @Override
+    void onDisplayChanged(WearBedtimeModeData displayData) {
+        mHandler.post(() -> {
+            mBrightnessCap = displayData.getBrightnessWearBedtimeModeCap();
+            mChangeListener.onChanged();
+        });
+    }
+
+    @Override
+    void stop() {
+        mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
+    }
+
+    interface WearBedtimeModeData {
+        float getBrightnessWearBedtimeModeCap();
+    }
+
+    @VisibleForTesting
+    static class Injector {
+        void registerBedtimeModeObserver(@NonNull ContentResolver cr,
+                @NonNull ContentObserver observer) {
+            cr.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.Wearable.BEDTIME_MODE),
+                    /* notifyForDescendants= */ false, observer, UserHandle.USER_ALL);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 5cfbf26..2d5da71 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -78,6 +78,9 @@
             Flags.FLAG_ENABLE_POWER_THROTTLING_CLAMPER,
             Flags::enablePowerThrottlingClamper);
 
+    private final FlagState mEvenDimmerFlagState = new FlagState(
+            Flags.FLAG_EVEN_DIMMER,
+            Flags::evenDimmer);
     private final FlagState mSmallAreaDetectionFlagState = new FlagState(
             com.android.graphics.surfaceflinger.flags.Flags.FLAG_ENABLE_SMALL_AREA_DETECTION,
             com.android.graphics.surfaceflinger.flags.Flags::enableSmallAreaDetection);
@@ -90,6 +93,14 @@
             Flags.FLAG_ENABLE_EXTERNAL_VSYNC_PROXIMITY_VOTE,
             Flags::enableExternalVsyncProximityVote);
 
+    private final FlagState mBrightnessWearBedtimeModeClamperFlagState = new FlagState(
+            Flags.FLAG_BRIGHTNESS_WEAR_BEDTIME_MODE_CLAMPER,
+            Flags::brightnessWearBedtimeModeClamper);
+
+    private final FlagState mAutoBrightnessModesFlagState = new FlagState(
+            Flags.FLAG_AUTO_BRIGHTNESS_MODES,
+            Flags::autoBrightnessModes);
+
     /** Returns whether connected display management is enabled or not. */
     public boolean isConnectedDisplayManagementEnabled() {
         return mConnectedDisplayManagementFlagState.isEnabled();
@@ -166,6 +177,11 @@
         return mBackUpSmoothDisplayAndForcePeakRefreshRateFlagState.isEnabled();
     }
 
+    /** Returns whether brightness range is allowed to extend below traditional range. */
+    public boolean isEvenDimmerEnabled() {
+        return mEvenDimmerFlagState.isEnabled();
+    }
+
     public boolean isSmallAreaDetectionEnabled() {
         return mSmallAreaDetectionFlagState.isEnabled();
     }
@@ -178,6 +194,17 @@
         return mVsyncProximityVote.isEnabled();
     }
 
+    public boolean isBrightnessWearBedtimeModeClamperEnabled() {
+        return mBrightnessWearBedtimeModeClamperFlagState.isEnabled();
+    }
+
+    /**
+     * @return Whether generic auto-brightness modes are enabled
+     */
+    public boolean areAutoBrightnessModesEnabled() {
+        return mAutoBrightnessModesFlagState.isEnabled();
+    }
+
     /**
      * dumps all flagstates
      * @param pw printWriter
@@ -197,6 +224,8 @@
         pw.println(" " + mSmallAreaDetectionFlagState);
         pw.println(" " + mBrightnessIntRangeUserPerceptionFlagState);
         pw.println(" " + mVsyncProximityVote);
+        pw.println(" " + mBrightnessWearBedtimeModeClamperFlagState);
+        pw.println(" " + mAutoBrightnessModesFlagState);
     }
 
     private static class FlagState {
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index d95bdae..1b4d74c 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -106,6 +106,14 @@
 }
 
 flag {
+    name: "even_dimmer"
+    namespace: "display_manager"
+    description: "Feature flag for extending the brightness below traditional range"
+    bug: "179428400"
+    is_fixed_read_only: true
+}
+
+flag {
     name: "brightness_int_range_user_perception"
     namespace: "display_manager"
     description: "Feature flag for converting the brightness integer range to the user perception scale"
@@ -120,3 +128,19 @@
     bug: "284866750"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "brightness_wear_bedtime_mode_clamper"
+    namespace: "display_manager"
+    description: "Feature flag for the Wear Bedtime mode brightness clamper"
+    bug: "293613040"
+    is_fixed_read_only: true
+}
+
+flag {
+    name: "auto_brightness_modes"
+    namespace: "display_manager"
+    description: "Feature flag for generic auto-brightness modes"
+    bug: "293613040"
+    is_fixed_read_only: true
+}
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 8eb03ec..8fa838d 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -21,8 +21,8 @@
 import static android.os.PowerManager.BRIGHTNESS_INVALID_FLOAT;
 import static android.view.Display.Mode.INVALID_MODE_ID;
 
-import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRate;
 import static com.android.server.display.DisplayDeviceConfig.DEFAULT_LOW_REFRESH_RATE;
+import static com.android.internal.display.RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay;
 
 import android.annotation.IntegerRes;
 import android.annotation.NonNull;
@@ -925,16 +925,11 @@
     }
 
     @VisibleForTesting
-    DisplayObserver getDisplayObserver() {
-        return mDisplayObserver;
-    }
-
-    @VisibleForTesting
     DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings(
             float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) {
         synchronized (mLock) {
-            mSettingsObserver.updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate,
-                    defaultRefreshRate, Display.DEFAULT_DISPLAY);
+            mSettingsObserver.updateRefreshRateSettingLocked(
+                    minRefreshRate, peakRefreshRate, defaultRefreshRate);
             return getDesiredDisplayModeSpecs(Display.DEFAULT_DISPLAY);
         }
     }
@@ -1268,23 +1263,9 @@
             mBrightnessObserver.onLowPowerModeEnabledLocked(inLowPowerMode);
         }
 
-        /**
-         * Update refresh rate settings for all displays
-         */
         private void updateRefreshRateSettingLocked() {
-            Display[] displays = mInjector.getDisplays();
-            for (int i = 0; i < displays.length; i++) {
-                updateRefreshRateSettingLocked(displays[i].getDisplayId());
-            }
-        }
-
-        /**
-         * Update refresh rate settings for a specific display
-         * @param displayId The display ID
-         */
-        private void updateRefreshRateSettingLocked(int displayId) {
             final ContentResolver cr = mContext.getContentResolver();
-            float highestRefreshRate = findHighestRefreshRate(mContext, displayId);
+            float highestRefreshRate = findHighestRefreshRateForDefaultDisplay(mContext);
 
             float minRefreshRate = Settings.System.getFloatForUser(cr,
                     Settings.System.MIN_REFRESH_RATE, 0f, cr.getUserId());
@@ -1312,12 +1293,11 @@
                 }
             }
 
-            updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate,
-                    displayId);
+            updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate);
         }
 
-        private void updateRefreshRateSettingLocked(float minRefreshRate, float peakRefreshRate,
-                float defaultRefreshRate, int displayId) {
+        private void updateRefreshRateSettingLocked(
+                float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) {
             // TODO(b/156304339): The logic in here, aside from updating the refresh rate votes, is
             // used to predict if we're going to be doing frequent refresh rate switching, and if
             // so, enable the brightness observer. The logic here is more complicated and fragile
@@ -1325,9 +1305,9 @@
             Vote peakVote = peakRefreshRate == 0f
                     ? null
                     : Vote.forRenderFrameRates(0f, Math.max(minRefreshRate, peakRefreshRate));
-            mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE,
+            mVotesStorage.updateGlobalVote(Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE,
                     peakVote);
-            mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE,
+            mVotesStorage.updateGlobalVote(Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE,
                     Vote.forRenderFrameRates(minRefreshRate, Float.POSITIVE_INFINITY));
             Vote defaultVote =
                     defaultRefreshRate == 0f
@@ -1484,8 +1464,7 @@
         }
     }
 
-    @VisibleForTesting
-    public final class DisplayObserver implements DisplayManager.DisplayListener {
+    private final class DisplayObserver implements DisplayManager.DisplayListener {
         // Note that we can never call into DisplayManager or any of the non-POD classes it
         // returns, while holding mLock since it may call into DMS, which might be simultaneously
         // calling into us already holding its own lock.
@@ -1577,7 +1556,6 @@
             updateDisplayModes(displayId, displayInfo);
             updateLayoutLimitedFrameRate(displayId, displayInfo);
             updateUserSettingDisplayPreferredSize(displayInfo);
-            mSettingsObserver.updateRefreshRateSettingLocked(displayId);
         }
 
         @Nullable
diff --git a/services/core/java/com/android/server/flags/OWNERS b/services/core/java/com/android/server/flags/OWNERS
new file mode 100644
index 0000000..535a750
--- /dev/null
+++ b/services/core/java/com/android/server/flags/OWNERS
@@ -0,0 +1 @@
+per-file pinner.aconfig = edgararriaga@google.com
\ No newline at end of file
diff --git a/services/core/java/com/android/server/flags/pinner.aconfig b/services/core/java/com/android/server/flags/pinner.aconfig
new file mode 100644
index 0000000..606a6be
--- /dev/null
+++ b/services/core/java/com/android/server/flags/pinner.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.server.flags"
+
+flag {
+    name: "pin_webview"
+    namespace: "system_performance"
+    description: "This flag controls if webview should be pinned in memory."
+    bug: "307594624"
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
index 2dd2a16..ebc784d 100644
--- a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
+++ b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
@@ -369,15 +369,15 @@
         if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
             return;
         }
-        int vendorId = inputDevice.getVendorId();
-        int productId = inputDevice.getProductId();
         if (keyboardSystemEvent == null) {
             Slog.w(TAG, "Invalid keyboard event logging, keycode = " + Arrays.toString(keyCodes)
                     + ", modifier state = " + modifierState);
             return;
         }
         FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
-                vendorId, productId, keyboardSystemEvent.getIntValue(), keyCodes, modifierState);
+                inputDevice.getVendorId(), inputDevice.getProductId(),
+                keyboardSystemEvent.getIntValue(), keyCodes, modifierState,
+                inputDevice.getDeviceBus());
 
         if (DEBUG) {
             Slog.d(TAG, "Logging Keyboard system event: " + keyboardSystemEvent.mName);
@@ -402,7 +402,7 @@
         // Push the atom to Statsd
         FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_CONFIGURED,
                 event.isFirstConfiguration(), event.getVendorId(), event.getProductId(),
-                proto.getBytes());
+                proto.getBytes(), event.getDeviceBus());
 
         if (DEBUG) {
             Slog.d(TAG, "Logging Keyboard configuration event: " + event);
@@ -467,6 +467,10 @@
             return mInputDevice.getProductId();
         }
 
+        public int getDeviceBus() {
+            return mInputDevice.getDeviceBus();
+        }
+
         public boolean isFirstConfiguration() {
             return mIsFirstConfiguration;
         }
@@ -479,6 +483,7 @@
         public String toString() {
             return "InputDevice = {VendorId = " + Integer.toHexString(getVendorId())
                     + ", ProductId = " + Integer.toHexString(getProductId())
+                    + ", Device Bus = " + Integer.toHexString(getDeviceBus())
                     + "}, isFirstConfiguration = " + mIsFirstConfiguration
                     + ", LayoutConfigurations = " + mLayoutConfigurations;
         }
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
index 749d6b0..dcb86a7 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
@@ -22,6 +22,8 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.UiThread;
+import android.content.ComponentName;
+import android.content.pm.PackageManagerInternal;
 import android.hardware.input.InputManagerGlobal;
 import android.os.Handler;
 import android.os.IBinder;
@@ -66,6 +68,7 @@
     private final Looper mLooper;
     private final InputManagerInternal mInputManagerInternal;
     private final WindowManagerInternal mWindowManagerInternal;
+    private final PackageManagerInternal mPackageManagerInternal;
 
     private ArrayList<MotionEvent> mHandwritingBuffer;
     private InputEventReceiver mHandwritingEventReceiver;
@@ -75,6 +78,7 @@
     // when set, package names are used for handwriting delegation.
     private @Nullable String mDelegatePackageName;
     private @Nullable String mDelegatorPackageName;
+    private boolean mDelegatorFromDefaultHomePackage;
     private Runnable mDelegationIdleTimeoutRunnable;
     private Handler mDelegationIdleTimeoutHandler;
 
@@ -88,6 +92,7 @@
         mCurrentDisplayId = Display.INVALID_DISPLAY;
         mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         mCurrentRequestId = 0;
         mInkWindowInitRunnable = inkWindowInitRunnable;
     }
@@ -151,9 +156,20 @@
      * @see InputMethodManager#prepareStylusHandwritingDelegation(View, String)
      */
     void prepareStylusHandwritingDelegation(
-            @NonNull String delegatePackageName, @NonNull String delegatorPackageName) {
+            int userId, @NonNull String delegatePackageName, @NonNull String delegatorPackageName) {
         mDelegatePackageName = delegatePackageName;
         mDelegatorPackageName = delegatorPackageName;
+        mDelegatorFromDefaultHomePackage = false;
+        // mDelegatorFromDefaultHomeActivity is only used in the cross-package delegation case.
+        // For same-package delegation, it doesn't need to be checked.
+        if (!delegatorPackageName.equals(delegatePackageName)) {
+            ComponentName defaultHomeActivity =
+                    mPackageManagerInternal.getDefaultHomeActivity(userId);
+            if (defaultHomeActivity != null) {
+                mDelegatorFromDefaultHomePackage =
+                        delegatorPackageName.equals(defaultHomeActivity.getPackageName());
+            }
+        }
         if (mHandwritingBuffer == null) {
             mHandwritingBuffer = new ArrayList<>(getHandwritingBufferSize());
         } else {
@@ -170,6 +186,10 @@
         return mDelegatorPackageName;
     }
 
+    boolean isDelegatorFromDefaultHomePackage() {
+        return mDelegatorFromDefaultHomePackage;
+    }
+
     private void scheduleHandwritingDelegationTimeout() {
         if (mDelegationIdleTimeoutHandler == null) {
             mDelegationIdleTimeoutHandler = new Handler(mLooper);
@@ -210,6 +230,7 @@
         mDelegationIdleTimeoutRunnable = null;
         mDelegatorPackageName = null;
         mDelegatePackageName = null;
+        mDelegatorFromDefaultHomePackage = false;
     }
 
     /**
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index ddb32fe..a0bc7c2 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2085,7 +2085,7 @@
                     new ArrayMap<>();
             AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
             queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap,
-                    methodList, directBootAwareness, mSettings.getEnabledInputMethodNames());
+                    methodList, directBootAwareness);
             settings = new InputMethodSettings(mContext, methodMap, userId, true /* copyOnWrite */);
         }
         // filter caller's access to input methods
@@ -2713,10 +2713,10 @@
     }
 
     @AnyThread
-    void schedulePrepareStylusHandwritingDelegation(
+    void schedulePrepareStylusHandwritingDelegation(@UserIdInt int userId,
             @NonNull String delegatePackageName, @NonNull String delegatorPackageName) {
         mHandler.obtainMessage(
-                MSG_PREPARE_HANDWRITING_DELEGATION,
+                MSG_PREPARE_HANDWRITING_DELEGATION, userId, 0 /* unused */,
                 new Pair<>(delegatePackageName, delegatorPackageName)).sendToTarget();
     }
 
@@ -3433,7 +3433,8 @@
             Slog.w(TAG, "prepareStylusHandwritingDelegation() fail");
             throw new IllegalArgumentException("Delegator doesn't match Uid");
         }
-        schedulePrepareStylusHandwritingDelegation(delegatePackageName, delegatorPackageName);
+        schedulePrepareStylusHandwritingDelegation(
+                userId, delegatePackageName, delegatorPackageName);
     }
 
     @Override
@@ -3441,13 +3442,14 @@
             @NonNull IInputMethodClient client,
             @UserIdInt int userId,
             @NonNull String delegatePackageName,
-            @NonNull String delegatorPackageName) {
+            @NonNull String delegatorPackageName,
+            @InputMethodManager.HandwritingDelegateFlags int flags) {
         if (!isStylusHandwritingEnabled(mContext, userId)) {
             Slog.w(TAG, "Can not accept stylus handwriting delegation. Stylus handwriting"
                     + " pref is disabled for user: " + userId);
             return false;
         }
-        if (!verifyDelegator(client, delegatePackageName, delegatorPackageName)) {
+        if (!verifyDelegator(client, delegatePackageName, delegatorPackageName, flags)) {
             return false;
         }
 
@@ -3471,14 +3473,20 @@
     private boolean verifyDelegator(
             @NonNull IInputMethodClient client,
             @NonNull String delegatePackageName,
-            @NonNull String delegatorPackageName) {
+            @NonNull String delegatorPackageName,
+            @InputMethodManager.HandwritingDelegateFlags int flags) {
         if (!verifyClientAndPackageMatch(client, delegatePackageName)) {
             Slog.w(TAG, "Delegate package does not belong to the same user. Ignoring"
                     + " startStylusHandwriting");
             return false;
         }
         synchronized (ImfLock.class) {
-            if (!delegatorPackageName.equals(mHwController.getDelegatorPackageName())) {
+            boolean homeDelegatorAllowed =
+                    (flags & InputMethodManager.HANDWRITING_DELEGATE_FLAG_HOME_DELEGATOR_ALLOWED)
+                            != 0;
+            if (!delegatorPackageName.equals(mHwController.getDelegatorPackageName())
+                    && !(homeDelegatorAllowed
+                            && mHwController.isDelegatorFromDefaultHomePackage())) {
                 Slog.w(TAG,
                         "Delegator package does not match. Ignoring startStylusHandwriting");
                 return false;
@@ -4200,7 +4208,7 @@
                     new ArrayMap<>();
             AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
             queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap,
-                    methodList, DirectBootAwareness.AUTO, mSettings.getEnabledInputMethodNames());
+                    methodList, DirectBootAwareness.AUTO);
             final InputMethodSettings settings = new InputMethodSettings(mContext, methodMap,
                     userId, false);
             settings.setAdditionalInputMethodSubtypes(imiId, toBeAdded, additionalSubtypeMap,
@@ -4924,9 +4932,10 @@
             }
             case MSG_PREPARE_HANDWRITING_DELEGATION:
                 synchronized (ImfLock.class) {
+                    int userId = msg.arg1;
                     String delegate = (String) ((Pair) msg.obj).first;
                     String delegator = (String) ((Pair) msg.obj).second;
-                    mHwController.prepareStylusHandwritingDelegation(delegate, delegator);
+                    mHwController.prepareStylusHandwritingDelegation(userId, delegate, delegator);
                 }
                 return true;
             case MSG_START_HANDWRITING:
@@ -5025,7 +5034,7 @@
     static void queryInputMethodServicesInternal(Context context,
             @UserIdInt int userId, ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap,
             ArrayMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList,
-            @DirectBootAwareness int directBootAwareness, List<String> enabledInputMethodList) {
+            @DirectBootAwareness int directBootAwareness) {
         final Context userAwareContext = context.getUserId() == userId
                 ? context
                 : context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
@@ -5058,6 +5067,11 @@
         methodList.ensureCapacity(services.size());
         methodMap.ensureCapacity(services.size());
 
+        // Note: This is a temporary solution for Bug 261723412.  If there is any better solution,
+        // we should remove this data dependency.
+        final List<String> enabledInputMethodList =
+                InputMethodUtils.getEnabledInputMethodIdsForFiltering(context, userId);
+
         filterInputMethodServices(additionalSubtypeMap, methodMap, methodList,
                 enabledInputMethodList, userAwareContext, services);
     }
@@ -5124,8 +5138,7 @@
         mMyPackageMonitor.clearKnownImePackageNamesLocked();
 
         queryInputMethodServicesInternal(mContext, mSettings.getCurrentUserId(),
-                mAdditionalSubtypeMap, mMethodMap, mMethodList, DirectBootAwareness.AUTO,
-                mSettings.getEnabledInputMethodNames());
+                mAdditionalSubtypeMap, mMethodMap, mMethodList, DirectBootAwareness.AUTO);
 
         // Construct the set of possible IME packages for onPackageChanged() to avoid false
         // negatives when the package state remains to be the same but only the component state is
@@ -5438,47 +5451,21 @@
      */
     @GuardedBy("ImfLock.class")
     private InputMethodInfo queryDefaultInputMethodForUserIdLocked(@UserIdInt int userId) {
-        final String imeId = mSettings.getSelectedInputMethodForUser(userId);
-        if (TextUtils.isEmpty(imeId)) {
-            Slog.e(TAG, "No default input method found for userId " + userId);
-            return null;
+        if (userId == mSettings.getCurrentUserId()) {
+            return mMethodMap.get(mSettings.getSelectedInputMethod());
         }
 
-        InputMethodInfo curInputMethodInfo;
-        if (userId == mSettings.getCurrentUserId()
-                && (curInputMethodInfo = mMethodMap.get(imeId)) != null) {
-            // clone the InputMethodInfo before returning.
-            return new InputMethodInfo(curInputMethodInfo);
-        }
-
+        final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+        final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
         final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap = new ArrayMap<>();
         AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
-        Context userAwareContext =
-                mContext.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
-
-        final int flags = PackageManager.GET_META_DATA
-                | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
-                | PackageManager.MATCH_DIRECT_BOOT_AUTO;
-        final List<ResolveInfo> services =
-                userAwareContext.getPackageManager().queryIntentServicesAsUser(
-                        new Intent(InputMethod.SERVICE_INTERFACE),
-                        PackageManager.ResolveInfoFlags.of(flags),
-                        userId);
-        for (ResolveInfo ri : services) {
-            final String imeIdResolved = InputMethodInfo.computeId(ri);
-            if (imeId.equals(imeIdResolved)) {
-                try {
-                    return new InputMethodInfo(
-                            userAwareContext, ri, additionalSubtypeMap.get(imeId));
-                } catch (Exception e) {
-                    Slog.wtf(TAG, "Unable to load input method " + imeId, e);
-                }
-            }
-        }
-        // we didn't find the InputMethodInfo for imeId. This shouldn't happen.
-        Slog.e(TAG, "Error while locating input method info for imeId: " + imeId);
-        return null;
+        queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap,
+                methodList, DirectBootAwareness.AUTO);
+        InputMethodSettings settings = new InputMethodSettings(mContext, methodMap, userId,
+                true /* copyOnWrite */);
+        return methodMap.get(settings.getSelectedInputMethod());
     }
+
     private ArrayMap<String, InputMethodInfo> queryMethodMapForUser(@UserIdInt int userId) {
         final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
         final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
@@ -5486,8 +5473,7 @@
                 new ArrayMap<>();
         AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
         queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
-                methodMap, methodList, DirectBootAwareness.AUTO,
-                mSettings.getEnabledInputMethodNames());
+                methodMap, methodList, DirectBootAwareness.AUTO);
         return methodMap;
     }
 
@@ -6511,8 +6497,7 @@
                                 new ArrayMap<>();
                         AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
                         queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
-                                methodMap, methodList, DirectBootAwareness.AUTO,
-                                mSettings.getEnabledInputMethodNames());
+                                methodMap, methodList, DirectBootAwareness.AUTO);
                         final InputMethodSettings settings = new InputMethodSettings(mContext,
                                 methodMap, userId, false);
 
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
index c97d8e2..984ae1f 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
@@ -330,17 +330,11 @@
 
         @Nullable
         private String getString(@NonNull String key, @Nullable String defaultValue) {
-            return getStringForUser(key, defaultValue, mCurrentUserId);
-        }
-
-        @Nullable
-        private String getStringForUser(
-                @NonNull String key, @Nullable String defaultValue, @UserIdInt int userId) {
             final String result;
             if (mCopyOnWrite && mCopyOnWriteDataStore.containsKey(key)) {
                 result = mCopyOnWriteDataStore.get(key);
             } else {
-                result = Settings.Secure.getStringForUser(mResolver, key, userId);
+                result = Settings.Secure.getStringForUser(mResolver, key, mCurrentUserId);
             }
             return result != null ? result : defaultValue;
         }
@@ -756,16 +750,6 @@
             return imi;
         }
 
-        @Nullable
-        String getSelectedInputMethodForUser(@UserIdInt int userId) {
-            final String imi =
-                    getStringForUser(Settings.Secure.DEFAULT_INPUT_METHOD, null, userId);
-            if (DEBUG) {
-                Slog.d(TAG, "getSelectedInputMethodForUserStr: " + imi);
-            }
-            return imi;
-        }
-
         void putDefaultVoiceInputMethod(String imeId) {
             if (DEBUG) {
                 Slog.d(TAG, "putDefaultVoiceInputMethodStr: " + imeId + ", " + mCurrentUserId);
@@ -1029,6 +1013,44 @@
     }
 
     /**
+     * Returns a list of enabled IME IDs to address Bug 261723412.
+     *
+     * <p>This is a temporary workaround until we come up with a better solution. Do not use this
+     * for anything other than Bug 261723412.</p>
+     *
+     * @param context {@link Context} object to query secure settings.
+     * @param userId User ID to query about.
+     * @return A list of enabled IME IDs.
+     */
+    @NonNull
+    static List<String> getEnabledInputMethodIdsForFiltering(@NonNull Context context,
+            @UserIdInt int userId) {
+        final String enabledInputMethodsStr = TextUtils.nullIfEmpty(
+                Settings.Secure.getStringForUser(
+                        context.getContentResolver(),
+                        Settings.Secure.ENABLED_INPUT_METHODS,
+                        userId));
+        if (enabledInputMethodsStr == null) {
+            return List.of();
+        }
+        final TextUtils.SimpleStringSplitter inputMethodSplitter =
+                new TextUtils.SimpleStringSplitter(INPUT_METHOD_SEPARATOR);
+        final TextUtils.SimpleStringSplitter subtypeSplitter =
+                new TextUtils.SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATOR);
+        inputMethodSplitter.setString(enabledInputMethodsStr);
+        final ArrayList<String> result = new ArrayList<>();
+        while (inputMethodSplitter.hasNext()) {
+            String nextImsStr = inputMethodSplitter.next();
+            subtypeSplitter.setString(nextImsStr);
+            if (subtypeSplitter.hasNext()) {
+                // The first element is ime id.
+                result.add(subtypeSplitter.next());
+            }
+        }
+        return result;
+    }
+
+    /**
      * Convert the input method ID to a component name
      *
      * @param id A unique ID for this input method.
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index 6f9b7d6..27b01a5 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -67,6 +67,7 @@
 import android.location.LocationManager;
 import android.location.LocationRequest;
 import android.location.LocationResult;
+import android.location.flags.Flags;
 import android.location.provider.ProviderProperties;
 import android.location.provider.ProviderRequest;
 import android.location.util.identity.CallerIdentity;
@@ -1048,10 +1049,22 @@
                 stopBatching();
 
                 if (mStarted && mGnssNative.getCapabilities().hasScheduling()) {
-                    // change period and/or lowPowerMode
-                    if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
-                            mFixInterval, mProviderRequest.isLowPower())) {
-                        Log.e(TAG, "set_position_mode failed in updateRequirements");
+                    if (Flags.gnssCallStopBeforeSetPositionMode()) {
+                        GnssPositionMode positionMode = new GnssPositionMode(mPositionMode,
+                                GNSS_POSITION_RECURRENCE_PERIODIC, mFixInterval,
+                                /* preferredAccuracy= */ 0,
+                                /* preferredTime= */ 0,
+                                mProviderRequest.isLowPower());
+                        if (!positionMode.equals(mLastPositionMode)) {
+                            stopNavigating();
+                            startNavigating();
+                        }
+                    } else {
+                        // change period and/or lowPowerMode
+                        if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
+                                mFixInterval, mProviderRequest.isLowPower())) {
+                            Log.e(TAG, "set_position_mode failed in updateRequirements");
+                        }
                     }
                 } else if (!mStarted) {
                     // start GPS
@@ -1234,11 +1247,32 @@
             }
 
             int interval = mGnssNative.getCapabilities().hasScheduling() ? mFixInterval : 1000;
-            if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
-                    interval, mProviderRequest.isLowPower())) {
-                setStarted(false);
-                Log.e(TAG, "set_position_mode failed in startNavigating()");
-                return;
+
+            if (Flags.gnssCallStopBeforeSetPositionMode()) {
+                boolean success = mGnssNative.setPositionMode(mPositionMode,
+                        GNSS_POSITION_RECURRENCE_PERIODIC, interval,
+                        /* preferredAccuracy= */ 0,
+                        /* preferredTime= */ 0,
+                        mProviderRequest.isLowPower());
+                if (success) {
+                    mLastPositionMode = new GnssPositionMode(mPositionMode,
+                            GNSS_POSITION_RECURRENCE_PERIODIC, interval,
+                            /* preferredAccuracy= */ 0,
+                            /* preferredTime= */ 0,
+                            mProviderRequest.isLowPower());
+                } else {
+                    mLastPositionMode = null;
+                    setStarted(false);
+                    Log.e(TAG, "set_position_mode failed in startNavigating()");
+                    return;
+                }
+            } else {
+                if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
+                        interval, mProviderRequest.isLowPower())) {
+                    setStarted(false);
+                    Log.e(TAG, "set_position_mode failed in startNavigating()");
+                    return;
+                }
             }
             if (!mGnssNative.start()) {
                 setStarted(false);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 57e424d..49095ce 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -246,7 +246,7 @@
     private static final String MIGRATED_SP_FULL = "migrated_all_users_to_sp_and_bound_keys";
 
     private static final boolean FIX_UNLOCKED_DEVICE_REQUIRED_KEYS =
-            android.security.Flags.fixUnlockedDeviceRequiredKeys();
+            android.security.Flags.fixUnlockedDeviceRequiredKeysV2();
 
     // Duration that LockSettingsService will store the gatekeeper password for. This allows
     // multiple biometric enrollments without prompting the user to enter their password via
diff --git a/services/core/java/com/android/server/media/AudioAttributesUtils.java b/services/core/java/com/android/server/media/AudioAttributesUtils.java
deleted file mode 100644
index 8cb334d..0000000
--- a/services/core/java/com/android/server/media/AudioAttributesUtils.java
+++ /dev/null
@@ -1,125 +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.media;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.media.AudioAttributes;
-import android.media.AudioDeviceAttributes;
-import android.media.AudioDeviceInfo;
-import android.media.MediaRoute2Info;
-
-import com.android.media.flags.Flags;
-
-/* package */ final class AudioAttributesUtils {
-
-    /* package */ static final AudioAttributes ATTRIBUTES_MEDIA = new AudioAttributes.Builder()
-            .setUsage(AudioAttributes.USAGE_MEDIA)
-            .build();
-
-    private AudioAttributesUtils() {
-        // no-op to prevent instantiation.
-    }
-
-    @MediaRoute2Info.Type
-    /* package */ static int mapToMediaRouteType(
-            @NonNull AudioDeviceAttributes audioDeviceAttributes) {
-        if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
-            switch (audioDeviceAttributes.getType()) {
-                case AudioDeviceInfo.TYPE_HDMI_ARC:
-                    return MediaRoute2Info.TYPE_HDMI_ARC;
-                case AudioDeviceInfo.TYPE_HDMI_EARC:
-                    return MediaRoute2Info.TYPE_HDMI_EARC;
-            }
-        }
-        switch (audioDeviceAttributes.getType()) {
-            case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
-            case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
-                return MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
-            case AudioDeviceInfo.TYPE_WIRED_HEADSET:
-                return MediaRoute2Info.TYPE_WIRED_HEADSET;
-            case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
-                return MediaRoute2Info.TYPE_WIRED_HEADPHONES;
-            case AudioDeviceInfo.TYPE_DOCK:
-            case AudioDeviceInfo.TYPE_DOCK_ANALOG:
-                return MediaRoute2Info.TYPE_DOCK;
-            case AudioDeviceInfo.TYPE_HDMI:
-            case AudioDeviceInfo.TYPE_HDMI_ARC:
-            case AudioDeviceInfo.TYPE_HDMI_EARC:
-                return MediaRoute2Info.TYPE_HDMI;
-            case AudioDeviceInfo.TYPE_USB_DEVICE:
-                return MediaRoute2Info.TYPE_USB_DEVICE;
-            case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
-                return MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
-            case AudioDeviceInfo.TYPE_BLE_HEADSET:
-                return MediaRoute2Info.TYPE_BLE_HEADSET;
-            case AudioDeviceInfo.TYPE_HEARING_AID:
-                return MediaRoute2Info.TYPE_HEARING_AID;
-            default:
-                return MediaRoute2Info.TYPE_UNKNOWN;
-        }
-    }
-
-    /* package */ static boolean isDeviceOutputAttributes(
-            @Nullable AudioDeviceAttributes audioDeviceAttributes) {
-        if (audioDeviceAttributes == null) {
-            return false;
-        }
-
-        if (audioDeviceAttributes.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) {
-            return false;
-        }
-
-        switch (audioDeviceAttributes.getType()) {
-            case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
-            case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
-            case AudioDeviceInfo.TYPE_WIRED_HEADSET:
-            case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
-            case AudioDeviceInfo.TYPE_DOCK:
-            case AudioDeviceInfo.TYPE_DOCK_ANALOG:
-            case AudioDeviceInfo.TYPE_HDMI:
-            case AudioDeviceInfo.TYPE_HDMI_ARC:
-            case AudioDeviceInfo.TYPE_HDMI_EARC:
-            case AudioDeviceInfo.TYPE_USB_DEVICE:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    /* package */ static boolean isBluetoothOutputAttributes(
-            @Nullable AudioDeviceAttributes audioDeviceAttributes) {
-        if (audioDeviceAttributes == null) {
-            return false;
-        }
-
-        if (audioDeviceAttributes.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) {
-            return false;
-        }
-
-        switch (audioDeviceAttributes.getType()) {
-            case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
-            case AudioDeviceInfo.TYPE_BLE_HEADSET:
-            case AudioDeviceInfo.TYPE_BLE_SPEAKER:
-            case AudioDeviceInfo.TYPE_HEARING_AID:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-}
diff --git a/services/core/java/com/android/server/media/AudioPoliciesBluetoothRouteController.java b/services/core/java/com/android/server/media/AudioPoliciesBluetoothRouteController.java
index 8bc69c2..a00999d 100644
--- a/services/core/java/com/android/server/media/AudioPoliciesBluetoothRouteController.java
+++ b/services/core/java/com/android/server/media/AudioPoliciesBluetoothRouteController.java
@@ -17,7 +17,6 @@
 package com.android.server.media;
 
 import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_AUDIO;
-import static android.bluetooth.BluetoothAdapter.STATE_CONNECTED;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -31,38 +30,37 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.media.AudioSystem;
 import android.media.MediaRoute2Info;
 import android.os.UserHandle;
 import android.text.TextUtils;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
- * Controls bluetooth routes and provides selected route override.
+ * Maintains a list of connected {@link BluetoothDevice bluetooth devices} and allows their
+ * activation.
  *
- * <p>The controller offers similar functionality to {@link LegacyBluetoothRouteController} but does
- * not support routes selection logic. Instead, relies on external clients to make a decision
- * about currently selected route.
- *
- * <p>Selected route override should be used by {@link AudioManager} which is aware of Audio
- * Policies.
+ * <p>This class also serves as ground truth for assigning {@link MediaRoute2Info#getId() route ids}
+ * for bluetooth routes via {@link #getRouteIdForBluetoothAddress}.
  */
-/* package */ class AudioPoliciesBluetoothRouteController
-        implements BluetoothRouteController {
-    private static final String TAG = "APBtRouteController";
+// TODO: b/305199571 - Rename this class to remove the RouteController suffix, which causes
+// confusion with the BluetoothRouteController interface.
+/* package */ class AudioPoliciesBluetoothRouteController {
+    private static final String TAG = SystemMediaRoute2Provider.TAG;
 
     private static final String HEARING_AID_ROUTE_ID_PREFIX = "HEARING_AID_";
     private static final String LE_AUDIO_ROUTE_ID_PREFIX = "LE_AUDIO_";
@@ -75,11 +73,8 @@
     private final DeviceStateChangedReceiver mDeviceStateChangedReceiver =
             new DeviceStateChangedReceiver();
 
-    @NonNull
-    private final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>();
-
-    @NonNull
-    private final SparseIntArray mVolumeMap = new SparseIntArray();
+    @NonNull private Map<String, BluetoothDevice> mAddressToBondedDevice = new HashMap<>();
+    @NonNull private final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>();
 
     @NonNull
     private final Context mContext;
@@ -89,11 +84,6 @@
     private final BluetoothRouteController.BluetoothRoutesUpdatedListener mListener;
     @NonNull
     private final BluetoothProfileMonitor mBluetoothProfileMonitor;
-    @NonNull
-    private final AudioManager mAudioManager;
-
-    @Nullable
-    private BluetoothRouteInfo mSelectedBluetoothRoute;
 
     AudioPoliciesBluetoothRouteController(@NonNull Context context,
             @NonNull BluetoothAdapter bluetoothAdapter,
@@ -107,21 +97,12 @@
             @NonNull BluetoothAdapter bluetoothAdapter,
             @NonNull BluetoothProfileMonitor bluetoothProfileMonitor,
             @NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) {
-        Objects.requireNonNull(context);
-        Objects.requireNonNull(bluetoothAdapter);
-        Objects.requireNonNull(bluetoothProfileMonitor);
-        Objects.requireNonNull(listener);
-
-        mContext = context;
-        mBluetoothAdapter = bluetoothAdapter;
-        mBluetoothProfileMonitor = bluetoothProfileMonitor;
-        mAudioManager = mContext.getSystemService(AudioManager.class);
-        mListener = listener;
-
-        updateBluetoothRoutes();
+        mContext = Objects.requireNonNull(context);
+        mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
+        mBluetoothProfileMonitor = Objects.requireNonNull(bluetoothProfileMonitor);
+        mListener = Objects.requireNonNull(listener);
     }
 
-    @Override
     public void start(UserHandle user) {
         mBluetoothProfileMonitor.start();
 
@@ -133,122 +114,63 @@
 
         IntentFilter deviceStateChangedIntentFilter = new IntentFilter();
 
-        deviceStateChangedIntentFilter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
         deviceStateChangedIntentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
         deviceStateChangedIntentFilter.addAction(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED);
         deviceStateChangedIntentFilter.addAction(
                 BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
         deviceStateChangedIntentFilter.addAction(
                 BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
-        deviceStateChangedIntentFilter.addAction(
-                BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED);
 
         mContext.registerReceiverAsUser(mDeviceStateChangedReceiver, user,
                 deviceStateChangedIntentFilter, null, null);
+        updateBluetoothRoutes();
     }
 
-    @Override
     public void stop() {
         mContext.unregisterReceiver(mAdapterStateChangedReceiver);
         mContext.unregisterReceiver(mDeviceStateChangedReceiver);
     }
 
-    @Override
-    public boolean selectRoute(@Nullable String deviceAddress) {
-        synchronized (this) {
-            // Fetch all available devices in order to avoid race conditions with Bluetooth stack.
-            updateBluetoothRoutes();
-
-            if (deviceAddress == null) {
-                mSelectedBluetoothRoute = null;
-                return true;
-            }
-
-            BluetoothRouteInfo bluetoothRouteInfo = mBluetoothRoutes.get(deviceAddress);
-
-            if (bluetoothRouteInfo == null) {
-                Slog.w(TAG, "Cannot find bluetooth route for " + deviceAddress);
-                return false;
-            }
-
-            mSelectedBluetoothRoute = bluetoothRouteInfo;
-            setRouteConnectionState(mSelectedBluetoothRoute, STATE_CONNECTED);
-
-            updateConnectivityStateForDevicesInTheSameGroup();
-
-            return true;
-        }
+    @Nullable
+    public synchronized String getRouteIdForBluetoothAddress(@Nullable String address) {
+        BluetoothDevice bluetoothDevice = mAddressToBondedDevice.get(address);
+        // TODO: b/305199571 - Optimize the following statement to avoid creating the full
+        // MediaRoute2Info instance. We just need the id.
+        return bluetoothDevice != null
+                ? createBluetoothRoute(bluetoothDevice).mRoute.getId()
+                : null;
     }
 
-    /**
-     * Updates connectivity state for devices in the same devices group.
-     *
-     * <p>{@link BluetoothProfile#LE_AUDIO} and {@link BluetoothProfile#HEARING_AID} support
-     * grouping devices. Devices that belong to the same group should have the same routeId but
-     * different physical address.
-     *
-     * <p>In case one of the devices from the group is selected then other devices should also
-     * reflect this by changing their connectivity status to
-     * {@link MediaRoute2Info#CONNECTION_STATE_CONNECTED}.
-     */
-    private void updateConnectivityStateForDevicesInTheSameGroup() {
-        synchronized (this) {
-            for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
-                if (TextUtils.equals(btRoute.mRoute.getId(), mSelectedBluetoothRoute.mRoute.getId())
-                        && !TextUtils.equals(btRoute.mBtDevice.getAddress(),
-                        mSelectedBluetoothRoute.mBtDevice.getAddress())) {
-                    setRouteConnectionState(btRoute, STATE_CONNECTED);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void transferTo(@Nullable String routeId) {
-        if (routeId == null) {
-            mBluetoothAdapter.removeActiveDevice(ACTIVE_DEVICE_AUDIO);
-            return;
-        }
-
-        BluetoothRouteInfo btRouteInfo = findBluetoothRouteWithRouteId(routeId);
+    public synchronized void activateBluetoothDeviceWithAddress(String address) {
+        BluetoothRouteInfo btRouteInfo = mBluetoothRoutes.get(address);
 
         if (btRouteInfo == null) {
-            Slog.w(TAG, "transferTo: Unknown route. ID=" + routeId);
+            Slog.w(TAG, "activateBluetoothDeviceWithAddress: Ignoring unknown address " + address);
             return;
         }
-
         mBluetoothAdapter.setActiveDevice(btRouteInfo.mBtDevice, ACTIVE_DEVICE_AUDIO);
     }
 
-    @Nullable
-    private BluetoothRouteInfo findBluetoothRouteWithRouteId(@Nullable String routeId) {
-        if (routeId == null) {
-            return null;
-        }
-        synchronized (this) {
-            for (BluetoothRouteInfo btRouteInfo : mBluetoothRoutes.values()) {
-                if (TextUtils.equals(btRouteInfo.mRoute.getId(), routeId)) {
-                    return btRouteInfo;
-                }
-            }
-        }
-        return null;
-    }
-
     private void updateBluetoothRoutes() {
         Set<BluetoothDevice> bondedDevices = mBluetoothAdapter.getBondedDevices();
 
-        if (bondedDevices == null) {
-            return;
-        }
-
         synchronized (this) {
             mBluetoothRoutes.clear();
-
-            // We need to query all available to BT stack devices in order to avoid inconsistency
-            // between external services, like, AndroidManager, and BT stack.
+            if (bondedDevices == null) {
+                // Bonded devices is null upon running into a BluetoothAdapter error.
+                Log.w(TAG, "BluetoothAdapter.getBondedDevices returned null.");
+                return;
+            }
+            // We don't clear bonded devices if we receive a null getBondedDevices result, because
+            // that probably means that the bluetooth stack ran into an issue. Not that all devices
+            // have been unpaired.
+            mAddressToBondedDevice =
+                    bondedDevices.stream()
+                            .collect(
+                                    Collectors.toMap(
+                                            BluetoothDevice::getAddress, Function.identity()));
             for (BluetoothDevice device : bondedDevices) {
-                if (isDeviceConnected(device)) {
+                if (device.isConnected()) {
                     BluetoothRouteInfo newBtRoute = createBluetoothRoute(device);
                     if (newBtRoute.mConnectedProfiles.size() > 0) {
                         mBluetoothRoutes.put(device.getAddress(), newBtRoute);
@@ -258,106 +180,51 @@
         }
     }
 
-    @VisibleForTesting
-        /* package */ boolean isDeviceConnected(@NonNull BluetoothDevice device) {
-        return device.isConnected();
-    }
-
-    @Nullable
-    @Override
-    public MediaRoute2Info getSelectedRoute() {
-        synchronized (this) {
-            if (mSelectedBluetoothRoute == null) {
-                return null;
-            }
-
-            return mSelectedBluetoothRoute.mRoute;
-        }
-    }
-
     @NonNull
-    @Override
-    public List<MediaRoute2Info> getTransferableRoutes() {
-        List<MediaRoute2Info> routes = getAllBluetoothRoutes();
-        synchronized (this) {
-            if (mSelectedBluetoothRoute != null) {
-                routes.remove(mSelectedBluetoothRoute.mRoute);
-            }
-        }
-        return routes;
-    }
-
-    @NonNull
-    @Override
-    public List<MediaRoute2Info> getAllBluetoothRoutes() {
+    public List<MediaRoute2Info> getAvailableBluetoothRoutes() {
         List<MediaRoute2Info> routes = new ArrayList<>();
-        List<String> routeIds = new ArrayList<>();
-
-        MediaRoute2Info selectedRoute = getSelectedRoute();
-        if (selectedRoute != null) {
-            routes.add(selectedRoute);
-            routeIds.add(selectedRoute.getId());
-        }
+        Set<String> routeIds = new HashSet<>();
 
         synchronized (this) {
             for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
-                // A pair of hearing aid devices or having the same hardware address
-                if (routeIds.contains(btRoute.mRoute.getId())) {
-                    continue;
+                // See createBluetoothRoute for info on why we do this.
+                if (routeIds.add(btRoute.mRoute.getId())) {
+                    routes.add(btRoute.mRoute);
                 }
-                routes.add(btRoute.mRoute);
-                routeIds.add(btRoute.mRoute.getId());
             }
         }
         return routes;
     }
 
-    @Override
-    public boolean updateVolumeForDevices(int devices, int volume) {
-        int routeType;
-        if ((devices & (AudioSystem.DEVICE_OUT_HEARING_AID)) != 0) {
-            routeType = MediaRoute2Info.TYPE_HEARING_AID;
-        } else if ((devices & (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP
-                | AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES
-                | AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
-            routeType = MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
-        } else if ((devices & (AudioManager.DEVICE_OUT_BLE_HEADSET)) != 0) {
-            routeType = MediaRoute2Info.TYPE_BLE_HEADSET;
-        } else {
-            return false;
-        }
-
-        synchronized (this) {
-            mVolumeMap.put(routeType, volume);
-            if (mSelectedBluetoothRoute == null
-                    || mSelectedBluetoothRoute.mRoute.getType() != routeType) {
-                return false;
-            }
-
-            mSelectedBluetoothRoute.mRoute =
-                    new MediaRoute2Info.Builder(mSelectedBluetoothRoute.mRoute)
-                            .setVolume(volume)
-                            .build();
-        }
-
-        notifyBluetoothRoutesUpdated();
-        return true;
-    }
-
     private void notifyBluetoothRoutesUpdated() {
         mListener.onBluetoothRoutesUpdated();
     }
 
+    /**
+     * Creates a new {@link BluetoothRouteInfo}, including its member {@link
+     * BluetoothRouteInfo#mRoute}.
+     *
+     * <p>The most important logic in this method is around the {@link MediaRoute2Info#getId() route
+     * id} assignment. In some cases we want to group multiple {@link BluetoothDevice bluetooth
+     * devices} as a single media route. For example, the left and right hearing aids get exposed as
+     * two different BluetoothDevice instances, but we want to show them as a single route. In this
+     * case, we assign the same route id to all "group" bluetooth devices (like left and right
+     * hearing aids), so that a single route is exposed for both of them.
+     *
+     * <p>Deduplication by id happens downstream because we need to be able to refer to all
+     * bluetooth devices individually, since the audio stack refers to a bluetooth device group by
+     * any of its member devices.
+     */
     private BluetoothRouteInfo createBluetoothRoute(BluetoothDevice device) {
         BluetoothRouteInfo
                 newBtRoute = new BluetoothRouteInfo();
         newBtRoute.mBtDevice = device;
-
-        String routeId = device.getAddress();
         String deviceName = device.getName();
         if (TextUtils.isEmpty(deviceName)) {
             deviceName = mContext.getResources().getText(R.string.unknownName).toString();
         }
+
+        String routeId = device.getAddress();
         int type = MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
         newBtRoute.mConnectedProfiles = new SparseBooleanArray();
         if (mBluetoothProfileMonitor.isProfileSupported(BluetoothProfile.A2DP, device)) {
@@ -365,7 +232,6 @@
         }
         if (mBluetoothProfileMonitor.isProfileSupported(BluetoothProfile.HEARING_AID, device)) {
             newBtRoute.mConnectedProfiles.put(BluetoothProfile.HEARING_AID, true);
-            // Intentionally assign the same ID for a pair of devices to publish only one of them.
             routeId = HEARING_AID_ROUTE_ID_PREFIX
                     + mBluetoothProfileMonitor.getGroupId(BluetoothProfile.HEARING_AID, device);
             type = MediaRoute2Info.TYPE_HEARING_AID;
@@ -377,66 +243,27 @@
             type = MediaRoute2Info.TYPE_BLE_HEADSET;
         }
 
-        // Current volume will be set when connected.
-        newBtRoute.mRoute = new MediaRoute2Info.Builder(routeId, deviceName)
-                .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
-                .addFeature(MediaRoute2Info.FEATURE_LOCAL_PLAYBACK)
-                .setConnectionState(MediaRoute2Info.CONNECTION_STATE_DISCONNECTED)
-                .setDescription(mContext.getResources().getText(
-                        R.string.bluetooth_a2dp_audio_route_name).toString())
-                .setType(type)
-                .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
-                .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
-                .setAddress(device.getAddress())
-                .build();
+        // Note that volume is only relevant for active bluetooth routes, and those are managed via
+        // AudioManager.
+        newBtRoute.mRoute =
+                new MediaRoute2Info.Builder(routeId, deviceName)
+                        .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
+                        .addFeature(MediaRoute2Info.FEATURE_LOCAL_PLAYBACK)
+                        .setConnectionState(MediaRoute2Info.CONNECTION_STATE_DISCONNECTED)
+                        .setDescription(
+                                mContext.getResources()
+                                        .getText(R.string.bluetooth_a2dp_audio_route_name)
+                                        .toString())
+                        .setType(type)
+                        .setAddress(device.getAddress())
+                        .build();
         return newBtRoute;
     }
 
-    private void setRouteConnectionState(@NonNull BluetoothRouteInfo btRoute,
-            @MediaRoute2Info.ConnectionState int state) {
-        if (btRoute == null) {
-            Slog.w(TAG, "setRouteConnectionState: route shouldn't be null");
-            return;
-        }
-        if (btRoute.mRoute.getConnectionState() == state) {
-            return;
-        }
-
-        MediaRoute2Info.Builder builder = new MediaRoute2Info.Builder(btRoute.mRoute)
-                .setConnectionState(state);
-        builder.setType(btRoute.getRouteType());
-
-
-
-        if (state == MediaRoute2Info.CONNECTION_STATE_CONNECTED) {
-            int currentVolume;
-            synchronized (this) {
-                currentVolume = mVolumeMap.get(btRoute.getRouteType(), 0);
-            }
-            builder.setVolume(currentVolume);
-        }
-
-        btRoute.mRoute = builder.build();
-    }
-
     private static class BluetoothRouteInfo {
         private BluetoothDevice mBtDevice;
         private MediaRoute2Info mRoute;
         private SparseBooleanArray mConnectedProfiles;
-
-        @MediaRoute2Info.Type
-        int getRouteType() {
-            // Let hearing aid profile have a priority.
-            if (mConnectedProfiles.get(BluetoothProfile.HEARING_AID, false)) {
-                return MediaRoute2Info.TYPE_HEARING_AID;
-            }
-
-            if (mConnectedProfiles.get(BluetoothProfile.LE_AUDIO, false)) {
-                return MediaRoute2Info.TYPE_BLE_HEADSET;
-            }
-
-            return MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
-        }
     }
 
     private class AdapterStateChangedReceiver extends BroadcastReceiver {
@@ -468,9 +295,6 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             switch (intent.getAction()) {
-                case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
-                case BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED:
-                case BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED:
                 case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
                 case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED:
                 case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED:
diff --git a/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java b/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java
index 6bdfae2..246d68d 100644
--- a/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java
+++ b/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java
@@ -17,228 +17,596 @@
 package com.android.server.media;
 
 import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
-import static android.media.MediaRoute2Info.FEATURE_LIVE_VIDEO;
 import static android.media.MediaRoute2Info.FEATURE_LOCAL_PLAYBACK;
-import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
-import static android.media.MediaRoute2Info.TYPE_DOCK;
-import static android.media.MediaRoute2Info.TYPE_HDMI;
-import static android.media.MediaRoute2Info.TYPE_HDMI_ARC;
-import static android.media.MediaRoute2Info.TYPE_HDMI_EARC;
-import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
-import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
-import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
 import android.content.Context;
+import android.media.AudioAttributes;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
 import android.media.AudioManager;
-import android.media.AudioRoutesInfo;
-import android.media.IAudioRoutesObserver;
-import android.media.IAudioService;
 import android.media.MediaRoute2Info;
-import android.os.RemoteException;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.media.BluetoothRouteController.NoOpBluetoothRouteController;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
+/**
+ * Maintains a list of all available routes and supports transfers to any of them.
+ *
+ * <p>This implementation is intended for use in conjunction with {@link
+ * NoOpBluetoothRouteController}, as it manages bluetooth devices directly.
+ *
+ * <p>This implementation obtains and manages all routes via {@link AudioManager}, with the
+ * exception of {@link AudioManager#handleBluetoothActiveDeviceChanged inactive bluetooth} routes
+ * which are managed by {@link AudioPoliciesBluetoothRouteController}, which depends on the
+ * bluetooth stack (for example {@link BluetoothAdapter}.
+ */
+// TODO: b/305199571 - Rename this class to avoid the AudioPolicies prefix, which has been flagged
+// by the audio team as a confusing name.
 /* package */ final class AudioPoliciesDeviceRouteController implements DeviceRouteController {
-
-    private static final String TAG = "APDeviceRoutesController";
+    private static final String TAG = SystemMediaRoute2Provider.TAG;
 
     @NonNull
-    private final Context mContext;
-    @NonNull
-    private final AudioManager mAudioManager;
-    @NonNull
-    private final IAudioService mAudioService;
+    private static final AudioAttributes MEDIA_USAGE_AUDIO_ATTRIBUTES =
+            new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
 
     @NonNull
-    private final OnDeviceRouteChangedListener mOnDeviceRouteChangedListener;
-    @NonNull
-    private final AudioRoutesObserver mAudioRoutesObserver = new AudioRoutesObserver();
+    private static final SparseArray<SystemRouteInfo> AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO =
+            new SparseArray<>();
 
-    private int mDeviceVolume;
+    @NonNull private final Context mContext;
+    @NonNull private final AudioManager mAudioManager;
+    @NonNull private final Handler mHandler;
+    @NonNull private final OnDeviceRouteChangedListener mOnDeviceRouteChangedListener;
+    @NonNull private final AudioPoliciesBluetoothRouteController mBluetoothRouteController;
 
     @NonNull
-    private MediaRoute2Info mDeviceRoute;
-    @Nullable
-    private MediaRoute2Info mSelectedRoute;
+    private final Map<String, MediaRoute2InfoHolder> mRouteIdToAvailableDeviceRoutes =
+            new HashMap<>();
 
-    @VisibleForTesting
-    /* package */ AudioPoliciesDeviceRouteController(@NonNull Context context,
+    @NonNull private final AudioProductStrategy mStrategyForMedia;
+
+    @NonNull private final AudioDeviceCallback mAudioDeviceCallback = new AudioDeviceCallbackImpl();
+
+    @NonNull
+    private final AudioManager.OnDevicesForAttributesChangedListener
+            mOnDevicesForAttributesChangedListener = this::onDevicesForAttributesChangedListener;
+
+    @NonNull private MediaRoute2Info mSelectedRoute;
+
+    // TODO: b/305199571 - Support nullable btAdapter and strategyForMedia which, when null, means
+    // no support for transferring to inactive bluetooth routes and transferring to any routes
+    // respectively.
+    @RequiresPermission(
+            anyOf = {
+                Manifest.permission.MODIFY_AUDIO_ROUTING,
+                Manifest.permission.QUERY_AUDIO_STATE
+            })
+    /* package */ AudioPoliciesDeviceRouteController(
+            @NonNull Context context,
             @NonNull AudioManager audioManager,
-            @NonNull IAudioService audioService,
+            @NonNull Looper looper,
+            @NonNull AudioProductStrategy strategyForMedia,
+            @NonNull BluetoothAdapter btAdapter,
             @NonNull OnDeviceRouteChangedListener onDeviceRouteChangedListener) {
-        Objects.requireNonNull(context);
-        Objects.requireNonNull(audioManager);
-        Objects.requireNonNull(audioService);
-        Objects.requireNonNull(onDeviceRouteChangedListener);
-
-        mContext = context;
-        mOnDeviceRouteChangedListener = onDeviceRouteChangedListener;
-
-        mAudioManager = audioManager;
-        mAudioService = audioService;
-
-        AudioRoutesInfo newAudioRoutes = null;
-        try {
-            newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Cannot connect to audio service to start listen to routes", e);
-        }
-
-        mDeviceRoute = createRouteFromAudioInfo(newAudioRoutes);
+        mContext = Objects.requireNonNull(context);
+        mAudioManager = Objects.requireNonNull(audioManager);
+        mHandler = new Handler(Objects.requireNonNull(looper));
+        mStrategyForMedia = Objects.requireNonNull(strategyForMedia);
+        mOnDeviceRouteChangedListener = Objects.requireNonNull(onDeviceRouteChangedListener);
+        mBluetoothRouteController =
+                new AudioPoliciesBluetoothRouteController(
+                        mContext, btAdapter, this::rebuildAvailableRoutesAndNotify);
+        // Just build routes but don't notify. The caller may not expect the listener to be invoked
+        // before this constructor has finished executing.
+        rebuildAvailableRoutes();
     }
 
+    @RequiresPermission(
+            anyOf = {
+                Manifest.permission.MODIFY_AUDIO_ROUTING,
+                Manifest.permission.QUERY_AUDIO_STATE
+            })
     @Override
-    public synchronized boolean selectRoute(@Nullable Integer type) {
-        if (type == null) {
-            mSelectedRoute = null;
-            return true;
-        }
+    public void start(UserHandle mUser) {
+        mBluetoothRouteController.start(mUser);
+        mAudioManager.registerAudioDeviceCallback(mAudioDeviceCallback, mHandler);
+        mAudioManager.addOnDevicesForAttributesChangedListener(
+                AudioRoutingUtils.ATTRIBUTES_MEDIA,
+                new HandlerExecutor(mHandler),
+                mOnDevicesForAttributesChangedListener);
+    }
 
-        if (!isDeviceRouteType(type)) {
-            return false;
-        }
-
-        mSelectedRoute = createRouteFromAudioInfo(type);
-        return true;
+    @RequiresPermission(
+            anyOf = {
+                Manifest.permission.MODIFY_AUDIO_ROUTING,
+                Manifest.permission.QUERY_AUDIO_STATE
+            })
+    @Override
+    public void stop() {
+        mAudioManager.removeOnDevicesForAttributesChangedListener(
+                mOnDevicesForAttributesChangedListener);
+        mAudioManager.unregisterAudioDeviceCallback(mAudioDeviceCallback);
+        mBluetoothRouteController.stop();
+        mHandler.removeCallbacksAndMessages(/* token= */ null);
     }
 
     @Override
     @NonNull
     public synchronized MediaRoute2Info getSelectedRoute() {
-        if (mSelectedRoute != null) {
-            return mSelectedRoute;
-        }
-        return mDeviceRoute;
+        return mSelectedRoute;
     }
 
     @Override
+    @NonNull
+    public synchronized List<MediaRoute2Info> getAvailableRoutes() {
+        return mRouteIdToAvailableDeviceRoutes.values().stream()
+                .map(it -> it.mMediaRoute2Info)
+                .toList();
+    }
+
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+    @Override
+    public synchronized void transferTo(@Nullable String routeId) {
+        if (routeId == null) {
+            // This should never happen: This branch should only execute when the matching bluetooth
+            // route controller is not the no-op one.
+            // TODO: b/305199571 - Make routeId non-null and remove this branch once we remove the
+            // legacy route controller implementations.
+            Slog.e(TAG, "Unexpected call to AudioPoliciesDeviceRouteController#transferTo(null)");
+            return;
+        }
+        MediaRoute2InfoHolder mediaRoute2InfoHolder = mRouteIdToAvailableDeviceRoutes.get(routeId);
+        if (mediaRoute2InfoHolder == null) {
+            Slog.w(TAG, "transferTo: Ignoring transfer request to unknown route id : " + routeId);
+            return;
+        }
+        if (mediaRoute2InfoHolder.mCorrespondsToInactiveBluetoothRoute) {
+            // By default, the last connected device is the active route so we don't need to apply a
+            // routing audio policy.
+            mBluetoothRouteController.activateBluetoothDeviceWithAddress(
+                    mediaRoute2InfoHolder.mMediaRoute2Info.getAddress());
+            mAudioManager.removePreferredDeviceForStrategy(mStrategyForMedia);
+        } else {
+            AudioDeviceAttributes attr =
+                    new AudioDeviceAttributes(
+                            AudioDeviceAttributes.ROLE_OUTPUT,
+                            mediaRoute2InfoHolder.mAudioDeviceInfoType,
+                            /* address= */ ""); // This is not a BT device, hence no address needed.
+            mAudioManager.setPreferredDeviceForStrategy(mStrategyForMedia, attr);
+        }
+    }
+
+    @RequiresPermission(
+            anyOf = {
+                Manifest.permission.MODIFY_AUDIO_ROUTING,
+                Manifest.permission.QUERY_AUDIO_STATE
+            })
+    @Override
     public synchronized boolean updateVolume(int volume) {
-        if (mDeviceVolume == volume) {
-            return false;
-        }
-
-        mDeviceVolume = volume;
-
-        if (mSelectedRoute != null) {
-            mSelectedRoute = new MediaRoute2Info.Builder(mSelectedRoute)
-                    .setVolume(volume)
-                    .build();
-        }
-
-        mDeviceRoute = new MediaRoute2Info.Builder(mDeviceRoute)
-                .setVolume(volume)
-                .build();
-
+        // TODO: b/305199571 - Optimize so that we only update the volume of the selected route. We
+        // don't need to rebuild all available routes.
+        rebuildAvailableRoutesAndNotify();
         return true;
     }
 
-    @NonNull
-    private MediaRoute2Info createRouteFromAudioInfo(@Nullable AudioRoutesInfo newRoutes) {
-        int type = TYPE_BUILTIN_SPEAKER;
+    @RequiresPermission(
+            anyOf = {
+                Manifest.permission.MODIFY_AUDIO_ROUTING,
+                Manifest.permission.QUERY_AUDIO_STATE
+            })
+    private void onDevicesForAttributesChangedListener(
+            AudioAttributes attributes, List<AudioDeviceAttributes> unusedAudioDeviceAttributes) {
+        if (attributes.getUsage() == AudioAttributes.USAGE_MEDIA) {
+            // We only care about the media usage. Ignore everything else.
+            rebuildAvailableRoutesAndNotify();
+        }
+    }
 
-        if (newRoutes != null) {
-            if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADPHONES) != 0) {
-                type = TYPE_WIRED_HEADPHONES;
-            } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADSET) != 0) {
-                type = TYPE_WIRED_HEADSET;
-            } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
-                type = TYPE_DOCK;
-            } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HDMI) != 0) {
-                type = TYPE_HDMI;
-            } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_USB) != 0) {
-                type = TYPE_USB_DEVICE;
+    private synchronized void rebuildAvailableRoutesAndNotify() {
+        rebuildAvailableRoutes();
+        mOnDeviceRouteChangedListener.onDeviceRouteChanged();
+    }
+
+    @RequiresPermission(
+            anyOf = {
+                Manifest.permission.MODIFY_AUDIO_ROUTING,
+                Manifest.permission.QUERY_AUDIO_STATE
+            })
+    private synchronized void rebuildAvailableRoutes() {
+        List<AudioDeviceAttributes> attributesOfSelectedOutputDevices =
+                mAudioManager.getDevicesForAttributes(MEDIA_USAGE_AUDIO_ATTRIBUTES);
+        int selectedDeviceAttributesType;
+        if (attributesOfSelectedOutputDevices.isEmpty()) {
+            Slog.e(
+                    TAG,
+                    "Unexpected empty list of output devices for media. Using built-in speakers.");
+            selectedDeviceAttributesType = AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+        } else {
+            if (attributesOfSelectedOutputDevices.size() > 1) {
+                Slog.w(
+                        TAG,
+                        "AudioManager.getDevicesForAttributes returned more than one element. Using"
+                                + " the first one.");
+            }
+            selectedDeviceAttributesType = attributesOfSelectedOutputDevices.get(0).getType();
+        }
+
+        AudioDeviceInfo[] audioDeviceInfos =
+                mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+        mRouteIdToAvailableDeviceRoutes.clear();
+        MediaRoute2InfoHolder newSelectedRouteHolder = null;
+        for (AudioDeviceInfo audioDeviceInfo : audioDeviceInfos) {
+            MediaRoute2Info mediaRoute2Info =
+                    createMediaRoute2InfoFromAudioDeviceInfo(audioDeviceInfo);
+            // Null means audioDeviceInfo is not a supported media output, like a phone's builtin
+            // earpiece. We ignore those.
+            if (mediaRoute2Info != null) {
+                int audioDeviceInfoType = audioDeviceInfo.getType();
+                MediaRoute2InfoHolder newHolder =
+                        MediaRoute2InfoHolder.createForAudioManagerRoute(
+                                mediaRoute2Info, audioDeviceInfoType);
+                mRouteIdToAvailableDeviceRoutes.put(mediaRoute2Info.getId(), newHolder);
+                if (selectedDeviceAttributesType == audioDeviceInfoType) {
+                    newSelectedRouteHolder = newHolder;
+                }
             }
         }
 
-        return createRouteFromAudioInfo(type);
-    }
-
-    @NonNull
-    private MediaRoute2Info createRouteFromAudioInfo(@MediaRoute2Info.Type int type) {
-        int name = R.string.default_audio_route_name;
-        switch (type) {
-            case TYPE_WIRED_HEADPHONES:
-            case TYPE_WIRED_HEADSET:
-                name = R.string.default_audio_route_name_headphones;
-                break;
-            case TYPE_DOCK:
-                name = R.string.default_audio_route_name_dock_speakers;
-                break;
-            case TYPE_HDMI:
-            case TYPE_HDMI_ARC:
-            case TYPE_HDMI_EARC:
-                name = R.string.default_audio_route_name_external_device;
-                break;
-            case TYPE_USB_DEVICE:
-                name = R.string.default_audio_route_name_usb;
-                break;
+        if (mRouteIdToAvailableDeviceRoutes.isEmpty()) {
+            // Due to an unknown reason (possibly an audio server crash), we ended up with an empty
+            // list of routes. Our entire codebase assumes at least one system route always exists,
+            // so we create a placeholder route represented as a built-in speaker for
+            // user-presentation purposes.
+            Slog.e(TAG, "Ended up with an empty list of routes. Creating a placeholder route.");
+            MediaRoute2InfoHolder placeholderRouteHolder = createPlaceholderBuiltinSpeakerRoute();
+            String placeholderRouteId = placeholderRouteHolder.mMediaRoute2Info.getId();
+            mRouteIdToAvailableDeviceRoutes.put(placeholderRouteId, placeholderRouteHolder);
         }
 
-        synchronized (this) {
-            return new MediaRoute2Info.Builder(
-                            MediaRoute2Info.ROUTE_ID_DEVICE,
-                            mContext.getResources().getText(name).toString())
-                    .setVolumeHandling(
-                            mAudioManager.isVolumeFixed()
-                                    ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
-                                    : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
-                    .setVolume(mDeviceVolume)
-                    .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
-                    .setType(type)
-                    .addFeature(FEATURE_LIVE_AUDIO)
-                    .addFeature(FEATURE_LIVE_VIDEO)
-                    .addFeature(FEATURE_LOCAL_PLAYBACK)
-                    .setConnectionState(MediaRoute2Info.CONNECTION_STATE_CONNECTED)
-                    .build();
+        if (newSelectedRouteHolder == null) {
+            Slog.e(
+                    TAG,
+                    "Could not map this selected device attribute type to an available route: "
+                            + selectedDeviceAttributesType);
+            // We know mRouteIdToAvailableDeviceRoutes is not empty.
+            newSelectedRouteHolder = mRouteIdToAvailableDeviceRoutes.values().iterator().next();
+        }
+        MediaRoute2InfoHolder selectedRouteHolderWithUpdatedVolumeInfo =
+                newSelectedRouteHolder.copyWithVolumeInfoFromAudioManager(mAudioManager);
+        mRouteIdToAvailableDeviceRoutes.put(
+                newSelectedRouteHolder.mMediaRoute2Info.getId(),
+                selectedRouteHolderWithUpdatedVolumeInfo);
+        mSelectedRoute = selectedRouteHolderWithUpdatedVolumeInfo.mMediaRoute2Info;
+
+        // We only add those BT routes that we have not already obtained from audio manager (which
+        // are active).
+        mBluetoothRouteController.getAvailableBluetoothRoutes().stream()
+                .filter(it -> !mRouteIdToAvailableDeviceRoutes.containsKey(it.getId()))
+                .map(MediaRoute2InfoHolder::createForInactiveBluetoothRoute)
+                .forEach(
+                        it -> mRouteIdToAvailableDeviceRoutes.put(it.mMediaRoute2Info.getId(), it));
+    }
+
+    private MediaRoute2InfoHolder createPlaceholderBuiltinSpeakerRoute() {
+        int type = AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+        return MediaRoute2InfoHolder.createForAudioManagerRoute(
+                createMediaRoute2Info(
+                        /* routeId= */ null, type, /* productName= */ null, /* address= */ null),
+                type);
+    }
+
+    @Nullable
+    private MediaRoute2Info createMediaRoute2InfoFromAudioDeviceInfo(
+            AudioDeviceInfo audioDeviceInfo) {
+        String address = audioDeviceInfo.getAddress();
+        // Passing a null route id means we want to get the default id for the route. Generally, we
+        // only expect to pass null for non-Bluetooth routes.
+        String routeId =
+                TextUtils.isEmpty(address)
+                        ? null
+                        : mBluetoothRouteController.getRouteIdForBluetoothAddress(address);
+        return createMediaRoute2Info(
+                routeId, audioDeviceInfo.getType(), audioDeviceInfo.getProductName(), address);
+    }
+
+    /**
+     * Creates a new {@link MediaRoute2Info} using the provided information.
+     *
+     * @param routeId A route id, or null to use an id pre-defined for the given {@code type}.
+     * @param audioDeviceInfoType The type as obtained from {@link AudioDeviceInfo#getType}.
+     * @param productName The product name as obtained from {@link
+     *     AudioDeviceInfo#getProductName()}, or null to use a predefined name for the given {@code
+     *     type}.
+     * @param address The type as obtained from {@link AudioDeviceInfo#getAddress()} or {@link
+     *     BluetoothDevice#getAddress()}.
+     * @return The new {@link MediaRoute2Info}.
+     */
+    @Nullable
+    private MediaRoute2Info createMediaRoute2Info(
+            @Nullable String routeId,
+            int audioDeviceInfoType,
+            @Nullable CharSequence productName,
+            @Nullable String address) {
+        SystemRouteInfo systemRouteInfo =
+                AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.get(audioDeviceInfoType);
+        if (systemRouteInfo == null) {
+            // Device type that's intentionally unsupported for media output, like the built-in
+            // earpiece.
+            return null;
+        }
+        CharSequence humanReadableName = productName;
+        if (TextUtils.isEmpty(humanReadableName)) {
+            humanReadableName = mContext.getResources().getText(systemRouteInfo.mNameResource);
+        }
+        if (routeId == null) {
+            // The caller hasn't provided an id, so we use a pre-defined one. This happens when we
+            // are creating a non-BT route, or we are creating a BT route but a race condition
+            // caused AudioManager to expose the BT route before BluetoothAdapter, preventing us
+            // from getting an id using BluetoothRouteController#getRouteIdForBluetoothAddress.
+            routeId = systemRouteInfo.mDefaultRouteId;
+        }
+        return new MediaRoute2Info.Builder(routeId, humanReadableName)
+                .setType(systemRouteInfo.mMediaRoute2InfoType)
+                .setAddress(address)
+                .setSystemRoute(true)
+                .addFeature(FEATURE_LIVE_AUDIO)
+                .addFeature(FEATURE_LOCAL_PLAYBACK)
+                .setConnectionState(MediaRoute2Info.CONNECTION_STATE_CONNECTED)
+                .build();
+    }
+
+    /**
+     * Holds a {@link MediaRoute2Info} and associated information that we don't want to put in the
+     * {@link MediaRoute2Info} class because it's solely necessary for the implementation of this
+     * class.
+     */
+    private static class MediaRoute2InfoHolder {
+
+        public final MediaRoute2Info mMediaRoute2Info;
+        public final int mAudioDeviceInfoType;
+        public final boolean mCorrespondsToInactiveBluetoothRoute;
+
+        public static MediaRoute2InfoHolder createForAudioManagerRoute(
+                MediaRoute2Info mediaRoute2Info, int audioDeviceInfoType) {
+            return new MediaRoute2InfoHolder(
+                    mediaRoute2Info,
+                    audioDeviceInfoType,
+                    /* correspondsToInactiveBluetoothRoute= */ false);
+        }
+
+        public static MediaRoute2InfoHolder createForInactiveBluetoothRoute(
+                MediaRoute2Info mediaRoute2Info) {
+            // There's no corresponding audio device info, hence the audio device info type is
+            // unknown.
+            return new MediaRoute2InfoHolder(
+                    mediaRoute2Info,
+                    /* audioDeviceInfoType= */ AudioDeviceInfo.TYPE_UNKNOWN,
+                    /* correspondsToInactiveBluetoothRoute= */ true);
+        }
+
+        private MediaRoute2InfoHolder(
+                MediaRoute2Info mediaRoute2Info,
+                int audioDeviceInfoType,
+                boolean correspondsToInactiveBluetoothRoute) {
+            mMediaRoute2Info = mediaRoute2Info;
+            mAudioDeviceInfoType = audioDeviceInfoType;
+            mCorrespondsToInactiveBluetoothRoute = correspondsToInactiveBluetoothRoute;
+        }
+
+        public MediaRoute2InfoHolder copyWithVolumeInfoFromAudioManager(
+                AudioManager mAudioManager) {
+            MediaRoute2Info routeInfoWithVolumeInfo =
+                    new MediaRoute2Info.Builder(mMediaRoute2Info)
+                            .setVolumeHandling(
+                                    mAudioManager.isVolumeFixed()
+                                            ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
+                                            : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
+                            .setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
+                            .setVolumeMax(
+                                    mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
+                            .build();
+            return new MediaRoute2InfoHolder(
+                    routeInfoWithVolumeInfo,
+                    mAudioDeviceInfoType,
+                    mCorrespondsToInactiveBluetoothRoute);
         }
     }
 
     /**
-     * Checks if the given type is a device route.
-     *
-     * <p>Device route means a route which is either built-in or wired to the current device.
-     *
-     * @param type specifies the type of the device.
-     * @return {@code true} if the device is wired or built-in and {@code false} otherwise.
+     * Holds route information about an {@link AudioDeviceInfo#getType() audio device info type}.
      */
-    private boolean isDeviceRouteType(@MediaRoute2Info.Type int type) {
-        switch (type) {
-            case TYPE_BUILTIN_SPEAKER:
-            case TYPE_WIRED_HEADPHONES:
-            case TYPE_WIRED_HEADSET:
-            case TYPE_DOCK:
-            case TYPE_HDMI:
-            case TYPE_HDMI_ARC:
-            case TYPE_HDMI_EARC:
-            case TYPE_USB_DEVICE:
-                return true;
-            default:
-                return false;
+    private static class SystemRouteInfo {
+        /** The type to use for {@link MediaRoute2Info#getType()}. */
+        public final int mMediaRoute2InfoType;
+
+        /**
+         * Holds the route id to use if no other id is provided.
+         *
+         * <p>We only expect this id to be used for non-bluetooth routes. For bluetooth routes, in a
+         * normal scenario, the id is generated from the device information (like address, or
+         * hiSyncId), and this value is ignored. A non-normal scenario may occur when there's race
+         * condition between {@link BluetoothAdapter} and {@link AudioManager}, who are not
+         * synchronized.
+         */
+        public final String mDefaultRouteId;
+
+        /**
+         * The name to use for {@link MediaRoute2Info#getName()}.
+         *
+         * <p>Usually replaced by the UI layer with a localized string.
+         */
+        public final int mNameResource;
+
+        private SystemRouteInfo(int mediaRoute2InfoType, String defaultRouteId, int nameResource) {
+            mMediaRoute2InfoType = mediaRoute2InfoType;
+            mDefaultRouteId = defaultRouteId;
+            mNameResource = nameResource;
         }
     }
 
-    private class AudioRoutesObserver extends IAudioRoutesObserver.Stub {
-
+    private class AudioDeviceCallbackImpl extends AudioDeviceCallback {
+        @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
         @Override
-        public void dispatchAudioRoutesChanged(AudioRoutesInfo newAudioRoutes) {
-            boolean isDeviceRouteChanged;
-            MediaRoute2Info deviceRoute = createRouteFromAudioInfo(newAudioRoutes);
-
-            synchronized (AudioPoliciesDeviceRouteController.this) {
-                mDeviceRoute = deviceRoute;
-                isDeviceRouteChanged = mSelectedRoute == null;
+        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+            for (AudioDeviceInfo deviceInfo : addedDevices) {
+                if (AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.contains(deviceInfo.getType())) {
+                    // When a new valid media output is connected, we clear any routing policies so
+                    // that the default routing logic from the audio framework kicks in. As a result
+                    // of this, when the user connects a bluetooth device or a wired headset, the
+                    // new device becomes the active route, which is the traditional behavior.
+                    mAudioManager.removePreferredDeviceForStrategy(mStrategyForMedia);
+                    rebuildAvailableRoutesAndNotify();
+                    break;
+                }
             }
+        }
 
-            if (isDeviceRouteChanged) {
-                mOnDeviceRouteChangedListener.onDeviceRouteChanged();
+        @RequiresPermission(
+                anyOf = {
+                    Manifest.permission.MODIFY_AUDIO_ROUTING,
+                    Manifest.permission.QUERY_AUDIO_STATE
+                })
+        @Override
+        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+            for (AudioDeviceInfo deviceInfo : removedDevices) {
+                if (AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.contains(deviceInfo.getType())) {
+                    rebuildAvailableRoutesAndNotify();
+                    break;
+                }
             }
         }
     }
 
+    static {
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_BUILTIN_SPEAKER,
+                        /* defaultRouteId= */ "ROUTE_ID_BUILTIN_SPEAKER",
+                        /* nameResource= */ R.string.default_audio_route_name));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_WIRED_HEADSET,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_WIRED_HEADSET,
+                        /* defaultRouteId= */ "ROUTE_ID_WIRED_HEADSET",
+                        /* nameResource= */ R.string.default_audio_route_name_headphones));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_WIRED_HEADPHONES,
+                        /* defaultRouteId= */ "ROUTE_ID_WIRED_HEADPHONES",
+                        /* nameResource= */ R.string.default_audio_route_name_headphones));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_BLUETOOTH_A2DP,
+                        /* defaultRouteId= */ "ROUTE_ID_BLUETOOTH_A2DP",
+                        /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_HDMI,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_HDMI,
+                        /* defaultRouteId= */ "ROUTE_ID_HDMI",
+                        /* nameResource= */ R.string.default_audio_route_name_external_device));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_DOCK,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_DOCK,
+                        /* defaultRouteId= */ "ROUTE_ID_DOCK",
+                        /* nameResource= */ R.string.default_audio_route_name_dock_speakers));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_USB_DEVICE,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_USB_DEVICE,
+                        /* defaultRouteId= */ "ROUTE_ID_USB_DEVICE",
+                        /* nameResource= */ R.string.default_audio_route_name_usb));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_USB_HEADSET,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_USB_HEADSET,
+                        /* defaultRouteId= */ "ROUTE_ID_USB_HEADSET",
+                        /* nameResource= */ R.string.default_audio_route_name_usb));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_HDMI_ARC,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_HDMI_ARC,
+                        /* defaultRouteId= */ "ROUTE_ID_HDMI_ARC",
+                        /* nameResource= */ R.string.default_audio_route_name_external_device));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_HDMI_EARC,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_HDMI_EARC,
+                        /* defaultRouteId= */ "ROUTE_ID_HDMI_EARC",
+                        /* nameResource= */ R.string.default_audio_route_name_external_device));
+        // TODO: b/305199571 - Add a proper type constants and human readable names for AUX_LINE,
+        // LINE_ANALOG, LINE_DIGITAL, BLE_BROADCAST, BLE_SPEAKER, BLE_HEADSET, and HEARING_AID.
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_HEARING_AID,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_HEARING_AID,
+                        /* defaultRouteId= */ "ROUTE_ID_HEARING_AID",
+                        /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_BLE_HEADSET,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_BLE_HEADSET,
+                        /* defaultRouteId= */ "ROUTE_ID_BLE_HEADSET",
+                        /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_BLE_SPEAKER,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_BLE_HEADSET, // TODO: b/305199571 - Make a new type.
+                        /* defaultRouteId= */ "ROUTE_ID_BLE_SPEAKER",
+                        /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_BLE_BROADCAST,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_BLE_HEADSET,
+                        /* defaultRouteId= */ "ROUTE_ID_BLE_BROADCAST",
+                        /* nameResource= */ R.string.bluetooth_a2dp_audio_route_name));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_LINE_DIGITAL,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_UNKNOWN,
+                        /* defaultRouteId= */ "ROUTE_ID_LINE_DIGITAL",
+                        /* nameResource= */ R.string.default_audio_route_name_external_device));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_LINE_ANALOG,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_UNKNOWN,
+                        /* defaultRouteId= */ "ROUTE_ID_LINE_ANALOG",
+                        /* nameResource= */ R.string.default_audio_route_name_external_device));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_AUX_LINE,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_UNKNOWN,
+                        /* defaultRouteId= */ "ROUTE_ID_AUX_LINE",
+                        /* nameResource= */ R.string.default_audio_route_name_external_device));
+        AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
+                AudioDeviceInfo.TYPE_DOCK_ANALOG,
+                new SystemRouteInfo(
+                        MediaRoute2Info.TYPE_DOCK,
+                        /* defaultRouteId= */ "ROUTE_ID_DOCK_ANALOG",
+                        /* nameResource= */ R.string.default_audio_route_name_dock_speakers));
+    }
 }
diff --git a/services/core/java/com/android/server/media/AudioRoutingUtils.java b/services/core/java/com/android/server/media/AudioRoutingUtils.java
new file mode 100644
index 0000000..13f11eb
--- /dev/null
+++ b/services/core/java/com/android/server/media/AudioRoutingUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.audiopolicy.AudioProductStrategy;
+
+/** Holds utils related to routing in the audio framework. */
+/* package */ final class AudioRoutingUtils {
+
+    /* package */ static final AudioAttributes ATTRIBUTES_MEDIA =
+            new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
+
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+    @Nullable
+    /* package */ static AudioProductStrategy getMediaAudioProductStrategy() {
+        for (AudioProductStrategy strategy : AudioManager.getAudioProductStrategies()) {
+            if (strategy.supportsAudioAttributes(AudioRoutingUtils.ATTRIBUTES_MEDIA)) {
+                return strategy;
+            }
+        }
+        return null;
+    }
+
+    private AudioRoutingUtils() {
+        // no-op to prevent instantiation.
+    }
+}
diff --git a/services/core/java/com/android/server/media/BluetoothRouteController.java b/services/core/java/com/android/server/media/BluetoothRouteController.java
index 2b01001..74fdf6e 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteController.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteController.java
@@ -44,19 +44,11 @@
     @NonNull
     static BluetoothRouteController createInstance(@NonNull Context context,
             @NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) {
-        Objects.requireNonNull(context);
         Objects.requireNonNull(listener);
+        BluetoothAdapter btAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
 
-        BluetoothManager bluetoothManager = (BluetoothManager)
-                context.getSystemService(Context.BLUETOOTH_SERVICE);
-        BluetoothAdapter btAdapter = bluetoothManager.getAdapter();
-
-        if (btAdapter == null) {
+        if (btAdapter == null || Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
             return new NoOpBluetoothRouteController();
-        }
-
-        if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
-            return new AudioPoliciesBluetoothRouteController(context, btAdapter, listener);
         } else {
             return new LegacyBluetoothRouteController(context, btAdapter, listener);
         }
@@ -74,17 +66,6 @@
      */
     void stop();
 
-
-    /**
-     * Selects the route with the given {@code deviceAddress}.
-     *
-     * @param deviceAddress The physical address of the device to select. May be null to unselect
-     *                      the currently selected device.
-     * @return Whether the selection succeeds. If the selection fails, the state of the instance
-     * remains unaltered.
-     */
-    boolean selectRoute(@Nullable String deviceAddress);
-
     /**
      * Transfers Bluetooth output to the given route.
      *
@@ -158,12 +139,6 @@
         }
 
         @Override
-        public boolean selectRoute(String deviceAddress) {
-            // no op
-            return false;
-        }
-
-        @Override
         public void transferTo(String routeId) {
             // no op
         }
diff --git a/services/core/java/com/android/server/media/DeviceRouteController.java b/services/core/java/com/android/server/media/DeviceRouteController.java
index 0fdaaa7..9f175a9 100644
--- a/services/core/java/com/android/server/media/DeviceRouteController.java
+++ b/services/core/java/com/android/server/media/DeviceRouteController.java
@@ -16,17 +16,25 @@
 
 package com.android.server.media;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
 import android.content.Context;
 import android.media.AudioManager;
-import android.media.IAudioRoutesObserver;
 import android.media.IAudioService;
 import android.media.MediaRoute2Info;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.os.Looper;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 
 import com.android.media.flags.Flags;
 
+import java.util.List;
+
 /**
  * Controls device routes.
  *
@@ -37,46 +45,67 @@
  */
 /* package */ interface DeviceRouteController {
 
-    /**
-     * Returns a new instance of {@link DeviceRouteController}.
-     */
-    /* package */ static DeviceRouteController createInstance(@NonNull Context context,
+    /** Returns a new instance of {@link DeviceRouteController}. */
+    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+    /* package */ static DeviceRouteController createInstance(
+            @NonNull Context context,
+            @NonNull Looper looper,
             @NonNull OnDeviceRouteChangedListener onDeviceRouteChangedListener) {
         AudioManager audioManager = context.getSystemService(AudioManager.class);
-        IAudioService audioService = IAudioService.Stub.asInterface(
-                ServiceManager.getService(Context.AUDIO_SERVICE));
+        AudioProductStrategy strategyForMedia = AudioRoutingUtils.getMediaAudioProductStrategy();
 
-        if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
-            return new AudioPoliciesDeviceRouteController(context,
+        BluetoothManager bluetoothManager = context.getSystemService(BluetoothManager.class);
+        BluetoothAdapter btAdapter =
+                bluetoothManager != null ? bluetoothManager.getAdapter() : null;
+
+        // TODO: b/305199571 - Make the audio policies implementation work without the need for a
+        // bluetooth adapter or a strategy for media. If no strategy for media is available we can
+        // disallow media router transfers, and without a bluetooth adapter we can remove support
+        // for transfers to inactive bluetooth routes.
+        if (strategyForMedia != null
+                && btAdapter != null
+                && Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
+            return new AudioPoliciesDeviceRouteController(
+                    context,
                     audioManager,
-                    audioService,
+                    looper,
+                    strategyForMedia,
+                    btAdapter,
                     onDeviceRouteChangedListener);
         } else {
-            return new LegacyDeviceRouteController(context,
-                    audioManager,
-                    audioService,
-                    onDeviceRouteChangedListener);
+            IAudioService audioService =
+                    IAudioService.Stub.asInterface(
+                            ServiceManager.getService(Context.AUDIO_SERVICE));
+            return new LegacyDeviceRouteController(
+                    context, audioManager, audioService, onDeviceRouteChangedListener);
         }
     }
 
-    /**
-     * Select the route with the given built-in or wired {@link MediaRoute2Info.Type}.
-     *
-     * <p>If the type is {@code null} then unselects the route and falls back to the default device
-     * route observed from
-     * {@link com.android.server.audio.AudioService#startWatchingRoutes(IAudioRoutesObserver)}.
-     *
-     * @param type device type. May be {@code null} to unselect currently selected route.
-     * @return whether the selection succeeds. If the selection fails the state of the controller
-     * remains intact.
-     */
-    boolean selectRoute(@Nullable @MediaRoute2Info.Type Integer type);
-
     /** Returns the currently selected device (built-in or wired) route. */
     @NonNull
     MediaRoute2Info getSelectedRoute();
 
     /**
+     * Returns all available routes.
+     *
+     * <p>Note that this method returns available routes including the selected route because (a)
+     * this interface doesn't guarantee that the internal state of the controller won't change
+     * between calls to {@link #getSelectedRoute()} and this method and (b) {@link
+     * #getSelectedRoute()} may be treated as a transferable route (not a selected route) if the
+     * selected route is from {@link BluetoothRouteController}.
+     */
+    List<MediaRoute2Info> getAvailableRoutes();
+
+    /**
+     * Transfers device output to the given route.
+     *
+     * <p>If the route is {@code null} then active route will be deactivated.
+     *
+     * @param routeId to switch to or {@code null} to unset the active device.
+     */
+    void transferTo(@Nullable String routeId);
+
+    /**
      * Updates device route volume.
      *
      * @param volume specifies a volume for the device route or 0 for unknown.
@@ -85,6 +114,18 @@
     boolean updateVolume(int volume);
 
     /**
+     * Starts listening for changes in the system to keep an up to date view of available and
+     * selected devices.
+     */
+    void start(UserHandle mUser);
+
+    /**
+     * Stops keeping the internal state up to date with the system, releasing any resources acquired
+     * in {@link #start}
+     */
+    void stop();
+
+    /**
      * Interface for receiving events when device route has changed.
      */
     interface OnDeviceRouteChangedListener {
diff --git a/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java b/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java
index ba3cecf..041fceaf 100644
--- a/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java
+++ b/services/core/java/com/android/server/media/LegacyBluetoothRouteController.java
@@ -132,12 +132,6 @@
         mContext.unregisterReceiver(mDeviceStateChangedReceiver);
     }
 
-    @Override
-    public boolean selectRoute(String deviceAddress) {
-        // No-op as the class decides if a route is selected based on Bluetooth events.
-        return false;
-    }
-
     /**
      * Transfers to a given bluetooth route.
      * The dedicated BT device with the route would be activated.
diff --git a/services/core/java/com/android/server/media/LegacyDeviceRouteController.java b/services/core/java/com/android/server/media/LegacyDeviceRouteController.java
index 65874e2..c0f2834 100644
--- a/services/core/java/com/android/server/media/LegacyDeviceRouteController.java
+++ b/services/core/java/com/android/server/media/LegacyDeviceRouteController.java
@@ -35,11 +35,13 @@
 import android.media.IAudioService;
 import android.media.MediaRoute2Info;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Slog;
 
 import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -73,7 +75,6 @@
     private int mDeviceVolume;
     private MediaRoute2Info mDeviceRoute;
 
-    @VisibleForTesting
     /* package */ LegacyDeviceRouteController(@NonNull Context context,
             @NonNull AudioManager audioManager,
             @NonNull IAudioService audioService,
@@ -100,9 +101,13 @@
     }
 
     @Override
-    public boolean selectRoute(@Nullable Integer type) {
-        // No-op as the controller does not support selection from the outside of the class.
-        return false;
+    public void start(UserHandle mUser) {
+        // Nothing to do.
+    }
+
+    @Override
+    public void stop() {
+        // Nothing to do.
     }
 
     @Override
@@ -112,6 +117,17 @@
     }
 
     @Override
+    public synchronized List<MediaRoute2Info> getAvailableRoutes() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public synchronized void transferTo(@Nullable String routeId) {
+        // Unsupported. This implementation doesn't support transferable routes (always exposes a
+        // single non-bluetooth route).
+    }
+
+    @Override
     public synchronized boolean updateVolume(int volume) {
         if (mDeviceVolume == volume) {
             return false;
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index c8dba80..86d7833 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -16,15 +16,12 @@
 
 package com.android.server.media;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.media.AudioAttributes;
-import android.media.AudioDeviceAttributes;
 import android.media.AudioManager;
 import android.media.MediaRoute2Info;
 import android.media.MediaRoute2ProviderInfo;
@@ -51,7 +48,8 @@
  */
 // TODO: check thread safety. We may need to use lock to protect variables.
 class SystemMediaRoute2Provider extends MediaRoute2Provider {
-    private static final String TAG = "MR2SystemProvider";
+    // Package-visible to use this tag for all system routing logic (done across multiple classes).
+    /* package */ static final String TAG = "MR2SystemProvider";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private static final ComponentName COMPONENT_NAME = new ComponentName(
@@ -77,26 +75,6 @@
     private final AudioManagerBroadcastReceiver mAudioReceiver =
             new AudioManagerBroadcastReceiver();
 
-    private final AudioManager.OnDevicesForAttributesChangedListener
-            mOnDevicesForAttributesChangedListener =
-            new AudioManager.OnDevicesForAttributesChangedListener() {
-                @Override
-                public void onDevicesForAttributesChanged(@NonNull AudioAttributes attributes,
-                        @NonNull List<AudioDeviceAttributes> devices) {
-                    if (attributes.getUsage() != AudioAttributes.USAGE_MEDIA) {
-                        return;
-                    }
-
-                    mHandler.post(() -> {
-                        updateSelectedAudioDevice(devices);
-                        notifyProviderState();
-                        if (updateSessionInfosIfNeeded()) {
-                            notifySessionInfoUpdated();
-                        }
-                    });
-                }
-            };
-
     private final Object mRequestLock = new Object();
     @GuardedBy("mRequestLock")
     private volatile SessionCreationRequest mPendingSessionCreationRequest;
@@ -106,7 +84,8 @@
         mIsSystemRouteProvider = true;
         mContext = context;
         mUser = user;
-        mHandler = new Handler(Looper.getMainLooper());
+        Looper looper = Looper.getMainLooper();
+        mHandler = new Handler(looper);
 
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
 
@@ -123,25 +102,15 @@
         mDeviceRouteController =
                 DeviceRouteController.createInstance(
                         context,
-                        () -> {
-                            mHandler.post(
-                                    () -> {
-                                        publishProviderState();
-                                        if (updateSessionInfosIfNeeded()) {
-                                            notifySessionInfoUpdated();
-                                        }
-                                    });
-                        });
-
-        mAudioManager.addOnDevicesForAttributesChangedListener(
-                AudioAttributesUtils.ATTRIBUTES_MEDIA, mContext.getMainExecutor(),
-                mOnDevicesForAttributesChangedListener);
-
-        // These methods below should be called after all fields are initialized, as they
-        // access the fields inside.
-        List<AudioDeviceAttributes> devices =
-                mAudioManager.getDevicesForAttributes(AudioAttributesUtils.ATTRIBUTES_MEDIA);
-        updateSelectedAudioDevice(devices);
+                        looper,
+                        () ->
+                                mHandler.post(
+                                        () -> {
+                                            publishProviderState();
+                                            if (updateSessionInfosIfNeeded()) {
+                                                notifySessionInfoUpdated();
+                                            }
+                                        }));
         updateProviderState();
         updateSessionInfosIfNeeded();
     }
@@ -151,20 +120,21 @@
         intentFilter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
         mContext.registerReceiverAsUser(mAudioReceiver, mUser,
                 intentFilter, null, null);
-
-        mHandler.post(() -> {
-            mBluetoothRouteController.start(mUser);
-            notifyProviderState();
-        });
-        updateVolume();
+        mHandler.post(
+                () -> {
+                    mDeviceRouteController.start(mUser);
+                    mBluetoothRouteController.start(mUser);
+                });
     }
 
     public void stop() {
         mContext.unregisterReceiver(mAudioReceiver);
-        mHandler.post(() -> {
-            mBluetoothRouteController.stop();
-            notifyProviderState();
-        });
+        mHandler.post(
+                () -> {
+                    mBluetoothRouteController.stop();
+                    mDeviceRouteController.stop();
+                    notifyProviderState();
+                });
     }
 
     @Override
@@ -225,13 +195,26 @@
     public void transferToRoute(long requestId, String sessionId, String routeId) {
         if (TextUtils.equals(routeId, MediaRoute2Info.ROUTE_ID_DEFAULT)) {
             // The currently selected route is the default route.
+            Log.w(TAG, "Ignoring transfer to " + MediaRoute2Info.ROUTE_ID_DEFAULT);
             return;
         }
-
         MediaRoute2Info selectedDeviceRoute = mDeviceRouteController.getSelectedRoute();
-        if (TextUtils.equals(routeId, selectedDeviceRoute.getId())) {
+        boolean isAvailableDeviceRoute =
+                mDeviceRouteController.getAvailableRoutes().stream()
+                        .anyMatch(it -> it.getId().equals(routeId));
+        boolean isSelectedDeviceRoute = TextUtils.equals(routeId, selectedDeviceRoute.getId());
+
+        if (isSelectedDeviceRoute || isAvailableDeviceRoute) {
+            // The requested route is managed by the device route controller. Note that the selected
+            // device route doesn't necessarily match mSelectedRouteId (which is the selected route
+            // of the routing session). If the selected device route is transferred to, we need to
+            // make the bluetooth routes inactive so that the device route becomes the selected
+            // route of the routing session.
+            mDeviceRouteController.transferTo(routeId);
             mBluetoothRouteController.transferTo(null);
         } else {
+            // The requested route is managed by the bluetooth route controller.
+            mDeviceRouteController.transferTo(null);
             mBluetoothRouteController.transferTo(routeId);
         }
     }
@@ -280,41 +263,38 @@
 
             MediaRoute2Info selectedDeviceRoute = mDeviceRouteController.getSelectedRoute();
 
-            RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
-                    SYSTEM_SESSION_ID, packageName).setSystemSession(true);
+            RoutingSessionInfo.Builder builder =
+                    new RoutingSessionInfo.Builder(SYSTEM_SESSION_ID, packageName)
+                            .setSystemSession(true);
             builder.addSelectedRoute(selectedDeviceRoute.getId());
             for (MediaRoute2Info route : mBluetoothRouteController.getAllBluetoothRoutes()) {
                 builder.addTransferableRoute(route.getId());
             }
+
+            if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
+                for (MediaRoute2Info route : mDeviceRouteController.getAvailableRoutes()) {
+                    if (!TextUtils.equals(selectedDeviceRoute.getId(), route.getId())) {
+                        builder.addTransferableRoute(route.getId());
+                    }
+                }
+            }
             return builder.setProviderId(mUniqueId).build();
         }
     }
 
-    private void updateSelectedAudioDevice(@NonNull List<AudioDeviceAttributes> devices) {
-        if (devices.isEmpty()) {
-            Slog.w(TAG, "The list of preferred devices was empty.");
-            return;
-        }
-
-        AudioDeviceAttributes audioDeviceAttributes = devices.get(0);
-
-        if (AudioAttributesUtils.isDeviceOutputAttributes(audioDeviceAttributes)) {
-            mDeviceRouteController.selectRoute(
-                    AudioAttributesUtils.mapToMediaRouteType(audioDeviceAttributes));
-            mBluetoothRouteController.selectRoute(null);
-        } else if (AudioAttributesUtils.isBluetoothOutputAttributes(audioDeviceAttributes)) {
-            mDeviceRouteController.selectRoute(null);
-            mBluetoothRouteController.selectRoute(audioDeviceAttributes.getAddress());
-        } else {
-            Slog.w(TAG, "Unknown audio attributes: " + audioDeviceAttributes);
-        }
-    }
-
     private void updateProviderState() {
         MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
 
         // We must have a device route in the provider info.
-        builder.addRoute(mDeviceRouteController.getSelectedRoute());
+        if (Flags.enableAudioPoliciesDeviceAndBluetoothController()) {
+            List<MediaRoute2Info> deviceRoutes = mDeviceRouteController.getAvailableRoutes();
+            for (MediaRoute2Info route : deviceRoutes) {
+                builder.addRoute(route);
+            }
+            setProviderState(builder.build());
+        } else {
+            builder.addRoute(mDeviceRouteController.getSelectedRoute());
+        }
 
         for (MediaRoute2Info route : mBluetoothRouteController.getAllBluetoothRoutes()) {
             builder.addRoute(route);
@@ -352,7 +332,12 @@
                             .setProviderId(mUniqueId)
                             .build();
             builder.addSelectedRoute(mSelectedRouteId);
-
+            for (MediaRoute2Info route : mDeviceRouteController.getAvailableRoutes()) {
+                String routeId = route.getId();
+                if (!mSelectedRouteId.equals(routeId)) {
+                    builder.addTransferableRoute(routeId);
+                }
+            }
             for (MediaRoute2Info route : mBluetoothRouteController.getTransferableRoutes()) {
                 builder.addTransferableRoute(route.getId());
             }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index aa0b9b8..3c6887c1 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -26,6 +26,7 @@
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
 import static android.app.Notification.FLAG_INSISTENT;
+import static android.app.Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
 import static android.app.Notification.FLAG_NO_CLEAR;
 import static android.app.Notification.FLAG_NO_DISMISS;
 import static android.app.Notification.FLAG_ONGOING_EVENT;
@@ -58,6 +59,7 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
+import static android.app.Flags.lifetimeExtensionRefactor;
 import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
 import static android.content.Context.BIND_AUTO_CREATE;
 import static android.content.Context.BIND_FOREGROUND_SERVICE;
@@ -1224,7 +1226,7 @@
         public void onClearAll(int callingUid, int callingPid, int userId) {
             synchronized (mNotificationLock) {
                 cancelAllLocked(callingUid, callingPid, userId, REASON_CANCEL_ALL, null,
-                        /*includeCurrentProfiles*/ true);
+                        /*includeCurrentProfiles*/ true, FLAG_ONGOING_EVENT | FLAG_NO_CLEAR);
             }
         }
 
@@ -1498,6 +1500,7 @@
             synchronized (mNotificationLock) {
                 NotificationRecord r = mNotificationsByKey.get(key);
                 if (r != null) {
+                    r.recordSmartReplied();
                     LogMaker logMaker = r.getLogMaker()
                             .setCategory(MetricsEvent.SMART_REPLY_ACTION)
                             .setSubtype(replyIndex)
@@ -1804,11 +1807,22 @@
                     record = findNotificationByKeyLocked(intent.getStringExtra(EXTRA_KEY));
                 }
                 if (record != null) {
-                    cancelNotification(record.getSbn().getUid(), record.getSbn().getInitialPid(),
-                            record.getSbn().getPackageName(), record.getSbn().getTag(),
-                            record.getSbn().getId(), 0,
-                            FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB,
-                            true, record.getUserId(), REASON_TIMEOUT, null);
+                    if (lifetimeExtensionRefactor()) {
+                        cancelNotification(record.getSbn().getUid(),
+                                record.getSbn().getInitialPid(),
+                                record.getSbn().getPackageName(), record.getSbn().getTag(),
+                                record.getSbn().getId(), 0,
+                                FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB
+                                        | FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY,
+                                true, record.getUserId(), REASON_TIMEOUT, null);
+                    } else {
+                        cancelNotification(record.getSbn().getUid(),
+                                record.getSbn().getInitialPid(),
+                                record.getSbn().getPackageName(), record.getSbn().getTag(),
+                                record.getSbn().getId(), 0,
+                                FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB,
+                                true, record.getUserId(), REASON_TIMEOUT, null);
+                    }
                 }
             }
         }
@@ -3728,8 +3742,16 @@
         @Override
         public void cancelNotificationWithTag(String pkg, String opPkg, String tag, int id,
                 int userId) {
+            // Don't allow client applications to cancel foreground service notifs, user-initiated
+            // job notifs, autobundled summaries, or notifs that have been replied to.
+            int mustNotHaveFlags = isCallingUidSystem() ? 0 :
+                    (FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB | FLAG_AUTOGROUP_SUMMARY);
+            if (lifetimeExtensionRefactor()) {
+                mustNotHaveFlags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+            }
+
             cancelNotificationInternal(pkg, opPkg, Binder.getCallingUid(), Binder.getCallingPid(),
-                    tag, id, userId);
+                    tag, id, userId, mustNotHaveFlags);
         }
 
         @Override
@@ -3740,9 +3762,16 @@
                     Binder.getCallingUid(), userId, true, false, "cancelAllNotifications", pkg);
 
             // Don't allow the app to cancel active FGS or UIJ notifications
-            cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
-                    pkg, null, 0, FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB,
-                    userId, REASON_APP_CANCEL_ALL);
+            if (lifetimeExtensionRefactor()) {
+                cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
+                        pkg, null, 0, FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB
+                                | FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY,
+                        userId, REASON_APP_CANCEL_ALL);
+            } else {
+                cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
+                        pkg, null, 0, FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB,
+                        userId, REASON_APP_CANCEL_ALL);
+            }
         }
 
         @Override
@@ -4808,8 +4837,16 @@
                                     r.getSbn().getId(), userId, reason);
                         }
                     } else {
-                        cancelAllLocked(callingUid, callingPid, info.userid,
-                                REASON_LISTENER_CANCEL_ALL, info, info.supportsProfiles());
+                        if (lifetimeExtensionRefactor()) {
+                            cancelAllLocked(callingUid, callingPid, info.userid,
+                                    REASON_LISTENER_CANCEL_ALL, info, info.supportsProfiles(),
+                                    FLAG_ONGOING_EVENT | FLAG_NO_CLEAR
+                                            | FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY);
+                        } else {
+                            cancelAllLocked(callingUid, callingPid, info.userid,
+                                    REASON_LISTENER_CANCEL_ALL, info, info.supportsProfiles(),
+                                    FLAG_ONGOING_EVENT | FLAG_NO_CLEAR);
+                        }
                     }
                 }
             } finally {
@@ -4923,6 +4960,9 @@
                 int callingUid, int callingPid, String pkg, String tag, int id, int userId,
                 int reason) {
             int mustNotHaveFlags = FLAG_ONGOING_EVENT;
+            if (lifetimeExtensionRefactor()) {
+                mustNotHaveFlags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+            }
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0 /* mustHaveFlags */,
                     mustNotHaveFlags,
                     true,
@@ -6712,7 +6752,12 @@
         @Override
         public void cancelNotification(String pkg, String opPkg, int callingUid, int callingPid,
                 String tag, int id, int userId) {
-            cancelNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, userId);
+            // Don't allow client applications to cancel foreground service notifs,
+            // user-initiated job notifs or autobundled summaries.
+            final int mustNotHaveFlags = isCallingUidSystem() ? 0 :
+                    (FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB | FLAG_AUTOGROUP_SUMMARY);
+            cancelNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, userId,
+                    mustNotHaveFlags);
         }
 
         @Override
@@ -6907,7 +6952,7 @@
     }
 
     void cancelNotificationInternal(String pkg, String opPkg, int callingUid, int callingPid,
-            String tag, int id, int userId) {
+            String tag, int id, int userId, int mustNotHaveFlags) {
         userId = ActivityManager.handleIncomingUser(callingPid,
                 callingUid, userId, true, false, "cancelNotificationWithTag", pkg);
 
@@ -6935,10 +6980,6 @@
             }
         }
 
-        // Don't allow client applications to cancel foreground service notifs, user-initiated job
-        // notifs or autobundled summaries.
-        final int mustNotHaveFlags = isCallingUidSystem() ? 0 :
-                (FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB | FLAG_AUTOGROUP_SUMMARY);
         cancelNotification(uid, callingPid, pkg, tag, id, 0,
                 mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null);
     }
@@ -7294,6 +7335,11 @@
 
         notification.flags &= ~FLAG_FSI_REQUESTED_BUT_DENIED;
 
+        // Apps should not create notifications that are lifetime extended.
+        if (lifetimeExtensionRefactor()) {
+            notification.flags &= ~FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+        }
+
         if (notification.fullScreenIntent != null) {
             final AttributionSource attributionSource =
                     new AttributionSource.Builder(notificationUid).setPackageName(pkg).build();
@@ -10088,7 +10134,7 @@
 
     @GuardedBy("mNotificationLock")
     void cancelAllLocked(int callingUid, int callingPid, int userId, int reason,
-            ManagedServiceInfo listener, boolean includeCurrentProfiles) {
+            ManagedServiceInfo listener, boolean includeCurrentProfiles, int mustNotHaveFlags) {
         final long cancellationElapsedTimeMs = SystemClock.elapsedRealtime();
         mHandler.post(new Runnable() {
             @Override
@@ -10100,7 +10146,7 @@
                             null, userId, 0, 0, reason, listenerName);
 
                     FlagChecker flagChecker = (int flags) -> {
-                        int flagsToCheck = FLAG_ONGOING_EVENT | FLAG_NO_CLEAR;
+                        int flagsToCheck = mustNotHaveFlags;
                         if (REASON_LISTENER_CANCEL_ALL == reason
                                 || REASON_CANCEL_ALL == reason) {
                             flagsToCheck |= FLAG_BUBBLE;
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 100c638..64d3a20 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -24,7 +24,9 @@
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
 
+import android.annotation.FlaggedApi;
 import android.annotation.Nullable;
+import android.app.Flags;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -1257,10 +1259,27 @@
         mStats.setExpanded();
     }
 
+    /** Run when the notification is direct replied. */
     public void recordDirectReplied() {
+        if (Flags.lifetimeExtensionRefactor()) {
+            // Mark the NotificationRecord as lifetime extended.
+            Notification notification = getSbn().getNotification();
+            notification.flags |= Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+        }
+
         mStats.setDirectReplied();
     }
 
+
+    /** Run when the notification is smart replied. */
+    @FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR)
+    public void recordSmartReplied() {
+        Notification notification = getSbn().getNotification();
+        notification.flags |= Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+
+        mStats.setSmartReplied();
+    }
+
     public void recordDismissalSurface(@NotificationStats.DismissalSurface int surface) {
         mStats.setDismissalSurface(surface);
     }
diff --git a/services/core/java/com/android/server/pdb/TEST_MAPPING b/services/core/java/com/android/server/pdb/TEST_MAPPING
new file mode 100644
index 0000000..e5f154a
--- /dev/null
+++ b/services/core/java/com/android/server/pdb/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+    "postsubmit": [
+        {
+            "name": " PersistentDataBlockServiceTest"
+        }
+    ]
+}
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 3b3d79e..07e0ddf 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -357,6 +357,12 @@
         final DeletePackageAction action;
         synchronized (mPm.mLock) {
             final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
+            if (ps == null) {
+                if (DEBUG_REMOVE) {
+                    Slog.d(TAG, "Attempted to remove non-existent package " + packageName);
+                }
+                return false;
+            }
             final PackageSetting disabledPs = mPm.mSettings.getDisabledSystemPkgLPr(ps);
             if (PackageManagerServiceUtils.isSystemApp(ps)
                     && mPm.checkPermission(CONTROL_KEYGUARD, packageName, UserHandle.USER_SYSTEM)
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 448f215..ba2cf1d 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -2861,10 +2861,11 @@
                     ? request.getRemovedInfo().mArgs : null;
             if (args != null) {
                 if (!killApp) {
-                    // If we didn't kill the app, defer the deletion of code/resource files, since
-                    // they may still be in use by the running application. This mitigates problems
-                    // in cases where resources or code is loaded by a new Activity before
-                    // ApplicationInfo changes have propagated to all application threads.
+                    // If we didn't kill the app, defer the deletion of code/resource files,
+                    // since the old code/resource files may still be in use by the running
+                    // application. This mitigates problems and cases where resources or
+                    // code is loaded by a new Activity before ApplicationInfo changes have
+                    // propagated to all application threads.
                     mPm.scheduleDeferredNoKillPostDelete(args);
                 } else {
                     mRemovePackageHelper.cleanUpResources(args.mCodeFile, args.mInstructionSets);
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index 0a81b2b..5494bd9 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -539,6 +539,12 @@
     }
 
     @Nullable
+    public PackageSetting getScanRequestDisabledPackageSetting() {
+        assertScanResultExists();
+        return mScanResult.mRequest.mDisabledPkgSetting;
+    }
+
+    @Nullable
     public String getRealPackageName() {
         assertScanResultExists();
         return mScanResult.mRequest.mRealPkgName;
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index c6e8a64..fb311da 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -116,7 +116,8 @@
 
     private static final String ARCHIVE_ICONS_DIR = "package_archiver";
 
-    private static final String ACTION_UNARCHIVE_DIALOG = "android.intent.action.UNARCHIVE_DIALOG";
+    private static final String ACTION_UNARCHIVE_DIALOG =
+            "com.android.intent.action.UNARCHIVE_DIALOG";
 
     private final Context mContext;
     private final PackageManagerService mPm;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 233bf4f..adb6906 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -523,6 +523,9 @@
     private static final String PROPERTY_IS_UPDATE_OWNERSHIP_ENFORCEMENT_AVAILABLE =
             "is_update_ownership_enforcement_available";
 
+    private static final String PROPERTY_DEFERRED_NO_KILL_POST_DELETE_DELAY_MS_EXTENDED =
+            "deferred_no_kill_post_delete_delay_ms_extended";
+
     /**
      * The default response for package verification timeout.
      *
@@ -924,7 +927,11 @@
 
     static final int WRITE_USER_PACKAGE_RESTRICTIONS = 30;
 
-    static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
+    private static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
+
+    private static final long DEFERRED_NO_KILL_POST_DELETE_DELAY_MS_EXTENDED =
+            TimeUnit.DAYS.toMillis(1);
+
     private static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
     private static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS = 1000;
 
@@ -1288,7 +1295,19 @@
 
     void scheduleDeferredNoKillPostDelete(InstallArgs args) {
         Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_POST_DELETE, args);
-        mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_POST_DELETE_DELAY_MS);
+        // If the feature flag is on, retain the old files for a day. Otherwise, delete the old
+        // files after a few seconds.
+        long deleteDelayMillis = DEFERRED_NO_KILL_POST_DELETE_DELAY_MS;
+        if (Flags.improveInstallDontKill()) {
+            deleteDelayMillis = Binder.withCleanCallingIdentity(() -> {
+                return DeviceConfig.getLong(NAMESPACE_PACKAGE_MANAGER_SERVICE,
+                        /* name= */ PROPERTY_DEFERRED_NO_KILL_POST_DELETE_DELAY_MS_EXTENDED,
+                        /* defaultValue= */ DEFERRED_NO_KILL_POST_DELETE_DELAY_MS_EXTENDED);
+            });
+            Slog.w(TAG, "Delaying the deletion of <" + args.getCodePath() + "> by "
+                    + deleteDelayMillis + "ms or till the next reboot");
+        }
+        mHandler.sendMessageDelayed(message, deleteDelayMillis);
     }
 
     void schedulePruneUnusedStaticSharedLibraries(boolean delay) {
diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
index d0fdfa9..9384c13 100644
--- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
+++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
@@ -856,9 +856,9 @@
         // We may not yet have disabled the updated package yet, so be sure to grab the
         // current setting if that's the case.
         final PackageSetting updatedSystemPs = isUpdatedSystemApp
-                ? installRequest.getDisabledPackageSetting() == null
+                ? installRequest.getScanRequestDisabledPackageSetting() == null
                 ? installRequest.getScanRequestOldPackageSetting()
-                : installRequest.getDisabledPackageSetting()
+                : installRequest.getScanRequestDisabledPackageSetting()
                 : null;
         if (isUpdatedSystemApp && (updatedSystemPs.getPkg() == null
                 || updatedSystemPs.getPkg().getLibraryNames() == null)) {
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 6d58d34..8adb566 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -23,10 +23,10 @@
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.RecoverySystem;
-import android.os.storage.StorageManager;
-import android.os.storage.VolumeInfo;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -35,6 +35,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.utils.Slogf;
 
 import java.io.File;
 import java.io.IOException;
@@ -43,7 +44,6 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
-import java.util.Set;
 
 /**
  * Helper class for preparing and destroying user storage
@@ -65,31 +65,37 @@
     /**
      * Prepare storage areas for given user on all mounted devices.
      */
-    void prepareUserData(int userId, int userSerial, int flags) {
+    void prepareUserData(UserInfo userInfo, int flags) {
         synchronized (mInstallLock) {
             final StorageManager storage = mContext.getSystemService(StorageManager.class);
             /*
              * Internal storage must be prepared before adoptable storage, since the user's volume
              * keys are stored in their internal storage.
              */
-            prepareUserDataLI(null /* internal storage */, userId, userSerial, flags, true);
+            prepareUserDataLI(null /* internal storage */, userInfo, flags, true);
             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
                 final String volumeUuid = vol.getFsUuid();
                 if (volumeUuid != null) {
-                    prepareUserDataLI(volumeUuid, userId, userSerial, flags, true);
+                    prepareUserDataLI(volumeUuid, userInfo, flags, true);
                 }
             }
         }
     }
 
-    private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags,
+    private void prepareUserDataLI(String volumeUuid, UserInfo userInfo, int flags,
             boolean allowRecover) {
-        // Prepare storage and verify that serial numbers are consistent; if
-        // there's a mismatch we need to destroy to avoid leaking data
+        final int userId = userInfo.id;
+        final int userSerial = userInfo.serialNumber;
         final StorageManager storage = mContext.getSystemService(StorageManager.class);
+        final boolean isNewUser = userInfo.lastLoggedInTime == 0;
+        Slogf.d(TAG, "Preparing user data; volumeUuid=%s, userId=%d, flags=0x%x, isNewUser=%s",
+                volumeUuid, userId, flags, isNewUser);
         try {
+            // Prepare CE and/or DE storage.
             storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
 
+            // Ensure that the data directories of a removed user with the same ID are not being
+            // reused.  New users must get fresh data directories, to avoid leaking data.
             if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
                 enforceSerialNumber(getDataUserDeDirectory(volumeUuid, userId), userSerial);
                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
@@ -103,9 +109,10 @@
                 }
             }
 
+            // Prepare the app data directories.
             mInstaller.createUserData(volumeUuid, userId, userSerial, flags);
 
-            // CE storage is available after they are prepared.
+            // If applicable, record that the system user's CE storage has been prepared.
             if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 &&
                     (userId == UserHandle.USER_SYSTEM)) {
                 String propertyName = "sys.user." + userId + ".ce_available";
@@ -113,20 +120,31 @@
                 SystemProperties.set(propertyName, "true");
             }
         } catch (Exception e) {
-            logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid
-                    + " because we failed to prepare: " + e);
-            destroyUserDataLI(volumeUuid, userId, flags);
-
+            // Failed to prepare user data.  For new users, specifically users that haven't ever
+            // been unlocked, destroy the user data, and try again (if not already retried).  This
+            // might be effective at resolving some errors, such as stale directories from a reused
+            // user ID.  Don't auto-destroy data for existing users, since issues with existing
+            // users might be fixable via an OTA without having to wipe the user's data.
+            if (isNewUser) {
+                logCriticalInfo(Log.ERROR, "Destroying user " + userId + " on volume " + volumeUuid
+                        + " because we failed to prepare: " + e);
+                destroyUserDataLI(volumeUuid, userId, flags);
+            } else {
+                logCriticalInfo(Log.ERROR, "Failed to prepare user " + userId + " on volume "
+                        + volumeUuid + ": " + e);
+            }
             if (allowRecover) {
                 // Try one last time; if we fail again we're really in trouble
-                prepareUserDataLI(volumeUuid, userId, userSerial,
-                    flags | StorageManager.FLAG_STORAGE_DE, false);
+                prepareUserDataLI(volumeUuid, userInfo, flags | StorageManager.FLAG_STORAGE_DE,
+                        false);
             } else {
+                // If internal storage of the system user fails to prepare on first boot, then
+                // things are *really* broken, so we might as well reboot to recovery right away.
                 try {
                     Log.wtf(TAG, "prepareUserData failed for user " + userId, e);
-                    if (userId == UserHandle.USER_SYSTEM) {
+                    if (isNewUser && userId == UserHandle.USER_SYSTEM && volumeUuid == null) {
                         RecoverySystem.rebootPromptAndWipeUserData(mContext,
-                                "prepareUserData failed for system user");
+                                "failed to prepare internal storage for system user");
                     }
                 } catch (IOException e2) {
                     throw new RuntimeException("error rebooting into recovery", e2);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index f90bf4b..1393121 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1566,6 +1566,7 @@
                 : now - userData.info.creationTime);
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.REQUEST_QUIET_MODE_ENABLED)
+                .setInt(UserJourneyLogger.getUserTypeForStatsd(userData.info.userType))
                 .setStrings(callingPackage)
                 .setBoolean(enableQuietMode)
                 .setTimePeriod(period)
@@ -5123,8 +5124,7 @@
             // unlocked.  We do this to ensure that CE storage isn't prepared before the CE key is
             // saved to disk.  This also matches what is done for user 0.
             t.traceBegin("prepareUserData");
-            mUserDataPreparer.prepareUserData(userId, userInfo.serialNumber,
-                    StorageManager.FLAG_STORAGE_DE);
+            mUserDataPreparer.prepareUserData(userInfo, StorageManager.FLAG_STORAGE_DE);
             t.traceEnd();
 
             t.traceBegin("LSS.createNewUser");
@@ -6386,12 +6386,11 @@
         }
         TimingsTraceAndSlog t = new TimingsTraceAndSlog();
         t.traceBegin("onBeforeStartUser-" + userId);
-        final int userSerial = userInfo.serialNumber;
         // Migrate only if build fingerprints mismatch
         boolean migrateAppsData = !PackagePartitions.FINGERPRINT.equals(
                 userInfo.lastLoggedInFingerprint);
         t.traceBegin("prepareUserData");
-        mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE);
+        mUserDataPreparer.prepareUserData(userInfo, StorageManager.FLAG_STORAGE_DE);
         t.traceEnd();
         t.traceBegin("reconcileAppsData");
         getPackageManagerInternal().reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE,
@@ -6417,14 +6416,13 @@
         if (userInfo == null) {
             return;
         }
-        final int userSerial = userInfo.serialNumber;
         // Migrate only if build fingerprints mismatch
         boolean migrateAppsData = !PackagePartitions.FINGERPRINT.equals(
                 userInfo.lastLoggedInFingerprint);
 
         final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
         t.traceBegin("prepareUserData-" + userId);
-        mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE);
+        mUserDataPreparer.prepareUserData(userInfo, StorageManager.FLAG_STORAGE_CE);
         t.traceEnd();
 
         StorageManagerInternal smInternal = LocalServices.getService(StorageManagerInternal.class);
diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
index d0c346a..57f4a5d 100644
--- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
+++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
@@ -337,7 +337,8 @@
                     0, // deprecated, used to be durationIncludingSleepMs
                     0, // optimizedPackagesCount
                     0, // packagesDependingOnBootClasspathCount
-                    0); // totalPackagesCount
+                    0, // totalPackagesCount
+                    ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__PASS__PASS_UNKNOWN);
         }
     }
 }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 73c4224..30bce2f4 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -22,6 +22,9 @@
 import static android.app.AppOpsManager.OP_CREATE_ACCESSIBILITY_OVERLAY;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
 import static android.app.AppOpsManager.OP_TOAST_WINDOW;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
 import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
@@ -563,6 +566,7 @@
     int mShortPressOnWindowBehavior;
     int mPowerVolUpBehavior;
     boolean mStylusButtonsEnabled = true;
+    boolean mKidsModeEnabled;
     boolean mHasSoftInput = false;
     boolean mUseTvRouting;
     boolean mAllowStartActivityForLongPressOnPowerDuringSetup;
@@ -887,6 +891,9 @@
             resolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.STYLUS_BUTTONS_ENABLED), false, this,
                     UserHandle.USER_ALL);
+            resolver.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.NAV_BAR_KIDS_MODE), false, this,
+                    UserHandle.USER_ALL);
             updateSettings();
         }
 
@@ -2964,12 +2971,44 @@
             mStylusButtonsEnabled = Settings.Secure.getIntForUser(resolver,
                     Secure.STYLUS_BUTTONS_ENABLED, 1, UserHandle.USER_CURRENT) == 1;
             mInputManagerInternal.setStylusButtonMotionEventsEnabled(mStylusButtonsEnabled);
+
+            final boolean kidsModeEnabled = Settings.Secure.getIntForUser(resolver,
+                    Settings.Secure.NAV_BAR_KIDS_MODE, 0, UserHandle.USER_CURRENT) == 1;
+            if (mKidsModeEnabled != kidsModeEnabled) {
+                mKidsModeEnabled = kidsModeEnabled;
+                updateKidsModeSettings();
+            }
         }
         if (updateRotation) {
             updateRotation(true);
         }
     }
 
+    private void updateKidsModeSettings() {
+        if (mKidsModeEnabled) {
+            // Needed since many Kids apps aren't optimised to support both orientations and it
+            // will be hard for kids to understand the app compat mode.
+            // TODO(229961548): Remove ignoreOrientationRequest exception for Kids Mode once
+            //                  possible.
+            if (mContext.getResources().getBoolean(R.bool.config_reverseDefaultRotation)) {
+                mWindowManagerInternal.setOrientationRequestPolicy(
+                        true /* isIgnoreOrientationRequestDisabled */,
+                        new int[]{SCREEN_ORIENTATION_LANDSCAPE,
+                                SCREEN_ORIENTATION_REVERSE_LANDSCAPE},
+                        new int[]{SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
+                                SCREEN_ORIENTATION_SENSOR_LANDSCAPE});
+            } else {
+                mWindowManagerInternal.setOrientationRequestPolicy(
+                        true /* isIgnoreOrientationRequestDisabled */,
+                        null /* fromOrientations */, null /* toOrientations */);
+            }
+        } else {
+            mWindowManagerInternal.setOrientationRequestPolicy(
+                    false /* isIgnoreOrientationRequestDisabled */,
+                    null /* fromOrientations */, null /* toOrientations */);
+        }
+    }
+
     private DreamManagerInternal getDreamManagerInternal() {
         if (mDreamManagerInternal == null) {
             // If mDreamManagerInternal is null, attempt to re-fetch it.
@@ -3433,7 +3472,7 @@
                 }
                 break;
             case KeyEvent.KEYCODE_DEL:
-            case KeyEvent.KEYCODE_GRAVE:
+            case KeyEvent.KEYCODE_ESCAPE:
                 if (firstDown && event.isMetaPressed()) {
                     logKeyboardSystemsEvent(event, KeyboardLogEvent.BACK);
                     injectBackGesture(event.getDownTime());
@@ -3638,15 +3677,6 @@
                     return true;
                 }
                 break;
-            case KeyEvent.KEYCODE_SPACE:
-                // Handle keyboard layout switching. (META + SPACE)
-                if (firstDown && event.isMetaPressed()) {
-                    int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
-                    sendSwitchKeyboardLayout(event, direction);
-                    logKeyboardSystemsEvent(event, KeyboardLogEvent.LANGUAGE_SWITCH);
-                    return true;
-                }
-                break;
             case KeyEvent.KEYCODE_META_LEFT:
             case KeyEvent.KEYCODE_META_RIGHT:
                 if (down) {
@@ -3941,7 +3971,9 @@
                 }
                 return true;
             case KeyEvent.KEYCODE_ESCAPE:
-                if (down && repeatCount == 0) {
+                if (down
+                        && KeyEvent.metaStateHasNoModifiers(metaState)
+                        && repeatCount == 0) {
                     mContext.closeSystemDialogs();
                 }
                 return true;
@@ -6430,6 +6462,7 @@
                 pw.print(!mAllowLockscreenWhenOnDisplays.isEmpty());
                 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
                 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
+        pw.print(prefix); pw.print("mKidsModeEnabled="); pw.println(mKidsModeEnabled);
 
         mHapticFeedbackVibrationProvider.dump(prefix, pw);
         mGlobalKeyManager.dump(prefix, pw);
diff --git a/services/core/java/com/android/server/power/LowPowerStandbyController.java b/services/core/java/com/android/server/power/LowPowerStandbyController.java
index fbad762..fa94b43 100644
--- a/services/core/java/com/android/server/power/LowPowerStandbyController.java
+++ b/services/core/java/com/android/server/power/LowPowerStandbyController.java
@@ -33,6 +33,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
@@ -146,6 +147,7 @@
             this::onStandbyTimeoutExpired;
     private final LowPowerStandbyControllerInternal mLocalService = new LocalService();
     private final SparseIntArray mUidAllowedReasons = new SparseIntArray();
+    private final List<String> mLowPowerStandbyManagingPackages = new ArrayList<>();
     private final List<StandbyPortsLock> mStandbyPortLocks = new ArrayList<>();
 
     @GuardedBy("mLock")
@@ -370,6 +372,14 @@
                 return;
             }
 
+            List<PackageInfo> manageLowPowerStandbyPackages = mContext.getPackageManager()
+                    .getPackagesHoldingPermissions(new String[]{
+                            Manifest.permission.MANAGE_LOW_POWER_STANDBY
+                    }, PackageManager.MATCH_SYSTEM_ONLY);
+            for (PackageInfo packageInfo : manageLowPowerStandbyPackages) {
+                mLowPowerStandbyManagingPackages.add(packageInfo.packageName);
+            }
+
             mAlarmManager = mContext.getSystemService(AlarmManager.class);
             mPowerManager = mContext.getSystemService(PowerManager.class);
             mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
@@ -756,9 +766,7 @@
             Slog.d(TAG, "notifyEnabledChangedLocked, mIsEnabled=" + mIsEnabled);
         }
 
-        final Intent intent = new Intent(PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+        sendExplicitBroadcast(PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
     }
 
     @GuardedBy("mLock")
@@ -772,10 +780,7 @@
             Slog.d(TAG, "notifyPolicyChanged, policy=" + policy);
         }
 
-        final Intent intent = new Intent(
-                PowerManager.ACTION_LOW_POWER_STANDBY_POLICY_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+        sendExplicitBroadcast(PowerManager.ACTION_LOW_POWER_STANDBY_POLICY_CHANGED);
     }
 
     private void onStandbyTimeoutExpired() {
@@ -787,6 +792,22 @@
         }
     }
 
+    private void sendExplicitBroadcast(String intentType) {
+        final Intent intent = new Intent(intentType);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+
+        // Send explicit broadcast to holders of MANAGE_LOW_POWER_STANDBY
+        final Intent privilegedIntent = new Intent(intentType);
+        privilegedIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        for (String packageName : mLowPowerStandbyManagingPackages) {
+            final Intent explicitIntent = new Intent(privilegedIntent);
+            explicitIntent.setPackage(packageName);
+            mContext.sendBroadcastAsUser(explicitIntent, UserHandle.ALL,
+                    Manifest.permission.MANAGE_LOW_POWER_STANDBY);
+        }
+    }
+
     @GuardedBy("mLock")
     private void enqueueNotifyActiveChangedLocked() {
         final Message msg = mHandler.obtainMessage(MSG_NOTIFY_ACTIVE_CHANGED, mIsActive);
@@ -1360,7 +1381,7 @@
         }
 
         final Intent intent = new Intent(PowerManager.ACTION_LOW_POWER_STANDBY_PORTS_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
                 Manifest.permission.MANAGE_LOW_POWER_STANDBY);
     }
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
index e3f3638..5d90851 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
@@ -32,7 +32,6 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.IndentingPrintWriter;
-import android.util.KeyValueListParser;
 import android.util.Slog;
 import android.view.accessibility.AccessibilityManager;
 
@@ -41,6 +40,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ConcurrentUtils;
+import com.android.server.utils.UserSettingDeviceConfigMediator;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -809,12 +809,13 @@
 
         private static Policy fromSettings(String settings, String deviceSpecificSettings,
                 DeviceConfig.Properties properties, String configSuffix, Policy defaultPolicy) {
-            final KeyValueListParser parser = new KeyValueListParser(',');
+            final UserSettingDeviceConfigMediator userSettingDeviceConfigMediator =
+                    new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
             configSuffix = TextUtils.emptyIfNull(configSuffix);
 
             // Device-specific parameters.
             try {
-                parser.setString(deviceSpecificSettings == null ? "" : deviceSpecificSettings);
+                userSettingDeviceConfigMediator.setSettingsString(deviceSpecificSettings);
             } catch (IllegalArgumentException e) {
                 Slog.wtf(TAG, "Bad device specific battery saver constants: "
                         + deviceSpecificSettings);
@@ -822,68 +823,58 @@
 
             // Non-device-specific parameters.
             try {
-                parser.setString(settings == null ? "" : settings);
+                userSettingDeviceConfigMediator.setSettingsString(settings);
+                userSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
             } catch (IllegalArgumentException e) {
                 Slog.wtf(TAG, "Bad battery saver constants: " + settings);
             }
 
             // The Settings value overrides everything, since that will be set by the user.
             // The DeviceConfig value takes second place, with the default as the last choice.
-            final float adjustBrightnessFactor = parser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR,
-                    properties.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR + configSuffix,
-                            defaultPolicy.adjustBrightnessFactor));
-            final boolean advertiseIsEnabled = parser.getBoolean(KEY_ADVERTISE_IS_ENABLED,
-                    properties.getBoolean(KEY_ADVERTISE_IS_ENABLED + configSuffix,
-                            defaultPolicy.advertiseIsEnabled));
-            final boolean deferFullBackup = parser.getBoolean(KEY_DEFER_FULL_BACKUP,
-                    properties.getBoolean(KEY_DEFER_FULL_BACKUP + configSuffix,
-                            defaultPolicy.deferFullBackup));
-            final boolean deferKeyValueBackup = parser.getBoolean(KEY_DEFER_KEYVALUE_BACKUP,
-                    properties.getBoolean(KEY_DEFER_KEYVALUE_BACKUP + configSuffix,
-                            defaultPolicy.deferKeyValueBackup));
-            final boolean disableAnimation = parser.getBoolean(KEY_DISABLE_ANIMATION,
-                    properties.getBoolean(KEY_DISABLE_ANIMATION + configSuffix,
-                            defaultPolicy.disableAnimation));
-            final boolean disableAod = parser.getBoolean(KEY_DISABLE_AOD,
-                    properties.getBoolean(KEY_DISABLE_AOD + configSuffix,
-                            defaultPolicy.disableAod));
-            final boolean disableLaunchBoost = parser.getBoolean(KEY_DISABLE_LAUNCH_BOOST,
-                    properties.getBoolean(KEY_DISABLE_LAUNCH_BOOST + configSuffix,
-                            defaultPolicy.disableLaunchBoost));
-            final boolean disableOptionalSensors = parser.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS,
-                    properties.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS + configSuffix,
-                            defaultPolicy.disableOptionalSensors));
-            final boolean disableVibrationConfig = parser.getBoolean(KEY_DISABLE_VIBRATION,
-                    properties.getBoolean(KEY_DISABLE_VIBRATION + configSuffix,
-                            defaultPolicy.disableVibration));
-            final boolean enableBrightnessAdjustment = parser.getBoolean(
-                    KEY_ENABLE_BRIGHTNESS_ADJUSTMENT,
-                    properties.getBoolean(KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + configSuffix,
-                            defaultPolicy.enableAdjustBrightness));
-            final boolean enableDataSaver = parser.getBoolean(KEY_ENABLE_DATASAVER,
-                    properties.getBoolean(KEY_ENABLE_DATASAVER + configSuffix,
-                            defaultPolicy.enableDataSaver));
-            final boolean enableFirewall = parser.getBoolean(KEY_ENABLE_FIREWALL,
-                    properties.getBoolean(KEY_ENABLE_FIREWALL + configSuffix,
-                            defaultPolicy.enableFirewall));
-            final boolean enableNightMode = parser.getBoolean(KEY_ENABLE_NIGHT_MODE,
-                    properties.getBoolean(KEY_ENABLE_NIGHT_MODE + configSuffix,
-                            defaultPolicy.enableNightMode));
-            final boolean enableQuickDoze = parser.getBoolean(KEY_ENABLE_QUICK_DOZE,
-                    properties.getBoolean(KEY_ENABLE_QUICK_DOZE + configSuffix,
-                            defaultPolicy.enableQuickDoze));
-            final boolean forceAllAppsStandby = parser.getBoolean(KEY_FORCE_ALL_APPS_STANDBY,
-                    properties.getBoolean(KEY_FORCE_ALL_APPS_STANDBY + configSuffix,
-                            defaultPolicy.forceAllAppsStandby));
-            final boolean forceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK,
-                    properties.getBoolean(KEY_FORCE_BACKGROUND_CHECK + configSuffix,
-                            defaultPolicy.forceBackgroundCheck));
-            final int locationMode = parser.getInt(KEY_LOCATION_MODE,
-                    properties.getInt(KEY_LOCATION_MODE + configSuffix,
-                            defaultPolicy.locationMode));
-            final int soundTriggerMode = parser.getInt(KEY_SOUNDTRIGGER_MODE,
-                    properties.getInt(KEY_SOUNDTRIGGER_MODE + configSuffix,
-                            defaultPolicy.soundTriggerMode));
+            final float adjustBrightnessFactor = userSettingDeviceConfigMediator.getFloat(
+                    KEY_ADJUST_BRIGHTNESS_FACTOR + configSuffix,
+                    defaultPolicy.adjustBrightnessFactor);
+            final boolean advertiseIsEnabled = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_ADVERTISE_IS_ENABLED + configSuffix,
+                    defaultPolicy.advertiseIsEnabled);
+            final boolean deferFullBackup = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_DEFER_FULL_BACKUP + configSuffix, defaultPolicy.deferFullBackup);
+            final boolean deferKeyValueBackup = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_DEFER_KEYVALUE_BACKUP + configSuffix,
+                    defaultPolicy.deferKeyValueBackup);
+            final boolean disableAnimation = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_DISABLE_ANIMATION + configSuffix, defaultPolicy.disableAnimation);
+            final boolean disableAod = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_DISABLE_AOD + configSuffix, defaultPolicy.disableAod);
+            final boolean disableLaunchBoost = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_DISABLE_LAUNCH_BOOST + configSuffix,
+                    defaultPolicy.disableLaunchBoost);
+            final boolean disableOptionalSensors = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_DISABLE_OPTIONAL_SENSORS + configSuffix,
+                    defaultPolicy.disableOptionalSensors);
+            final boolean disableVibrationConfig = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_DISABLE_VIBRATION + configSuffix, defaultPolicy.disableVibration);
+            final boolean enableBrightnessAdjustment = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + configSuffix,
+                    defaultPolicy.enableAdjustBrightness);
+            final boolean enableDataSaver = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_ENABLE_DATASAVER + configSuffix, defaultPolicy.enableDataSaver);
+            final boolean enableFirewall = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_ENABLE_FIREWALL + configSuffix, defaultPolicy.enableFirewall);
+            final boolean enableNightMode = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_ENABLE_NIGHT_MODE + configSuffix, defaultPolicy.enableNightMode);
+            final boolean enableQuickDoze = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_ENABLE_QUICK_DOZE + configSuffix, defaultPolicy.enableQuickDoze);
+            final boolean forceAllAppsStandby = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_FORCE_ALL_APPS_STANDBY + configSuffix,
+                    defaultPolicy.forceAllAppsStandby);
+            final boolean forceBackgroundCheck = userSettingDeviceConfigMediator.getBoolean(
+                    KEY_FORCE_BACKGROUND_CHECK + configSuffix,
+                    defaultPolicy.forceBackgroundCheck);
+            final int locationMode = userSettingDeviceConfigMediator.getInt(
+                    KEY_LOCATION_MODE + configSuffix, defaultPolicy.locationMode);
+            final int soundTriggerMode = userSettingDeviceConfigMediator.getInt(
+                    KEY_SOUNDTRIGGER_MODE + configSuffix, defaultPolicy.soundTriggerMode);
             return new Policy(
                     adjustBrightnessFactor,
                     advertiseIsEnabled,
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index dd39fb0..c17d6ab 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -51,6 +51,7 @@
 import java.io.PrintWriter;
 import java.util.Arrays;
 import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.Objects;
 
 /** An hint service implementation that runs in System Server process. */
@@ -544,7 +545,11 @@
                 if (mHalSessionPtr == 0) return;
                 mNativeWrapper.halCloseHintSession(mHalSessionPtr);
                 mHalSessionPtr = 0;
-                mToken.unlinkToDeath(this, 0);
+                try {
+                    mToken.unlinkToDeath(this, 0);
+                } catch (NoSuchElementException ignored) {
+                    Slogf.d(TAG, "Death link does not exist for session with UID " + mUid);
+                }
             }
             synchronized (mLock) {
                 ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = mActiveSessions.get(mUid);
diff --git a/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java b/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
index aadd03b..894226c 100644
--- a/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
+++ b/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
@@ -33,6 +33,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -265,4 +266,11 @@
             ipw.decreaseIndent();
         }
     }
+
+    @Override
+    public String toString() {
+        StringWriter sw = new StringWriter();
+        dump(new IndentingPrintWriter(sw));
+        return sw.toString();
+    }
 }
diff --git a/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
index f9d57e4..a8eda3c 100644
--- a/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
@@ -44,11 +44,8 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.power.EnergyConsumerStats;
-import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
 
-import libcore.util.EmptyArray;
-
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
@@ -128,9 +125,6 @@
     private boolean mUseLatestStates = true;
 
     @GuardedBy("this")
-    private final IntArray mUidsToRemove = new IntArray();
-
-    @GuardedBy("this")
     private Future<?> mWakelockChangesUpdate;
 
     @GuardedBy("this")
@@ -260,7 +254,6 @@
 
     @Override
     public synchronized Future<?> scheduleCpuSyncDueToRemovedUid(int uid) {
-        mUidsToRemove.add(uid);
         return scheduleSyncLocked("remove-uid", UPDATE_CPU);
     }
 
@@ -459,7 +452,6 @@
             // Capture a snapshot of the state we are meant to process.
             final int updateFlags;
             final String reason;
-            final int[] uidsToRemove;
             final boolean onBattery;
             final boolean onBatteryScreenOff;
             final int screenState;
@@ -468,7 +460,6 @@
             synchronized (BatteryExternalStatsWorker.this) {
                 updateFlags = mUpdateFlags;
                 reason = mCurrentReason;
-                uidsToRemove = mUidsToRemove.size() > 0 ? mUidsToRemove.toArray() : EmptyArray.INT;
                 onBattery = mOnBattery;
                 onBatteryScreenOff = mOnBatteryScreenOff;
                 screenState = mScreenState;
@@ -476,7 +467,6 @@
                 useLatestStates = mUseLatestStates;
                 mUpdateFlags = 0;
                 mCurrentReason = null;
-                mUidsToRemove.clear();
                 mCurrentFuture = null;
                 mUseLatestStates = true;
                 if ((updateFlags & UPDATE_ALL) == UPDATE_ALL) {
@@ -512,12 +502,6 @@
 
                 // Clean up any UIDs if necessary.
                 synchronized (mStats) {
-                    for (int uid : uidsToRemove) {
-                        FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, -1, uid,
-                                FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__REMOVED);
-                        mStats.maybeRemoveIsolatedUidLocked(uid, SystemClock.elapsedRealtime(),
-                                SystemClock.uptimeMillis());
-                    }
                     mStats.clearPendingRemovedUidsLocked();
                 }
             } catch (Exception e) {
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsDumpHelperImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsDumpHelperImpl.java
new file mode 100644
index 0000000..ad146af
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsDumpHelperImpl.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power.stats;
+
+import android.os.BatteryStats;
+import android.os.BatteryUsageStats;
+import android.os.BatteryUsageStatsQuery;
+
+public class BatteryStatsDumpHelperImpl implements BatteryStats.BatteryStatsDumpHelper {
+    private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;
+
+    public BatteryStatsDumpHelperImpl(BatteryUsageStatsProvider batteryUsageStatsProvider) {
+        mBatteryUsageStatsProvider = batteryUsageStatsProvider;
+    }
+
+    @Override
+    public BatteryUsageStats getBatteryUsageStats(BatteryStats batteryStats, boolean detailed) {
+        BatteryUsageStatsQuery.Builder builder = new BatteryUsageStatsQuery.Builder()
+                .setMaxStatsAgeMs(0);
+        if (detailed) {
+            builder.includePowerModels().includeProcessStateData().includeVirtualUids();
+        }
+        return mBatteryUsageStatsProvider.getBatteryUsageStats((BatteryStatsImpl) batteryStats,
+                builder.build());
+    }
+}
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index eb40104..b8d26d9 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -185,7 +185,7 @@
     // TODO: remove "tcp" from network methods, since we measure total stats.
 
     // Current on-disk Parcel version. Must be updated when the format of the parcelable changes
-    public static final int VERSION = 213;
+    public static final int VERSION = 214;
 
     // The maximum number of names wakelocks we will keep track of
     // per uid; once the limit is reached, we batch the remaining wakelocks
@@ -220,6 +220,8 @@
     public static final int RESET_REASON_FULL_CHARGE = 3;
     public static final int RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE = 4;
     public static final int RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION = 5;
+    @NonNull
+    private final MonotonicClock mMonotonicClock;
 
     protected Clock mClock;
 
@@ -284,6 +286,7 @@
     private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>();
     private int[] mCpuPowerBracketMap;
     private final CpuPowerStatsCollector mCpuPowerStatsCollector;
+    private boolean mPowerStatsCollectorEnabled;
 
     public LongSparseArray<SamplingTimer> getKernelMemoryStats() {
         return mKernelMemoryStats;
@@ -393,19 +396,9 @@
         }
     }
 
-    /**
-     * Listener for the battery stats reset.
-     */
-    public interface BatteryResetListener {
-
-        /**
-         * Callback invoked immediately prior to resetting battery stats.
-         * @param resetReason One of the RESET_REASON_* constants.
-         */
-        void prepareForBatteryStatsReset(int resetReason);
-    }
-
-    private BatteryResetListener mBatteryResetListener;
+    private boolean mSaveBatteryUsageStatsOnReset;
+    private BatteryUsageStatsProvider mBatteryUsageStatsProvider;
+    private PowerStatsStore mPowerStatsStore;
 
     public interface BatteryCallback {
         public void batteryNeedsCpuUpdate();
@@ -609,6 +602,10 @@
     @SuppressWarnings("GuardedBy")    // errorprone false positive on getProcStateTimeCounter
     @VisibleForTesting
     public void updateProcStateCpuTimesLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
+        if (mPowerStatsCollectorEnabled) {
+            return;
+        }
+
         ensureKernelSingleUidTimeReaderLocked();
 
         final Uid u = getUidStatsLocked(uid);
@@ -661,8 +658,9 @@
      */
     @SuppressWarnings("GuardedBy")    // errorprone false positive on getProcStateTimeCounter
     public void updateCpuTimesForAllUids() {
-        if (mCpuPowerStatsCollector != null) {
+        if (mPowerStatsCollectorEnabled && mCpuPowerStatsCollector != null) {
             mCpuPowerStatsCollector.schedule();
+            return;
         }
 
         synchronized (BatteryStatsImpl.this) {
@@ -720,7 +718,7 @@
 
     @GuardedBy("this")
     private void ensureKernelSingleUidTimeReaderLocked() {
-        if (mKernelSingleUidTimeReader != null) {
+        if (mPowerStatsCollectorEnabled || mKernelSingleUidTimeReader != null) {
             return;
         }
 
@@ -787,13 +785,10 @@
     private BatteryCallback mCallback;
 
     /**
-     * Mapping isolated uids to the actual owning app uid.
+     * Mapping child uids to their parent uid.
      */
-    private final SparseIntArray mIsolatedUids = new SparseIntArray();
-    /**
-     * Internal reference count of isolated uids.
-     */
-    private final SparseIntArray mIsolatedUidRefCounts = new SparseIntArray();
+    @VisibleForTesting
+    protected final PowerStatsUidResolver mPowerStatsUidResolver;
 
     /**
      * The statistics we have collected organized by uids.
@@ -874,6 +869,8 @@
     long mUptimeStartUs;
     long mRealtimeUs;
     long mRealtimeStartUs;
+    long mMonotonicStartTime;
+    long mMonotonicEndTime = MonotonicClock.UNDEFINED;
 
     int mWakeLockNesting;
     boolean mWakeLockImportant;
@@ -1724,25 +1721,26 @@
     }
 
     @VisibleForTesting
-    public BatteryStatsImpl(Clock clock, File historyDirectory) {
+    public BatteryStatsImpl(Clock clock, File historyDirectory, @NonNull Handler handler,
+            @NonNull PowerStatsUidResolver powerStatsUidResolver) {
         init(clock);
         mBatteryStatsConfig = new BatteryStatsConfig.Builder().build();
-        mHandler = null;
+        mHandler = handler;
+        mPowerStatsUidResolver = powerStatsUidResolver;
         mConstants = new Constants(mHandler);
         mStartClockTimeMs = clock.currentTimeMillis();
         mDailyFile = null;
+        mMonotonicClock = new MonotonicClock(0, mClock);
         if (historyDirectory == null) {
             mCheckinFile = null;
             mStatsFile = null;
             mHistory = new BatteryStatsHistory(mConstants.MAX_HISTORY_FILES,
-                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock,
-                    new MonotonicClock(0, mClock));
+                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock);
         } else {
             mCheckinFile = new AtomicFile(new File(historyDirectory, "batterystats-checkin.bin"));
             mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin"));
             mHistory = new BatteryStatsHistory(historyDirectory, mConstants.MAX_HISTORY_FILES,
-                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock,
-                    new MonotonicClock(0, mClock));
+                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock);
         }
         mPlatformIdleStateCallback = null;
         mEnergyConsumerRetriever = null;
@@ -4278,92 +4276,51 @@
         }
     }
 
-    @GuardedBy("this")
-    public void addIsolatedUidLocked(int isolatedUid, int appUid) {
-        addIsolatedUidLocked(isolatedUid, appUid,
-                mClock.elapsedRealtime(), mClock.uptimeMillis());
+    private void onIsolatedUidAdded(int isolatedUid, int parentUid) {
+        long realtime = mClock.elapsedRealtime();
+        long uptime = mClock.uptimeMillis();
+        synchronized (this) {
+            getUidStatsLocked(parentUid, realtime, uptime).addIsolatedUid(isolatedUid);
+        }
     }
 
-    @GuardedBy("this")
-    @SuppressWarnings("GuardedBy")   // errorprone false positive on u.addIsolatedUid
-    public void addIsolatedUidLocked(int isolatedUid, int appUid,
-            long elapsedRealtimeMs, long uptimeMs) {
-        mIsolatedUids.put(isolatedUid, appUid);
-        mIsolatedUidRefCounts.put(isolatedUid, 1);
-        final Uid u = getUidStatsLocked(appUid, elapsedRealtimeMs, uptimeMs);
-        u.addIsolatedUid(isolatedUid);
+    private void onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid) {
+        long realtime = mClock.elapsedRealtime();
+        mPowerStatsUidResolver.retainIsolatedUid(isolatedUid);
+        synchronized (this) {
+            mPendingRemovedUids.add(new UidToRemove(isolatedUid, realtime));
+        }
+        if (mExternalSync != null) {
+            mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid);
+        }
     }
 
-    /**
-     * Schedules a read of the latest cpu times before removing the isolated UID.
-     * @see #removeIsolatedUidLocked(int, int, int)
-     */
-    public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) {
-        int curUid = mIsolatedUids.get(isolatedUid, -1);
-        if (curUid == appUid) {
-            if (mExternalSync != null) {
-                mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid);
-            }
+    private void onAfterIsolatedUidRemoved(int isolatedUid, int parentUid) {
+        long realtime = mClock.elapsedRealtime();
+        long uptime = mClock.uptimeMillis();
+        synchronized (this) {
+            getUidStatsLocked(parentUid, realtime, uptime).removeIsolatedUid(isolatedUid);
         }
     }
 
     /**
      * Isolated uid should only be removed after all wakelocks associated with the uid are stopped
      * and the cpu time-in-state has been read one last time for the uid.
-     *
-     * @see #scheduleRemoveIsolatedUidLocked(int, int)
-     *
-     * @return true if the isolated uid is actually removed.
      */
     @GuardedBy("this")
-    public boolean maybeRemoveIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs,
-            long uptimeMs) {
-        final int refCount = mIsolatedUidRefCounts.get(isolatedUid, 0) - 1;
-        if (refCount > 0) {
-            // Isolated uid is still being tracked
-            mIsolatedUidRefCounts.put(isolatedUid, refCount);
-            return false;
-        }
-
-        final int idx = mIsolatedUids.indexOfKey(isolatedUid);
-        if (idx >= 0) {
-            final int ownerUid = mIsolatedUids.valueAt(idx);
-            final Uid u = getUidStatsLocked(ownerUid, elapsedRealtimeMs, uptimeMs);
-            u.removeIsolatedUid(isolatedUid);
-            mIsolatedUids.removeAt(idx);
-            mIsolatedUidRefCounts.delete(isolatedUid);
-        } else {
-            Slog.w(TAG, "Attempted to remove untracked isolated uid (" + isolatedUid + ")");
-        }
-        mPendingRemovedUids.add(new UidToRemove(isolatedUid, elapsedRealtimeMs));
-
-        return true;
-    }
-
-    /**
-     * Increment the ref count for an isolated uid.
-     * call #maybeRemoveIsolatedUidLocked to decrement.
-     */
-    public void incrementIsolatedUidRefCount(int uid) {
-        final int refCount = mIsolatedUidRefCounts.get(uid, 0);
-        if (refCount <= 0) {
-            // Uid is not mapped or referenced
-            Slog.w(TAG,
-                    "Attempted to increment ref counted of untracked isolated uid (" + uid + ")");
-            return;
-        }
-        mIsolatedUidRefCounts.put(uid, refCount + 1);
+    public void releaseIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs) {
+        mPowerStatsUidResolver.releaseIsolatedUid(isolatedUid);
     }
 
     private int mapUid(int uid) {
         if (Process.isSdkSandboxUid(uid)) {
             return Process.getAppUidForSdkSandboxUid(uid);
         }
-        return mapIsolatedUid(uid);
+        return mPowerStatsUidResolver.mapUid(uid);
     }
 
     private int mapIsolatedUid(int uid) {
-        return mIsolatedUids.get(/*key=*/uid, /*valueIfKeyNotFound=*/uid);
+        return mPowerStatsUidResolver.mapUid(uid);
     }
 
     @GuardedBy("this")
@@ -4745,7 +4702,7 @@
             if (mappedUid != uid) {
                 // Prevent the isolated uid mapping from being removed while the wakelock is
                 // being held.
-                incrementIsolatedUidRefCount(uid);
+                mPowerStatsUidResolver.retainIsolatedUid(uid);
             }
             if (mOnBatteryScreenOffTimeBase.isRunning()) {
                 // We only update the cpu time when a wake lock is acquired if the screen is off.
@@ -4825,7 +4782,7 @@
 
             if (mappedUid != uid) {
                 // Decrement the ref count for the isolated uid and delete the mapping if uneeded.
-                maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs);
+                releaseIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs);
             }
         }
     }
@@ -4996,7 +4953,7 @@
         if (mappedUid != uid) {
             // Prevent the isolated uid mapping from being removed while the wakelock is
             // being held.
-            incrementIsolatedUidRefCount(uid);
+            mPowerStatsUidResolver.retainIsolatedUid(uid);
         }
     }
 
@@ -5048,7 +5005,7 @@
                 historyName, mappedUid);
         if (mappedUid != uid) {
             // Decrement the ref count for the isolated uid and delete the mapping if uneeded.
-            maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs);
+            releaseIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs);
         }
     }
 
@@ -7642,35 +7599,53 @@
     /**
      * Returns the names of custom power components.
      */
-    @GuardedBy("this")
     @Override
     public @NonNull String[] getCustomEnergyConsumerNames() {
-        if (mEnergyConsumerStatsConfig == null) {
-            return new String[0];
-        }
-        final String[] names = mEnergyConsumerStatsConfig.getCustomBucketNames();
-        for (int i = 0; i < names.length; i++) {
-            if (TextUtils.isEmpty(names[i])) {
-                names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i;
+        synchronized (this) {
+            if (mEnergyConsumerStatsConfig == null) {
+                return new String[0];
             }
+            final String[] names = mEnergyConsumerStatsConfig.getCustomBucketNames();
+            for (int i = 0; i < names.length; i++) {
+                if (TextUtils.isEmpty(names[i])) {
+                    names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i;
+                }
+            }
+            return names;
         }
-        return names;
     }
 
-    @GuardedBy("this")
-    @Override public long getStartClockTime() {
-        final long currentTimeMs = mClock.currentTimeMillis();
-        if ((currentTimeMs > MILLISECONDS_IN_YEAR
-                && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR))
+    @Override
+    public long getStartClockTime() {
+        synchronized (this) {
+            final long currentTimeMs = mClock.currentTimeMillis();
+            if ((currentTimeMs > MILLISECONDS_IN_YEAR
+                    && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR))
                 || (mStartClockTimeMs > currentTimeMs)) {
-            // If the start clock time has changed by more than a year, then presumably
-            // the previous time was completely bogus.  So we are going to figure out a
-            // new time based on how much time has elapsed since we started counting.
-            mHistory.recordCurrentTimeChange(mClock.elapsedRealtime(), mClock.uptimeMillis(),
-                    currentTimeMs);
-            adjustStartClockTime(currentTimeMs);
+                // If the start clock time has changed by more than a year, then presumably
+                // the previous time was completely bogus.  So we are going to figure out a
+                // new time based on how much time has elapsed since we started counting.
+                mHistory.recordCurrentTimeChange(mClock.elapsedRealtime(), mClock.uptimeMillis(),
+                        currentTimeMs);
+                adjustStartClockTime(currentTimeMs);
+            }
+            return mStartClockTimeMs;
         }
-        return mStartClockTimeMs;
+    }
+
+    /**
+     * Returns the monotonic time when the BatteryStats session started.
+     */
+    public long getMonotonicStartTime() {
+        return mMonotonicStartTime;
+    }
+
+    /**
+     * Returns the monotonic time when the BatteryStats session ended, or
+     * {@link MonotonicClock#UNDEFINED} if the session is still ongoing.
+     */
+    public long getMonotonicEndTime() {
+        return mMonotonicEndTime;
     }
 
     @Override public String getStartPlatformVersion() {
@@ -8197,7 +8172,9 @@
             return mProportionalSystemServiceUsage;
         }
 
-        @GuardedBy("mBsi")
+        /**
+         * Adds isolated UID to the list of children.
+         */
         public void addIsolatedUid(int isolatedUid) {
             if (mChildUids == null) {
                 mChildUids = new SparseArray<>();
@@ -8207,6 +8184,9 @@
             mChildUids.put(isolatedUid, new ChildUid());
         }
 
+        /**
+         * Removes isolated UID from the list of children.
+         */
         public void removeIsolatedUid(int isolatedUid) {
             final int idx = mChildUids == null ? -1 : mChildUids.indexOfKey(isolatedUid);
             if (idx < 0) {
@@ -8239,6 +8219,10 @@
 
         @GuardedBy("mBsi")
         private void ensureMultiStateCounters(long timestampMs) {
+            if (mBsi.mPowerStatsCollectorEnabled) {
+                throw new IllegalStateException("Multi-state counters used in streamlined mode");
+            }
+
             if (mProcStateTimeMs == null) {
                 mProcStateTimeMs =
                         new TimeInFreqMultiStateCounter(mBsi.mOnBatteryTimeBase,
@@ -10537,7 +10521,7 @@
                     mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs);
                 }
 
-                if (mBsi.trackPerProcStateCpuTimes()) {
+                if (!mBsi.mPowerStatsCollectorEnabled && mBsi.trackPerProcStateCpuTimes()) {
                     mBsi.updateProcStateCpuTimesLocked(mUid, elapsedRealtimeMs, uptimeMs);
 
                     LongArrayMultiStateCounter onBatteryCounter =
@@ -10910,15 +10894,18 @@
             @NonNull Handler handler, @Nullable PlatformIdleStateCallback cb,
             @Nullable EnergyStatsRetriever energyStatsCb,
             @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile,
-            @NonNull CpuScalingPolicies cpuScalingPolicies) {
+            @NonNull CpuScalingPolicies cpuScalingPolicies,
+            @NonNull PowerStatsUidResolver powerStatsUidResolver) {
         init(clock);
 
         mBatteryStatsConfig = config;
+        mMonotonicClock = monotonicClock;
         mHandler = new MyHandler(handler.getLooper());
         mConstants = new Constants(mHandler);
 
         mPowerProfile = powerProfile;
         mCpuScalingPolicies = cpuScalingPolicies;
+        mPowerStatsUidResolver = powerStatsUidResolver;
 
         initPowerProfile();
 
@@ -10927,17 +10914,17 @@
             mCheckinFile = null;
             mDailyFile = null;
             mHistory = new BatteryStatsHistory(mConstants.MAX_HISTORY_FILES,
-                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, monotonicClock);
+                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock);
         } else {
             mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin"));
             mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
             mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
             mHistory = new BatteryStatsHistory(systemDir, mConstants.MAX_HISTORY_FILES,
-                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, monotonicClock);
+                    mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator, mClock, mMonotonicClock);
         }
 
         mCpuPowerStatsCollector = new CpuPowerStatsCollector(mCpuScalingPolicies, mPowerProfile,
-                () -> mBatteryVoltageMv, mHandler,
+                mPowerStatsUidResolver, () -> mBatteryVoltageMv, mHandler,
                 mBatteryStatsConfig.getPowerStatsThrottlePeriodCpu());
         mCpuPowerStatsCollector.addConsumer(this::recordPowerStats);
 
@@ -10954,6 +10941,23 @@
         mEnergyConsumerRetriever = energyStatsCb;
         mUserInfoProvider = userInfoProvider;
 
+        mPowerStatsUidResolver.addListener(new PowerStatsUidResolver.Listener() {
+            @Override
+            public void onIsolatedUidAdded(int isolatedUid, int parentUid) {
+                BatteryStatsImpl.this.onIsolatedUidAdded(isolatedUid, parentUid);
+            }
+
+            @Override
+            public void onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid) {
+                BatteryStatsImpl.this.onBeforeIsolatedUidRemoved(isolatedUid, parentUid);
+            }
+
+            @Override
+            public void onAfterIsolatedUidRemoved(int isolatedUid, int parentUid) {
+                BatteryStatsImpl.this.onAfterIsolatedUidRemoved(isolatedUid, parentUid);
+            }
+        });
+
         // Notify statsd that the system is initially not in doze.
         mDeviceIdleMode = DEVICE_IDLE_MODE_OFF;
         FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mDeviceIdleMode);
@@ -11497,6 +11501,7 @@
         mUptimeUs = 0;
         mRealtimeStartUs = realtimeUs;
         mUptimeStartUs = uptimeUs;
+        mMonotonicStartTime = mMonotonicClock.monotonicTime();
     }
 
     void initDischarge(long elapsedRealtimeUs) {
@@ -11517,8 +11522,17 @@
         mDischargeCounter.reset(false, elapsedRealtimeUs);
     }
 
-    public void setBatteryResetListener(BatteryResetListener batteryResetListener) {
-        mBatteryResetListener = batteryResetListener;
+    /**
+     * Associates the BatteryStatsImpl object with a BatteryUsageStatsProvider and PowerStatsStore
+     * to allow for a snapshot of battery usage stats to be taken and stored just before battery
+     * reset.
+     */
+    public void saveBatteryUsageStatsOnReset(
+            @NonNull BatteryUsageStatsProvider batteryUsageStatsProvider,
+            @NonNull PowerStatsStore powerStatsStore) {
+        mSaveBatteryUsageStatsOnReset = true;
+        mBatteryUsageStatsProvider = batteryUsageStatsProvider;
+        mPowerStatsStore = powerStatsStore;
     }
 
     @GuardedBy("this")
@@ -11557,9 +11571,7 @@
     @GuardedBy("this")
     private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis,
             int resetReason) {
-        if (mBatteryResetListener != null) {
-            mBatteryResetListener.prepareForBatteryStatsReset(resetReason);
-        }
+        saveBatteryUsageStatsOnReset(resetReason);
 
         final long uptimeUs = uptimeMillis * 1000;
         final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000;
@@ -11707,6 +11719,31 @@
         mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS);
     }
 
+    private void saveBatteryUsageStatsOnReset(int resetReason) {
+        if (!mSaveBatteryUsageStatsOnReset
+                || resetReason == BatteryStatsImpl.RESET_REASON_CORRUPT_FILE) {
+            return;
+        }
+
+        final BatteryUsageStats batteryUsageStats;
+        synchronized (this) {
+            batteryUsageStats = mBatteryUsageStatsProvider.getBatteryUsageStats(this,
+                    new BatteryUsageStatsQuery.Builder()
+                            .setMaxStatsAgeMs(0)
+                            .includePowerModels()
+                            .includeProcessStateData()
+                            .build());
+        }
+
+        // TODO(b/188068523): BatteryUsageStats should use monotonic time for start and end
+        // Once that change is made, we will be able to use the BatteryUsageStats' monotonic
+        // start time
+        long monotonicStartTime =
+                mMonotonicClock.monotonicTime() - batteryUsageStats.getStatsDuration();
+        mHandler.post(() ->
+                mPowerStatsStore.storeBatteryUsageStats(monotonicStartTime, batteryUsageStats));
+    }
+
     @GuardedBy("this")
     private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
         for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
@@ -14184,7 +14221,7 @@
             mCpuUidFreqTimeReader.onSystemReady();
         }
         if (mCpuPowerStatsCollector != null) {
-            mCpuPowerStatsCollector.onSystemReady();
+            mCpuPowerStatsCollector.setEnabled(mPowerStatsCollectorEnabled);
         }
         mSystemReady = true;
     }
@@ -15137,6 +15174,7 @@
             if (mKernelSingleUidTimeReader != null) {
                 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid);
             }
+            mPowerStatsUidResolver.releaseUidsInRange(startUid, endUid);
             // Treat as one. We don't know how many uids there are in between.
             mNumUidsRemoved++;
         } else {
@@ -15192,10 +15230,11 @@
         mShuttingDown = true;
     }
 
-    @GuardedBy("this")
     @Override
     public boolean isProcessStateDataAvailable() {
-        return trackPerProcStateCpuTimes();
+        synchronized (this) {
+            return trackPerProcStateCpuTimes();
+        }
     }
 
     @GuardedBy("this")
@@ -15203,6 +15242,15 @@
         return mCpuUidFreqTimeReader.isFastCpuTimesReader();
     }
 
+    /**
+     * Enables or disables the PowerStatsCollector mode.
+     */
+    public void setPowerStatsCollectorEnabled(boolean enabled) {
+        synchronized (this) {
+            mPowerStatsCollectorEnabled = enabled;
+        }
+    }
+
     @GuardedBy("this")
     public void systemServicesReady(Context context) {
         mConstants.startObserving(context.getContentResolver());
@@ -15862,6 +15910,8 @@
         mUptimeUs = in.readLong();
         mRealtimeUs = in.readLong();
         mStartClockTimeMs = in.readLong();
+        mMonotonicStartTime = in.readLong();
+        mMonotonicEndTime = in.readLong();
         mStartPlatformVersion = in.readString();
         mEndPlatformVersion = in.readString();
         mOnBatteryTimeBase.readSummaryFromParcel(in);
@@ -16382,6 +16432,8 @@
         out.writeLong(computeUptime(nowUptime, STATS_SINCE_CHARGED));
         out.writeLong(computeRealtime(nowRealtime, STATS_SINCE_CHARGED));
         out.writeLong(mStartClockTimeMs);
+        out.writeLong(mMonotonicStartTime);
+        out.writeLong(mMonotonicClock.monotonicTime());
         out.writeString(mStartPlatformVersion);
         out.writeString(mEndPlatformVersion);
         mOnBatteryTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime);
@@ -16912,7 +16964,8 @@
     }
 
     @GuardedBy("this")
-    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
+    public void dump(Context context, PrintWriter pw, int flags, int reqUid, long histStart,
+            BatteryStatsDumpHelper dumpHelper) {
         if (DEBUG) {
             pw.println("mOnBatteryTimeBase:");
             mOnBatteryTimeBase.dump(pw, "  ");
@@ -16984,7 +17037,7 @@
             pr.println("*** Camera timer:");
             mCameraOnTimer.logState(pr, "  ");
         }
-        super.dump(context, pw, flags, reqUid, histStart);
+        super.dump(context, pw, flags, reqUid, histStart, dumpHelper);
 
         synchronized (this) {
             pw.print("Per process state tracking available: ");
@@ -16998,15 +17051,7 @@
             pw.print("UIDs removed since the later of device start or stats reset: ");
             pw.println(mNumUidsRemoved);
 
-            pw.println("Currently mapped isolated uids:");
-            final int numIsolatedUids = mIsolatedUids.size();
-            for (int i = 0; i < numIsolatedUids; i++) {
-                final int isolatedUid = mIsolatedUids.keyAt(i);
-                final int ownerUid = mIsolatedUids.valueAt(i);
-                final int refCount = mIsolatedUidRefCounts.get(isolatedUid);
-                pw.println(
-                        "  " + isolatedUid + "->" + ownerUid + " (ref count = " + refCount + ")");
-            }
+            mPowerStatsUidResolver.dump(pw);
 
             pw.println();
             dumpConstantsLocked(pw);
@@ -17020,15 +17065,4 @@
             dumpEnergyConsumerStatsLocked(pw);
         }
     }
-
-    @Override
-    protected BatteryUsageStats getBatteryUsageStats(Context context, boolean detailed) {
-        final BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, this);
-        BatteryUsageStatsQuery.Builder builder = new BatteryUsageStatsQuery.Builder()
-                .setMaxStatsAgeMs(0);
-        if (detailed) {
-            builder.includePowerModels().includeProcessStateData().includeVirtualUids();
-        }
-        return provider.getBatteryUsageStats(builder.build());
-    }
 }
diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
index 83d7d72..303c245 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -23,14 +23,12 @@
 import android.os.BatteryUsageStats;
 import android.os.BatteryUsageStatsQuery;
 import android.os.Process;
-import android.os.SystemClock;
 import android.os.UidBatteryConsumer;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.Clock;
 import com.android.internal.os.CpuScalingPolicies;
 import com.android.internal.os.PowerProfile;
 
@@ -45,27 +43,25 @@
 public class BatteryUsageStatsProvider {
     private static final String TAG = "BatteryUsageStatsProv";
     private final Context mContext;
-    private final BatteryStats mStats;
+    private boolean mPowerStatsExporterEnabled;
+    private final PowerStatsExporter mPowerStatsExporter;
     private final PowerStatsStore mPowerStatsStore;
     private final PowerProfile mPowerProfile;
     private final CpuScalingPolicies mCpuScalingPolicies;
+    private final Clock mClock;
     private final Object mLock = new Object();
     private List<PowerCalculator> mPowerCalculators;
 
-    public BatteryUsageStatsProvider(Context context, BatteryStats stats) {
-        this(context, stats, null);
-    }
-
-    @VisibleForTesting
-    public BatteryUsageStatsProvider(Context context, BatteryStats stats,
-            PowerStatsStore powerStatsStore) {
+    public BatteryUsageStatsProvider(Context context,
+            PowerStatsExporter powerStatsExporter,
+            PowerProfile powerProfile, CpuScalingPolicies cpuScalingPolicies,
+            PowerStatsStore powerStatsStore, Clock clock) {
         mContext = context;
-        mStats = stats;
+        mPowerStatsExporter = powerStatsExporter;
         mPowerStatsStore = powerStatsStore;
-        mPowerProfile = stats instanceof BatteryStatsImpl
-                ? ((BatteryStatsImpl) stats).getPowerProfile()
-                : new PowerProfile(context);
-        mCpuScalingPolicies = stats.getCpuScalingPolicies();
+        mPowerProfile = powerProfile;
+        mCpuScalingPolicies = cpuScalingPolicies;
+        mClock = clock;
     }
 
     private List<PowerCalculator> getPowerCalculators() {
@@ -75,7 +71,10 @@
 
                 // Power calculators are applied in the order of registration
                 mPowerCalculators.add(new BatteryChargeCalculator());
-                mPowerCalculators.add(new CpuPowerCalculator(mCpuScalingPolicies, mPowerProfile));
+                if (mPowerStatsExporterEnabled) {
+                    mPowerCalculators.add(
+                            new CpuPowerCalculator(mCpuScalingPolicies, mPowerProfile));
+                }
                 mPowerCalculators.add(new MemoryPowerCalculator(mPowerProfile));
                 mPowerCalculators.add(new WakelockPowerCalculator(mPowerProfile));
                 if (!BatteryStats.checkWifiOnly(mContext)) {
@@ -111,27 +110,28 @@
      * Returns true if the last update was too long ago for the tolerances specified
      * by the supplied queries.
      */
-    public boolean shouldUpdateStats(List<BatteryUsageStatsQuery> queries,
-            long lastUpdateTimeStampMs) {
+    public static boolean shouldUpdateStats(List<BatteryUsageStatsQuery> queries,
+            long elapsedRealtime, long lastUpdateTimeStampMs) {
         long allowableStatsAge = Long.MAX_VALUE;
         for (int i = queries.size() - 1; i >= 0; i--) {
             BatteryUsageStatsQuery query = queries.get(i);
             allowableStatsAge = Math.min(allowableStatsAge, query.getMaxStatsAge());
         }
 
-        return elapsedRealtime() - lastUpdateTimeStampMs > allowableStatsAge;
+        return elapsedRealtime - lastUpdateTimeStampMs > allowableStatsAge;
     }
 
     /**
      * Returns snapshots of battery attribution data, one per supplied query.
      */
-    public List<BatteryUsageStats> getBatteryUsageStats(List<BatteryUsageStatsQuery> queries) {
+    public List<BatteryUsageStats> getBatteryUsageStats(BatteryStatsImpl stats,
+            List<BatteryUsageStatsQuery> queries) {
         ArrayList<BatteryUsageStats> results = new ArrayList<>(queries.size());
-        synchronized (mStats) {
-            mStats.prepareForDumpLocked();
-            final long currentTimeMillis = currentTimeMillis();
+        synchronized (stats) {
+            stats.prepareForDumpLocked();
+            final long currentTimeMillis = mClock.currentTimeMillis();
             for (int i = 0; i < queries.size(); i++) {
-                results.add(getBatteryUsageStats(queries.get(i), currentTimeMillis));
+                results.add(getBatteryUsageStats(stats, queries.get(i), currentTimeMillis));
             }
         }
         return results;
@@ -140,60 +140,59 @@
     /**
      * Returns a snapshot of battery attribution data.
      */
-    @VisibleForTesting
-    public BatteryUsageStats getBatteryUsageStats(BatteryUsageStatsQuery query) {
-        synchronized (mStats) {
-            return getBatteryUsageStats(query, currentTimeMillis());
-        }
+    public BatteryUsageStats getBatteryUsageStats(BatteryStatsImpl stats,
+            BatteryUsageStatsQuery query) {
+        return getBatteryUsageStats(stats, query, mClock.currentTimeMillis());
     }
 
-    @GuardedBy("mStats")
-    private BatteryUsageStats getBatteryUsageStats(BatteryUsageStatsQuery query,
-            long currentTimeMs) {
+    private BatteryUsageStats getBatteryUsageStats(BatteryStatsImpl stats,
+            BatteryUsageStatsQuery query, long currentTimeMs) {
         if (query.getToTimestamp() == 0) {
-            return getCurrentBatteryUsageStats(query, currentTimeMs);
+            return getCurrentBatteryUsageStats(stats, query, currentTimeMs);
         } else {
-            return getAggregatedBatteryUsageStats(query);
+            return getAggregatedBatteryUsageStats(stats, query);
         }
     }
 
-    @GuardedBy("mStats")
-    private BatteryUsageStats getCurrentBatteryUsageStats(BatteryUsageStatsQuery query,
-            long currentTimeMs) {
-        final long realtimeUs = elapsedRealtime() * 1000;
-        final long uptimeUs = uptimeMillis() * 1000;
+    private BatteryUsageStats getCurrentBatteryUsageStats(BatteryStatsImpl stats,
+            BatteryUsageStatsQuery query, long currentTimeMs) {
+        final long realtimeUs = mClock.elapsedRealtime() * 1000;
+        final long uptimeUs = mClock.uptimeMillis() * 1000;
 
         final boolean includePowerModels = (query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0;
         final boolean includeProcessStateData = ((query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0)
-                && mStats.isProcessStateDataAvailable();
+                && stats.isProcessStateDataAvailable();
         final boolean includeVirtualUids =  ((query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS) != 0);
         final double minConsumedPowerThreshold = query.getMinConsumedPowerThreshold();
 
         final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder(
-                mStats.getCustomEnergyConsumerNames(), includePowerModels,
+                stats.getCustomEnergyConsumerNames(), includePowerModels,
                 includeProcessStateData, minConsumedPowerThreshold);
         // TODO(b/188068523): use a monotonic clock to ensure resilience of order and duration
-        // of stats sessions to wall-clock adjustments
-        batteryUsageStatsBuilder.setStatsStartTimestamp(mStats.getStartClockTime());
+        // of batteryUsageStats sessions to wall-clock adjustments
+        batteryUsageStatsBuilder.setStatsStartTimestamp(stats.getStartClockTime());
         batteryUsageStatsBuilder.setStatsEndTimestamp(currentTimeMs);
 
-        SparseArray<? extends BatteryStats.Uid> uidStats = mStats.getUidStats();
-        for (int i = uidStats.size() - 1; i >= 0; i--) {
-            final BatteryStats.Uid uid = uidStats.valueAt(i);
-            if (!includeVirtualUids && uid.getUid() == Process.SDK_SANDBOX_VIRTUAL_UID) {
-                continue;
-            }
+        synchronized (stats) {
+            SparseArray<? extends BatteryStats.Uid> uidStats = stats.getUidStats();
+            for (int i = uidStats.size() - 1; i >= 0; i--) {
+                final BatteryStats.Uid uid = uidStats.valueAt(i);
+                if (!includeVirtualUids && uid.getUid() == Process.SDK_SANDBOX_VIRTUAL_UID) {
+                    continue;
+                }
 
-            batteryUsageStatsBuilder.getOrCreateUidBatteryConsumerBuilder(uid)
-                    .setTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_BACKGROUND,
-                            getProcessBackgroundTimeMs(uid, realtimeUs))
-                    .setTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_FOREGROUND,
-                            getProcessForegroundTimeMs(uid, realtimeUs))
-                    .setTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE,
-                            getProcessForegroundServiceTimeMs(uid, realtimeUs));
+                batteryUsageStatsBuilder.getOrCreateUidBatteryConsumerBuilder(uid)
+                        .setTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_BACKGROUND,
+                                getProcessBackgroundTimeMs(uid, realtimeUs))
+                        .setTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_FOREGROUND,
+                                getProcessForegroundTimeMs(uid, realtimeUs))
+                        .setTimeInProcessStateMs(
+                                UidBatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE,
+                                getProcessForegroundServiceTimeMs(uid, realtimeUs));
+            }
         }
 
         final int[] powerComponents = query.getPowerComponents();
@@ -202,8 +201,8 @@
             PowerCalculator powerCalculator = powerCalculators.get(i);
             if (powerComponents != null) {
                 boolean include = false;
-                for (int j = 0; j < powerComponents.length; j++) {
-                    if (powerCalculator.isPowerComponentSupported(powerComponents[j])) {
+                for (int powerComponent : powerComponents) {
+                    if (powerCalculator.isPowerComponentSupported(powerComponent)) {
                         include = true;
                         break;
                     }
@@ -212,26 +211,24 @@
                     continue;
                 }
             }
-            powerCalculator.calculate(batteryUsageStatsBuilder, mStats, realtimeUs, uptimeUs,
-                    query);
+            powerCalculator.calculate(batteryUsageStatsBuilder, stats, realtimeUs, uptimeUs, query);
+        }
+
+        if (mPowerStatsExporterEnabled) {
+            mPowerStatsExporter.exportAggregatedPowerStats(batteryUsageStatsBuilder,
+                    stats.getMonotonicStartTime(), stats.getMonotonicEndTime());
         }
 
         if ((query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY) != 0) {
-            if (!(mStats instanceof BatteryStatsImpl)) {
-                throw new UnsupportedOperationException(
-                        "History cannot be included for " + getClass().getName());
-            }
-
-            BatteryStatsImpl batteryStatsImpl = (BatteryStatsImpl) mStats;
-            batteryUsageStatsBuilder.setBatteryHistory(batteryStatsImpl.copyHistory());
+            batteryUsageStatsBuilder.setBatteryHistory(stats.copyHistory());
         }
 
-        BatteryUsageStats stats = batteryUsageStatsBuilder.build();
+        BatteryUsageStats batteryUsageStats = batteryUsageStatsBuilder.build();
         if (includeProcessStateData) {
-            verify(stats);
+            verify(batteryUsageStats);
         }
-        return stats;
+        return batteryUsageStats;
     }
 
     // STOPSHIP(b/229906525): remove verification before shipping
@@ -308,15 +305,16 @@
                 / 1000;
     }
 
-    private BatteryUsageStats getAggregatedBatteryUsageStats(BatteryUsageStatsQuery query) {
+    private BatteryUsageStats getAggregatedBatteryUsageStats(BatteryStatsImpl stats,
+            BatteryUsageStatsQuery query) {
         final boolean includePowerModels = (query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0;
         final boolean includeProcessStateData = ((query.getFlags()
                 & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0)
-                && mStats.isProcessStateDataAvailable();
+                && stats.isProcessStateDataAvailable();
         final double minConsumedPowerThreshold = query.getMinConsumedPowerThreshold();
 
-        final String[] customEnergyConsumerNames = mStats.getCustomEnergyConsumerNames();
+        final String[] customEnergyConsumerNames = stats.getCustomEnergyConsumerNames();
         final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
                 customEnergyConsumerNames, includePowerModels, includeProcessStateData,
                 minConsumedPowerThreshold);
@@ -386,27 +384,8 @@
         return builder.build();
     }
 
-    private long elapsedRealtime() {
-        if (mStats instanceof BatteryStatsImpl) {
-            return ((BatteryStatsImpl) mStats).mClock.elapsedRealtime();
-        } else {
-            return SystemClock.elapsedRealtime();
-        }
-    }
+    public void setPowerStatsExporterEnabled(boolean enabled) {
 
-    private long uptimeMillis() {
-        if (mStats instanceof BatteryStatsImpl) {
-            return ((BatteryStatsImpl) mStats).mClock.uptimeMillis();
-        } else {
-            return SystemClock.uptimeMillis();
-        }
-    }
-
-    private long currentTimeMillis() {
-        if (mStats instanceof BatteryStatsImpl) {
-            return ((BatteryStatsImpl) mStats).mClock.currentTimeMillis();
-        } else {
-            return System.currentTimeMillis();
-        }
+        mPowerStatsExporterEnabled = enabled;
     }
 }
diff --git a/services/core/java/com/android/server/power/stats/CpuAggregatedPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/CpuAggregatedPowerStatsProcessor.java
index f40eef2..ed9414f 100644
--- a/services/core/java/com/android/server/power/stats/CpuAggregatedPowerStatsProcessor.java
+++ b/services/core/java/com/android/server/power/stats/CpuAggregatedPowerStatsProcessor.java
@@ -64,7 +64,7 @@
     private PowerStats.Descriptor mLastUsedDescriptor;
     // Cached results of parsing of current PowerStats.Descriptor. Only refreshed when
     // mLastUsedDescriptor changes
-    private CpuPowerStatsCollector.StatsArrayLayout mStatsLayout;
+    private CpuPowerStatsCollector.CpuStatsArrayLayout mStatsLayout;
     // Sequence of steps for power estimation and intermediate results.
     private PowerEstimationPlan mPlan;
 
@@ -106,7 +106,7 @@
         }
 
         mLastUsedDescriptor = descriptor;
-        mStatsLayout = new CpuPowerStatsCollector.StatsArrayLayout();
+        mStatsLayout = new CpuPowerStatsCollector.CpuStatsArrayLayout();
         mStatsLayout.fromExtras(descriptor.extras);
 
         mTmpDeviceStatsArray = new long[descriptor.statsArrayLength];
@@ -149,7 +149,7 @@
 
         if (mPlan == null) {
             mPlan = new PowerEstimationPlan(stats.getConfig());
-            if (mStatsLayout.getCpuClusterEnergyConsumerCount() != 0) {
+            if (mStatsLayout.getEnergyConsumerCount() != 0) {
                 initEnergyConsumerToPowerBracketMaps();
             }
         }
@@ -212,7 +212,7 @@
      *          CL_2: [bracket3, bracket4]
      */
     private void initEnergyConsumerToPowerBracketMaps() {
-        int energyConsumerCount = mStatsLayout.getCpuClusterEnergyConsumerCount();
+        int energyConsumerCount = mStatsLayout.getEnergyConsumerCount();
         int powerBracketCount = mStatsLayout.getCpuPowerBracketCount();
 
         mEnergyConsumerToCombinedEnergyConsumerMap = new int[energyConsumerCount];
@@ -294,7 +294,7 @@
                 continue;
             }
 
-            intermediates.uptime += mStatsLayout.getUptime(mTmpDeviceStatsArray);
+            intermediates.uptime += mStatsLayout.getUsageDuration(mTmpDeviceStatsArray);
 
             for (int cluster = 0; cluster < mCpuClusterCount; cluster++) {
                 intermediates.timeByCluster[cluster] +=
@@ -351,7 +351,7 @@
         int cpuScalingStepCount = mStatsLayout.getCpuScalingStepCount();
         int powerBracketCount = mStatsLayout.getCpuPowerBracketCount();
         int[] scalingStepToBracketMap = mStatsLayout.getScalingStepToPowerBracketMap();
-        int energyConsumerCount = mStatsLayout.getCpuClusterEnergyConsumerCount();
+        int energyConsumerCount = mStatsLayout.getEnergyConsumerCount();
         List<DeviceStateEstimation> deviceStateEstimations = mPlan.deviceStateEstimations;
         for (int dse = deviceStateEstimations.size() - 1; dse >= 0; dse--) {
             DeviceStateEstimation deviceStateEstimation = deviceStateEstimations.get(dse);
@@ -392,7 +392,7 @@
 
     private void adjustEstimatesUsingEnergyConsumers(
             Intermediates intermediates, DeviceStatsIntermediates deviceStatsIntermediates) {
-        int energyConsumerCount = mStatsLayout.getCpuClusterEnergyConsumerCount();
+        int energyConsumerCount = mStatsLayout.getEnergyConsumerCount();
         if (energyConsumerCount == 0) {
             return;
         }
@@ -509,8 +509,8 @@
             }
             sb.append(mStatsLayout.getTimeByCluster(stats, cluster));
         }
-        sb.append("] uptime: ").append(mStatsLayout.getUptime(stats));
-        int energyConsumerCount = mStatsLayout.getCpuClusterEnergyConsumerCount();
+        sb.append("] uptime: ").append(mStatsLayout.getUsageDuration(stats));
+        int energyConsumerCount = mStatsLayout.getEnergyConsumerCount();
         if (energyConsumerCount > 0) {
             sb.append(" energy: [");
             for (int i = 0; i < energyConsumerCount; i++) {
diff --git a/services/core/java/com/android/server/power/stats/CpuPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/CpuPowerStatsCollector.java
index b8e581f..4442845 100644
--- a/services/core/java/com/android/server/power/stats/CpuPowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/CpuPowerStatsCollector.java
@@ -22,6 +22,7 @@
 import android.os.BatteryConsumer;
 import android.os.Handler;
 import android.os.PersistableBundle;
+import android.os.Process;
 import android.power.PowerStatsInternal;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -34,7 +35,6 @@
 import com.android.internal.os.PowerProfile;
 import com.android.internal.os.PowerStats;
 import com.android.server.LocalServices;
-import com.android.server.power.optimization.Flags;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -67,6 +67,7 @@
     private final CpuScalingPolicies mCpuScalingPolicies;
     private final PowerProfile mPowerProfile;
     private final KernelCpuStatsReader mKernelCpuStatsReader;
+    private final PowerStatsUidResolver mUidResolver;
     private final Supplier<PowerStatsInternal> mPowerStatsSupplier;
     private final IntSupplier mVoltageSupplier;
     private final int mDefaultCpuPowerBrackets;
@@ -81,7 +82,7 @@
     private PowerStats.Descriptor mPowerStatsDescriptor;
     // Reusable instance
     private PowerStats mCpuPowerStats;
-    private StatsArrayLayout mLayout;
+    private CpuStatsArrayLayout mLayout;
     private long mLastUpdateTimestampNanos;
     private long mLastUpdateUptimeMillis;
     private int mLastVoltageMv;
@@ -91,55 +92,30 @@
      * Captures the positions and lengths of sections of the stats array, such as time-in-state,
      * power usage estimates etc.
      */
-    public static class StatsArrayLayout {
+    public static class CpuStatsArrayLayout extends StatsArrayLayout {
         private static final String EXTRA_DEVICE_TIME_BY_SCALING_STEP_POSITION = "dt";
         private static final String EXTRA_DEVICE_TIME_BY_SCALING_STEP_COUNT = "dtc";
         private static final String EXTRA_DEVICE_TIME_BY_CLUSTER_POSITION = "dc";
         private static final String EXTRA_DEVICE_TIME_BY_CLUSTER_COUNT = "dcc";
-        private static final String EXTRA_DEVICE_POWER_POSITION = "dp";
-        private static final String EXTRA_DEVICE_UPTIME_POSITION = "du";
-        private static final String EXTRA_DEVICE_ENERGY_CONSUMERS_POSITION = "de";
-        private static final String EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT = "dec";
         private static final String EXTRA_UID_BRACKETS_POSITION = "ub";
         private static final String EXTRA_UID_STATS_SCALING_STEP_TO_POWER_BRACKET = "us";
-        private static final String EXTRA_UID_POWER_POSITION = "up";
-
-        private static final double MILLI_TO_NANO_MULTIPLIER = 1000000.0;
-
-        private int mDeviceStatsArrayLength;
-        private int mUidStatsArrayLength;
 
         private int mDeviceCpuTimeByScalingStepPosition;
         private int mDeviceCpuTimeByScalingStepCount;
         private int mDeviceCpuTimeByClusterPosition;
         private int mDeviceCpuTimeByClusterCount;
-        private int mDeviceCpuUptimePosition;
-        private int mDeviceEnergyConsumerPosition;
-        private int mDeviceEnergyConsumerCount;
-        private int mDevicePowerEstimatePosition;
 
         private int mUidPowerBracketsPosition;
         private int mUidPowerBracketCount;
-        private int[][] mEnergyConsumerToPowerBucketMaps;
-        private int mUidPowerEstimatePosition;
 
         private int[] mScalingStepToPowerBracketMap;
 
-        public int getDeviceStatsArrayLength() {
-            return mDeviceStatsArrayLength;
-        }
-
-        public int getUidStatsArrayLength() {
-            return mUidStatsArrayLength;
-        }
-
         /**
          * Declare that the stats array has a section capturing CPU time per scaling step
          */
         public void addDeviceSectionCpuTimeByScalingStep(int scalingStepCount) {
-            mDeviceCpuTimeByScalingStepPosition = mDeviceStatsArrayLength;
+            mDeviceCpuTimeByScalingStepPosition = addDeviceSection(scalingStepCount);
             mDeviceCpuTimeByScalingStepCount = scalingStepCount;
-            mDeviceStatsArrayLength += scalingStepCount;
         }
 
         public int getCpuScalingStepCount() {
@@ -166,9 +142,8 @@
          * Declare that the stats array has a section capturing CPU time in each cluster
          */
         public void addDeviceSectionCpuTimeByCluster(int clusterCount) {
+            mDeviceCpuTimeByClusterPosition = addDeviceSection(clusterCount);
             mDeviceCpuTimeByClusterCount = clusterCount;
-            mDeviceCpuTimeByClusterPosition = mDeviceStatsArrayLength;
-            mDeviceStatsArrayLength += clusterCount;
         }
 
         public int getCpuClusterCount() {
@@ -192,86 +167,12 @@
         }
 
         /**
-         * Declare that the stats array has a section capturing CPU uptime
-         */
-        public void addDeviceSectionUptime() {
-            mDeviceCpuUptimePosition = mDeviceStatsArrayLength++;
-        }
-
-        /**
-         * Saves the CPU uptime duration in the corresponding <code>stats</code> element.
-         */
-        public void setUptime(long[] stats, long value) {
-            stats[mDeviceCpuUptimePosition] = value;
-        }
-
-        /**
-         * Extracts the CPU uptime duration from the corresponding <code>stats</code> element.
-         */
-        public long getUptime(long[] stats) {
-            return stats[mDeviceCpuUptimePosition];
-        }
-
-        /**
-         * Declares that the stats array has a section capturing EnergyConsumer data from
-         * PowerStatsService.
-         */
-        public void addDeviceSectionEnergyConsumers(int energyConsumerCount) {
-            mDeviceEnergyConsumerPosition = mDeviceStatsArrayLength;
-            mDeviceEnergyConsumerCount = energyConsumerCount;
-            mDeviceStatsArrayLength += energyConsumerCount;
-        }
-
-        public int getCpuClusterEnergyConsumerCount() {
-            return mDeviceEnergyConsumerCount;
-        }
-
-        /**
-         * Saves the accumulated energy for the specified rail the corresponding
-         * <code>stats</code> element.
-         */
-        public void setConsumedEnergy(long[] stats, int index, long energy) {
-            stats[mDeviceEnergyConsumerPosition + index] = energy;
-        }
-
-        /**
-         * Extracts the EnergyConsumer data from a device stats array for the specified
-         * EnergyConsumer.
-         */
-        public long getConsumedEnergy(long[] stats, int index) {
-            return stats[mDeviceEnergyConsumerPosition + index];
-        }
-
-        /**
-         * Declare that the stats array has a section capturing a power estimate
-         */
-        public void addDeviceSectionPowerEstimate() {
-            mDevicePowerEstimatePosition = mDeviceStatsArrayLength++;
-        }
-
-        /**
-         * Converts the supplied mAh power estimate to a long and saves it in the corresponding
-         * element of <code>stats</code>.
-         */
-        public void setDevicePowerEstimate(long[] stats, double power) {
-            stats[mDevicePowerEstimatePosition] = (long) (power * MILLI_TO_NANO_MULTIPLIER);
-        }
-
-        /**
-         * Extracts the power estimate from a device stats array and converts it to mAh.
-         */
-        public double getDevicePowerEstimate(long[] stats) {
-            return stats[mDevicePowerEstimatePosition] / MILLI_TO_NANO_MULTIPLIER;
-        }
-
-        /**
          * Declare that the UID stats array has a section capturing CPU time per power bracket.
          */
         public void addUidSectionCpuTimeByPowerBracket(int[] scalingStepToPowerBracketMap) {
             mScalingStepToPowerBracketMap = scalingStepToPowerBracketMap;
-            mUidPowerBracketsPosition = mUidStatsArrayLength;
             updatePowerBracketCount();
-            mUidStatsArrayLength += mUidPowerBracketCount;
+            mUidPowerBracketsPosition = addUidSection(mUidPowerBracketCount);
         }
 
         private void updatePowerBracketCount() {
@@ -306,31 +207,10 @@
         }
 
         /**
-         * Declare that the UID stats array has a section capturing a power estimate
-         */
-        public void addUidSectionPowerEstimate() {
-            mUidPowerEstimatePosition = mUidStatsArrayLength++;
-        }
-
-        /**
-         * Converts the supplied mAh power estimate to a long and saves it in the corresponding
-         * element of <code>stats</code>.
-         */
-        public void setUidPowerEstimate(long[] stats, double power) {
-            stats[mUidPowerEstimatePosition] = (long) (power * MILLI_TO_NANO_MULTIPLIER);
-        }
-
-        /**
-         * Extracts the power estimate from a UID stats array and converts it to mAh.
-         */
-        public double getUidPowerEstimate(long[] stats) {
-            return stats[mUidPowerEstimatePosition] / MILLI_TO_NANO_MULTIPLIER;
-        }
-
-        /**
          * Copies the elements of the stats array layout into <code>extras</code>
          */
         public void toExtras(PersistableBundle extras) {
+            super.toExtras(extras);
             extras.putInt(EXTRA_DEVICE_TIME_BY_SCALING_STEP_POSITION,
                     mDeviceCpuTimeByScalingStepPosition);
             extras.putInt(EXTRA_DEVICE_TIME_BY_SCALING_STEP_COUNT,
@@ -339,22 +219,16 @@
                     mDeviceCpuTimeByClusterPosition);
             extras.putInt(EXTRA_DEVICE_TIME_BY_CLUSTER_COUNT,
                     mDeviceCpuTimeByClusterCount);
-            extras.putInt(EXTRA_DEVICE_UPTIME_POSITION, mDeviceCpuUptimePosition);
-            extras.putInt(EXTRA_DEVICE_ENERGY_CONSUMERS_POSITION,
-                    mDeviceEnergyConsumerPosition);
-            extras.putInt(EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT,
-                    mDeviceEnergyConsumerCount);
-            extras.putInt(EXTRA_DEVICE_POWER_POSITION, mDevicePowerEstimatePosition);
             extras.putInt(EXTRA_UID_BRACKETS_POSITION, mUidPowerBracketsPosition);
-            extras.putIntArray(EXTRA_UID_STATS_SCALING_STEP_TO_POWER_BRACKET,
+            putIntArray(extras, EXTRA_UID_STATS_SCALING_STEP_TO_POWER_BRACKET,
                     mScalingStepToPowerBracketMap);
-            extras.putInt(EXTRA_UID_POWER_POSITION, mUidPowerEstimatePosition);
         }
 
         /**
          * Retrieves elements of the stats array layout from <code>extras</code>
          */
         public void fromExtras(PersistableBundle extras) {
+            super.fromExtras(extras);
             mDeviceCpuTimeByScalingStepPosition =
                     extras.getInt(EXTRA_DEVICE_TIME_BY_SCALING_STEP_POSITION);
             mDeviceCpuTimeByScalingStepCount =
@@ -363,59 +237,48 @@
                     extras.getInt(EXTRA_DEVICE_TIME_BY_CLUSTER_POSITION);
             mDeviceCpuTimeByClusterCount =
                     extras.getInt(EXTRA_DEVICE_TIME_BY_CLUSTER_COUNT);
-            mDeviceCpuUptimePosition = extras.getInt(EXTRA_DEVICE_UPTIME_POSITION);
-            mDeviceEnergyConsumerPosition = extras.getInt(EXTRA_DEVICE_ENERGY_CONSUMERS_POSITION);
-            mDeviceEnergyConsumerCount = extras.getInt(EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT);
-            mDevicePowerEstimatePosition = extras.getInt(EXTRA_DEVICE_POWER_POSITION);
             mUidPowerBracketsPosition = extras.getInt(EXTRA_UID_BRACKETS_POSITION);
             mScalingStepToPowerBracketMap =
-                    extras.getIntArray(EXTRA_UID_STATS_SCALING_STEP_TO_POWER_BRACKET);
+                    getIntArray(extras, EXTRA_UID_STATS_SCALING_STEP_TO_POWER_BRACKET);
             if (mScalingStepToPowerBracketMap == null) {
                 mScalingStepToPowerBracketMap = new int[mDeviceCpuTimeByScalingStepCount];
             }
             updatePowerBracketCount();
-            mUidPowerEstimatePosition = extras.getInt(EXTRA_UID_POWER_POSITION);
         }
     }
 
     public CpuPowerStatsCollector(CpuScalingPolicies cpuScalingPolicies, PowerProfile powerProfile,
-            IntSupplier voltageSupplier, Handler handler, long throttlePeriodMs) {
-        this(cpuScalingPolicies, powerProfile, handler, new KernelCpuStatsReader(),
+            PowerStatsUidResolver uidResolver, IntSupplier voltageSupplier, Handler handler,
+            long throttlePeriodMs) {
+        this(cpuScalingPolicies, powerProfile, handler, new KernelCpuStatsReader(), uidResolver,
                 () -> LocalServices.getService(PowerStatsInternal.class), voltageSupplier,
                 throttlePeriodMs, Clock.SYSTEM_CLOCK, DEFAULT_CPU_POWER_BRACKETS,
                 DEFAULT_CPU_POWER_BRACKETS_PER_ENERGY_CONSUMER);
     }
 
     public CpuPowerStatsCollector(CpuScalingPolicies cpuScalingPolicies, PowerProfile powerProfile,
-                                  Handler handler, KernelCpuStatsReader kernelCpuStatsReader,
-            Supplier<PowerStatsInternal> powerStatsSupplier,
+            Handler handler, KernelCpuStatsReader kernelCpuStatsReader,
+            PowerStatsUidResolver uidResolver, Supplier<PowerStatsInternal> powerStatsSupplier,
             IntSupplier voltageSupplier, long throttlePeriodMs, Clock clock,
             int defaultCpuPowerBrackets, int defaultCpuPowerBracketsPerEnergyConsumer) {
         super(handler, throttlePeriodMs, clock);
         mCpuScalingPolicies = cpuScalingPolicies;
         mPowerProfile = powerProfile;
         mKernelCpuStatsReader = kernelCpuStatsReader;
+        mUidResolver = uidResolver;
         mPowerStatsSupplier = powerStatsSupplier;
         mVoltageSupplier = voltageSupplier;
         mDefaultCpuPowerBrackets = defaultCpuPowerBrackets;
         mDefaultCpuPowerBracketsPerEnergyConsumer = defaultCpuPowerBracketsPerEnergyConsumer;
-
     }
 
-    /**
-     * Initializes the collector during the boot sequence.
-     */
-    public void onSystemReady() {
-        setEnabled(Flags.streamlinedBatteryStats());
-    }
-
-    private void ensureInitialized() {
+    private boolean ensureInitialized() {
         if (mIsInitialized) {
-            return;
+            return true;
         }
 
         if (!isEnabled()) {
-            return;
+            return false;
         }
 
         mIsPerUidTimeInStateSupported = mKernelCpuStatsReader.nativeIsSupportedFeature();
@@ -432,10 +295,10 @@
         mTempCpuTimeByScalingStep = new long[cpuScalingStepCount];
         int[] scalingStepToPowerBracketMap = initPowerBrackets();
 
-        mLayout = new StatsArrayLayout();
+        mLayout = new CpuStatsArrayLayout();
         mLayout.addDeviceSectionCpuTimeByScalingStep(cpuScalingStepCount);
         mLayout.addDeviceSectionCpuTimeByCluster(mCpuScalingPolicies.getPolicies().length);
-        mLayout.addDeviceSectionUptime();
+        mLayout.addDeviceSectionUsageDuration();
         mLayout.addDeviceSectionEnergyConsumers(mCpuEnergyConsumerIds.length);
         mLayout.addDeviceSectionPowerEstimate();
         mLayout.addUidSectionCpuTimeByPowerBracket(scalingStepToPowerBracketMap);
@@ -451,6 +314,7 @@
         mTempUidStats = new long[mLayout.getCpuPowerBracketCount()];
 
         mIsInitialized = true;
+        return true;
     }
 
     private void readCpuEnergyConsumerIds() {
@@ -590,7 +454,9 @@
      * Prints the definitions of power brackets.
      */
     public void dumpCpuPowerBracketsLocked(PrintWriter pw) {
-        ensureInitialized();
+        if (!ensureInitialized()) {
+            return;
+        }
 
         if (mLayout == null) {
             return;
@@ -610,7 +476,9 @@
      */
     @VisibleForTesting
     public String getCpuPowerBracketDescription(int powerBracket) {
-        ensureInitialized();
+        if (!ensureInitialized()) {
+            return "";
+        }
 
         int[] stepToPowerBracketMap = mLayout.getScalingStepToPowerBracketMap();
         StringBuilder sb = new StringBuilder();
@@ -647,14 +515,18 @@
      */
     @VisibleForTesting
     public PowerStats.Descriptor getPowerStatsDescriptor() {
-        ensureInitialized();
+        if (!ensureInitialized()) {
+            return null;
+        }
 
         return mPowerStatsDescriptor;
     }
 
     @Override
     protected PowerStats collectStats() {
-        ensureInitialized();
+        if (!ensureInitialized()) {
+            return null;
+        }
 
         if (!mIsPerUidTimeInStateSupported) {
             return null;
@@ -682,7 +554,7 @@
         if (uptimeDelta > mCpuPowerStats.durationMs) {
             uptimeDelta = mCpuPowerStats.durationMs;
         }
-        mLayout.setUptime(mCpuPowerStats.stats, uptimeDelta);
+        mLayout.setUsageDuration(mCpuPowerStats.stats, uptimeDelta);
 
         if (mCpuEnergyConsumerIds.length != 0) {
             collectEnergyConsumers();
@@ -761,7 +633,21 @@
             uidStats.timeByPowerBracket[bracket] = timeByPowerBracket[bracket];
         }
         if (nonzero) {
-            mCpuPowerStats.uidStats.put(uid, uidStats.stats);
+            int ownerUid;
+            if (Process.isSdkSandboxUid(uid)) {
+                ownerUid = Process.getAppUidForSdkSandboxUid(uid);
+            } else {
+                ownerUid = mUidResolver.mapUid(uid);
+            }
+
+            long[] ownerStats = mCpuPowerStats.uidStats.get(ownerUid);
+            if (ownerStats == null) {
+                mCpuPowerStats.uidStats.put(ownerUid, uidStats.stats);
+            } else {
+                for (int i = 0; i < ownerStats.length; i++) {
+                    ownerStats[i] += uidStats.stats[i];
+                }
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java b/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java
index 2c7843e..0facb9c 100644
--- a/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java
+++ b/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java
@@ -44,6 +44,7 @@
     private static final String XML_TAG_DEVICE_STATS = "device-stats";
     private static final String XML_TAG_UID_STATS = "uid-stats";
     private static final String XML_ATTR_UID = "uid";
+    private static final long UNKNOWN = -1;
 
     public final int powerComponentId;
     private final MultiStateStats.States[] mDeviceStateConfig;
@@ -51,17 +52,16 @@
     @NonNull
     private final AggregatedPowerStatsConfig.PowerComponent mConfig;
     private final int[] mDeviceStates;
-    private final long[] mDeviceStateTimestamps;
 
     private MultiStateStats.Factory mStatsFactory;
     private MultiStateStats.Factory mUidStatsFactory;
     private PowerStats.Descriptor mPowerStatsDescriptor;
+    private long mPowerStatsTimestamp;
     private MultiStateStats mDeviceStats;
     private final SparseArray<UidStats> mUidStats = new SparseArray<>();
 
     private static class UidStats {
         public int[] states;
-        public long[] stateTimestampMs;
         public MultiStateStats stats;
     }
 
@@ -71,7 +71,7 @@
         mDeviceStateConfig = config.getDeviceStateConfig();
         mUidStateConfig = config.getUidStateConfig();
         mDeviceStates = new int[mDeviceStateConfig.length];
-        mDeviceStateTimestamps = new long[mDeviceStateConfig.length];
+        mPowerStatsTimestamp = UNKNOWN;
     }
 
     @NonNull
@@ -85,8 +85,11 @@
     }
 
     void setState(@AggregatedPowerStatsConfig.TrackedState int stateId, int state, long time) {
+        if (mDeviceStats == null) {
+            createDeviceStats();
+        }
+
         mDeviceStates[stateId] = state;
-        mDeviceStateTimestamps[stateId] = time;
 
         if (mDeviceStateConfig[stateId].isTracked()) {
             if (mDeviceStats != null) {
@@ -97,6 +100,11 @@
         if (mUidStateConfig[stateId].isTracked()) {
             for (int i = mUidStats.size() - 1; i >= 0; i--) {
                 PowerComponentAggregatedPowerStats.UidStats uidStats = mUidStats.valueAt(i);
+                if (uidStats.stats == null) {
+                    createUidStats(uidStats);
+                }
+
+                uidStats.states[stateId] = state;
                 if (uidStats.stats != null) {
                     uidStats.stats.setState(stateId, state, time);
                 }
@@ -111,8 +119,11 @@
         }
 
         UidStats uidStats = getUidStats(uid);
+        if (uidStats.stats == null) {
+            createUidStats(uidStats);
+        }
+
         uidStats.states[stateId] = state;
-        uidStats.stateTimestampMs[stateId] = time;
 
         if (uidStats.stats != null) {
             uidStats.stats.setState(stateId, state, time);
@@ -150,10 +161,11 @@
             }
             uidStats.stats.increment(powerStats.uidStats.valueAt(i), timestampMs);
         }
+
+        mPowerStatsTimestamp = timestampMs;
     }
 
     void reset() {
-        mPowerStatsDescriptor = null;
         mStatsFactory = null;
         mUidStatsFactory = null;
         mDeviceStats = null;
@@ -163,12 +175,10 @@
     }
 
     private UidStats getUidStats(int uid) {
-        // TODO(b/292247660): map isolated and sandbox UIDs
         UidStats uidStats = mUidStats.get(uid);
         if (uidStats == null) {
             uidStats = new UidStats();
             uidStats.states = new int[mUidStateConfig.length];
-            uidStats.stateTimestampMs = new long[mUidStateConfig.length];
             mUidStats.put(uid, uidStats);
         }
         return uidStats;
@@ -209,42 +219,38 @@
         return false;
     }
 
-    private boolean createDeviceStats() {
+    private void createDeviceStats() {
         if (mStatsFactory == null) {
             if (mPowerStatsDescriptor == null) {
-                return false;
+                return;
             }
             mStatsFactory = new MultiStateStats.Factory(
                     mPowerStatsDescriptor.statsArrayLength, mDeviceStateConfig);
         }
 
         mDeviceStats = mStatsFactory.create();
-        for (int stateId = 0; stateId < mDeviceStateConfig.length; stateId++) {
-            mDeviceStats.setState(stateId, mDeviceStates[stateId],
-                    mDeviceStateTimestamps[stateId]);
+        if (mPowerStatsTimestamp != UNKNOWN) {
+            for (int stateId = 0; stateId < mDeviceStateConfig.length; stateId++) {
+                mDeviceStats.setState(stateId, mDeviceStates[stateId], mPowerStatsTimestamp);
+            }
         }
-        return true;
     }
 
-    private boolean createUidStats(UidStats uidStats) {
+    private void createUidStats(UidStats uidStats) {
         if (mUidStatsFactory == null) {
             if (mPowerStatsDescriptor == null) {
-                return false;
+                return;
             }
             mUidStatsFactory = new MultiStateStats.Factory(
                     mPowerStatsDescriptor.uidStatsArrayLength, mUidStateConfig);
         }
 
         uidStats.stats = mUidStatsFactory.create();
-        for (int stateId = 0; stateId < mDeviceStateConfig.length; stateId++) {
-            uidStats.stats.setState(stateId, mDeviceStates[stateId],
-                    mDeviceStateTimestamps[stateId]);
+        for (int stateId = 0; stateId < mUidStateConfig.length; stateId++) {
+            if (mPowerStatsTimestamp != UNKNOWN) {
+                uidStats.stats.setState(stateId, uidStats.states[stateId], mPowerStatsTimestamp);
+            }
         }
-        for (int stateId = mDeviceStateConfig.length; stateId < mUidStateConfig.length; stateId++) {
-            uidStats.stats.setState(stateId, uidStats.states[stateId],
-                    uidStats.stateTimestampMs[stateId]);
-        }
-        return true;
     }
 
     public void writeXml(TypedXmlSerializer serializer) throws IOException {
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
index 2f9d567..3f88a2d 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
@@ -29,13 +29,18 @@
  * {@link AggregatedPowerStats} that adds up power stats from the samples found in battery history.
  */
 public class PowerStatsAggregator {
+    private static final long UNINITIALIZED = -1;
     private final AggregatedPowerStats mStats;
+    private final AggregatedPowerStatsConfig mAggregatedPowerStatsConfig;
     private final BatteryStatsHistory mHistory;
     private final SparseArray<AggregatedPowerStatsProcessor> mProcessors = new SparseArray<>();
+    private int mCurrentBatteryState = AggregatedPowerStatsConfig.POWER_STATE_BATTERY;
+    private int mCurrentScreenState = AggregatedPowerStatsConfig.SCREEN_STATE_OTHER;
 
     public PowerStatsAggregator(AggregatedPowerStatsConfig aggregatedPowerStatsConfig,
             BatteryStatsHistory history) {
         mStats = new AggregatedPowerStats(aggregatedPowerStatsConfig);
+        mAggregatedPowerStatsConfig = aggregatedPowerStatsConfig;
         mHistory = history;
         for (AggregatedPowerStatsConfig.PowerComponent powerComponentsConfig :
                 aggregatedPowerStatsConfig.getPowerComponentsAggregatedStatsConfigs()) {
@@ -44,6 +49,10 @@
         }
     }
 
+    AggregatedPowerStatsConfig getConfig() {
+        return mAggregatedPowerStatsConfig;
+    }
+
     /**
      * Iterates of the battery history and aggregates power stats between the specified times.
      * The start and end are specified in the battery-stats monotonic time, which is the
@@ -58,18 +67,20 @@
      */
     public void aggregatePowerStats(long startTimeMs, long endTimeMs,
             Consumer<AggregatedPowerStats> consumer) {
-        int currentBatteryState = AggregatedPowerStatsConfig.POWER_STATE_BATTERY;
-        int currentScreenState = AggregatedPowerStatsConfig.SCREEN_STATE_OTHER;
-        long baseTime = -1;
+        boolean clockUpdateAdded = false;
+        long baseTime = startTimeMs > 0 ? startTimeMs : UNINITIALIZED;
         long lastTime = 0;
         try (BatteryStatsHistoryIterator iterator =
                      mHistory.copy().iterate(startTimeMs, endTimeMs)) {
             while (iterator.hasNext()) {
                 BatteryStats.HistoryItem item = iterator.next();
 
-                if (baseTime < 0) {
+                if (!clockUpdateAdded) {
                     mStats.addClockUpdate(item.time, item.currentTime);
-                    baseTime = item.time;
+                    if (baseTime == UNINITIALIZED) {
+                        baseTime = item.time;
+                    }
+                    clockUpdateAdded = true;
                 } else if (item.cmd == BatteryStats.HistoryItem.CMD_CURRENT_TIME
                            || item.cmd == BatteryStats.HistoryItem.CMD_RESET) {
                     mStats.addClockUpdate(item.time, item.currentTime);
@@ -81,20 +92,20 @@
                         (item.states & BatteryStats.HistoryItem.STATE_BATTERY_PLUGGED_FLAG) != 0
                                 ? AggregatedPowerStatsConfig.POWER_STATE_OTHER
                                 : AggregatedPowerStatsConfig.POWER_STATE_BATTERY;
-                if (batteryState != currentBatteryState) {
+                if (batteryState != mCurrentBatteryState) {
                     mStats.setDeviceState(AggregatedPowerStatsConfig.STATE_POWER, batteryState,
                             item.time);
-                    currentBatteryState = batteryState;
+                    mCurrentBatteryState = batteryState;
                 }
 
                 int screenState =
                         (item.states & BatteryStats.HistoryItem.STATE_SCREEN_ON_FLAG) != 0
                                 ? AggregatedPowerStatsConfig.SCREEN_STATE_ON
                                 : AggregatedPowerStatsConfig.SCREEN_STATE_OTHER;
-                if (screenState != currentScreenState) {
+                if (screenState != mCurrentScreenState) {
                     mStats.setDeviceState(AggregatedPowerStatsConfig.STATE_SCREEN, screenState,
                             item.time);
-                    currentScreenState = screenState;
+                    mCurrentScreenState = screenState;
                 }
 
                 if (item.processStateChange != null) {
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsCollector.java b/services/core/java/com/android/server/power/stats/PowerStatsCollector.java
index 84cc21e..abfe9de 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsCollector.java
@@ -16,10 +16,13 @@
 
 package com.android.server.power.stats;
 
+import android.annotation.Nullable;
 import android.os.ConditionVariable;
 import android.os.Handler;
+import android.os.PersistableBundle;
 import android.util.FastImmutableArraySet;
 import android.util.IndentingPrintWriter;
+import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.Clock;
@@ -38,6 +41,7 @@
  * except where noted.
  */
 public abstract class PowerStatsCollector {
+    private static final String TAG = "PowerStatsCollector";
     private static final int MILLIVOLTS_PER_VOLT = 1000;
     private final Handler mHandler;
     protected final Clock mClock;
@@ -46,6 +50,200 @@
     private boolean mEnabled;
     private long mLastScheduledUpdateMs = -1;
 
+    /**
+     * Captures the positions and lengths of sections of the stats array, such as usage duration,
+     * power usage estimates etc.
+     */
+    public static class StatsArrayLayout {
+        private static final String EXTRA_DEVICE_POWER_POSITION = "dp";
+        private static final String EXTRA_DEVICE_DURATION_POSITION = "dd";
+        private static final String EXTRA_DEVICE_ENERGY_CONSUMERS_POSITION = "de";
+        private static final String EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT = "dec";
+        private static final String EXTRA_UID_POWER_POSITION = "up";
+
+        protected static final double MILLI_TO_NANO_MULTIPLIER = 1000000.0;
+
+        private int mDeviceStatsArrayLength;
+        private int mUidStatsArrayLength;
+
+        protected int mDeviceDurationPosition;
+        private int mDeviceEnergyConsumerPosition;
+        private int mDeviceEnergyConsumerCount;
+        private int mDevicePowerEstimatePosition;
+        private int mUidPowerEstimatePosition;
+
+        public int getDeviceStatsArrayLength() {
+            return mDeviceStatsArrayLength;
+        }
+
+        public int getUidStatsArrayLength() {
+            return mUidStatsArrayLength;
+        }
+
+        protected int addDeviceSection(int length) {
+            int position = mDeviceStatsArrayLength;
+            mDeviceStatsArrayLength += length;
+            return position;
+        }
+
+        protected int addUidSection(int length) {
+            int position = mUidStatsArrayLength;
+            mUidStatsArrayLength += length;
+            return position;
+        }
+
+        /**
+         * Declare that the stats array has a section capturing usage duration
+         */
+        public void addDeviceSectionUsageDuration() {
+            mDeviceDurationPosition = addDeviceSection(1);
+        }
+
+        /**
+         * Saves the usage duration in the corresponding <code>stats</code> element.
+         */
+        public void setUsageDuration(long[] stats, long value) {
+            stats[mDeviceDurationPosition] = value;
+        }
+
+        /**
+         * Extracts the usage duration from the corresponding <code>stats</code> element.
+         */
+        public long getUsageDuration(long[] stats) {
+            return stats[mDeviceDurationPosition];
+        }
+
+        /**
+         * Declares that the stats array has a section capturing EnergyConsumer data from
+         * PowerStatsService.
+         */
+        public void addDeviceSectionEnergyConsumers(int energyConsumerCount) {
+            mDeviceEnergyConsumerPosition = addDeviceSection(energyConsumerCount);
+            mDeviceEnergyConsumerCount = energyConsumerCount;
+        }
+
+        public int getEnergyConsumerCount() {
+            return mDeviceEnergyConsumerCount;
+        }
+
+        /**
+         * Saves the accumulated energy for the specified rail the corresponding
+         * <code>stats</code> element.
+         */
+        public void setConsumedEnergy(long[] stats, int index, long energy) {
+            stats[mDeviceEnergyConsumerPosition + index] = energy;
+        }
+
+        /**
+         * Extracts the EnergyConsumer data from a device stats array for the specified
+         * EnergyConsumer.
+         */
+        public long getConsumedEnergy(long[] stats, int index) {
+            return stats[mDeviceEnergyConsumerPosition + index];
+        }
+
+        /**
+         * Declare that the stats array has a section capturing a power estimate
+         */
+        public void addDeviceSectionPowerEstimate() {
+            mDevicePowerEstimatePosition = addDeviceSection(1);
+        }
+
+        /**
+         * Converts the supplied mAh power estimate to a long and saves it in the corresponding
+         * element of <code>stats</code>.
+         */
+        public void setDevicePowerEstimate(long[] stats, double power) {
+            stats[mDevicePowerEstimatePosition] = (long) (power * MILLI_TO_NANO_MULTIPLIER);
+        }
+
+        /**
+         * Extracts the power estimate from a device stats array and converts it to mAh.
+         */
+        public double getDevicePowerEstimate(long[] stats) {
+            return stats[mDevicePowerEstimatePosition] / MILLI_TO_NANO_MULTIPLIER;
+        }
+
+        /**
+         * Declare that the UID stats array has a section capturing a power estimate
+         */
+        public void addUidSectionPowerEstimate() {
+            mUidPowerEstimatePosition = addUidSection(1);
+        }
+
+        /**
+         * Converts the supplied mAh power estimate to a long and saves it in the corresponding
+         * element of <code>stats</code>.
+         */
+        public void setUidPowerEstimate(long[] stats, double power) {
+            stats[mUidPowerEstimatePosition] = (long) (power * MILLI_TO_NANO_MULTIPLIER);
+        }
+
+        /**
+         * Extracts the power estimate from a UID stats array and converts it to mAh.
+         */
+        public double getUidPowerEstimate(long[] stats) {
+            return stats[mUidPowerEstimatePosition] / MILLI_TO_NANO_MULTIPLIER;
+        }
+
+        /**
+         * Copies the elements of the stats array layout into <code>extras</code>
+         */
+        public void toExtras(PersistableBundle extras) {
+            extras.putInt(EXTRA_DEVICE_DURATION_POSITION, mDeviceDurationPosition);
+            extras.putInt(EXTRA_DEVICE_ENERGY_CONSUMERS_POSITION,
+                    mDeviceEnergyConsumerPosition);
+            extras.putInt(EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT,
+                    mDeviceEnergyConsumerCount);
+            extras.putInt(EXTRA_DEVICE_POWER_POSITION, mDevicePowerEstimatePosition);
+            extras.putInt(EXTRA_UID_POWER_POSITION, mUidPowerEstimatePosition);
+        }
+
+        /**
+         * Retrieves elements of the stats array layout from <code>extras</code>
+         */
+        public void fromExtras(PersistableBundle extras) {
+            mDeviceDurationPosition = extras.getInt(EXTRA_DEVICE_DURATION_POSITION);
+            mDeviceEnergyConsumerPosition = extras.getInt(EXTRA_DEVICE_ENERGY_CONSUMERS_POSITION);
+            mDeviceEnergyConsumerCount = extras.getInt(EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT);
+            mDevicePowerEstimatePosition = extras.getInt(EXTRA_DEVICE_POWER_POSITION);
+            mUidPowerEstimatePosition = extras.getInt(EXTRA_UID_POWER_POSITION);
+        }
+
+        protected void putIntArray(PersistableBundle extras, String key, int[] array) {
+            if (array == null) {
+                return;
+            }
+
+            StringBuilder sb = new StringBuilder();
+            for (int value : array) {
+                if (!sb.isEmpty()) {
+                    sb.append(',');
+                }
+                sb.append(value);
+            }
+            extras.putString(key, sb.toString());
+        }
+
+        protected int[] getIntArray(PersistableBundle extras, String key) {
+            String string = extras.getString(key);
+            if (string == null) {
+                return null;
+            }
+            String[] values = string.trim().split(",");
+            int[] result = new int[values.length];
+            for (int i = 0; i < values.length; i++) {
+                try {
+                    result[i] = Integer.parseInt(values[i]);
+                } catch (NumberFormatException e) {
+                    Slog.wtf(TAG, "Invalid CSV format: " + string);
+                    return null;
+                }
+            }
+            return result;
+        }
+    }
+
     @GuardedBy("this")
     @SuppressWarnings("unchecked")
     private volatile FastImmutableArraySet<Consumer<PowerStats>> mConsumerList =
@@ -141,6 +339,7 @@
         return true;
     }
 
+    @Nullable
     protected abstract PowerStats collectStats();
 
     /**
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsExporter.java b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
new file mode 100644
index 0000000..70c24d5
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power.stats;
+
+import android.os.AggregateBatteryConsumer;
+import android.os.BatteryConsumer;
+import android.os.BatteryUsageStats;
+import android.os.UidBatteryConsumer;
+import android.util.Slog;
+
+import com.android.internal.os.MultiStateStats;
+import com.android.internal.os.PowerStats;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Given a time range, converts accumulated PowerStats to BatteryUsageStats.  Combines
+ * stores spans of PowerStats with the yet-unprocessed tail of battery history.
+ */
+public class PowerStatsExporter {
+    private static final String TAG = "PowerStatsExporter";
+    private final PowerStatsStore mPowerStatsStore;
+    private final PowerStatsAggregator mPowerStatsAggregator;
+    private final long mBatterySessionTimeSpanSlackMillis;
+    private static final long BATTERY_SESSION_TIME_SPAN_SLACK_MILLIS = TimeUnit.MINUTES.toMillis(2);
+
+    public PowerStatsExporter(PowerStatsStore powerStatsStore,
+            PowerStatsAggregator powerStatsAggregator) {
+        this(powerStatsStore, powerStatsAggregator, BATTERY_SESSION_TIME_SPAN_SLACK_MILLIS);
+    }
+
+    public PowerStatsExporter(PowerStatsStore powerStatsStore,
+            PowerStatsAggregator powerStatsAggregator,
+            long batterySessionTimeSpanSlackMillis) {
+        mPowerStatsStore = powerStatsStore;
+        mPowerStatsAggregator = powerStatsAggregator;
+        mBatterySessionTimeSpanSlackMillis = batterySessionTimeSpanSlackMillis;
+    }
+
+    /**
+     * Populates the provided BatteryUsageStats.Builder with power estimates from the accumulated
+     * PowerStats, both stored in PowerStatsStore and not-yet processed.
+     */
+    public void exportAggregatedPowerStats(BatteryUsageStats.Builder batteryUsageStatsBuilder,
+            long monotonicStartTime, long monotonicEndTime) {
+        long maxEndTime = monotonicStartTime;
+        List<PowerStatsSpan.Metadata> spans = mPowerStatsStore.getTableOfContents();
+        for (int i = spans.size() - 1; i >= 0; i--) {
+            PowerStatsSpan.Metadata metadata = spans.get(i);
+            if (!metadata.getSections().contains(AggregatedPowerStatsSection.TYPE)) {
+                continue;
+            }
+
+            List<PowerStatsSpan.TimeFrame> timeFrames = metadata.getTimeFrames();
+            long spanMinTime = Long.MAX_VALUE;
+            long spanMaxTime = Long.MIN_VALUE;
+            for (int j = 0; j < timeFrames.size(); j++) {
+                PowerStatsSpan.TimeFrame timeFrame = timeFrames.get(j);
+                long startMonotonicTime = timeFrame.startMonotonicTime;
+                long endMonotonicTime = startMonotonicTime + timeFrame.duration;
+                if (startMonotonicTime < spanMinTime) {
+                    spanMinTime = startMonotonicTime;
+                }
+                if (endMonotonicTime > spanMaxTime) {
+                    spanMaxTime = endMonotonicTime;
+                }
+            }
+
+            if (!(spanMinTime >= monotonicStartTime && spanMaxTime < monotonicEndTime)) {
+                continue;
+            }
+
+            if (spanMaxTime > maxEndTime) {
+                maxEndTime = spanMaxTime;
+            }
+
+            PowerStatsSpan span = mPowerStatsStore.loadPowerStatsSpan(metadata.getId(),
+                    AggregatedPowerStatsSection.TYPE);
+            if (span == null) {
+                Slog.e(TAG, "Could not read PowerStatsStore section " + metadata);
+                continue;
+            }
+            List<PowerStatsSpan.Section> sections = span.getSections();
+            for (int k = 0; k < sections.size(); k++) {
+                PowerStatsSpan.Section section = sections.get(k);
+                populateBatteryUsageStatsBuilder(batteryUsageStatsBuilder,
+                        ((AggregatedPowerStatsSection) section).getAggregatedPowerStats());
+            }
+        }
+
+        if (maxEndTime < monotonicEndTime - mBatterySessionTimeSpanSlackMillis) {
+            mPowerStatsAggregator.aggregatePowerStats(maxEndTime, monotonicEndTime,
+                    stats -> populateBatteryUsageStatsBuilder(batteryUsageStatsBuilder, stats));
+        }
+    }
+
+    private void populateBatteryUsageStatsBuilder(
+            BatteryUsageStats.Builder batteryUsageStatsBuilder, AggregatedPowerStats stats) {
+        AggregatedPowerStatsConfig config = mPowerStatsAggregator.getConfig();
+        List<AggregatedPowerStatsConfig.PowerComponent> powerComponents =
+                config.getPowerComponentsAggregatedStatsConfigs();
+        for (int i = powerComponents.size() - 1; i >= 0; i--) {
+            populateBatteryUsageStatsBuilder(batteryUsageStatsBuilder, stats,
+                    powerComponents.get(i));
+        }
+    }
+
+    private void populateBatteryUsageStatsBuilder(
+            BatteryUsageStats.Builder batteryUsageStatsBuilder, AggregatedPowerStats stats,
+            AggregatedPowerStatsConfig.PowerComponent powerComponent) {
+        int powerComponentId = powerComponent.getPowerComponentId();
+        PowerComponentAggregatedPowerStats powerComponentStats = stats.getPowerComponentStats(
+                powerComponentId);
+        if (powerComponentStats == null) {
+            return;
+        }
+
+        PowerStats.Descriptor descriptor = powerComponentStats.getPowerStatsDescriptor();
+        if (descriptor == null) {
+            return;
+        }
+
+        PowerStatsCollector.StatsArrayLayout layout = new PowerStatsCollector.StatsArrayLayout();
+        layout.fromExtras(descriptor.extras);
+
+        long[] deviceStats = new long[descriptor.statsArrayLength];
+        double[] totalPower = new double[1];
+        MultiStateStats.States.forEachTrackedStateCombination(powerComponent.getDeviceStateConfig(),
+                states -> {
+                    if (states[AggregatedPowerStatsConfig.STATE_POWER]
+                            != AggregatedPowerStatsConfig.POWER_STATE_BATTERY) {
+                        return;
+                    }
+
+                    if (!powerComponentStats.getDeviceStats(deviceStats, states)) {
+                        return;
+                    }
+
+                    totalPower[0] += layout.getDevicePowerEstimate(deviceStats);
+                });
+
+        AggregateBatteryConsumer.Builder deviceScope =
+                batteryUsageStatsBuilder.getAggregateBatteryConsumerBuilder(
+                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
+        deviceScope.addConsumedPower(powerComponentId,
+                totalPower[0], BatteryConsumer.POWER_MODEL_UNDEFINED);
+
+        long[] uidStats = new long[descriptor.uidStatsArrayLength];
+        ArrayList<Integer> uids = new ArrayList<>();
+        powerComponentStats.collectUids(uids);
+
+        boolean breakDownByProcState =
+                batteryUsageStatsBuilder.isProcessStateDataNeeded()
+                && powerComponent
+                        .getUidStateConfig()[AggregatedPowerStatsConfig.STATE_PROCESS_STATE]
+                        .isTracked();
+
+        double[] powerByProcState =
+                new double[breakDownByProcState ? BatteryConsumer.PROCESS_STATE_COUNT : 1];
+        double powerAllApps = 0;
+        for (int uid : uids) {
+            UidBatteryConsumer.Builder builder =
+                    batteryUsageStatsBuilder.getOrCreateUidBatteryConsumerBuilder(uid);
+
+            Arrays.fill(powerByProcState, 0);
+
+            MultiStateStats.States.forEachTrackedStateCombination(
+                    powerComponent.getUidStateConfig(),
+                    states -> {
+                        if (states[AggregatedPowerStatsConfig.STATE_POWER]
+                                != AggregatedPowerStatsConfig.POWER_STATE_BATTERY) {
+                            return;
+                        }
+
+                        if (!powerComponentStats.getUidStats(uidStats, uid, states)) {
+                            return;
+                        }
+
+                        double power = layout.getUidPowerEstimate(uidStats);
+                        int procState = breakDownByProcState
+                                ? states[AggregatedPowerStatsConfig.STATE_PROCESS_STATE]
+                                : BatteryConsumer.PROCESS_STATE_UNSPECIFIED;
+                        powerByProcState[procState] += power;
+                    });
+
+            double powerAllProcStates = 0;
+            for (int procState = 0; procState < powerByProcState.length; procState++) {
+                double power = powerByProcState[procState];
+                if (power == 0) {
+                    continue;
+                }
+                powerAllProcStates += power;
+                if (breakDownByProcState
+                        && procState != BatteryConsumer.PROCESS_STATE_UNSPECIFIED) {
+                    builder.addConsumedPower(builder.getKey(powerComponentId, procState),
+                            power, BatteryConsumer.POWER_MODEL_UNDEFINED);
+                }
+            }
+            builder.addConsumedPower(powerComponentId, powerAllProcStates,
+                    BatteryConsumer.POWER_MODEL_UNDEFINED);
+            powerAllApps += powerAllProcStates;
+        }
+
+        AggregateBatteryConsumer.Builder allAppsScope =
+                batteryUsageStatsBuilder.getAggregateBatteryConsumerBuilder(
+                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
+        allAppsScope.addConsumedPower(powerComponentId, powerAllApps,
+                BatteryConsumer.POWER_MODEL_UNDEFINED);
+    }
+}
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsScheduler.java b/services/core/java/com/android/server/power/stats/PowerStatsScheduler.java
index 551302e..97d872a 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsScheduler.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsScheduler.java
@@ -19,8 +19,6 @@
 import android.annotation.DurationMillisLong;
 import android.app.AlarmManager;
 import android.content.Context;
-import android.os.BatteryUsageStats;
-import android.os.BatteryUsageStatsQuery;
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.util.IndentingPrintWriter;
@@ -52,7 +50,6 @@
     private final MonotonicClock mMonotonicClock;
     private final Handler mHandler;
     private final BatteryStatsImpl mBatteryStats;
-    private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;
     private final PowerStatsAggregator mPowerStatsAggregator;
     private long mLastSavedSpanEndMonotonicTime;
 
@@ -60,7 +57,7 @@
             @DurationMillisLong long aggregatedPowerStatsSpanDuration,
             @DurationMillisLong long powerStatsAggregationPeriod, PowerStatsStore powerStatsStore,
             Clock clock, MonotonicClock monotonicClock, Handler handler,
-            BatteryStatsImpl batteryStats, BatteryUsageStatsProvider batteryUsageStatsProvider) {
+            BatteryStatsImpl batteryStats) {
         mContext = context;
         mPowerStatsAggregator = powerStatsAggregator;
         mAggregatedPowerStatsSpanDuration = aggregatedPowerStatsSpanDuration;
@@ -70,16 +67,15 @@
         mMonotonicClock = monotonicClock;
         mHandler = handler;
         mBatteryStats = batteryStats;
-        mBatteryUsageStatsProvider = batteryUsageStatsProvider;
     }
 
     /**
      * Kicks off the scheduling of power stats aggregation spans.
      */
     public void start(boolean enablePeriodicPowerStatsCollection) {
-        mBatteryStats.setBatteryResetListener(this::storeBatteryUsageStatsOnReset);
         mEnablePeriodicPowerStatsCollection = enablePeriodicPowerStatsCollection;
         if (mEnablePeriodicPowerStatsCollection) {
+            schedulePowerStatsAggregation();
             scheduleNextPowerStatsAggregation();
         }
     }
@@ -235,28 +231,6 @@
         mPowerStatsStore.storeAggregatedPowerStats(stats);
     }
 
-    private void storeBatteryUsageStatsOnReset(int resetReason) {
-        if (resetReason == BatteryStatsImpl.RESET_REASON_CORRUPT_FILE) {
-            return;
-        }
-
-        final BatteryUsageStats batteryUsageStats =
-                mBatteryUsageStatsProvider.getBatteryUsageStats(
-                        new BatteryUsageStatsQuery.Builder()
-                                .setMaxStatsAgeMs(0)
-                                .includePowerModels()
-                                .includeProcessStateData()
-                                .build());
-
-        // TODO(b/188068523): BatteryUsageStats should use monotonic time for start and end
-        // Once that change is made, we will be able to use the BatteryUsageStats' monotonic
-        // start time
-        long monotonicStartTime =
-                mMonotonicClock.monotonicTime() - batteryUsageStats.getStatsDuration();
-        mHandler.post(() ->
-                mPowerStatsStore.storeBatteryUsageStats(monotonicStartTime, batteryUsageStats));
-    }
-
     private void awaitCompletion() {
         ConditionVariable done = new ConditionVariable();
         mHandler.post(done::open);
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsUidResolver.java b/services/core/java/com/android/server/power/stats/PowerStatsUidResolver.java
new file mode 100644
index 0000000..8dc3609
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/PowerStatsUidResolver.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power.stats;
+
+import android.util.IntArray;
+import android.util.Slog;
+import android.util.SparseIntArray;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Maintains a map of isolated UIDs to their respective owner UIDs, to support combining
+ * power stats for isolated UIDs, which are typically short-lived, into the corresponding app UID.
+ */
+public class PowerStatsUidResolver {
+    private static final String TAG = "PowerStatsUidResolver";
+
+    /**
+     * Listener notified when isolated UIDs are created and removed.
+     */
+    public interface Listener {
+
+        /**
+         * Callback invoked when a new isolated UID is registered.
+         */
+        void onIsolatedUidAdded(int isolatedUid, int parentUid);
+
+        /**
+         * Callback invoked before an isolated UID is evicted from the resolver.
+         * If the listener calls {@link PowerStatsUidResolver#retainIsolatedUid}, the mapping
+         * will be retained until {@link PowerStatsUidResolver#releaseIsolatedUid} is called.
+         */
+        void onBeforeIsolatedUidRemoved(int isolatedUid, int parentUid);
+
+        /**
+         * Callback invoked when an isolated UID to owner UID mapping is removed.
+         */
+        void onAfterIsolatedUidRemoved(int isolatedUid, int parentUid);
+    }
+
+    /**
+     * Mapping isolated uids to the actual owning app uid.
+     */
+    private final SparseIntArray mIsolatedUids = new SparseIntArray();
+
+    /**
+     * Internal reference count of isolated uids.
+     */
+    private final SparseIntArray mIsolatedUidRefCounts = new SparseIntArray();
+
+    // Keep the list read-only in order to avoid locking during the delivery of listener calls.
+    private volatile List<Listener> mListeners = Collections.emptyList();
+
+    /**
+     * Adds a listener.
+     */
+    public void addListener(Listener listener) {
+        synchronized (this) {
+            List<Listener> newList = new ArrayList<>(mListeners);
+            newList.add(listener);
+            mListeners = Collections.unmodifiableList(newList);
+        }
+    }
+
+    /**
+     * Removes a listener.
+     */
+    public void removeListener(Listener listener) {
+        synchronized (this) {
+            List<Listener> newList = new ArrayList<>(mListeners);
+            newList.remove(listener);
+            mListeners = Collections.unmodifiableList(newList);
+        }
+    }
+
+    /**
+     * Remembers the connection between a newly created isolated UID and its owner app UID.
+     * Calls {@link Listener#onIsolatedUidAdded} on each registered listener.
+     */
+    public void noteIsolatedUidAdded(int isolatedUid, int parentUid) {
+        synchronized (this) {
+            mIsolatedUids.put(isolatedUid, parentUid);
+            mIsolatedUidRefCounts.put(isolatedUid, 1);
+        }
+
+        List<Listener> listeners = mListeners;
+        for (int i = listeners.size() - 1; i >= 0; i--) {
+            listeners.get(i).onIsolatedUidAdded(isolatedUid, parentUid);
+        }
+    }
+
+    /**
+     * Handles the removal of an isolated UID by invoking
+     * {@link Listener#onBeforeIsolatedUidRemoved} on each registered listener and the releases
+     * the UID, see {@link #releaseIsolatedUid}.
+     */
+    public void noteIsolatedUidRemoved(int isolatedUid, int parentUid) {
+        synchronized (this) {
+            int curUid = mIsolatedUids.get(isolatedUid, -1);
+            if (curUid != parentUid) {
+                Slog.wtf(TAG, "Attempt to remove an isolated UID " + isolatedUid
+                              + " with the parent UID " + parentUid
+                              + ". The registered parent UID is " + curUid);
+                return;
+            }
+        }
+
+        List<Listener> listeners = mListeners;
+        for (int i = listeners.size() - 1; i >= 0; i--) {
+            listeners.get(i).onBeforeIsolatedUidRemoved(isolatedUid, parentUid);
+        }
+
+        releaseIsolatedUid(isolatedUid);
+    }
+
+    /**
+     * Increments the ref count for an isolated uid.
+     * Call #releaseIsolatedUid to decrement.
+     */
+    public void retainIsolatedUid(int uid) {
+        synchronized (this) {
+            final int refCount = mIsolatedUidRefCounts.get(uid, 0);
+            if (refCount <= 0) {
+                // Uid is not mapped or referenced
+                Slog.w(TAG,
+                        "Attempted to increment ref counted of untracked isolated uid (" + uid
+                        + ")");
+                return;
+            }
+            mIsolatedUidRefCounts.put(uid, refCount + 1);
+        }
+    }
+
+    /**
+     * Decrements the ref count for the given isolated UID.  If the ref count drops to zero,
+     * removes the mapping and calls {@link Listener#onAfterIsolatedUidRemoved} on each registered
+     * listener.
+     */
+    public void releaseIsolatedUid(int isolatedUid) {
+        int parentUid;
+        synchronized (this) {
+            final int refCount = mIsolatedUidRefCounts.get(isolatedUid, 0) - 1;
+            if (refCount > 0) {
+                // Isolated uid is still being tracked
+                mIsolatedUidRefCounts.put(isolatedUid, refCount);
+                return;
+            }
+
+            final int idx = mIsolatedUids.indexOfKey(isolatedUid);
+            if (idx >= 0) {
+                parentUid = mIsolatedUids.valueAt(idx);
+                mIsolatedUids.removeAt(idx);
+                mIsolatedUidRefCounts.delete(isolatedUid);
+            } else {
+                Slog.w(TAG, "Attempted to remove untracked child uid (" + isolatedUid + ")");
+                return;
+            }
+        }
+
+        List<Listener> listeners = mListeners;
+        for (int i = listeners.size() - 1; i >= 0; i--) {
+            listeners.get(i).onAfterIsolatedUidRemoved(isolatedUid, parentUid);
+        }
+    }
+
+    /**
+     * Releases all isolated UIDs in the specified range, both ends inclusive.
+     */
+    public void releaseUidsInRange(int startUid, int endUid) {
+        IntArray toRelease;
+        synchronized (this) {
+            int startIndex = mIsolatedUids.indexOfKey(startUid);
+            int endIndex = mIsolatedUids.indexOfKey(endUid);
+
+            if (startIndex < 0) {
+                startIndex = ~startIndex;
+            }
+
+            if (endIndex < 0) {
+                // In this ~endIndex is pointing just past where endUid would be, so we must -1.
+                endIndex = ~endIndex - 1;
+            }
+
+            if (startIndex > endIndex) {
+                return;
+            }
+
+            toRelease = new IntArray(endIndex - startIndex);
+            for (int i = startIndex; i <= endIndex; i++) {
+                toRelease.add(mIsolatedUids.keyAt(i));
+            }
+        }
+
+        for (int i = toRelease.size() - 1; i >= 0; i--) {
+            releaseIsolatedUid(toRelease.get(i));
+        }
+    }
+
+    /**
+     * Given an isolated UID, returns the corresponding owner UID.  For a non-isolated
+     * UID, returns the UID itself.
+     */
+    public int mapUid(int uid) {
+        synchronized (this) {
+            return mIsolatedUids.get(/*key=*/uid, /*valueIfKeyNotFound=*/uid);
+        }
+    }
+
+    /**
+     * Dumps the current contents of the resolver for the sake of dumpsys.
+     */
+    public void dump(PrintWriter pw) {
+        pw.println("Currently mapped isolated uids:");
+        synchronized (this) {
+            final int numIsolatedUids = mIsolatedUids.size();
+            for (int i = 0; i < numIsolatedUids; i++) {
+                final int isolatedUid = mIsolatedUids.keyAt(i);
+                final int ownerUid = mIsolatedUids.valueAt(i);
+                final int refs = mIsolatedUidRefCounts.get(isolatedUid);
+                pw.println("  " + isolatedUid + "->" + ownerUid + " (ref count = " + refs + ")");
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
index 0656a6a..59766ec 100644
--- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
@@ -35,6 +35,7 @@
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.hardware.SensorPrivacyManager.EXTRA_ALL_SENSORS;
+import static android.hardware.SensorPrivacyManager.EXTRA_NOTIFICATION_ID;
 import static android.hardware.SensorPrivacyManager.EXTRA_SENSOR;
 import static android.hardware.SensorPrivacyManager.EXTRA_TOGGLE_TYPE;
 import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
@@ -164,6 +165,7 @@
     private final AppOpsManagerInternal mAppOpsManagerInternal;
     private final TelephonyManager mTelephonyManager;
     private final PackageManagerInternal mPackageManagerInternal;
+    private final NotificationManager mNotificationManager;
 
     private CameraPrivacyLightController mCameraPrivacyLightController;
 
@@ -188,6 +190,7 @@
         mActivityTaskManager = context.getSystemService(ActivityTaskManager.class);
         mTelephonyManager = context.getSystemService(TelephonyManager.class);
         mPackageManagerInternal = getLocalService(PackageManagerInternal.class);
+        mNotificationManager = mContext.getSystemService(NotificationManager.class);
         mSensorPrivacyServiceImpl = new SensorPrivacyServiceImpl();
     }
 
@@ -288,9 +291,18 @@
                 @Override
                 public void onReceive(Context context, Intent intent) {
                     setToggleSensorPrivacy(
-                            ((UserHandle) intent.getParcelableExtra(
-                                    Intent.EXTRA_USER, android.os.UserHandle.class)).getIdentifier(), OTHER,
-                            intent.getIntExtra(EXTRA_SENSOR, UNKNOWN), false);
+                            intent.getParcelableExtra(Intent.EXTRA_USER, UserHandle.class)
+                                    .getIdentifier(),
+                            OTHER,
+                            intent.getIntExtra(EXTRA_SENSOR, UNKNOWN),
+                            false
+                    );
+
+                    int notificationId =
+                            intent.getIntExtra(EXTRA_NOTIFICATION_ID, SystemMessage.NOTE_UNKNOWN);
+                    if (notificationId != SystemMessage.NOTE_UNKNOWN) {
+                        mNotificationManager.cancel(notificationId);
+                    }
                 }
             }, new IntentFilter(ACTION_DISABLE_TOGGLE_SENSOR_PRIVACY),
                     MANAGE_SENSOR_PRIVACY, null, Context.RECEIVER_EXPORTED);
@@ -635,8 +647,6 @@
                 notificationId = SystemMessage.NOTE_UNBLOCK_CAM_TOGGLE;
             }
 
-            NotificationManager notificationManager =
-                    mContext.getSystemService(NotificationManager.class);
             NotificationChannel channel = new NotificationChannel(
                     SENSOR_PRIVACY_CHANNEL_ID,
                     getUiContext().getString(R.string.sensor_privacy_notification_channel_label),
@@ -646,7 +656,7 @@
             channel.enableVibration(false);
             channel.setBlockable(false);
 
-            notificationManager.createNotificationChannel(channel);
+            mNotificationManager.createNotificationChannel(channel);
 
             Icon icon = Icon.createWithResource(getUiContext().getResources(), iconRes);
 
@@ -669,10 +679,11 @@
                     new Intent(ACTION_DISABLE_TOGGLE_SENSOR_PRIVACY)
                             .setPackage(mContext.getPackageName())
                             .putExtra(EXTRA_SENSOR, sensor)
+                            .putExtra(EXTRA_NOTIFICATION_ID, notificationId)
                             .putExtra(Intent.EXTRA_USER, user),
                     PendingIntent.FLAG_IMMUTABLE
                             | PendingIntent.FLAG_UPDATE_CURRENT);
-            notificationManager.notify(notificationId,
+            mNotificationManager.notify(notificationId,
                     new Notification.Builder(mContext, SENSOR_PRIVACY_CHANNEL_ID)
                             .setContentTitle(contentTitle)
                             .setContentText(contentText)
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index f82f08b..2bf7075 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -827,7 +827,7 @@
             }
 
             final boolean trusted;
-            if (android.security.Flags.fixUnlockedDeviceRequiredKeys()) {
+            if (android.security.Flags.fixUnlockedDeviceRequiredKeysV2()) {
                 trusted = getUserTrustStateInner(id) == TrustState.TRUSTED;
             } else {
                 trusted = aggregateIsTrusted(id);
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 e6273d3..0467d0c 100644
--- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
+++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
@@ -38,6 +38,7 @@
 import android.media.tv.BroadcastInfoResponse;
 import android.media.tv.TvRecordingInfo;
 import android.media.tv.TvTrackInfo;
+import android.media.tv.ad.ITvAdManager;
 import android.media.tv.interactive.AppLinkInfo;
 import android.media.tv.interactive.ITvInteractiveAppClient;
 import android.media.tv.interactive.ITvInteractiveAppManager;
@@ -345,6 +346,7 @@
             Slogf.d(TAG, "onStart");
         }
         publishBinderService(Context.TV_INTERACTIVE_APP_SERVICE, new BinderService());
+        publishBinderService(Context.TV_AD_SERVICE, new TvAdBinderService());
     }
 
     @Override
@@ -688,6 +690,12 @@
         }
         return session;
     }
+    private final class TvAdBinderService extends ITvAdManager.Stub {
+        @Override
+        public void startAdService(IBinder sessionToken, int userId) {
+        }
+
+    }
 
     private final class BinderService extends ITvInteractiveAppManager.Stub {
 
diff --git a/services/core/java/com/android/server/utils/UserSettingDeviceConfigMediator.java b/services/core/java/com/android/server/utils/UserSettingDeviceConfigMediator.java
new file mode 100644
index 0000000..e542349
--- /dev/null
+++ b/services/core/java/com/android/server/utils/UserSettingDeviceConfigMediator.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.utils;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.provider.DeviceConfig;
+import android.util.KeyValueListParser;
+
+/**
+ * Helper class to mediate the value to use when a constant exists in both a key=value pair Settings
+ * constant (that can be parsed by {@link KeyValueListParser})
+ * and the {@link DeviceConfig} properties.
+ */
+public abstract class UserSettingDeviceConfigMediator {
+    private static final String TAG = UserSettingDeviceConfigMediator.class.getSimpleName();
+
+    @Nullable
+    protected DeviceConfig.Properties mProperties;
+    @NonNull
+    protected final KeyValueListParser mSettingsParser;
+
+    /**
+     * @param keyValueListDelimiter The delimiter passed into the {@link KeyValueListParser}.
+     */
+    protected UserSettingDeviceConfigMediator(char keyValueListDelimiter) {
+        mSettingsParser = new KeyValueListParser(keyValueListDelimiter);
+    }
+
+    /**
+     * Sets the key=value list string to read from. Setting {@code null} will clear any previously
+     * set string.
+     */
+    public void setSettingsString(@Nullable String settings) {
+        mSettingsParser.setString(settings);
+    }
+
+    /**
+     * Sets the DeviceConfig Properties to read from. Setting {@code null} will clear any previously
+     * set properties.
+     */
+    public void setDeviceConfigProperties(@Nullable DeviceConfig.Properties properties) {
+        mProperties = properties;
+    }
+
+    /**
+     * Get the value for key as a boolean.
+     *
+     * @param key          The key to lookup.
+     * @param defaultValue The value to return if the key was not found, or not properly defined.
+     */
+    public abstract boolean getBoolean(@NonNull String key, boolean defaultValue);
+
+    /**
+     * Get the value for key as a float.
+     *
+     * @param key          The key to lookup.
+     * @param defaultValue The value to return if the key was not found, or not properly defined.
+     */
+    public abstract float getFloat(@NonNull String key, float defaultValue);
+
+    /**
+     * Get the value for key as an int.
+     *
+     * @param key          The key to lookup.
+     * @param defaultValue The value to return if the key was not found, or not properly defined.
+     */
+    public abstract int getInt(@NonNull String key, int defaultValue);
+
+    /**
+     * Get the value for key as a long.
+     *
+     * @param key          The key to lookup.
+     * @param defaultValue The value to return if the key was not found, or not properly defined.
+     */
+    public abstract long getLong(@NonNull String key, long defaultValue);
+
+    /**
+     * Get the value for key as a String.
+     *
+     * @param key          The key to lookup.
+     * @param defaultValue The value to return if the key was not found, or not properly defined.
+     */
+    public abstract String getString(@NonNull String key, @Nullable String defaultValue);
+
+    /**
+     * A mediator in which the existence of a single settings key-value pair will override usage
+     * of DeviceConfig properties. That is, if the Settings constant has any values set,
+     * then everything in the DeviceConfig namespace will be ignored.
+     */
+    public static class SettingsOverridesAllMediator extends UserSettingDeviceConfigMediator {
+        public SettingsOverridesAllMediator(char keyValueListDelimiter) {
+            super(keyValueListDelimiter);
+        }
+
+        @Override
+        public boolean getBoolean(@NonNull String key, boolean defaultValue) {
+            if (mSettingsParser.size() == 0) {
+                return mProperties == null
+                        ? defaultValue : mProperties.getBoolean(key, defaultValue);
+            }
+            return mSettingsParser.getBoolean(key, defaultValue);
+        }
+
+        @Override
+        public float getFloat(@NonNull String key, float defaultValue) {
+            if (mSettingsParser.size() == 0) {
+                return mProperties == null ? defaultValue : mProperties.getFloat(key, defaultValue);
+            }
+            return mSettingsParser.getFloat(key, defaultValue);
+        }
+
+        @Override
+        public int getInt(@NonNull String key, int defaultValue) {
+            if (mSettingsParser.size() == 0) {
+                return mProperties == null ? defaultValue : mProperties.getInt(key, defaultValue);
+            }
+            return mSettingsParser.getInt(key, defaultValue);
+        }
+
+        @Override
+        public long getLong(@NonNull String key, long defaultValue) {
+            if (mSettingsParser.size() == 0) {
+                return mProperties == null ? defaultValue : mProperties.getLong(key, defaultValue);
+            }
+            return mSettingsParser.getLong(key, defaultValue);
+        }
+
+        @Override
+        public String getString(@NonNull String key, @Nullable String defaultValue) {
+            if (mSettingsParser.size() == 0) {
+                return mProperties == null
+                        ? defaultValue : mProperties.getString(key, defaultValue);
+            }
+            return mSettingsParser.getString(key, defaultValue);
+        }
+    }
+
+    /**
+     * A mediator in which only individual keys in the DeviceConfig namespace will be overridden
+     * by the same key in the Settings constant. If the Settings constant does not have a specific
+     * key set, then the DeviceConfig value will be used instead.
+     */
+    public static class SettingsOverridesIndividualMediator
+            extends UserSettingDeviceConfigMediator {
+        public SettingsOverridesIndividualMediator(char keyValueListDelimiter) {
+            super(keyValueListDelimiter);
+        }
+
+        @Override
+        public boolean getBoolean(@NonNull String key, boolean defaultValue) {
+            return mSettingsParser.getBoolean(key,
+                    mProperties == null ? defaultValue : mProperties.getBoolean(key, defaultValue));
+        }
+
+        @Override
+        public float getFloat(@NonNull String key, float defaultValue) {
+            return mSettingsParser.getFloat(key,
+                    mProperties == null ? defaultValue : mProperties.getFloat(key, defaultValue));
+        }
+
+        @Override
+        public int getInt(@NonNull String key, int defaultValue) {
+            return mSettingsParser.getInt(key,
+                    mProperties == null ? defaultValue : mProperties.getInt(key, defaultValue));
+        }
+
+        @Override
+        public long getLong(@NonNull String key, long defaultValue) {
+            return mSettingsParser.getLong(key,
+                    mProperties == null ? defaultValue : mProperties.getLong(key, defaultValue));
+        }
+
+        @Override
+        public String getString(@NonNull String key, @Nullable String defaultValue) {
+            return mSettingsParser.getString(key,
+                    mProperties == null ? defaultValue : mProperties.getString(key, defaultValue));
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index b12da61..e9c4096 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -258,6 +258,11 @@
         }
 
         @Override // Binder call
+        public WebViewProviderInfo getDefaultWebViewPackage() {
+            return WebViewUpdateService.this.mImpl.getDefaultWebViewPackage();
+        }
+
+        @Override // Binder call
         public WebViewProviderInfo[] getAllWebViewPackages() {
             return WebViewUpdateService.this.mImpl.getWebViewPackages();
         }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index cfdef14..60dc4ff 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -17,6 +17,7 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.Signature;
@@ -29,8 +30,12 @@
 import android.webkit.WebViewProviderInfo;
 import android.webkit.WebViewProviderResponse;
 
+import com.android.server.LocalServices;
+import com.android.server.PinnerService;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -88,6 +93,8 @@
     private static final int MULTIPROCESS_SETTING_ON_VALUE = Integer.MAX_VALUE;
     private static final int MULTIPROCESS_SETTING_OFF_VALUE = Integer.MIN_VALUE;
 
+    private static final String PIN_GROUP = "webview";
+
     private final SystemInterface mSystemInterface;
     private final Context mContext;
 
@@ -339,6 +346,34 @@
         return newPackage;
     }
 
+    private void pinWebviewIfRequired(ApplicationInfo appInfo) {
+        PinnerService pinnerService = LocalServices.getService(PinnerService.class);
+        int webviewPinQuota = pinnerService.getWebviewPinQuota();
+        if (webviewPinQuota <= 0) {
+            return;
+        }
+
+        pinnerService.unpinGroup(PIN_GROUP);
+
+        ArrayList<String> apksToPin = new ArrayList<>();
+        boolean pinSharedFirst = appInfo.metaData.getBoolean("PIN_SHARED_LIBS_FIRST", true);
+        for (String sharedLib : appInfo.sharedLibraryFiles) {
+            apksToPin.add(sharedLib);
+        }
+        apksToPin.add(appInfo.sourceDir);
+        if (!pinSharedFirst) {
+            // We want to prioritize pinning of the native library that is most likely used by apps
+            // which in some build flavors live in the main apk and as a shared library for others.
+            Collections.reverse(apksToPin);
+        }
+        for (String apk : apksToPin) {
+            if (webviewPinQuota <= 0) {
+                break;
+            }
+            int bytesPinned = pinnerService.pinFile(apk, webviewPinQuota, appInfo, PIN_GROUP);
+            webviewPinQuota -= bytesPinned;
+        }
+    }
     /**
      * This is called when we change WebView provider, either when the current provider is
      * updated or a new provider is chosen / takes precedence.
@@ -347,6 +382,7 @@
         synchronized (mLock) {
             mAnyWebViewInstalled = true;
             if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) {
+                pinWebviewIfRequired(newPackage.applicationInfo);
                 mCurrentWebViewPackage = newPackage;
 
                 // The relro creations might 'finish' (not start at all) before
@@ -385,6 +421,13 @@
         return providers;
     }
 
+    @Override
+    public WebViewProviderInfo getDefaultWebViewPackage() {
+        throw new IllegalStateException(
+                "getDefaultWebViewPackage shouldn't be called if update_service_v2 flag is"
+                        + " disabled.");
+    }
+
     private static class ProviderAndPackageInfo {
         public final WebViewProviderInfo provider;
         public final PackageInfo packageInfo;
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java
index 89cb4c8..29782d9 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java
@@ -24,6 +24,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.text.TextUtils;
+import android.util.AndroidRuntimeException;
 import android.util.Slog;
 import android.webkit.UserPackage;
 import android.webkit.WebViewFactory;
@@ -374,6 +375,23 @@
         return providers;
     }
 
+    /**
+     * Returns the default WebView provider which should be first availableByDefault option in the
+     * system config.
+     */
+    @Override
+    public WebViewProviderInfo getDefaultWebViewPackage() {
+        WebViewProviderInfo[] webviewProviders = getWebViewPackages();
+        for (WebViewProviderInfo provider : webviewProviders) {
+            if (provider.availableByDefault) {
+                return provider;
+            }
+        }
+        // This should be unreachable because the config parser enforces that there is at least one
+        // availableByDefault provider.
+        throw new AndroidRuntimeException("No available by default WebView Provider.");
+    }
+
     private static class ProviderAndPackageInfo {
         public final WebViewProviderInfo provider;
         public final PackageInfo packageInfo;
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceInterface.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceInterface.java
index a9c3dc4..1772ef9 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceInterface.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceInterface.java
@@ -40,6 +40,8 @@
 
     WebViewProviderInfo[] getValidWebViewPackages();
 
+    WebViewProviderInfo getDefaultWebViewPackage();
+
     PackageInfo getCurrentWebViewPackage();
 
     boolean isMultiProcessEnabled();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 75e6faf..6e9219a 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5262,7 +5262,7 @@
 
     boolean canAffectSystemUiFlags() {
         return task != null && task.canAffectSystemUiFlags() && isVisible()
-                && !inPinnedWindowingMode();
+                && !mWaitForEnteringPinnedMode && !inPinnedWindowingMode();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index d6302e0..e5794a1 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1582,6 +1582,7 @@
                 // An activity has changed order/visibility or the task is occluded by a transient
                 // activity, so this isn't just deliver-to-top
                 && mMovedToTopActivity == null
+                && !transitionController.hasOrderChanges()
                 && !transitionController.isTransientHide(startedActivityRootTask)) {
             // We just delivered to top, so there isn't an actual transition here.
             if (!forceTransientTransition) {
@@ -1860,7 +1861,10 @@
                     + "PendingIntent. However, only the creator of the PendingIntent allows BAL, "
                     + "while the sender does not allow BAL. realCallingPackage: "
                     + realCallingPackage + "; callingPackage: " + mRequest.callingPackage
-                    + "; mTargetRootTask:" + mTargetRootTask);
+                    + "; mTargetRootTask:" + mTargetRootTask + "; mIntent: " + mIntent
+                    + "; mTargetRootTask.getTopNonFinishingActivity: "
+                    + mTargetRootTask.getTopNonFinishingActivity()
+                    + "; mTargetRootTask.getRootActivity: " + mTargetRootTask.getRootActivity());
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 39e900a..4625b4fe 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -60,9 +60,9 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.FrameworkStatsLog;
-import com.android.internal.util.Preconditions;
 import com.android.server.UiThread;
 import com.android.server.am.PendingIntentRecord;
+import com.android.window.flags.Flags;
 
 import java.lang.annotation.Retention;
 import java.util.HashMap;
@@ -236,6 +236,7 @@
         private final @ActivityManager.ProcessState int mCallingUidProcState;
         private final boolean mIsCallingUidPersistentSystemProcess;
         private final BackgroundStartPrivileges mBalAllowedByPiSender;
+        private final BackgroundStartPrivileges mBalAllowedByPiCreatorWithHardening;
         private final BackgroundStartPrivileges mBalAllowedByPiCreator;
         private final String mRealCallingPackage;
         private final int mRealCallingUid;
@@ -267,20 +268,33 @@
             mIntent = intent;
             mRealCallingPackage = mService.getPackageNameIfUnique(realCallingUid, realCallingPid);
             if (originatingPendingIntent == null) {
-                // grant creator BAL privileges unless explicitly opted out
-                mBalAllowedByPiCreator =
+                // grant BAL privileges unless explicitly opted out
+                mBalAllowedByPiCreatorWithHardening = mBalAllowedByPiCreator =
                         checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                                 == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
                                 ? BackgroundStartPrivileges.NONE
                                 : BackgroundStartPrivileges.ALLOW_BAL;
+                mBalAllowedByPiSender =
+                        checkedOptions.getPendingIntentBackgroundActivityStartMode()
+                                == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
+                                ? BackgroundStartPrivileges.NONE
+                                : BackgroundStartPrivileges.ALLOW_BAL;
             } else {
                 // for PendingIntents we restrict BAL based on target_sdk
-                mBalAllowedByPiCreator = getBackgroundStartPrivilegesAllowedByCreator(
+                mBalAllowedByPiCreatorWithHardening = getBackgroundStartPrivilegesAllowedByCreator(
                         callingUid, callingPackage, checkedOptions);
+                final BackgroundStartPrivileges mBalAllowedByPiCreatorWithoutHardening =
+                        checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
+                                == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
+                                ? BackgroundStartPrivileges.NONE
+                                : BackgroundStartPrivileges.ALLOW_BAL;
+                mBalAllowedByPiCreator = balRequireOptInByPendingIntentCreator()
+                        ? mBalAllowedByPiCreatorWithHardening
+                        : mBalAllowedByPiCreatorWithoutHardening;
+                mBalAllowedByPiSender =
+                        PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
+                                checkedOptions, realCallingUid, mRealCallingPackage);
             }
-            mBalAllowedByPiSender =
-                    PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
-                            checkedOptions, realCallingUid, mRealCallingPackage);
             mAppSwitchState = mService.getBalAppSwitchesState();
             mCallingUidProcState = mService.mActiveUids.getUidState(callingUid);
             mIsCallingUidPersistentSystemProcess =
@@ -319,10 +333,6 @@
                     return BackgroundStartPrivileges.NONE;
                 case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED:
                     // no explicit choice by the app - let us decide what to do
-                    if (!balRequireOptInByPendingIntentCreator()) {
-                        // if feature is disabled allow
-                        return BackgroundStartPrivileges.ALLOW_BAL;
-                    }
                     if (callingPackage != null) {
                         // determine based on the calling/creating package
                         boolean changeEnabled = CompatChanges.isChangeEnabled(
@@ -367,11 +377,6 @@
             return mOriginatingPendingIntent != null && hasRealCaller();
         }
 
-        private String dump(BalVerdict resultIfPiCreatorAllowsBal) {
-            Preconditions.checkState(!isPendingIntent());
-            return dump(resultIfPiCreatorAllowsBal, null);
-        }
-
         private boolean callerIsRealCaller() {
             return mCallingUid == mRealCallingUid;
         }
@@ -396,6 +401,8 @@
                 sb.append("; inVisibleTask: ").append(mCallerApp.hasActivityInVisibleTask());
             }
             sb.append("; balAllowedByPiCreator: ").append(mBalAllowedByPiCreator);
+            sb.append("; balAllowedByPiCreatorWithHardening: ")
+                    .append(mBalAllowedByPiCreatorWithHardening);
             sb.append("; resultIfPiCreatorAllowsBal: ").append(resultIfPiCreatorAllowsBal);
             sb.append("; hasRealCaller: ").append(hasRealCaller());
             sb.append("; isPendingIntent: ").append(isPendingIntent());
@@ -579,11 +586,12 @@
                     resultForCaller.allows() && resultForRealCaller.blocks());
         }
 
+        // Handle cases with explicit opt-in
         if (resultForCaller.allows()
                 && checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                 == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) {
             if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG, "Activity start explicitly allowed by PI creator. "
+                Slog.d(TAG, "Activity start explicitly allowed by caller. "
                         + state.dump(resultForCaller, resultForRealCaller));
             }
             return statsLog(resultForCaller, state);
@@ -592,11 +600,12 @@
                 && checkedOptions.getPendingIntentBackgroundActivityStartMode()
                 == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) {
             if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG, "Activity start explicitly allowed by PI sender. "
+                Slog.d(TAG, "Activity start explicitly allowed by real caller. "
                         + state.dump(resultForCaller, resultForRealCaller));
             }
             return statsLog(resultForRealCaller, state);
         }
+        // Handle PendingIntent cases with default behavior next
         boolean callerCanAllow = resultForCaller.allows()
                 && checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
                 == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
@@ -716,17 +725,18 @@
         // is allowed, or apps like live wallpaper with non app visible window will be allowed.
         final boolean appSwitchAllowedOrFg =
                 appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY;
-        final boolean allowCallingUidStartActivity =
-                ((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid))
-                        && callingUidHasAnyVisibleWindow)
-                        || isCallingUidPersistentSystemProcess;
-        if (allowCallingUidStartActivity) {
+        if (appSwitchAllowedOrFg && callingUidHasAnyVisibleWindow) {
             return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW,
-                    /*background*/ false,
-                    "callingUidHasAnyVisibleWindow = "
-                            + callingUid
-                            + ", isCallingUidPersistentSystemProcess = "
-                            + isCallingUidPersistentSystemProcess);
+                    /*background*/ false, "callingUid has visible window");
+        }
+        if (mService.mActiveUids.hasNonAppVisibleWindow(callingUid)) {
+            return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW,
+                    /*background*/ false, "callingUid has non-app visible window");
+        }
+
+        if (isCallingUidPersistentSystemProcess) {
+            return new BalVerdict(BAL_ALLOW_ALLOWLISTED_COMPONENT,
+                    /*background*/ false, "callingUid is persistent system process");
         }
 
         // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
@@ -806,13 +816,29 @@
                     "realCallingUid has BAL permission.");
         }
 
-        // don't abort if the realCallingUid has a visible window
-        // TODO(b/171459802): We should check appSwitchAllowed also
-        if (state.mRealCallingUidHasAnyVisibleWindow) {
-            return new BalVerdict(BAL_ALLOW_PENDING_INTENT,
-                    /*background*/ false,
-                    "realCallingUid has visible (non-toast) window.");
+        // Normal apps with visible app window will be allowed to start activity if app switching
+        // is allowed, or apps like live wallpaper with non app visible window will be allowed.
+        final boolean appSwitchAllowedOrFg = state.mAppSwitchState == APP_SWITCH_ALLOW
+                || state.mAppSwitchState == APP_SWITCH_FG_ONLY;
+        if (Flags.balImproveRealCallerVisibilityCheck()) {
+            if (appSwitchAllowedOrFg && state.mRealCallingUidHasAnyVisibleWindow) {
+                return new BalVerdict(BAL_ALLOW_PENDING_INTENT,
+                        /*background*/ false, "realCallingUid has visible window");
+            }
+            if (mService.mActiveUids.hasNonAppVisibleWindow(state.mRealCallingUid)) {
+                return new BalVerdict(BAL_ALLOW_PENDING_INTENT,
+                        /*background*/ false, "realCallingUid has non-app visible window");
+            }
+        } else {
+            // don't abort if the realCallingUid has a visible window
+            // TODO(b/171459802): We should check appSwitchAllowed also
+            if (state.mRealCallingUidHasAnyVisibleWindow) {
+                return new BalVerdict(BAL_ALLOW_PENDING_INTENT,
+                        /*background*/ false,
+                        "realCallingUid has visible (non-toast) window.");
+            }
         }
+
         // if the realCallingUid is a persistent system process, abort if the IntentSender
         // wasn't allowed to start an activity
         if (state.mForcedBalByPiSender.allowsBackgroundActivityStarts()
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index 2fabb0e..7ce9de4 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -83,6 +83,7 @@
     /**
      * Mark all dims as pending completion on the next call to {@link #updateDims}
      *
+     * Called before iterating on mHost's children, first step of dimming.
      * This is intended for us by the host container, to be called at the beginning of
      * {@link WindowContainer#prepareSurfaces}. After calling this, the container should
      * chain {@link WindowContainer#prepareSurfaces} down to it's children to give them
@@ -100,8 +101,7 @@
 
     /**
      * Call after invoking {@link WindowContainer#prepareSurfaces} on children as
-     * described in {@link #resetDimStates}. The dim bounds returned by {@link #resetDimStates}
-     * should be set before calling this method.
+     * described in {@link #resetDimStates}.
      *
      * @param t      A transaction in which to update the dims.
      * @return true if any Dims were updated.
diff --git a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
new file mode 100644
index 0000000..e91857f
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_DIMMER;
+import static com.android.server.wm.AlphaAnimationSpecProto.DURATION_MS;
+import static com.android.server.wm.AlphaAnimationSpecProto.FROM;
+import static com.android.server.wm.AlphaAnimationSpecProto.TO;
+import static com.android.server.wm.AnimationSpecProto.ALPHA;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_DIMMER;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import android.util.Log;
+import android.util.proto.ProtoOutputStream;
+import android.view.SurfaceControl;
+
+import com.android.internal.protolog.common.ProtoLog;
+
+import java.io.PrintWriter;
+
+/**
+ * Contains the information relative to the changes to apply to the dim layer
+ */
+public class DimmerAnimationHelper {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "DimmerAnimationHelper" : TAG_WM;
+    private static final int DEFAULT_DIM_ANIM_DURATION_MS = 200;
+
+    /**
+     * Contains the requested changes
+     */
+    static class Change {
+        private float mAlpha = -1f;
+        private int mBlurRadius = -1;
+        private WindowContainer mDimmingContainer = null;
+        private int mRelativeLayer = -1;
+        private static final float EPSILON = 0.0001f;
+
+        Change() {}
+
+        Change(Change other) {
+            mAlpha = other.mAlpha;
+            mBlurRadius = other.mBlurRadius;
+            mDimmingContainer = other.mDimmingContainer;
+            mRelativeLayer = other.mRelativeLayer;
+        }
+
+        // Same alpha and blur
+        boolean hasSameVisualProperties(Change other) {
+            return Math.abs(mAlpha - other.mAlpha) < EPSILON && mBlurRadius == other.mBlurRadius;
+        }
+
+        boolean hasSameDimmingContainer(Change other) {
+            return mDimmingContainer != null && mDimmingContainer == other.mDimmingContainer;
+        }
+
+        void inheritPropertiesFromAnimation(AnimationSpec anim) {
+            mAlpha = anim.mCurrentAlpha;
+            mBlurRadius = anim.mCurrentBlur;
+        }
+
+        @Override
+        public String toString() {
+            return "Dim state: alpha=" + mAlpha + ", blur=" + mBlurRadius + ", container="
+                    + mDimmingContainer + ", relativePosition=" + mRelativeLayer;
+        }
+    }
+
+    private Change mCurrentProperties = new Change();
+    private Change mRequestedProperties = new Change();
+    private AnimationSpec mAlphaAnimationSpec;
+
+    private final AnimationAdapterFactory mAnimationAdapterFactory;
+    private AnimationAdapter mLocalAnimationAdapter;
+
+    DimmerAnimationHelper(AnimationAdapterFactory animationFactory) {
+        mAnimationAdapterFactory = animationFactory;
+    }
+
+    void setExitParameters() {
+        setRequestedRelativeParent(mRequestedProperties.mDimmingContainer, -1 /* relativeLayer */);
+        setRequestedAppearance(0f /* alpha */, 0 /* blur */);
+    }
+
+    // Sets a requested change without applying it immediately
+    void setRequestedRelativeParent(WindowContainer relativeParent, int relativeLayer) {
+        mRequestedProperties.mDimmingContainer = relativeParent;
+        mRequestedProperties.mRelativeLayer = relativeLayer;
+    }
+
+    // Sets a requested change without applying it immediately
+    void setRequestedAppearance(float alpha, int blurRadius) {
+        mRequestedProperties.mAlpha = alpha;
+        mRequestedProperties.mBlurRadius = blurRadius;
+    }
+
+    /**
+     * Commit the last changes we received. Called after
+     * {@link Change#setExitParameters()},
+     * {@link Change#setRequestedRelativeParent(WindowContainer, int)}, or
+     * {@link Change#setRequestedAppearance(float, int)}
+     */
+    void applyChanges(SurfaceControl.Transaction t, SmoothDimmer.DimState dim) {
+        if (mRequestedProperties.mDimmingContainer == null) {
+            Log.e(TAG, this + " does not have a dimming container. Have you forgotten to "
+                    + "call adjustRelativeLayer?");
+            return;
+        }
+        if (mRequestedProperties.mDimmingContainer.mSurfaceControl == null) {
+            Log.w(TAG, "container " + mRequestedProperties.mDimmingContainer
+                    + "does not have a surface");
+            dim.remove(t);
+            return;
+        }
+
+        dim.ensureVisible(t);
+        relativeReparent(dim.mDimSurface,
+                mRequestedProperties.mDimmingContainer.getSurfaceControl(),
+                mRequestedProperties.mRelativeLayer, t);
+
+        if (!mCurrentProperties.hasSameVisualProperties(mRequestedProperties)) {
+            stopCurrentAnimation(dim.mDimSurface);
+
+            if (dim.mSkipAnimation
+                    // If the container doesn't change but requests a dim change, then it is
+                    // directly providing us the animated values
+                    || (mRequestedProperties.hasSameDimmingContainer(mCurrentProperties)
+                    && dim.isDimming())) {
+                ProtoLog.d(WM_DEBUG_DIMMER,
+                        "%s skipping animation and directly setting alpha=%f, blur=%d",
+                        dim, mRequestedProperties.mAlpha,
+                        mRequestedProperties.mBlurRadius);
+                setAlphaBlur(dim.mDimSurface, mRequestedProperties.mAlpha,
+                        mRequestedProperties.mBlurRadius, t);
+                dim.mSkipAnimation = false;
+            } else {
+                startAnimation(t, dim);
+            }
+
+        } else if (!dim.isDimming()) {
+            // We are not dimming, so we tried the exit animation but the alpha is already 0,
+            // therefore, let's just remove this surface
+            dim.remove(t);
+        }
+        mCurrentProperties = new Change(mRequestedProperties);
+    }
+
+    private void startAnimation(
+            SurfaceControl.Transaction t, SmoothDimmer.DimState dim) {
+        ProtoLog.v(WM_DEBUG_DIMMER, "Starting animation on %s", dim);
+        mAlphaAnimationSpec = getRequestedAnimationSpec();
+        mLocalAnimationAdapter = mAnimationAdapterFactory.get(mAlphaAnimationSpec,
+                dim.mHostContainer.mWmService.mSurfaceAnimationRunner);
+
+        float targetAlpha = mRequestedProperties.mAlpha;
+        int targetBlur = mRequestedProperties.mBlurRadius;
+
+        mLocalAnimationAdapter.startAnimation(dim.mDimSurface, t,
+                ANIMATION_TYPE_DIMMER, /* finishCallback */ (type, animator) -> {
+                    setAlphaBlur(dim.mDimSurface, targetAlpha, targetBlur, t);
+                    if (targetAlpha == 0f && !dim.isDimming()) {
+                        dim.remove(t);
+                    }
+                    mLocalAnimationAdapter = null;
+                    mAlphaAnimationSpec = null;
+                });
+    }
+
+    private boolean isAnimating() {
+        return mAlphaAnimationSpec != null;
+    }
+
+    void stopCurrentAnimation(SurfaceControl surface) {
+        if (mLocalAnimationAdapter != null && isAnimating()) {
+            // Save the current animation progress and cancel the animation
+            mCurrentProperties.inheritPropertiesFromAnimation(mAlphaAnimationSpec);
+            mLocalAnimationAdapter.onAnimationCancelled(surface);
+            mLocalAnimationAdapter = null;
+            mAlphaAnimationSpec = null;
+        }
+    }
+
+    private AnimationSpec getRequestedAnimationSpec() {
+        final float startAlpha = Math.max(mCurrentProperties.mAlpha, 0f);
+        final int startBlur = Math.max(mCurrentProperties.mBlurRadius, 0);
+        long duration = (long) (getDimDuration(mRequestedProperties.mDimmingContainer)
+                * Math.abs(mRequestedProperties.mAlpha - startAlpha));
+
+        final AnimationSpec spec =  new AnimationSpec(
+                new AnimationSpec.AnimationExtremes<>(startAlpha, mRequestedProperties.mAlpha),
+                new AnimationSpec.AnimationExtremes<>(startBlur, mRequestedProperties.mBlurRadius),
+                duration
+        );
+        ProtoLog.v(WM_DEBUG_DIMMER, "Dim animation requested: %s", spec);
+        return spec;
+    }
+
+    /**
+     * Change the relative parent of this dim layer
+     */
+    void relativeReparent(SurfaceControl dimLayer, SurfaceControl relativeParent,
+                          int relativePosition, SurfaceControl.Transaction t) {
+        try {
+            t.setRelativeLayer(dimLayer, relativeParent, relativePosition);
+        } catch (NullPointerException e) {
+            Log.w(TAG, "Tried to change parent of dim " + dimLayer + " after remove", e);
+        }
+    }
+
+    void setAlphaBlur(SurfaceControl sc, float alpha, int blur, SurfaceControl.Transaction t) {
+        try {
+            t.setAlpha(sc, alpha);
+            t.setBackgroundBlurRadius(sc, blur);
+        } catch (NullPointerException e) {
+            Log.w(TAG , "Tried to change look of dim " + sc + " after remove",  e);
+        }
+    }
+
+    private long getDimDuration(WindowContainer container) {
+        // Use the same duration as the animation on the WindowContainer
+        AnimationAdapter animationAdapter = container.mSurfaceAnimator.getAnimation();
+        final float durationScale = container.mWmService.getTransitionAnimationScaleLocked();
+        return animationAdapter == null ? (long) (DEFAULT_DIM_ANIM_DURATION_MS * durationScale)
+                : animationAdapter.getDurationHint();
+    }
+
+    /**
+     * Collects the animation specifics
+     */
+    static class AnimationSpec implements LocalAnimationAdapter.AnimationSpec {
+        private static final String TAG = TAG_WITH_CLASS_NAME ? "DimmerAnimationSpec" : TAG_WM;
+
+        static class AnimationExtremes<T> {
+            final T mStartValue;
+            final T mFinishValue;
+
+            AnimationExtremes(T fromValue, T toValue) {
+                mStartValue = fromValue;
+                mFinishValue = toValue;
+            }
+
+            @Override
+            public String toString() {
+                return "[" + mStartValue + "->" + mFinishValue + "]";
+            }
+        }
+
+        private final long mDuration;
+        private final AnimationSpec.AnimationExtremes<Float> mAlpha;
+        private final AnimationSpec.AnimationExtremes<Integer> mBlur;
+
+        float mCurrentAlpha = 0;
+        int mCurrentBlur = 0;
+        boolean mStarted = false;
+
+        AnimationSpec(AnimationSpec.AnimationExtremes<Float> alpha,
+                      AnimationSpec.AnimationExtremes<Integer> blur, long duration) {
+            mAlpha = alpha;
+            mBlur = blur;
+            mDuration = duration;
+        }
+
+        @Override
+        public long getDuration() {
+            return mDuration;
+        }
+
+        @Override
+        public void apply(SurfaceControl.Transaction t, SurfaceControl sc, long currentPlayTime) {
+            if (!mStarted) {
+                // The first frame would end up in the sync transaction, and since this could be
+                // applied after the animation transaction, we avoid putting visible changes here.
+                // The initial state of the animation matches the current state of the dim anyway.
+                mStarted = true;
+                return;
+            }
+            final float fraction = getFraction(currentPlayTime);
+            mCurrentAlpha =
+                    fraction * (mAlpha.mFinishValue - mAlpha.mStartValue) + mAlpha.mStartValue;
+            mCurrentBlur =
+                    (int) fraction * (mBlur.mFinishValue - mBlur.mStartValue) + mBlur.mStartValue;
+            if (sc.isValid()) {
+                t.setAlpha(sc, mCurrentAlpha);
+                t.setBackgroundBlurRadius(sc, mCurrentBlur);
+            } else {
+                Log.w(TAG, "Dimmer#AnimationSpec tried to access " + sc + " after release");
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "Animation spec: alpha=" + mAlpha + ", blur=" + mBlur;
+        }
+
+        @Override
+        public void dump(PrintWriter pw, String prefix) {
+            pw.print(prefix); pw.print("from_alpha="); pw.print(mAlpha.mStartValue);
+            pw.print(" to_alpha="); pw.print(mAlpha.mFinishValue);
+            pw.print(prefix); pw.print("from_blur="); pw.print(mBlur.mStartValue);
+            pw.print(" to_blur="); pw.print(mBlur.mFinishValue);
+            pw.print(" duration="); pw.println(mDuration);
+        }
+
+        @Override
+        public void dumpDebugInner(ProtoOutputStream proto) {
+            final long token = proto.start(ALPHA);
+            proto.write(FROM, mAlpha.mStartValue);
+            proto.write(TO, mAlpha.mFinishValue);
+            proto.write(DURATION_MS, mDuration);
+            proto.end(token);
+        }
+    }
+
+    static class AnimationAdapterFactory {
+        public AnimationAdapter get(LocalAnimationAdapter.AnimationSpec alphaAnimationSpec,
+                                    SurfaceAnimationRunner runner) {
+            return new LocalAnimationAdapter(alphaAnimationSpec, runner);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 07cbd58..50376fe 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1153,12 +1153,12 @@
         mDisplay = display;
         mDisplayId = display.getDisplayId();
         mCurrentUniqueDisplayId = display.getUniqueId();
-        mDisplayUpdater = new ImmediateDisplayUpdater(this);
         mOffTokenAcquirer = mRootWindowContainer.mDisplayOffTokenAcquirer;
         mWallpaperController = new WallpaperController(mWmService, this);
         mWallpaperController.resetLargestDisplay(display);
         display.getDisplayInfo(mDisplayInfo);
         display.getMetrics(mDisplayMetrics);
+        mDisplayUpdater = new ImmediateDisplayUpdater(this);
         mSystemGestureExclusionLimit = mWmService.mConstants.mSystemGestureExclusionLimitDp
                 * mDisplayMetrics.densityDpi / DENSITY_DEFAULT;
         isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
@@ -1648,7 +1648,7 @@
                 ? new Transition.ReadyCondition("displayConfig", this) : null;
         if (displayConfig != null) {
             mTransitionController.waitFor(displayConfig);
-        } else if (mTransitionController.isShellTransitionsEnabled()) {
+        } else if (mTransitionController.isShellTransitionsEnabled() && mLastHasContent) {
             Slog.e(TAG, "Display reconfigured outside of a transition: " + this);
         }
         final boolean configUpdated = updateDisplayOverrideConfigurationLocked();
diff --git a/services/core/java/com/android/server/wm/ImmediateDisplayUpdater.java b/services/core/java/com/android/server/wm/ImmediateDisplayUpdater.java
index 72e8fcb..4af9013 100644
--- a/services/core/java/com/android/server/wm/ImmediateDisplayUpdater.java
+++ b/services/core/java/com/android/server/wm/ImmediateDisplayUpdater.java
@@ -30,6 +30,7 @@
 
     public ImmediateDisplayUpdater(@NonNull DisplayContent displayContent) {
         mDisplayContent = displayContent;
+        mDisplayInfo.copyFrom(mDisplayContent.getDisplayInfo());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index e6bbd52..c089d10 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -740,6 +740,8 @@
         private final Handler mHandler;
         private final String mName;
 
+        private boolean mInsetsAnimationRunning;
+
         Host(Handler handler, String name) {
             mHandler = handler;
             mName = name;
@@ -841,5 +843,10 @@
         public IBinder getWindowToken() {
             return null;
         }
+
+        @Override
+        public void notifyAnimationRunningStateChanged(boolean running) {
+            mInsetsAnimationRunning = running;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 2bd7327..522e7d2 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -627,7 +627,7 @@
     void refreshSecureSurfaceState() {
         forAllWindows((w) -> {
             if (w.mHasSurface) {
-                w.mWinAnimator.setSecureLocked(w.isSecureLocked());
+                w.setSecureLocked(w.isSecureLocked());
             }
         }, true /* traverseTopToBottom */);
     }
diff --git a/services/core/java/com/android/server/wm/SmoothDimmer.java b/services/core/java/com/android/server/wm/SmoothDimmer.java
index 2549bbf..b5d94a2 100644
--- a/services/core/java/com/android/server/wm/SmoothDimmer.java
+++ b/services/core/java/com/android/server/wm/SmoothDimmer.java
@@ -17,265 +17,203 @@
 package com.android.server.wm;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_DIMMER;
-import static com.android.server.wm.AlphaAnimationSpecProto.DURATION_MS;
-import static com.android.server.wm.AlphaAnimationSpecProto.FROM;
-import static com.android.server.wm.AlphaAnimationSpecProto.TO;
-import static com.android.server.wm.AnimationSpecProto.ALPHA;
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_DIMMER;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.graphics.Rect;
 import android.util.Log;
-import android.util.proto.ProtoOutputStream;
 import android.view.Surface;
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
 
-import java.io.PrintWriter;
-
 class SmoothDimmer extends Dimmer {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "Dimmer" : TAG_WM;
-    private static final float EPSILON = 0.0001f;
-    // This is in milliseconds.
-    private static final int DEFAULT_DIM_ANIM_DURATION = 200;
-    DimState mDimState;
-    private WindowContainer mLastRequestedDimContainer;
-    private final AnimationAdapterFactory mAnimationAdapterFactory;
 
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "Dimmer" : TAG_WM;
+    DimState mDimState;
+    final DimmerAnimationHelper.AnimationAdapterFactory mAnimationAdapterFactory;
+
+    /**
+     * Controls the dim behaviour
+     */
     @VisibleForTesting
     class DimState {
-        /**
-         * The layer where property changes should be invoked on.
-         */
-        SurfaceControl mDimLayer;
-        boolean mDimming;
-        boolean mIsVisible;
-
+        /** Related objects */
+        SurfaceControl mDimSurface;
+        final WindowContainer mHostContainer;
+        // The last container to request to dim
+        private WindowContainer mLastRequestedDimContainer;
+        /** Animation */
+        private final DimmerAnimationHelper mAnimationHelper;
+        boolean mSkipAnimation = false;
+        // Determines whether the dim layer should animate before destroying.
+        boolean mAnimateExit = true;
+        /** Surface visibility and bounds */
+        private boolean mIsVisible = false;
         // TODO(b/64816140): Remove after confirming dimmer layer always matches its container.
         final Rect mDimBounds = new Rect();
 
-        /**
-         * Determines whether the dim layer should animate before destroying.
-         */
-        boolean mAnimateExit = true;
-
-        /**
-         * Used for Dims not associated with a WindowContainer.
-         * See {@link Dimmer#adjustRelativeLayer(WindowContainer, int)} for details on Dim
-         * lifecycle.
-         */
-        boolean mDontReset;
-
-        Change mCurrentProperties;
-        Change mRequestedProperties;
-        private AnimationSpec mAlphaAnimationSpec;
-        private AnimationAdapter mLocalAnimationAdapter;
-
-        static class Change {
-            private float mAlpha = -1f;
-            private int mBlurRadius = -1;
-            private WindowContainer mDimmingContainer = null;
-            private int mRelativeLayer = -1;
-            private boolean mSkipAnimation = false;
-
-            Change() {}
-
-            Change(Change other) {
-                mAlpha = other.mAlpha;
-                mBlurRadius = other.mBlurRadius;
-                mDimmingContainer = other.mDimmingContainer;
-                mRelativeLayer = other.mRelativeLayer;
-            }
-
-            @Override
-            public String toString() {
-                return "Dim state: alpha=" + mAlpha + ", blur=" + mBlurRadius + ", container="
-                        + mDimmingContainer + ", relativePosition=" + mRelativeLayer
-                        + ", skipAnimation=" + mSkipAnimation;
-            }
-        }
-
-        DimState(SurfaceControl dimLayer) {
-            mDimLayer = dimLayer;
-            mDimming = true;
-            mCurrentProperties = new Change();
-            mRequestedProperties = new Change();
-        }
-
-        void setExitParameters(WindowContainer container) {
-            setRequestedRelativeParent(container, -1 /* relativeLayer */);
-            setRequestedAppearance(0f /* alpha */, 0 /* blur */);
-        }
-
-        // Sets a requested change without applying it immediately
-        void setRequestedRelativeParent(WindowContainer relativeParent, int relativeLayer) {
-            mRequestedProperties.mDimmingContainer = relativeParent;
-            mRequestedProperties.mRelativeLayer = relativeLayer;
-        }
-
-        // Sets a requested change without applying it immediately
-        void setRequestedAppearance(float alpha, int blurRadius) {
-            mRequestedProperties.mAlpha = alpha;
-            mRequestedProperties.mBlurRadius = blurRadius;
-        }
-
-        /**
-         * Commit the last changes we received. Called after
-         * {@link Change#setExitParameters(WindowContainer)},
-         * {@link Change#setRequestedRelativeParent(WindowContainer, int)}, or
-         * {@link Change#setRequestedAppearance(float, int)}
-         */
-        void applyChanges(SurfaceControl.Transaction t) {
-            if (mRequestedProperties.mDimmingContainer == null) {
-                Log.e(TAG, this + " does not have a dimming container. Have you forgotten to "
-                        + "call adjustRelativeLayer?");
-                return;
-            }
-            if (mRequestedProperties.mDimmingContainer.mSurfaceControl == null) {
-                Log.w(TAG, "container " + mRequestedProperties.mDimmingContainer
-                        + "does not have a surface");
-                return;
-            }
-            if (!mDimState.mIsVisible) {
-                mDimState.mIsVisible = true;
-                t.show(mDimState.mDimLayer);
-            }
-            t.setRelativeLayer(mDimLayer,
-                    mRequestedProperties.mDimmingContainer.getSurfaceControl(),
-                    mRequestedProperties.mRelativeLayer);
-
-            if (aspectChanged()) {
-                if (isAnimating()) {
-                    mLocalAnimationAdapter.onAnimationCancelled(mDimLayer);
-                }
-                if (mRequestedProperties.mSkipAnimation
-                        || (!dimmingContainerChanged() && mDimming)) {
-                    // If the dimming container has not changed, then it is running its own
-                    // animation, thus we can directly set the values we get requested, unless it's
-                    // the exiting animation
-                    ProtoLog.d(WM_DEBUG_DIMMER,
-                            "Dim %s skipping animation and directly setting alpha=%f, blur=%d",
-                            mDimLayer, mRequestedProperties.mAlpha,
-                            mRequestedProperties.mBlurRadius);
-                    t.setAlpha(mDimLayer, mRequestedProperties.mAlpha);
-                    t.setBackgroundBlurRadius(mDimLayer, mRequestedProperties.mBlurRadius);
-                    mRequestedProperties.mSkipAnimation = false;
-                } else {
-                    startAnimation(t);
-                }
-            }
-            mCurrentProperties = new Change(mRequestedProperties);
-        }
-
-        private void startAnimation(SurfaceControl.Transaction t) {
-            mAlphaAnimationSpec = getRequestedAnimationSpec(mRequestedProperties.mAlpha,
-                    mRequestedProperties.mBlurRadius);
-            mLocalAnimationAdapter = mAnimationAdapterFactory.get(mAlphaAnimationSpec,
-                    mHost.mWmService.mSurfaceAnimationRunner);
-
-            mLocalAnimationAdapter.startAnimation(mDimLayer, t,
-                    ANIMATION_TYPE_DIMMER, (type, animator) -> {
-                        t.setAlpha(mDimLayer, mRequestedProperties.mAlpha);
-                        t.setBackgroundBlurRadius(mDimLayer, mRequestedProperties.mBlurRadius);
-                        if (mRequestedProperties.mAlpha == 0f && !mDimming) {
-                            ProtoLog.d(WM_DEBUG_DIMMER,
-                                    "Removing dim surface %s on transaction %s", mDimLayer, t);
-                            t.remove(mDimLayer);
-                        }
-                        mLocalAnimationAdapter = null;
-                        mAlphaAnimationSpec = null;
-                    });
-        }
-
-        private boolean isAnimating() {
-            return mAlphaAnimationSpec != null;
-        }
-
-        private boolean aspectChanged() {
-            return Math.abs(mRequestedProperties.mAlpha - mCurrentProperties.mAlpha) > EPSILON
-                    || mRequestedProperties.mBlurRadius != mCurrentProperties.mBlurRadius;
-        }
-
-        private boolean dimmingContainerChanged() {
-            return mRequestedProperties.mDimmingContainer != mCurrentProperties.mDimmingContainer;
-        }
-
-        private AnimationSpec getRequestedAnimationSpec(float targetAlpha, int targetBlur) {
-            final float startAlpha;
-            final int startBlur;
-            if (mAlphaAnimationSpec != null) {
-                startAlpha = mAlphaAnimationSpec.mCurrentAlpha;
-                startBlur = mAlphaAnimationSpec.mCurrentBlur;
-            } else {
-                startAlpha = Math.max(mCurrentProperties.mAlpha, 0f);
-                startBlur = Math.max(mCurrentProperties.mBlurRadius, 0);
-            }
-            long duration = (long) (getDimDuration(mRequestedProperties.mDimmingContainer)
-                    * Math.abs(targetAlpha - startAlpha));
-
-            ProtoLog.v(WM_DEBUG_DIMMER, "Starting animation on dim layer %s, requested by %s, "
-                            + "alpha: %f -> %f, blur: %d -> %d",
-                    mDimLayer, mRequestedProperties.mDimmingContainer, startAlpha, targetAlpha,
-                    startBlur, targetBlur);
-            return new AnimationSpec(
-                    new AnimationExtremes<>(startAlpha, targetAlpha),
-                    new AnimationExtremes<>(startBlur, targetBlur),
-                    duration
-            );
-        }
-    }
-
-    protected SmoothDimmer(WindowContainer host) {
-        this(host, new AnimationAdapterFactory());
-    }
-
-    @VisibleForTesting
-    SmoothDimmer(WindowContainer host, AnimationAdapterFactory animationFactory) {
-        super(host);
-        mAnimationAdapterFactory = animationFactory;
-    }
-
-    private DimState obtainDimState(WindowContainer container) {
-        if (mDimState == null) {
+        DimState() {
+            mHostContainer = mHost;
+            mAnimationHelper = new DimmerAnimationHelper(mAnimationAdapterFactory);
             try {
-                final SurfaceControl ctl = makeDimLayer();
-                mDimState = new DimState(ctl);
+                mDimSurface = makeDimLayer();
             } catch (Surface.OutOfResourcesException e) {
                 Log.w(TAG, "OutOfResourcesException creating dim surface");
             }
         }
 
-        mLastRequestedDimContainer = container;
-        return mDimState;
+        void ensureVisible(SurfaceControl.Transaction t) {
+            if (!mIsVisible) {
+                t.show(mDimSurface);
+                t.setAlpha(mDimSurface, 0f);
+                mIsVisible = true;
+            }
+        }
+
+        void adjustSurfaceLayout(SurfaceControl.Transaction t) {
+            // TODO: Once we use geometry from hierarchy this falls away.
+            t.setPosition(mDimSurface, mDimBounds.left, mDimBounds.top);
+            t.setWindowCrop(mDimSurface, mDimBounds.width(), mDimBounds.height());
+        }
+
+        /**
+         * Set the parameters to prepare the dim to change its appearance
+         */
+        void prepareLookChange(float alpha, int blurRadius) {
+            mAnimationHelper.setRequestedAppearance(alpha, blurRadius);
+        }
+
+        /**
+         * Prepare the dim for the exit animation
+         */
+        void exit(SurfaceControl.Transaction t) {
+            if (!mAnimateExit) {
+                remove(t);
+            } else {
+                mAnimationHelper.setExitParameters();
+                setReady(t);
+            }
+        }
+
+        void remove(SurfaceControl.Transaction t) {
+            mAnimationHelper.stopCurrentAnimation(mDimSurface);
+            if (mDimSurface.isValid()) {
+                t.remove(mDimSurface);
+                ProtoLog.d(WM_DEBUG_DIMMER,
+                        "Removing dim surface %s on transaction %s", this, t);
+            } else {
+                Log.w(TAG, "Tried to remove " + mDimSurface + " multiple times\n");
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "SmoothDimmer#DimState with host=" + mHostContainer + ", surface=" + mDimSurface;
+        }
+
+        /**
+         * Set the parameters to prepare the dim to be relative parented to the dimming container
+         */
+        void prepareReparent(WindowContainer relativeParent, int relativeLayer) {
+            mAnimationHelper.setRequestedRelativeParent(relativeParent, relativeLayer);
+        }
+
+        /**
+         * Call when all the changes have been requested to have them applied
+         * @param t The transaction in which to apply the changes
+         */
+        void setReady(SurfaceControl.Transaction t) {
+            mAnimationHelper.applyChanges(t, this);
+        }
+
+        /**
+         * Whether anyone is currently requesting the dim
+         */
+        boolean isDimming() {
+            return mLastRequestedDimContainer != null;
+        }
+
+        private SurfaceControl makeDimLayer() {
+            return mHost.makeChildSurface(null)
+                    .setParent(mHost.getSurfaceControl())
+                    .setColorLayer()
+                    .setName("Dim Layer for - " + mHost.getName())
+                    .setCallsite("DimLayer.makeDimLayer")
+                    .build();
+        }
     }
 
-    private SurfaceControl makeDimLayer() {
-        return mHost.makeChildSurface(null)
-                .setParent(mHost.getSurfaceControl())
-                .setColorLayer()
-                .setName("Dim Layer for - " + mHost.getName())
-                .setCallsite("Dimmer.makeDimLayer")
-                .build();
+    protected SmoothDimmer(WindowContainer host) {
+        this(host, new DimmerAnimationHelper.AnimationAdapterFactory());
     }
 
-    @Override
-    SurfaceControl getDimLayer() {
-        return mDimState != null ? mDimState.mDimLayer : null;
+    @VisibleForTesting
+    SmoothDimmer(WindowContainer host,
+                 DimmerAnimationHelper.AnimationAdapterFactory animationFactory) {
+        super(host);
+        mAnimationAdapterFactory = animationFactory;
     }
 
     @Override
     void resetDimStates() {
+        if (mDimState != null) {
+            mDimState.mLastRequestedDimContainer = null;
+        }
+    }
+
+    @Override
+    protected void adjustAppearance(WindowContainer container, float alpha, int blurRadius) {
+        final DimState d = obtainDimState(container);
+        d.prepareLookChange(alpha, blurRadius);
+    }
+
+    @Override
+    protected void adjustRelativeLayer(WindowContainer container, int relativeLayer) {
+        if (mDimState != null) {
+            mDimState.prepareReparent(container, relativeLayer);
+        }
+    }
+
+    @Override
+    boolean updateDims(SurfaceControl.Transaction t) {
         if (mDimState == null) {
-            return;
+            return false;
         }
-        if (!mDimState.mDontReset) {
-            mDimState.mDimming = false;
+        if (!mDimState.isDimming()) {
+            // No one is dimming, fade out and remove the dim
+            mDimState.exit(t);
+            mDimState = null;
+            return false;
+        } else {
+            // Someone is dimming, show the requested changes
+            mDimState.adjustSurfaceLayout(t);
+            final WindowState ws = mDimState.mLastRequestedDimContainer.asWindowState();
+            if (!mDimState.mIsVisible && ws != null && ws.mActivityRecord != null
+                    && ws.mActivityRecord.mStartingData != null) {
+                // Skip enter animation while starting window is on top of its activity
+                mDimState.mSkipAnimation = true;
+            }
+            mDimState.setReady(t);
+            return true;
         }
     }
 
+    private DimState obtainDimState(WindowContainer container) {
+        if (mDimState == null) {
+            mDimState = new DimState();
+        }
+        mDimState.mLastRequestedDimContainer = container;
+        return mDimState;
+    }
+
+    @Override
+    @VisibleForTesting
+    SurfaceControl getDimLayer() {
+        return mDimState != null ? mDimState.mDimSurface : null;
+    }
+
     @Override
     Rect getDimBounds() {
         return mDimState != null ? mDimState.mDimBounds : null;
@@ -287,127 +225,4 @@
             mDimState.mAnimateExit = false;
         }
     }
-
-    @Override
-    protected void adjustAppearance(WindowContainer container, float alpha, int blurRadius) {
-        final DimState d = obtainDimState(container);
-        mDimState.setRequestedAppearance(alpha, blurRadius);
-        d.mDimming = true;
-    }
-
-    @Override
-    protected void adjustRelativeLayer(WindowContainer container, int relativeLayer) {
-        if (mDimState != null) {
-            mDimState.setRequestedRelativeParent(container, relativeLayer);
-        }
-    }
-
-    boolean updateDims(SurfaceControl.Transaction t) {
-        if (mDimState == null) {
-            return false;
-        }
-
-        if (!mDimState.mDimming) {
-            // No one is dimming anymore, fade out dim and remove
-            if (!mDimState.mAnimateExit) {
-                if (mDimState.mDimLayer.isValid()) {
-                    t.remove(mDimState.mDimLayer);
-                }
-            } else {
-                mDimState.setExitParameters(
-                        mDimState.mRequestedProperties.mDimmingContainer);
-                mDimState.applyChanges(t);
-            }
-            mDimState = null;
-            return false;
-        }
-        final Rect bounds = mDimState.mDimBounds;
-        // TODO: Once we use geometry from hierarchy this falls away.
-        t.setPosition(mDimState.mDimLayer, bounds.left, bounds.top);
-        t.setWindowCrop(mDimState.mDimLayer, bounds.width(), bounds.height());
-        // Skip enter animation while starting window is on top of its activity
-        final WindowState ws = mLastRequestedDimContainer.asWindowState();
-        if (!mDimState.mIsVisible && ws != null && ws.mActivityRecord != null
-                && ws.mActivityRecord.mStartingData != null) {
-            mDimState.mRequestedProperties.mSkipAnimation = true;
-        }
-        mDimState.applyChanges(t);
-        return true;
-    }
-
-    private long getDimDuration(WindowContainer container) {
-        // Use the same duration as the animation on the WindowContainer
-        AnimationAdapter animationAdapter = container.mSurfaceAnimator.getAnimation();
-        final float durationScale = container.mWmService.getTransitionAnimationScaleLocked();
-        return animationAdapter == null ? (long) (DEFAULT_DIM_ANIM_DURATION * durationScale)
-                : animationAdapter.getDurationHint();
-    }
-
-    private static class AnimationExtremes<T> {
-        final T mStartValue;
-        final T mFinishValue;
-
-        AnimationExtremes(T fromValue, T toValue) {
-            mStartValue = fromValue;
-            mFinishValue = toValue;
-        }
-    }
-
-    private static class AnimationSpec implements LocalAnimationAdapter.AnimationSpec {
-        private final long mDuration;
-        private final AnimationExtremes<Float> mAlpha;
-        private final AnimationExtremes<Integer> mBlur;
-
-        float mCurrentAlpha = 0;
-        int mCurrentBlur = 0;
-
-        AnimationSpec(AnimationExtremes<Float> alpha,
-                AnimationExtremes<Integer> blur, long duration) {
-            mAlpha = alpha;
-            mBlur = blur;
-            mDuration = duration;
-        }
-
-        @Override
-        public long getDuration() {
-            return mDuration;
-        }
-
-        @Override
-        public void apply(SurfaceControl.Transaction t, SurfaceControl sc, long currentPlayTime) {
-            final float fraction = getFraction(currentPlayTime);
-            mCurrentAlpha =
-                    fraction * (mAlpha.mFinishValue - mAlpha.mStartValue) + mAlpha.mStartValue;
-            mCurrentBlur =
-                    (int) fraction * (mBlur.mFinishValue - mBlur.mStartValue) + mBlur.mStartValue;
-            t.setAlpha(sc, mCurrentAlpha);
-            t.setBackgroundBlurRadius(sc, mCurrentBlur);
-        }
-
-        @Override
-        public void dump(PrintWriter pw, String prefix) {
-            pw.print(prefix); pw.print("from_alpha="); pw.print(mAlpha.mStartValue);
-            pw.print(" to_alpha="); pw.print(mAlpha.mFinishValue);
-            pw.print(prefix); pw.print("from_blur="); pw.print(mBlur.mStartValue);
-            pw.print(" to_blur="); pw.print(mBlur.mFinishValue);
-            pw.print(" duration="); pw.println(mDuration);
-        }
-
-        @Override
-        public void dumpDebugInner(ProtoOutputStream proto) {
-            final long token = proto.start(ALPHA);
-            proto.write(FROM, mAlpha.mStartValue);
-            proto.write(TO, mAlpha.mFinishValue);
-            proto.write(DURATION_MS, mDuration);
-            proto.end(token);
-        }
-    }
-
-    static class AnimationAdapterFactory {
-
-        public AnimationAdapter get(LocalAnimationAdapter.AnimationSpec alphaAnimationSpec,
-                SurfaceAnimationRunner runner) {
-            return new LocalAnimationAdapter(alphaAnimationSpec, runner);
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7375512..5f08212 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -422,6 +422,11 @@
     // TODO: remove this once the recents animation is moved to the Shell
     SurfaceControl mLastRecentsAnimationOverlay;
 
+    // A surface that is used by TaskFragmentOrganizer to place content on top of own activities and
+    // trusted TaskFragments.
+    @Nullable
+    DecorSurfaceContainer mDecorSurfaceContainer;
+
     static final int LAYER_RANK_INVISIBLE = -1;
     // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
     // This number will be assigned when we evaluate OOM scores for all visible tasks.
@@ -1540,6 +1545,11 @@
             mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
         }
 
+        if (mDecorSurfaceContainer != null && r == mDecorSurfaceContainer.mOwnerTaskFragment) {
+            // Remove the decor surface if the owner TaskFragment is removed;
+            removeDecorSurface();
+        }
+
         if (hasChild()) {
             updateEffectiveIntent();
 
@@ -2638,6 +2648,9 @@
         }
         // If applicable let the TaskOrganizer know the Task is vanishing.
         setTaskOrganizer(null);
+        if (mDecorSurfaceContainer != null) {
+            mDecorSurfaceContainer.release();
+        }
 
         super.removeImmediately();
         mRemoving = false;
@@ -3644,7 +3657,8 @@
      */
     TaskFragmentParentInfo getTaskFragmentParentInfo() {
         return new TaskFragmentParentInfo(getConfiguration(), getDisplayId(),
-                shouldBeVisible(null /* starting */), hasNonFinishingDirectActivity());
+                shouldBeVisible(null /* starting */), hasNonFinishingDirectActivity(),
+                getDecorSurface());
     }
 
     @Override
@@ -3666,6 +3680,62 @@
         }
     }
 
+    @Override
+    void assignChildLayers(@NonNull SurfaceControl.Transaction t) {
+        int layer = 0;
+        boolean decorSurfacePlaced = false;
+
+        // We use two passes as a way to promote children which
+        // need Z-boosting to the end of the list.
+        for (int j = 0; j < mChildren.size(); ++j) {
+            final WindowContainer wc = mChildren.get(j);
+            wc.assignChildLayers(t);
+            if (!wc.needsZBoost()) {
+                // Place the decor surface under any untrusted content.
+                if (mDecorSurfaceContainer != null && !decorSurfacePlaced
+                        && shouldPlaceDecorSurfaceBelowContainer(wc)) {
+                    mDecorSurfaceContainer.assignLayer(t, layer++);
+                    decorSurfacePlaced = true;
+                }
+                wc.assignLayer(t, layer++);
+
+                // Place the decor surface just above the owner TaskFragment.
+                if (mDecorSurfaceContainer != null && !decorSurfacePlaced
+                        && wc == mDecorSurfaceContainer.mOwnerTaskFragment) {
+                    mDecorSurfaceContainer.assignLayer(t, layer++);
+                    decorSurfacePlaced = true;
+                }
+            }
+        }
+
+        // If not placed yet, the decor surface should be on top of all non-boosted children.
+        if (mDecorSurfaceContainer != null && !decorSurfacePlaced) {
+            mDecorSurfaceContainer.assignLayer(t, layer++);
+            decorSurfacePlaced = true;
+        }
+
+        for (int j = 0; j < mChildren.size(); ++j) {
+            final WindowContainer wc = mChildren.get(j);
+            if (wc.needsZBoost()) {
+                wc.assignLayer(t, layer++);
+            }
+        }
+        if (mOverlayHost != null) {
+            mOverlayHost.setLayer(t, layer++);
+        }
+    }
+
+    boolean shouldPlaceDecorSurfaceBelowContainer(@NonNull WindowContainer wc) {
+        boolean isOwnActivity =
+                wc.asActivityRecord() != null
+                        && wc.asActivityRecord().isUid(effectiveUid);
+        boolean isTrustedTaskFragment =
+                wc.asTaskFragment() != null
+                        && wc.asTaskFragment().isEmbedded()
+                        && wc.asTaskFragment().isAllowedToBeEmbeddedInTrustedMode();
+        return !isOwnActivity && !isTrustedTaskFragment;
+    }
+
     boolean isTaskId(int taskId) {
         return mTaskId == taskId;
     }
@@ -6177,6 +6247,7 @@
                 // Avoid resuming activities on secondary displays since we don't want bubble
                 // activities to be resumed while bubble is still collapsed.
                 // TODO(b/113840485): Having keyguard going away state for secondary displays.
+                && display != null
                 && display.isDefaultDisplay) {
             return false;
         }
@@ -6672,4 +6743,77 @@
             mOverlayHost.dispatchInsetsChanged(s, mTmpRect);
         }
     }
+
+    /**
+     * Associates the decor surface with the given TF, or create one if there
+     * isn't one in the Task yet. The surface will be removed with the TF,
+     * and become invisible if the TF is invisible. */
+    void moveOrCreateDecorSurfaceFor(TaskFragment taskFragment) {
+        if (mDecorSurfaceContainer != null) {
+            mDecorSurfaceContainer.mOwnerTaskFragment = taskFragment;
+        } else {
+            mDecorSurfaceContainer = new DecorSurfaceContainer(taskFragment);
+            assignChildLayers();
+            sendTaskFragmentParentInfoChangedIfNeeded();
+        }
+    }
+
+    void removeDecorSurface() {
+        if (mDecorSurfaceContainer == null) {
+            return;
+        }
+        mDecorSurfaceContainer.release();
+        mDecorSurfaceContainer = null;
+        sendTaskFragmentParentInfoChangedIfNeeded();
+    }
+
+    @Nullable SurfaceControl getDecorSurface() {
+        return mDecorSurfaceContainer != null ? mDecorSurfaceContainer.mDecorSurface : null;
+    }
+
+    /**
+     * A decor surface that is requested by a {@code TaskFragmentOrganizer} which will be placed
+     * below children windows except for own Activities and TaskFragment in fully trusted mode.
+     */
+    @VisibleForTesting
+    class DecorSurfaceContainer {
+        @VisibleForTesting
+        @NonNull final SurfaceControl mContainerSurface;
+
+        @VisibleForTesting
+        @NonNull final SurfaceControl mDecorSurface;
+
+        // The TaskFragment that requested the decor surface. If it is destroyed, the decor surface
+        // is also released.
+        @VisibleForTesting
+        @NonNull TaskFragment mOwnerTaskFragment;
+
+        private DecorSurfaceContainer(@NonNull TaskFragment initialOwner) {
+            mOwnerTaskFragment = initialOwner;
+            mContainerSurface = makeSurface().setContainerLayer()
+                    .setParent(mSurfaceControl)
+                    .setName(mSurfaceControl + " - decor surface container")
+                    .setEffectLayer()
+                    .setHidden(false)
+                    .setCallsite("Task.DecorSurfaceContainer")
+                    .build();
+
+            mDecorSurface = makeSurface()
+                    .setParent(mContainerSurface)
+                    .setName(mSurfaceControl + " - decor surface")
+                    .setHidden(false)
+                    .setCallsite("Task.DecorSurfaceContainer")
+                    .build();
+        }
+
+        private void assignLayer(@NonNull SurfaceControl.Transaction t, int layer) {
+            t.setLayer(mContainerSurface, layer);
+            t.setVisibility(mContainerSurface, mOwnerTaskFragment.isVisible());
+        }
+
+        private void release() {
+            mDecorSurface.release();
+            mContainerSurface.release();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 8bc461f..39b4480 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -316,7 +316,8 @@
     /** Organizer that organizing this TaskFragment. */
     @Nullable
     private ITaskFragmentOrganizer mTaskFragmentOrganizer;
-    private int mTaskFragmentOrganizerUid = INVALID_UID;
+    @VisibleForTesting
+    int mTaskFragmentOrganizerUid = INVALID_UID;
     private @Nullable String mTaskFragmentOrganizerProcessName;
 
     /** Client assigned unique token for this TaskFragment if this is created by an organizer. */
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index e7a1cf1..707f9fc 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -762,6 +762,8 @@
                     .setTask(task)
                     .build());
         }
+        // Make sure the parent info changed event will be dispatched if there are no other changes.
+        mAtmService.mWindowManager.mWindowPlacerLocked.requestTraversal();
     }
 
     boolean isSystemOrganizer(@NonNull IBinder organizerToken) {
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 3a711b2..27cc2d6 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -1182,22 +1182,6 @@
         }
     }
 
-    @Override
-    public void setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled,
-            @Nullable int[] fromOrientations, @Nullable int[] toOrientations) {
-        enforceTaskPermission("setOrientationRequestPolicy()");
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                mService.mWindowManager
-                        .setOrientationRequestPolicy(isIgnoreOrientationRequestDisabled,
-                                fromOrientations, toOrientations);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
     public boolean handleInterceptBackPressedOnTaskRoot(Task task) {
         if (!shouldInterceptBackPressedOnRootTask(task)) {
             return false;
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index caa57bb..e5604ec 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1737,8 +1737,8 @@
         // Since we created root-leash but no longer reference it from core, release it now
         info.releaseAnimSurfaces();
 
-        mLogger.logOnSendAsync(mController.mLoggerHandler);
         if (mLogger.mInfo != null) {
+            mLogger.logOnSendAsync(mController.mLoggerHandler);
             mController.mTransitionTracer.logSentTransition(this, mTargets);
         }
     }
@@ -1756,6 +1756,27 @@
     }
 
     /**
+     * Checks if the transition contains order changes.
+     *
+     * This is a shallow check that doesn't account for collection in parallel, unlike
+     * {@code collectOrderChanges}
+     */
+    boolean hasOrderChanges() {
+        ArrayList<Task> onTopTasks = new ArrayList<>();
+        // Iterate over target displays to get up to date on top tasks.
+        // Cannot use `mOnTopTasksAtReady` as it's not populated before the `applyReady` is called.
+        for (DisplayContent dc : mTargetDisplays) {
+            addOnTopTasks(dc, onTopTasks);
+        }
+        for (Task task : onTopTasks) {
+            if (!mOnTopTasksStart.contains(task)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Collect tasks which moved-to-top as part of this transition. This also updates the
      * controller's latest-reported when relevant.
      *
@@ -3305,7 +3326,6 @@
          */
         void addGroup(WindowContainer wc) {
             if (mReadyGroups.containsKey(wc)) {
-                Slog.e(TAG, "Trying to add a ready-group twice: " + wc);
                 return;
             }
             mReadyGroups.put(wc, false);
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index bacfda5..e648d64 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -792,6 +792,12 @@
         mCollectingTransition.recordTaskOrder(wc);
     }
 
+    /** @see Transition#hasOrderChanges */
+    boolean hasOrderChanges() {
+        if (mCollectingTransition == null) return false;
+        return mCollectingTransition.hasOrderChanges();
+    }
+
     /**
      * Collects the window containers which need to be synced with the changing display area into
      * the current collecting transition.
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index ae171a0..808a11d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -993,4 +993,18 @@
      * @param displayId the id of display to check if there is a software navigation bar.
      */
     public abstract boolean hasNavigationBar(int displayId);
+
+    /**
+     * Controls whether the app-requested screen orientation is always respected.
+     *
+     * @param respected If {@code true}, the app requested orientation is always respected.
+     *                  Otherwise, the system might ignore the request due to
+     *                  {@link com.android.server.wm.DisplayArea#getIgnoreOrientationRequest}.
+     * @param fromOrientations The orientations we want to map to the correspondent orientations
+     *                         in toOrientation.
+     * @param toOrientations The orientations we map to the ones in fromOrientations at the same
+     *                       index
+     */
+    public abstract void setOrientationRequestPolicy(boolean respected,
+            int[] fromOrientations, int[] toOrientations);
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 575ae69b..0d2c94d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2327,8 +2327,8 @@
             boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
                     && win.hasWallpaper();
             wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
-            if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {
-                winAnimator.mSurfaceController.setSecure(win.isSecureLocked());
+            if ((flagChanges & FLAG_SECURE) != 0) {
+                win.setSecureLocked(win.isSecureLocked());
             }
 
             final boolean wasVisible = win.isVisible();
@@ -8523,6 +8523,15 @@
                 mImeTargetChangeListener = listener;
             }
         }
+
+        @Override
+        public void setOrientationRequestPolicy(boolean respected,
+                int[] fromOrientations, int[] toOrientations) {
+            synchronized (mGlobalLock) {
+                WindowManagerService.this.setOrientationRequestPolicy(respected,
+                        fromOrientations, toOrientations);
+            }
+        }
     }
 
     private final class ImeTargetVisibilityPolicyImpl extends ImeTargetVisibilityPolicy {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 208df6c7..2af6569 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -23,7 +23,9 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.window.TaskFragmentOperation.OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS;
 import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE;
 import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE;
 import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_BOTTOM_OF_TASK;
 import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
 import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_TOP_OF_TASK;
@@ -1468,6 +1470,16 @@
                 }
                 break;
             }
+            case OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE: {
+                final Task task = taskFragment.getTask();
+                task.moveOrCreateDecorSurfaceFor(taskFragment);
+                break;
+            }
+            case OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE: {
+                final Task task = taskFragment.getTask();
+                task.removeDecorSurface();
+                break;
+            }
         }
         return effects;
     }
@@ -1507,6 +1519,19 @@
             return false;
         }
 
+        // TODO (b/293654166) remove the decor surface checks once we clear security reviews
+        if ((opType == OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE
+                || opType == OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE)
+                && !mTaskFragmentOrganizerController.isSystemOrganizer(organizer.asBinder())) {
+            final Throwable exception = new SecurityException(
+                    "Only a system organizer can perform OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE"
+                            + " or OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE."
+            );
+            sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+                    opType, exception);
+            return false;
+        }
+
         final IBinder secondaryFragmentToken = operation.getSecondaryFragmentToken();
         return secondaryFragmentToken == null
                 || validateTaskFragment(mLaunchTaskFragments.get(secondaryFragmentToken), opType,
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 6d6bcc8..e1f1f66 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -109,6 +109,7 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SYNC_ENGINE;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_INSETS;
+import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.policy.WindowManagerPolicy.TRANSIT_ENTER;
 import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT;
@@ -177,6 +178,7 @@
 import static com.android.server.wm.WindowStateProto.VIEW_VISIBILITY;
 import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES;
+import static com.android.window.flags.Flags.secureWindowState;
 import static com.android.window.flags.Flags.surfaceTrustedOverlay;
 
 import android.annotation.CallSuper;
@@ -1195,6 +1197,9 @@
         if (surfaceTrustedOverlay() && isWindowTrustedOverlay()) {
             getPendingTransaction().setTrustedOverlay(mSurfaceControl, true);
         }
+        if (secureWindowState()) {
+            getPendingTransaction().setSecure(mSurfaceControl, isSecureLocked());
+        }
     }
 
     void updateTrustedOverlay() {
@@ -6042,4 +6047,25 @@
         // Cancel any draw requests during a sync.
         return mPrepareSyncSeqId > 0;
     }
+
+    void setSecureLocked(boolean isSecure) {
+        ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isSecure=%b: %s", isSecure, getName());
+        if (secureWindowState()) {
+            if (mSurfaceControl == null) {
+                return;
+            }
+            getPendingTransaction().setSecure(mSurfaceControl, isSecure);
+        } else {
+            if (mWinAnimator.mSurfaceController == null
+                    || mWinAnimator.mSurfaceController.mSurfaceControl == null) {
+                return;
+            }
+            getPendingTransaction().setSecure(mWinAnimator.mSurfaceController.mSurfaceControl,
+                    isSecure);
+        }
+        if (mDisplayContent != null) {
+            mDisplayContent.refreshImeSecureFlag(getSyncTransaction());
+        }
+        mWmService.scheduleAnimationLocked();
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3aac816..44cd23d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -44,6 +44,7 @@
 import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE;
 import static com.android.server.wm.WindowStateAnimatorProto.SURFACE;
 import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT;
+import static com.android.window.flags.Flags.secureWindowState;
 
 import android.content.Context;
 import android.graphics.PixelFormat;
@@ -286,8 +287,10 @@
         int flags = SurfaceControl.HIDDEN;
         final WindowManager.LayoutParams attrs = w.mAttrs;
 
-        if (w.isSecureLocked()) {
-            flags |= SurfaceControl.SECURE;
+        if (!secureWindowState()) {
+            if (w.isSecureLocked()) {
+                flags |= SurfaceControl.SECURE;
+            }
         }
 
         if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
@@ -488,13 +491,6 @@
         mSurfaceController.setOpaque(isOpaque);
     }
 
-    void setSecureLocked(boolean isSecure) {
-        if (mSurfaceController == null) {
-            return;
-        }
-        mSurfaceController.setSecure(isSecure);
-    }
-
     void setColorSpaceAgnosticLocked(boolean agnostic) {
         if (mSurfaceController == null) {
             return;
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index d348491..4456a94 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -24,7 +24,6 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowSurfaceControllerProto.SHOWN;
@@ -152,24 +151,6 @@
         mService.scheduleAnimationLocked();
     }
 
-    void setSecure(boolean isSecure) {
-        ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isSecure=%b: %s", isSecure, title);
-
-        if (mSurfaceControl == null) {
-            return;
-        }
-        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
-
-        final SurfaceControl.Transaction t = mAnimator.mWin.getPendingTransaction();
-        t.setSecure(mSurfaceControl, isSecure);
-
-        final DisplayContent dc = mAnimator.mWin.mDisplayContent;
-        if (dc != null) {
-            dc.refreshImeSecureFlag(t);
-        }
-        mService.scheduleAnimationLocked();
-    }
-
     void setColorSpaceAgnostic(SurfaceControl.Transaction t, boolean agnostic) {
         ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isColorSpaceAgnostic=%b: %s", agnostic, title);
 
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 cca4261..c625b1e 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -159,6 +159,12 @@
                 <xs:element type="usiVersion" name="usiVersion">
                     <xs:annotation name="final"/>
                 </xs:element>
+                <!-- Maximum screen brightness setting when screen brightness capped in
+                Wear Bedtime mode. This must be a non-negative decimal within the range defined by
+                the first and the last brightness value in screenBrightnessMap. -->
+                <xs:element type="nonNegativeDecimal" name="screenBrightnessCapForWearBedtimeMode">
+                    <xs:annotation name="final"/>
+                </xs:element>
             </xs:sequence>
         </xs:complexType>
     </xs:element>
@@ -586,42 +592,39 @@
                         minOccurs="0" maxOccurs="1">
                 <xs:annotation name="final"/>
             </xs:element>
-            <!-- Sets the brightness mapping of the desired screen brightness in nits to the
-             corresponding lux for the current display -->
-            <xs:element name="displayBrightnessMapping" type="displayBrightnessMapping"
+            <!-- Sets the brightness mapping of the desired screen brightness to the corresponding
+            lux for the current display -->
+            <xs:element name="luxToBrightnessMapping" type="luxToBrightnessMapping"
                         minOccurs="0" maxOccurs="1">
                 <xs:annotation name="final"/>
             </xs:element>
         </xs:sequence>
     </xs:complexType>
 
-    <!-- Represents the brightness mapping of the desired screen brightness in nits to the
-             corresponding lux for the current display -->
-    <xs:complexType name="displayBrightnessMapping">
-        <xs:sequence>
-            <!-- Sets the list of display brightness points, each representing the desired screen
-            brightness in nits to the corresponding lux for the current display
+    <!-- Sets the list of display brightness points, each representing the desired screen brightness
+    in a certain lux environment.
 
-            The N entries of this array define N + 1 control points as follows:
-            (1-based arrays)
+    The first value of each point is the lux value and the second value is the brightness value.
 
-            Point 1:            (0, nits[1]):             currentLux <= 0
-            Point 2:     (lux[1], nits[2]):       0 < currentLux <= lux[1]
-            Point 3:     (lux[2], nits[3]):  lux[2] < currentLux <= lux[3]
-            ...
-            Point N+1: (lux[N], nits[N+1]):            lux[N] < currentLux
+    The first lux value must be 0.
 
-            The control points must be strictly increasing. Each control point
-            corresponds to an entry in the brightness backlight values arrays.
-            For example, if currentLux == lux[1] (first element of the levels array)
-            then the brightness will be determined by nits[2] (second element
-            of the brightness values array).
-            -->
-            <xs:element name="displayBrightnessPoint" type="displayBrightnessPoint"
-                        minOccurs="1" maxOccurs="unbounded">
-                <xs:annotation name="final"/>
-            </xs:element>
-        </xs:sequence>
+    The control points must be strictly increasing.
+
+    Example: if currentLux == the second lux value in the mapping then the brightness will be
+    determined by the second brightness value in the mapping. Spline interpolation is used
+    to determine the auto-brightness values for lux levels between these control points.
+
+    The brightness values must be non-negative decimals within the range between the first and
+    the last brightness values in screenBrightnessMap.
+
+    This is used in place of config_autoBrightnessLevels and config_autoBrightnessLcdBacklightValues
+    defined in the config XML resource.
+    -->
+    <xs:complexType name="luxToBrightnessMapping">
+        <xs:element name="map" type="nonNegativeFloatToFloatMap">
+            <xs:annotation name="nonnull"/>
+            <xs:annotation name="final"/>
+        </xs:element>
     </xs:complexType>
 
     <!-- Represents a point in the display brightness mapping, representing the lux level from the
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index f767291..8c8c123 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -7,14 +7,14 @@
     method public final java.math.BigInteger getBrighteningLightDebounceMillis();
     method public final java.math.BigInteger getDarkeningLightDebounceIdleMillis();
     method public final java.math.BigInteger getDarkeningLightDebounceMillis();
-    method public final com.android.server.display.config.DisplayBrightnessMapping getDisplayBrightnessMapping();
     method public boolean getEnabled();
+    method public final com.android.server.display.config.LuxToBrightnessMapping getLuxToBrightnessMapping();
     method public final void setBrighteningLightDebounceIdleMillis(java.math.BigInteger);
     method public final void setBrighteningLightDebounceMillis(java.math.BigInteger);
     method public final void setDarkeningLightDebounceIdleMillis(java.math.BigInteger);
     method public final void setDarkeningLightDebounceMillis(java.math.BigInteger);
-    method public final void setDisplayBrightnessMapping(com.android.server.display.config.DisplayBrightnessMapping);
     method public void setEnabled(boolean);
+    method public final void setLuxToBrightnessMapping(com.android.server.display.config.LuxToBrightnessMapping);
   }
 
   public class BlockingZoneConfig {
@@ -78,11 +78,6 @@
     method public java.util.List<com.android.server.display.config.Density> getDensity();
   }
 
-  public class DisplayBrightnessMapping {
-    ctor public DisplayBrightnessMapping();
-    method public final java.util.List<com.android.server.display.config.DisplayBrightnessPoint> getDisplayBrightnessPoint();
-  }
-
   public class DisplayBrightnessPoint {
     ctor public DisplayBrightnessPoint();
     method public final java.math.BigInteger getLux();
@@ -110,6 +105,7 @@
     method public final com.android.server.display.config.SensorDetails getProxSensor();
     method public com.android.server.display.config.DisplayQuirks getQuirks();
     method public com.android.server.display.config.RefreshRateConfigs getRefreshRate();
+    method public final java.math.BigDecimal getScreenBrightnessCapForWearBedtimeMode();
     method @NonNull public final java.math.BigDecimal getScreenBrightnessDefault();
     method @NonNull public final com.android.server.display.config.NitsMap getScreenBrightnessMap();
     method public final java.math.BigInteger getScreenBrightnessRampDecreaseMaxIdleMillis();
@@ -143,6 +139,7 @@
     method public final void setProxSensor(com.android.server.display.config.SensorDetails);
     method public void setQuirks(com.android.server.display.config.DisplayQuirks);
     method public void setRefreshRate(com.android.server.display.config.RefreshRateConfigs);
+    method public final void setScreenBrightnessCapForWearBedtimeMode(java.math.BigDecimal);
     method public final void setScreenBrightnessDefault(@NonNull java.math.BigDecimal);
     method public final void setScreenBrightnessMap(@NonNull com.android.server.display.config.NitsMap);
     method public final void setScreenBrightnessRampDecreaseMaxIdleMillis(java.math.BigInteger);
@@ -220,6 +217,12 @@
     method @NonNull public final java.util.List<com.android.server.display.config.BrightnessLimitMap> getBrightnessLimitMap();
   }
 
+  public class LuxToBrightnessMapping {
+    ctor public LuxToBrightnessMapping();
+    method @NonNull public final com.android.server.display.config.NonNegativeFloatToFloatMap getMap();
+    method public final void setMap(@NonNull com.android.server.display.config.NonNegativeFloatToFloatMap);
+  }
+
   public class NitsMap {
     ctor public NitsMap();
     method public String getInterpolation();
diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java
index 1988bb6..da44aac 100644
--- a/services/credentials/java/com/android/server/credentials/RequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/RequestSession.java
@@ -23,12 +23,14 @@
 import android.content.Context;
 import android.content.Intent;
 import android.credentials.CredentialProviderInfo;
+import android.credentials.flags.Flags;
 import android.credentials.ui.ProviderData;
 import android.credentials.ui.UserSelectionDialogResult;
 import android.os.Binder;
 import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IInterface;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -94,6 +96,9 @@
 
     private final Set<ComponentName> mEnabledProviders;
 
+    private final RequestSessionDeathRecipient mDeathRecipient =
+            new RequestSessionDeathRecipient();
+
     protected PendingIntent mPendingIntent;
 
     @NonNull
@@ -141,11 +146,26 @@
         mRequestSessionMetric.collectInitialPhaseMetricInfo(timestampStarted,
                 mCallingUid, ApiName.getMetricCodeFromRequestInfo(mRequestType));
         setCancellationListener();
+        if (Flags.clearSessionEnabled()) {
+            setUpClientCallbackListener();
+        }
+    }
+
+    private void setUpClientCallbackListener() {
+        if (mClientCallback != null && mClientCallback instanceof IInterface) {
+            IInterface callback = (IInterface) mClientCallback;
+            try {
+                callback.asBinder().linkToDeath(mDeathRecipient, 0);
+            } catch (RemoteException e) {
+                Slog.e(TAG, e.getMessage());
+            }
+        }
     }
 
     private void setCancellationListener() {
         mCancellationSignal.setOnCancelListener(
                 () -> {
+                    Slog.d(TAG, "Cancellation invoked from the client - clearing session");
                     boolean isUiActive = maybeCancelUi();
                     finishSession(!isUiActive);
                 }
@@ -168,6 +188,17 @@
         return false;
     }
 
+    private boolean isUiWaitingForData() {
+        // Technically, the status can also be IN_PROGRESS when the user has made a selection
+        // so this an over estimation, but safe to do so as it is used for cancellation
+        // propagation to the provider in a very narrow time frame. If provider has
+        // already responded, cancellation is not an issue as the cancellation listener
+        // is independent of the service binding.
+        // TODO(b/313512500): Do not propagate cancelation if provider has responded in
+        // query phase.
+        return mCredentialManagerUi.getStatus() == CredentialManagerUi.UiStatus.IN_PROGRESS;
+    }
+
     public abstract ProviderSession initiateProviderSession(CredentialProviderInfo providerInfo,
             RemoteCredentialService remoteCredentialService);
 
@@ -373,4 +404,12 @@
         return chosenProviderSession != null && chosenProviderSession.mProviderInfo != null
                 && chosenProviderSession.mProviderInfo.isPrimary();
     }
+
+    private class RequestSessionDeathRecipient implements IBinder.DeathRecipient {
+        @Override
+        public void binderDied() {
+            Slog.d(TAG, "Client binder died - clearing session");
+            finishSession(isUiWaitingForData());
+        }
+    }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0a2e806..1919eb3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2112,6 +2112,15 @@
             networkPolicy.bindConnectivityManager();
             t.traceEnd();
 
+            t.traceBegin("StartSecurityStateManagerService");
+            try {
+                ServiceManager.addService(Context.SECURITY_STATE_SERVICE,
+                        new SecurityStateManagerService(context));
+            } catch (Throwable e) {
+                reportWtf("starting SecurityStateManagerService", e);
+            }
+            t.traceEnd();
+
             t.traceBegin("StartVpnManagerService");
             try {
                 vpnManager = VpnManagerService.create(context);
diff --git a/services/permission/OWNERS b/services/permission/OWNERS
index e464038..487c992 100644
--- a/services/permission/OWNERS
+++ b/services/permission/OWNERS
@@ -1,5 +1,3 @@
 #Bug component: 137825
 
-joecastro@google.com
-ntmyren@google.com
-zhanghai@google.com
+include platform/frameworks/base:/core/java/android/permission/OWNERS
diff --git a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
index f94a0d6..8f464d4 100644
--- a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
+++ b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
@@ -71,7 +71,7 @@
         // Not implemented because upgrades are handled automatically.
     }
 
-    override fun getNonDefaultUidModes(uid: Int): SparseIntArray {
+    override fun getNonDefaultUidModes(uid: Int, persistentDeviceId: String): SparseIntArray {
         return opNameMapToOpSparseArray(getUidModes(uid))
     }
 
@@ -79,7 +79,7 @@
         return opNameMapToOpSparseArray(getPackageModes(packageName, userId))
     }
 
-    override fun getUidMode(uid: Int, op: Int): Int {
+    override fun getUidMode(uid: Int, persistentDeviceId: String, op: Int): Int {
         val appId = UserHandle.getAppId(uid)
         val userId = UserHandle.getUserId(uid)
         val opName = AppOpsManager.opToPublicName(op)
@@ -92,7 +92,7 @@
         return service.getState { with(appIdPolicy) { getAppOpModes(appId, userId) } }?.map
     }
 
-    override fun setUidMode(uid: Int, op: Int, mode: Int): Boolean {
+    override fun setUidMode(uid: Int, persistentDeviceId: String, op: Int, mode: Int): Boolean {
         val appId = UserHandle.getAppId(uid)
         val userId = UserHandle.getUserId(uid)
         val opName = AppOpsManager.opToPublicName(op)
@@ -150,7 +150,7 @@
         // and we have our own persistence.
     }
 
-    override fun getForegroundOps(uid: Int): SparseBooleanArray {
+    override fun getForegroundOps(uid: Int, persistentDeviceId: String): SparseBooleanArray {
         return SparseBooleanArray().apply {
             getUidModes(uid)?.forEachIndexed { _, op, mode ->
                 if (mode == AppOpsManager.MODE_FOREGROUND) {
diff --git a/services/robotests/src/com/android/server/media/AudioPoliciesBluetoothRouteControllerTest.java b/services/robotests/src/com/android/server/media/AudioPoliciesBluetoothRouteControllerTest.java
deleted file mode 100644
index 0ad4184..0000000
--- a/services/robotests/src/com/android/server/media/AudioPoliciesBluetoothRouteControllerTest.java
+++ /dev/null
@@ -1,293 +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.media;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.when;
-
-import android.app.Application;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
-import android.bluetooth.BluetoothProfile;
-import android.content.Context;
-import android.content.Intent;
-import android.media.AudioManager;
-import android.media.MediaRoute2Info;
-import android.os.UserHandle;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.Shadows;
-import org.robolectric.shadows.ShadowBluetoothAdapter;
-import org.robolectric.shadows.ShadowBluetoothDevice;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(RobolectricTestRunner.class)
-public class AudioPoliciesBluetoothRouteControllerTest {
-
-    private static final String DEVICE_ADDRESS_UNKNOWN = ":unknown:ip:address:";
-    private static final String DEVICE_ADDRESS_SAMPLE_1 = "30:59:8B:E4:C6:35";
-    private static final String DEVICE_ADDRESS_SAMPLE_2 = "0D:0D:A6:FF:8D:B6";
-    private static final String DEVICE_ADDRESS_SAMPLE_3 = "2D:9B:0C:C2:6F:78";
-    private static final String DEVICE_ADDRESS_SAMPLE_4 = "66:88:F9:2D:A8:1E";
-
-    private Context mContext;
-
-    private ShadowBluetoothAdapter mShadowBluetoothAdapter;
-
-    @Mock
-    private BluetoothRouteController.BluetoothRoutesUpdatedListener mListener;
-
-    @Mock
-    private BluetoothProfileMonitor mBluetoothProfileMonitor;
-
-    private AudioPoliciesBluetoothRouteController mAudioPoliciesBluetoothRouteController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        Application application = ApplicationProvider.getApplicationContext();
-        mContext = application;
-
-        BluetoothManager bluetoothManager = (BluetoothManager)
-                mContext.getSystemService(Context.BLUETOOTH_SERVICE);
-
-        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
-        mShadowBluetoothAdapter = Shadows.shadowOf(bluetoothAdapter);
-
-        mAudioPoliciesBluetoothRouteController =
-                new AudioPoliciesBluetoothRouteController(mContext, bluetoothAdapter,
-                        mBluetoothProfileMonitor, mListener) {
-                    @Override
-                    boolean isDeviceConnected(BluetoothDevice device) {
-                        return true;
-                    }
-                };
-
-        // Enable A2DP profile.
-        when(mBluetoothProfileMonitor.isProfileSupported(eq(BluetoothProfile.A2DP), any()))
-                .thenReturn(true);
-        mShadowBluetoothAdapter.setProfileConnectionState(BluetoothProfile.A2DP,
-                BluetoothProfile.STATE_CONNECTED);
-
-        mAudioPoliciesBluetoothRouteController.start(UserHandle.of(0));
-    }
-
-    @Test
-    public void getSelectedRoute_noBluetoothRoutesAvailable_returnsNull() {
-        assertThat(mAudioPoliciesBluetoothRouteController.getSelectedRoute()).isNull();
-    }
-
-    @Test
-    public void selectRoute_noBluetoothRoutesAvailable_returnsFalse() {
-        assertThat(mAudioPoliciesBluetoothRouteController
-                .selectRoute(DEVICE_ADDRESS_UNKNOWN)).isFalse();
-    }
-
-    @Test
-    public void selectRoute_noDeviceWithGivenAddress_returnsFalse() {
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
-                DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_3);
-
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        assertThat(mAudioPoliciesBluetoothRouteController
-                .selectRoute(DEVICE_ADDRESS_SAMPLE_2)).isFalse();
-    }
-
-    @Test
-    public void selectRoute_deviceIsInDevicesSet_returnsTrue() {
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
-                DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2);
-
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        assertThat(mAudioPoliciesBluetoothRouteController
-                .selectRoute(DEVICE_ADDRESS_SAMPLE_1)).isTrue();
-    }
-
-    @Test
-    public void selectRoute_resetSelectedDevice_returnsTrue() {
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
-                DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2);
-
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_1);
-        assertThat(mAudioPoliciesBluetoothRouteController.selectRoute(null)).isTrue();
-    }
-
-    @Test
-    public void selectRoute_noSelectedDevice_returnsTrue() {
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
-                DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2);
-
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        assertThat(mAudioPoliciesBluetoothRouteController.selectRoute(null)).isTrue();
-    }
-
-    @Test
-    public void getSelectedRoute_updateRouteFailed_returnsNull() {
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
-                DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2);
-
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-        mAudioPoliciesBluetoothRouteController
-                .selectRoute(DEVICE_ADDRESS_SAMPLE_3);
-
-        assertThat(mAudioPoliciesBluetoothRouteController.getSelectedRoute()).isNull();
-    }
-
-    @Test
-    public void getSelectedRoute_updateRouteSuccessful_returnsUpdateDevice() {
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
-                DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4);
-
-        assertThat(mAudioPoliciesBluetoothRouteController.getSelectedRoute()).isNull();
-
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        assertThat(mAudioPoliciesBluetoothRouteController
-                .selectRoute(DEVICE_ADDRESS_SAMPLE_4)).isTrue();
-
-        MediaRoute2Info selectedRoute = mAudioPoliciesBluetoothRouteController.getSelectedRoute();
-        assertThat(selectedRoute.getAddress()).isEqualTo(DEVICE_ADDRESS_SAMPLE_4);
-    }
-
-    @Test
-    public void getSelectedRoute_resetSelectedRoute_returnsNull() {
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(
-                DEVICE_ADDRESS_SAMPLE_1, DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4);
-
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        // Device is not null now.
-        mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_4);
-        // Rest the device.
-        mAudioPoliciesBluetoothRouteController.selectRoute(null);
-
-        assertThat(mAudioPoliciesBluetoothRouteController.getSelectedRoute())
-                .isNull();
-    }
-
-    @Test
-    public void getTransferableRoutes_noSelectedRoute_returnsAllBluetoothDevices() {
-        String[] addresses = new String[] { DEVICE_ADDRESS_SAMPLE_1,
-                DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4 };
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(addresses);
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        // Force route controller to update bluetooth devices list.
-        sendBluetoothDevicesChangedBroadcast();
-
-        Set<String> transferableDevices = extractAddressesListFrom(
-                mAudioPoliciesBluetoothRouteController.getTransferableRoutes());
-        assertThat(transferableDevices).containsExactlyElementsIn(addresses);
-    }
-
-    @Test
-    public void getTransferableRoutes_hasSelectedRoute_returnsRoutesWithoutSelectedDevice() {
-        String[] addresses = new String[] { DEVICE_ADDRESS_SAMPLE_1,
-                DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4 };
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(addresses);
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        // Force route controller to update bluetooth devices list.
-        sendBluetoothDevicesChangedBroadcast();
-        mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_4);
-
-        Set<String> transferableDevices = extractAddressesListFrom(
-                mAudioPoliciesBluetoothRouteController.getTransferableRoutes());
-        assertThat(transferableDevices).containsExactly(DEVICE_ADDRESS_SAMPLE_1,
-                DEVICE_ADDRESS_SAMPLE_2);
-    }
-
-    @Test
-    public void getAllBluetoothRoutes_hasSelectedRoute_returnsAllRoutes() {
-        String[] addresses = new String[] { DEVICE_ADDRESS_SAMPLE_1,
-                DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4 };
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(addresses);
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        // Force route controller to update bluetooth devices list.
-        sendBluetoothDevicesChangedBroadcast();
-        mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_4);
-
-        Set<String> bluetoothDevices = extractAddressesListFrom(
-                mAudioPoliciesBluetoothRouteController.getAllBluetoothRoutes());
-        assertThat(bluetoothDevices).containsExactlyElementsIn(addresses);
-    }
-
-    @Test
-    public void updateVolumeForDevice_setVolumeForA2DPTo25_selectedRouteVolumeIsUpdated() {
-        String[] addresses = new String[] { DEVICE_ADDRESS_SAMPLE_1,
-                DEVICE_ADDRESS_SAMPLE_2, DEVICE_ADDRESS_SAMPLE_4 };
-        Set<BluetoothDevice> devices = generateFakeBluetoothDevicesSet(addresses);
-        mShadowBluetoothAdapter.setBondedDevices(devices);
-
-        // Force route controller to update bluetooth devices list.
-        sendBluetoothDevicesChangedBroadcast();
-        mAudioPoliciesBluetoothRouteController.selectRoute(DEVICE_ADDRESS_SAMPLE_4);
-
-        mAudioPoliciesBluetoothRouteController.updateVolumeForDevices(
-                AudioManager.DEVICE_OUT_BLUETOOTH_A2DP, 25);
-
-        MediaRoute2Info selectedRoute = mAudioPoliciesBluetoothRouteController.getSelectedRoute();
-        assertThat(selectedRoute.getVolume()).isEqualTo(25);
-    }
-
-    private void sendBluetoothDevicesChangedBroadcast() {
-        Intent intent = new Intent(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
-        mContext.sendBroadcast(intent);
-    }
-
-    private static Set<String> extractAddressesListFrom(Collection<MediaRoute2Info> routes) {
-        Set<String> addresses = new HashSet<>();
-
-        for (MediaRoute2Info route: routes) {
-            addresses.add(route.getAddress());
-        }
-
-        return addresses;
-    }
-
-    private static Set<BluetoothDevice> generateFakeBluetoothDevicesSet(String... addresses) {
-        Set<BluetoothDevice> devices = new HashSet<>();
-
-        for (String address: addresses) {
-            devices.add(ShadowBluetoothDevice.newInstance(address));
-        }
-
-        return devices;
-    }
-}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java
index afbe352..e5be4d9 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java
@@ -21,6 +21,8 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -56,6 +58,7 @@
 
     private static final int TEST_USER_SERIAL = 1000;
     private static final int TEST_USER_ID = 10;
+    private static final UserInfo TEST_USER = new UserInfo();
 
     private TestUserDataPreparer mUserDataPreparer;
 
@@ -72,6 +75,8 @@
 
     @Before
     public void setup() {
+        TEST_USER.id = TEST_USER_ID;
+        TEST_USER.serialNumber = TEST_USER_SERIAL;
         Context ctx = InstrumentationRegistry.getContext();
         FileUtils.deleteContents(ctx.getCacheDir());
         mInstallLock = new Object();
@@ -92,8 +97,7 @@
         userDeDir.mkdirs();
         File systemDeDir = mUserDataPreparer.getDataSystemDeDirectory(TEST_USER_ID);
         systemDeDir.mkdirs();
-        mUserDataPreparer
-                .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_DE);
+        mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_DE);
         verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID),
                 eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_DE));
         verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID),
@@ -110,8 +114,7 @@
         userCeDir.mkdirs();
         File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID);
         systemCeDir.mkdirs();
-        mUserDataPreparer
-                .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_CE);
+        mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_CE);
         verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID),
                 eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_CE));
         verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID),
@@ -123,6 +126,28 @@
     }
 
     @Test
+    public void testPrepareUserData_forNewUser_destroysOnFailure() throws Exception {
+        TEST_USER.lastLoggedInTime = 0;
+        doThrow(new IllegalStateException("expected exception for test")).when(mStorageManagerMock)
+                .prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL),
+                        eq(StorageManager.FLAG_STORAGE_CE));
+        mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_CE);
+        verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID),
+                eq(StorageManager.FLAG_STORAGE_CE));
+    }
+
+    @Test
+    public void testPrepareUserData_forExistingUser_doesNotDestroyOnFailure() throws Exception {
+        TEST_USER.lastLoggedInTime = System.currentTimeMillis();
+        doThrow(new IllegalStateException("expected exception for test")).when(mStorageManagerMock)
+                .prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL),
+                        eq(StorageManager.FLAG_STORAGE_CE));
+        mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_CE);
+        verify(mStorageManagerMock, never()).destroyUserStorage(isNull(String.class),
+                eq(TEST_USER_ID), eq(StorageManager.FLAG_STORAGE_CE));
+    }
+
+    @Test
     public void testDestroyUserData_De_DoesNotDestroyCe() throws Exception {
         // Add file in CE storage
         File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java
index 97e5826..a2e80f0 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java
@@ -104,7 +104,7 @@
         468.5f,
     };
 
-    private static final int[] DISPLAY_LEVELS_BACKLIGHT = {
+    private static final int[] DISPLAY_LEVELS_INT = {
         9,
         30,
         45,
@@ -118,6 +118,20 @@
         255
     };
 
+    private static final float[] DISPLAY_LEVELS = {
+        0.03f,
+        0.11f,
+        0.17f,
+        0.24f,
+        0.3f,
+        0.37f,
+        0.46f,
+        0.57f,
+        0.7f,
+        0.87f,
+        1
+    };
+
     private static final float[] DISPLAY_RANGE_NITS = { 2.685f, 478.5f };
     private static final float[] BACKLIGHT_RANGE_ZERO_TO_ONE = { 0.0f, 1.0f };
     private static final float[] DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT = { 0.03149606299f, 1.0f };
@@ -155,23 +169,23 @@
     DisplayWhiteBalanceController mMockDwbc;
 
     @Test
-    public void testSimpleStrategyMappingAtControlPoints() {
-        Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+    public void testSimpleStrategyMappingAtControlPoints_IntConfig() {
+        Resources res = createResources(DISPLAY_LEVELS_INT);
         DisplayDeviceConfig ddc = createDdc();
         BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
         assertNotNull("BrightnessMappingStrategy should not be null", simple);
         for (int i = 0; i < LUX_LEVELS.length; i++) {
             final float expectedLevel = MathUtils.map(PowerManager.BRIGHTNESS_OFF + 1,
                     PowerManager.BRIGHTNESS_ON, PowerManager.BRIGHTNESS_MIN,
-                    PowerManager.BRIGHTNESS_MAX, DISPLAY_LEVELS_BACKLIGHT[i]);
+                    PowerManager.BRIGHTNESS_MAX, DISPLAY_LEVELS_INT[i]);
             assertEquals(expectedLevel,
                     simple.getBrightness(LUX_LEVELS[i]), 0.0001f /*tolerance*/);
         }
     }
 
     @Test
-    public void testSimpleStrategyMappingBetweenControlPoints() {
-        Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+    public void testSimpleStrategyMappingBetweenControlPoints_IntConfig() {
+        Resources res = createResources(DISPLAY_LEVELS_INT);
         DisplayDeviceConfig ddc = createDdc();
         BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
         assertNotNull("BrightnessMappingStrategy should not be null", simple);
@@ -179,14 +193,42 @@
             final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2;
             final float backlight = simple.getBrightness(lux) * PowerManager.BRIGHTNESS_ON;
             assertTrue("Desired brightness should be between adjacent control points.",
-                    backlight > DISPLAY_LEVELS_BACKLIGHT[i - 1]
-                            && backlight < DISPLAY_LEVELS_BACKLIGHT[i]);
+                    backlight > DISPLAY_LEVELS_INT[i - 1]
+                            && backlight < DISPLAY_LEVELS_INT[i]);
+        }
+    }
+
+    @Test
+    public void testSimpleStrategyMappingAtControlPoints_FloatConfig() {
+        Resources res = createResources(EMPTY_INT_ARRAY);
+        DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS,
+                EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS);
+        BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
+        assertNotNull("BrightnessMappingStrategy should not be null", simple);
+        for (int i = 0; i < LUX_LEVELS.length; i++) {
+            assertEquals(DISPLAY_LEVELS[i], simple.getBrightness(LUX_LEVELS[i]),
+                    /* tolerance= */ 0.0001f);
+        }
+    }
+
+    @Test
+    public void testSimpleStrategyMappingBetweenControlPoints_FloatConfig() {
+        Resources res = createResources(EMPTY_INT_ARRAY);
+        DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS,
+                EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS);
+        BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
+        assertNotNull("BrightnessMappingStrategy should not be null", simple);
+        for (int i = 1; i < LUX_LEVELS.length; i++) {
+            final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2;
+            final float brightness = simple.getBrightness(lux);
+            assertTrue("Desired brightness should be between adjacent control points.",
+                    brightness > DISPLAY_LEVELS[i - 1] && brightness < DISPLAY_LEVELS[i]);
         }
     }
 
     @Test
     public void testSimpleStrategyIgnoresNewConfiguration() {
-        Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+        Resources res = createResources(DISPLAY_LEVELS_INT);
         DisplayDeviceConfig ddc = createDdc();
         BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
 
@@ -201,14 +243,14 @@
 
     @Test
     public void testSimpleStrategyIgnoresNullConfiguration() {
-        Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+        Resources res = createResources(DISPLAY_LEVELS_INT);
         DisplayDeviceConfig ddc = createDdc();
         BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
 
         strategy.setBrightnessConfiguration(null);
-        final int n = DISPLAY_LEVELS_BACKLIGHT.length;
+        final int n = DISPLAY_LEVELS_INT.length;
         final float expectedBrightness =
-                (float) DISPLAY_LEVELS_BACKLIGHT[n - 1] / PowerManager.BRIGHTNESS_ON;
+                (float) DISPLAY_LEVELS_INT[n - 1] / PowerManager.BRIGHTNESS_ON;
         assertEquals(expectedBrightness,
                 strategy.getBrightness(LUX_LEVELS[n - 1]), 0.0001f /*tolerance*/);
     }
@@ -322,7 +364,7 @@
 
     @Test
     public void testDefaultStrategyIsPhysical() {
-        Resources res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+        Resources res = createResources(DISPLAY_LEVELS_INT);
         DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
                 DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS);
         BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
@@ -363,13 +405,13 @@
         BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
         assertNull(strategy);
 
-        res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+        res = createResources(DISPLAY_LEVELS_INT);
         strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc);
         assertNull(strategy);
 
         // Extra backlight level
         final int[] backlight = Arrays.copyOf(
-                DISPLAY_LEVELS_BACKLIGHT, DISPLAY_LEVELS_BACKLIGHT.length + 1);
+                DISPLAY_LEVELS_INT, DISPLAY_LEVELS_INT.length + 1);
         backlight[backlight.length - 1] = backlight[backlight.length - 2] + 1;
         res = createResources(backlight);
         ddc = createDdc(DISPLAY_RANGE_NITS,
@@ -410,7 +452,7 @@
                 LUX_LEVELS, DISPLAY_LEVELS_NITS);
         assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, mMockDwbc));
         ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE);
-        res = createResources(DISPLAY_LEVELS_BACKLIGHT);
+        res = createResources(DISPLAY_LEVELS_INT);
         assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, mMockDwbc));
     }
 
@@ -546,16 +588,24 @@
         when(mockDdc.getBrightness()).thenReturn(backlightArray);
         when(mockDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(LUX_LEVELS);
         when(mockDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(EMPTY_FLOAT_ARRAY);
+        when(mockDdc.getAutoBrightnessBrighteningLevels()).thenReturn(EMPTY_FLOAT_ARRAY);
         return mockDdc;
     }
 
     private DisplayDeviceConfig createDdc(float[] nitsArray, float[] backlightArray,
             float[] luxLevelsFloat, float[] brightnessLevelsNits) {
+        return createDdc(nitsArray, backlightArray, luxLevelsFloat, brightnessLevelsNits,
+                EMPTY_FLOAT_ARRAY);
+    }
+
+    private DisplayDeviceConfig createDdc(float[] nitsArray, float[] backlightArray,
+            float[] luxLevelsFloat, float[] brightnessLevelsNits, float[] brightnessLevels) {
         DisplayDeviceConfig mockDdc = mock(DisplayDeviceConfig.class);
         when(mockDdc.getNits()).thenReturn(nitsArray);
         when(mockDdc.getBrightness()).thenReturn(backlightArray);
         when(mockDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(luxLevelsFloat);
         when(mockDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(brightnessLevelsNits);
+        when(mockDdc.getAutoBrightnessBrighteningLevels()).thenReturn(brightnessLevels);
         return mockDdc;
     }
 
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 0bcbeb9..31d7e88 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -47,8 +47,10 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
+import com.android.internal.display.BrightnessSynchronizer;
 import com.android.server.display.config.HdrBrightnessData;
 import com.android.server.display.config.ThermalStatus;
+import com.android.server.display.feature.DisplayManagerFlags;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -92,10 +94,14 @@
     @Mock
     private Resources mResources;
 
+    @Mock
+    private DisplayManagerFlags mFlags;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mContext.getResources()).thenReturn(mResources);
+        when(mFlags.areAutoBrightnessModesEnabled()).thenReturn(true);
         mockDeviceConfigs();
     }
 
@@ -110,10 +116,6 @@
         assertArrayEquals(mDisplayDeviceConfig.getBrightness(), BRIGHTNESS, ZERO_DELTA);
         assertArrayEquals(mDisplayDeviceConfig.getNits(), NITS, ZERO_DELTA);
         assertArrayEquals(mDisplayDeviceConfig.getBacklight(), BRIGHTNESS, ZERO_DELTA);
-        assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
-                float[]{0.0f, 50.0f, 80.0f}, ZERO_DELTA);
-        assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
-                float[]{45.32f, 75.43f}, ZERO_DELTA);
 
         // Test thresholds
         assertEquals(10, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(),
@@ -606,7 +608,7 @@
         assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
                 float[]{2.0f, 200.0f, 600.0f}, ZERO_DELTA);
         assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
-                float[]{0.0f, 0.0f, 110.0f, 500.0f}, ZERO_DELTA);
+                float[]{0.0f, 110.0f, 500.0f}, ZERO_DELTA);
 
         // Test thresholds
         assertEquals(0, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(), ZERO_DELTA);
@@ -671,6 +673,9 @@
 
         assertEquals("test_light_sensor", mDisplayDeviceConfig.getAmbientLightSensor().type);
         assertEquals("", mDisplayDeviceConfig.getAmbientLightSensor().name);
+
+        assertEquals(BrightnessSynchronizer.brightnessIntToFloat(35),
+                mDisplayDeviceConfig.getBrightnessCapForWearBedtimeMode(), ZERO_DELTA);
     }
 
     @Test
@@ -716,6 +721,38 @@
         assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle(), 0.04f, ZERO_DELTA);
     }
 
+    @Test
+    public void testBrightnessCapForWearBedtimeMode() throws IOException {
+        setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(),
+                getValidProxSensor(), /* includeIdleMode= */ false));
+        assertEquals(0.1f, mDisplayDeviceConfig.getBrightnessCapForWearBedtimeMode(), ZERO_DELTA);
+    }
+
+    @Test
+    public void testAutoBrightnessBrighteningLevels() throws IOException {
+        setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(),
+                getValidProxSensor(), /* includeIdleMode= */ false));
+
+        assertArrayEquals(new float[]{0.0f, 80},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.2f, 0.3f},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(), SMALL_DELTA);
+    }
+
+    @Test
+    public void testAutoBrightnessBrighteningLevels_FeatureFlagOff() throws IOException {
+        when(mFlags.areAutoBrightnessModesEnabled()).thenReturn(false);
+        setupDisplayDeviceConfigFromConfigResourceFile();
+        setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(),
+                getValidProxSensor(), /* includeIdleMode= */ false));
+
+        assertNull(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels());
+        assertArrayEquals(new float[]{0, 110, 500},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), ZERO_DELTA);
+        assertArrayEquals(new float[]{2, 200, 600},
+                mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), SMALL_DELTA);
+    }
+
     private String getValidLuxThrottling() {
         return "<luxThrottling>\n"
                 + "    <brightnessLimitMap>\n"
@@ -1037,8 +1074,8 @@
                 +   "<screenBrightnessRampDecreaseMaxIdleMillis>"
                 +       "5000"
                 +   "</screenBrightnessRampDecreaseMaxIdleMillis>\n";
-
     }
+
     private String getContent() {
         return getContent(getValidLuxThrottling(), getValidProxSensor(),
                 /* includeIdleMode= */ true);
@@ -1089,16 +1126,18 @@
                 +       "<brighteningLightDebounceMillis>2000</brighteningLightDebounceMillis>\n"
                 +       "<darkeningLightDebounceMillis>1000</darkeningLightDebounceMillis>\n"
                 + (includeIdleMode ? getRampSpeedsIdle() : "")
-                +       "<displayBrightnessMapping>\n"
-                +            "<displayBrightnessPoint>\n"
-                +                "<lux>50</lux>\n"
-                +                "<nits>45.32</nits>\n"
-                +            "</displayBrightnessPoint>\n"
-                +            "<displayBrightnessPoint>\n"
-                +                "<lux>80</lux>\n"
-                +                "<nits>75.43</nits>\n"
-                +            "</displayBrightnessPoint>\n"
-                +       "</displayBrightnessMapping>\n"
+                +       "<luxToBrightnessMapping>\n"
+                +           "<map>\n"
+                +               "<point>\n"
+                +                   "<first>0</first>\n"
+                +                   "<second>0.2</second>\n"
+                +               "</point>\n"
+                +               "<point>\n"
+                +                   "<first>80</first>\n"
+                +                   "<second>0.3</second>\n"
+                +               "</point>\n"
+                +           "</map>\n"
+                +       "</luxToBrightnessMapping>\n"
                 +   "</autoBrightness>\n"
                 +  getPowerThrottlingConfig()
                 +   "<highBrightnessMode enabled=\"true\">\n"
@@ -1355,6 +1394,9 @@
                 +       "<majorVersion>2</majorVersion>\n"
                 +       "<minorVersion>0</minorVersion>\n"
                 +   "</usiVersion>\n"
+                +   "<screenBrightnessCapForWearBedtimeMode>"
+                +       "0.1"
+                +   "</screenBrightnessCapForWearBedtimeMode>"
                 + "</displayConfiguration>\n";
     }
 
@@ -1372,7 +1414,7 @@
     private void setupDisplayDeviceConfigFromDisplayConfigFile(String content) throws IOException {
         Path tempFile = Files.createTempFile("display_config", ".tmp");
         Files.write(tempFile, content.getBytes(StandardCharsets.UTF_8));
-        mDisplayDeviceConfig = new DisplayDeviceConfig(mContext);
+        mDisplayDeviceConfig = new DisplayDeviceConfig(mContext, mFlags);
         mDisplayDeviceConfig.initFromFile(tempFile.toFile());
     }
 
@@ -1381,25 +1423,15 @@
         when(mResources.obtainTypedArray(
                 com.android.internal.R.array.config_screenBrightnessNits))
                 .thenReturn(screenBrightnessNits);
-        TypedArray screenBrightnessBacklight = createFloatTypedArray(new
-                float[]{0.0f, 120.0f, 255.0f});
-        when(mResources.obtainTypedArray(
-                com.android.internal.R.array.config_screenBrightnessBacklight))
-                .thenReturn(screenBrightnessBacklight);
         when(mResources.getIntArray(com.android.internal.R.array
                 .config_screenBrightnessBacklight)).thenReturn(new int[]{0, 120, 255});
 
-        when(mResources.getIntArray(com.android.internal.R.array
-                .config_autoBrightnessLevels)).thenReturn(new int[]{30, 80});
-        when(mResources.getIntArray(com.android.internal.R.array
-                .config_autoBrightnessDisplayValuesNits)).thenReturn(new int[]{25, 55});
-
         TypedArray screenBrightnessLevelNits = createFloatTypedArray(new
                 float[]{2.0f, 200.0f, 600.0f});
         when(mResources.obtainTypedArray(
                 com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
                 .thenReturn(screenBrightnessLevelNits);
-        int[] screenBrightnessLevelLux = new int[]{0, 110, 500};
+        int[] screenBrightnessLevelLux = new int[]{110, 500};
         when(mResources.getIntArray(
                 com.android.internal.R.array.config_autoBrightnessLevels))
                 .thenReturn(screenBrightnessLevelLux);
@@ -1457,7 +1489,12 @@
                 R.integer.config_autoBrightnessDarkeningLightDebounce))
                 .thenReturn(4000);
 
-        mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
+        when(mResources.getInteger(
+                R.integer.config_screenBrightnessCapForWearBedtimeMode))
+                .thenReturn(35);
+
+        mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, /* useConfigXml= */ true,
+                mFlags);
     }
 
     private TypedArray createFloatTypedArray(float[] vals) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
index 4fd8f26..dc6abf1 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
@@ -57,6 +57,9 @@
     @Mock
     private SurfaceControl.Transaction mMockTransaction;
 
+    @Mock
+    private DisplayAdapter mMockDisplayAdapter;
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
@@ -67,34 +70,39 @@
 
     @Test
     public void testGetDisplaySurfaceDefaultSizeLocked_notRotated() {
-        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+                mMockDisplayAdapter);
         assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
     }
 
     @Test
     public void testGetDisplaySurfaceDefaultSizeLocked_rotation0() {
-        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+                mMockDisplayAdapter);
         displayDevice.setProjectionLocked(mMockTransaction, ROTATION_0, new Rect(), new Rect());
         assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
     }
 
     @Test
     public void testGetDisplaySurfaceDefaultSizeLocked_rotation90() {
-        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+                mMockDisplayAdapter);
         displayDevice.setProjectionLocked(mMockTransaction, ROTATION_90, new Rect(), new Rect());
         assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE);
     }
 
     @Test
     public void testGetDisplaySurfaceDefaultSizeLocked_rotation180() {
-        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+                mMockDisplayAdapter);
         displayDevice.setProjectionLocked(mMockTransaction, ROTATION_180, new Rect(), new Rect());
         assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
     }
 
     @Test
     public void testGetDisplaySurfaceDefaultSizeLocked_rotation270() {
-        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo);
+        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+                mMockDisplayAdapter);
         displayDevice.setProjectionLocked(mMockTransaction, ROTATION_270, new Rect(), new Rect());
         assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE);
     }
@@ -102,8 +110,9 @@
     private static class FakeDisplayDevice extends DisplayDevice {
         private final DisplayDeviceInfo mDisplayDeviceInfo;
 
-        FakeDisplayDevice(DisplayDeviceInfo displayDeviceInfo) {
-            super(null, null, "", InstrumentationRegistry.getInstrumentation().getContext());
+        FakeDisplayDevice(DisplayDeviceInfo displayDeviceInfo, DisplayAdapter displayAdapter) {
+            super(displayAdapter, /* displayToken= */ null, /* uniqueId= */ "",
+                    InstrumentationRegistry.getInstrumentation().getContext());
             mDisplayDeviceInfo = displayDeviceInfo;
         }
 
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 55f56e9..02e3ef4 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -212,7 +212,8 @@
             new DisplayManagerService.Injector() {
                 @Override
                 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
-                        Context context, Handler handler, DisplayAdapter.Listener listener) {
+                        Context context, Handler handler, DisplayAdapter.Listener listener,
+                        DisplayManagerFlags flags) {
                     return mMockVirtualDisplayAdapter;
                 }
 
@@ -251,7 +252,8 @@
 
         @Override
         VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
-                Handler handler, DisplayAdapter.Listener displayAdapterListener) {
+                Handler handler, DisplayAdapter.Listener displayAdapterListener,
+                DisplayManagerFlags flags) {
             return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener,
                     new VirtualDisplayAdapter.SurfaceControlDisplayFactory() {
                         @Override
@@ -263,7 +265,7 @@
                         @Override
                         public void destroyDisplay(IBinder displayToken) {
                         }
-                    });
+                    }, flags);
         }
 
         @Override
@@ -329,6 +331,7 @@
     @Mock SensorManager mSensorManager;
     @Mock DisplayDeviceConfig mMockDisplayDeviceConfig;
     @Mock PackageManagerInternal mMockPackageManagerInternal;
+    @Mock DisplayAdapter mMockDisplayAdapter;
 
     @Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor;
     @Mock DisplayManagerFlags mMockFlags;
@@ -788,7 +791,8 @@
                 new DisplayManagerService.Injector() {
                     @Override
                     VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
-                            Context context, Handler handler, DisplayAdapter.Listener listener) {
+                            Context context, Handler handler, DisplayAdapter.Listener listener,
+                            DisplayManagerFlags flags) {
                         return null;  // return null for the adapter.  This should cause a failure.
                     }
 
@@ -3194,7 +3198,7 @@
         private DisplayDeviceInfo mDisplayDeviceInfo;
 
         FakeDisplayDevice() {
-            super(null, null, "", mContext);
+            super(mMockDisplayAdapter, /* displayToken= */ null, /* uniqueId= */ "", mContext);
         }
 
         public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 8270845..f36854b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -1455,8 +1455,8 @@
         // mMockContext and values will be loaded from mMockResources.
         @Override
         public DisplayDeviceConfig createDisplayDeviceConfig(Context context,
-                long physicalDisplayId, boolean isFirstDisplay) {
-            return DisplayDeviceConfig.create(context, isFirstDisplay);
+                long physicalDisplayId, boolean isFirstDisplay, DisplayManagerFlags flags) {
+            return DisplayDeviceConfig.create(context, isFirstDisplay, flags);
         }
     }
 
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
index 43d2b8f..28ec896 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -119,8 +119,8 @@
     @Mock IThermalService mIThermalServiceMock;
     @Spy DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy =
             new DeviceStateToLayoutMap(mIdProducer, NON_EXISTING_FILE);
-    @Mock
-    DisplayManagerFlags mFlagsMock;
+    @Mock DisplayManagerFlags mFlagsMock;
+    @Mock DisplayAdapter mDisplayAdapterMock;
 
     @Captor ArgumentCaptor<LogicalDisplay> mDisplayCaptor;
     @Captor ArgumentCaptor<Integer> mDisplayEventCaptor;
@@ -1075,7 +1075,8 @@
         private int mState;
 
         TestDisplayDevice() {
-            super(null, null, "test_display_" + sUniqueTestDisplayId++, mContextMock);
+            super(mDisplayAdapterMock, /* displayToken= */ null,
+                    "test_display_" + sUniqueTestDisplayId++, mContextMock);
             mInfo = new DisplayDeviceInfo();
         }
 
diff --git a/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java b/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java
index 9f91916..5676a38 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/PersistentDataStoreTest.java
@@ -32,9 +32,12 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -51,8 +54,12 @@
     private TestInjector mInjector;
     private TestLooper mTestLooper;
 
+    @Mock
+    private DisplayAdapter mDisplayAdapter;
+
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mInjector = new TestInjector();
         mTestLooper = new TestLooper();
         Handler handler = new Handler(mTestLooper.getLooper());
@@ -62,8 +69,8 @@
     @Test
     public void testLoadBrightness() {
         final String uniqueDisplayId = "test:123";
-        final DisplayDevice testDisplayDevice = new DisplayDevice(
-                null, null, uniqueDisplayId, null) {
+        final DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+                /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
             @Override
             public boolean hasStableUniqueId() {
                 return true;
@@ -100,7 +107,8 @@
     public void testSetBrightness_brightnessTagWithNoUserId_updatesToBrightnessTagWithUserId() {
         final String uniqueDisplayId = "test:123";
         final DisplayDevice testDisplayDevice =
-                new DisplayDevice(null, null, uniqueDisplayId, null) {
+                new DisplayDevice(mDisplayAdapter, /* displayToken= */ null, uniqueDisplayId,
+                        /* context= */ null) {
             @Override
             public boolean hasStableUniqueId() {
                 return true;
@@ -273,7 +281,8 @@
         assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId,
                 userSerial));
 
-        DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+        DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+                /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
             @Override
             public boolean hasStableUniqueId() {
                 return true;
@@ -319,7 +328,8 @@
         assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId,
                 userSerial));
 
-        DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+        DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+                /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
             @Override
             public boolean hasStableUniqueId() {
                 return false;
@@ -386,7 +396,8 @@
     @Test
     public void testStoreAndRestoreResolution() {
         final String uniqueDisplayId = "test:123";
-        DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+        DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+                /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
             @Override
             public boolean hasStableUniqueId() {
                 return true;
@@ -422,7 +433,8 @@
     @Test
     public void testStoreAndRestoreRefreshRate() {
         final String uniqueDisplayId = "test:123";
-        DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+        DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+                /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
             @Override
             public boolean hasStableUniqueId() {
                 return true;
@@ -455,7 +467,8 @@
     @Test
     public void testBrightnessInitialisesWithInvalidFloat() {
         final String uniqueDisplayId = "test:123";
-        DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) {
+        DisplayDevice testDisplayDevice = new DisplayDevice(mDisplayAdapter,
+                /* displayToken= */ null, uniqueDisplayId, /* context= */ null) {
             @Override
             public boolean hasStableUniqueId() {
                 return true;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java b/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
index b7cbac5..5c50acb 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/RefreshRateSettingsUtilsTest.java
@@ -72,27 +72,14 @@
 
     @Test
     public void testFindHighestRefreshRateForDefaultDisplay() {
-        when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
-        assertEquals(120,
-                RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
-                /* delta= */ 0);
-    }
-
-    @Test
-    public void testFindHighestRefreshRate() {
-        int displayId = 13;
-        when(mDisplayManagerMock.getDisplay(displayId)).thenReturn(mDisplayMock);
-        assertEquals(120,
-                RefreshRateSettingsUtils.findHighestRefreshRate(mContext, displayId),
-                /* delta= */ 0);
-    }
-
-    @Test
-    public void testFindHighestRefreshRate_DisplayIsNull() {
         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);
     }
 }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
index 73e7ba0..c01b15c 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
@@ -28,6 +28,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.testutils.TestHandler;
 
 import org.junit.Before;
@@ -59,13 +60,17 @@
 
     private VirtualDisplayAdapter mVirtualDisplayAdapter;
 
+    @Mock
+    private DisplayManagerFlags mFeatureFlags;
+
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mHandler = new TestHandler(null);
         mVirtualDisplayAdapter = new VirtualDisplayAdapter(new DisplayManagerService.SyncRoot(),
-                mContextMock, mHandler, mMockListener, mMockSufaceControlDisplayFactory);
+                mContextMock, mHandler, mMockListener, mMockSufaceControlDisplayFactory,
+                mFeatureFlags);
 
         when(mMockCallback.asBinder()).thenReturn(mMockBinder);
     }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
index ff2b1f4..6ba7368 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
@@ -262,7 +262,7 @@
                 Handler handler,
                 BrightnessClamperController.ClamperChangeListener clamperChangeListener,
                 BrightnessClamperController.DisplayDeviceData data,
-                DisplayManagerFlags flags) {
+                DisplayManagerFlags flags, Context context) {
             mCapturedChangeListener = clamperChangeListener;
             return mClampers;
         }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessWearBedtimeModeClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessWearBedtimeModeClamperTest.java
new file mode 100644
index 0000000..3458b08
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessWearBedtimeModeClamperTest.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.server.display.brightness.clamper;
+
+import static com.android.server.display.brightness.clamper.BrightnessWearBedtimeModeClamper.BEDTIME_MODE_OFF;
+import static com.android.server.display.brightness.clamper.BrightnessWearBedtimeModeClamper.BEDTIME_MODE_ON;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
+
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.provider.Settings;
+import android.testing.TestableContext;
+
+import androidx.annotation.NonNull;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.internal.display.BrightnessSynchronizer;
+import com.android.server.testutils.TestHandler;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class BrightnessWearBedtimeModeClamperTest {
+
+    private static final float BRIGHTNESS_CAP = 0.3f;
+
+    @Mock
+    private BrightnessClamperController.ClamperChangeListener mMockClamperChangeListener;
+
+    @Rule
+    public final TestableContext mContext = new TestableContext(
+            InstrumentationRegistry.getInstrumentation().getContext());
+
+    private final TestHandler mTestHandler = new TestHandler(null);
+    private final TestInjector mInjector = new TestInjector();
+    private BrightnessWearBedtimeModeClamper mClamper;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mClamper = new BrightnessWearBedtimeModeClamper(mInjector, mTestHandler, mContext,
+                mMockClamperChangeListener, () -> BRIGHTNESS_CAP);
+        mTestHandler.flush();
+    }
+
+    @Test
+    public void testBrightnessCap() {
+        assertEquals(BRIGHTNESS_CAP, mClamper.getBrightnessCap(), BrightnessSynchronizer.EPSILON);
+    }
+
+    @Test
+    public void testBedtimeModeOn() {
+        setBedtimeModeEnabled(true);
+        assertTrue(mClamper.isActive());
+        verify(mMockClamperChangeListener).onChanged();
+    }
+
+    @Test
+    public void testBedtimeModeOff() {
+        setBedtimeModeEnabled(false);
+        assertFalse(mClamper.isActive());
+        verify(mMockClamperChangeListener).onChanged();
+    }
+
+    @Test
+    public void testType() {
+        assertEquals(BrightnessClamper.Type.BEDTIME_MODE, mClamper.getType());
+    }
+
+    @Test
+    public void testOnDisplayChanged() {
+        float newBrightnessCap = 0.61f;
+
+        mClamper.onDisplayChanged(() -> newBrightnessCap);
+        mTestHandler.flush();
+
+        assertEquals(newBrightnessCap, mClamper.getBrightnessCap(), BrightnessSynchronizer.EPSILON);
+        verify(mMockClamperChangeListener).onChanged();
+    }
+
+    private void setBedtimeModeEnabled(boolean enabled) {
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.Wearable.BEDTIME_MODE,
+                enabled ? BEDTIME_MODE_ON : BEDTIME_MODE_OFF);
+        mInjector.notifyBedtimeModeChanged();
+        mTestHandler.flush();
+    }
+
+    private static class TestInjector extends BrightnessWearBedtimeModeClamper.Injector {
+
+        private ContentObserver mObserver;
+
+        @Override
+        void registerBedtimeModeObserver(@NonNull ContentResolver cr,
+                @NonNull ContentObserver observer) {
+            mObserver = observer;
+        }
+
+        private void notifyBedtimeModeChanged() {
+            if (mObserver != null) {
+                mObserver.dispatchChange(/* selfChange= */ false,
+                        Settings.Global.getUriFor(Settings.Global.Wearable.BEDTIME_MODE));
+            }
+        }
+    }
+}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
index d085923..60a0c03 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
@@ -290,7 +290,6 @@
     };
 
     private static final int DISPLAY_ID = Display.DEFAULT_DISPLAY;
-    private static final int DISPLAY_ID_2 = Display.DEFAULT_DISPLAY + 1;
     private static final int MODE_ID = 1;
     private static final float TRANSITION_POINT = 0.763f;
 
@@ -1551,12 +1550,9 @@
     public void testPeakRefreshRate_FlagEnabled() {
         when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
                 .thenReturn(true);
-        float highestRefreshRate1 = 130;
-        float highestRefreshRate2 = 132;
-        doReturn(highestRefreshRate1).when(() ->
-                RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
-        doReturn(highestRefreshRate2).when(() ->
-                RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID_2));
+        float highestRefreshRate = 130;
+        doReturn(highestRefreshRate).when(() ->
+                RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
         director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
@@ -1567,14 +1563,10 @@
 
         setPeakRefreshRate(Float.POSITIVE_INFINITY);
 
-        Vote vote1 = director.getVote(DISPLAY_ID,
+        Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
                 Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        Vote vote2 = director.getVote(DISPLAY_ID_2,
-                Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote1, /* frameRateLow= */ 0,
-                /* frameRateHigh= */ highestRefreshRate1);
-        assertVoteForRenderFrameRateRange(vote2, /* frameRateLow= */ 0,
-                /* frameRateHigh= */ highestRefreshRate2);
+        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
+                highestRefreshRate);
     }
 
     @Test
@@ -1592,54 +1584,19 @@
 
         setPeakRefreshRate(peakRefreshRate);
 
-        Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0,
-                /* frameRateHigh= */ peakRefreshRate);
-    }
-
-    @Test
-    public void testPeakRefreshRate_DisplayChanged() {
-        when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
-                .thenReturn(true);
-        float highestRefreshRate = 130;
-        doReturn(highestRefreshRate).when(() ->
-                RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
-        DisplayModeDirector director =
-                createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
-        director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
-
-        Sensor lightSensor = createLightSensor();
-        SensorManager sensorManager = createMockSensorManager(lightSensor);
-        director.start(sensorManager);
-
-        setPeakRefreshRate(Float.POSITIVE_INFINITY);
-
-        Vote vote = director.getVote(DISPLAY_ID,
+        Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
                 Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0,
-                /* frameRateHigh= */ highestRefreshRate);
-
-        // The highest refresh rate of the display changes
-        highestRefreshRate = 140;
-        doReturn(highestRefreshRate).when(() ->
-                RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
-        director.getDisplayObserver().onDisplayChanged(DISPLAY_ID);
-
-        vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0,
-                /* frameRateHigh= */ highestRefreshRate);
+        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
+                peakRefreshRate);
     }
 
     @Test
     public void testMinRefreshRate_FlagEnabled() {
         when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
                 .thenReturn(true);
-        float highestRefreshRate1 = 130;
-        float highestRefreshRate2 = 132;
-        doReturn(highestRefreshRate1).when(() ->
-                RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
-        doReturn(highestRefreshRate2).when(() ->
-                RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID_2));
+        float highestRefreshRate = 130;
+        doReturn(highestRefreshRate).when(() ->
+                RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
         director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
@@ -1650,12 +1607,9 @@
 
         setMinRefreshRate(Float.POSITIVE_INFINITY);
 
-        Vote vote1 = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
-        Vote vote2 = director.getVote(DISPLAY_ID_2,
+        Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
                 Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote1, /* frameRateLow= */ highestRefreshRate1,
-                /* frameRateHigh= */ Float.POSITIVE_INFINITY);
-        assertVoteForRenderFrameRateRange(vote2, /* frameRateLow= */ highestRefreshRate2,
+        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ highestRefreshRate,
                 /* frameRateHigh= */ Float.POSITIVE_INFINITY);
     }
 
@@ -1674,44 +1628,13 @@
 
         setMinRefreshRate(minRefreshRate);
 
-        Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
+        Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
+                Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
         assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ minRefreshRate,
                 /* frameRateHigh= */ Float.POSITIVE_INFINITY);
     }
 
     @Test
-    public void testMinRefreshRate_DisplayChanged() {
-        when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
-                .thenReturn(true);
-        float highestRefreshRate = 130;
-        doReturn(highestRefreshRate).when(() ->
-                RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
-        DisplayModeDirector director =
-                createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
-        director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
-
-        Sensor lightSensor = createLightSensor();
-        SensorManager sensorManager = createMockSensorManager(lightSensor);
-        director.start(sensorManager);
-
-        setMinRefreshRate(Float.POSITIVE_INFINITY);
-
-        Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ highestRefreshRate,
-                /* frameRateHigh= */ Float.POSITIVE_INFINITY);
-
-        // The highest refresh rate of the display changes
-        highestRefreshRate = 140;
-        doReturn(highestRefreshRate).when(() ->
-                RefreshRateSettingsUtils.findHighestRefreshRate(mContext, DISPLAY_ID));
-        director.getDisplayObserver().onDisplayChanged(DISPLAY_ID);
-
-        vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
-        assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ highestRefreshRate,
-                /* frameRateHigh= */ Float.POSITIVE_INFINITY);
-    }
-
-    @Test
     public void testSensorRegistration() {
         // First, configure brightness zones or DMD won't register for sensor data.
         final FakeDeviceConfig config = mInjector.getDeviceConfig();
@@ -3406,7 +3329,7 @@
     public static class FakesInjector implements DisplayModeDirector.Injector {
         private final FakeDeviceConfig mDeviceConfig;
         private final DisplayInfo mDisplayInfo;
-        private final Map<Integer, Display> mDisplays;
+        private final Display mDisplay;
         private boolean mDisplayInfoValid = true;
         private final DisplayManagerInternal mDisplayManagerInternal;
         private final StatusBarManagerInternal mStatusBarManagerInternal;
@@ -3427,8 +3350,7 @@
             mDisplayInfo.defaultModeId = MODE_ID;
             mDisplayInfo.supportedModes = new Display.Mode[] {new Display.Mode(MODE_ID,
                     800, 600, /* refreshRate= */ 60)};
-            mDisplays = Map.of(DISPLAY_ID, createDisplay(DISPLAY_ID),
-                    DISPLAY_ID_2, createDisplay(DISPLAY_ID_2));
+            mDisplay = createDisplay(DISPLAY_ID);
             mDisplayManagerInternal = displayManagerInternal;
             mStatusBarManagerInternal = statusBarManagerInternal;
             mSensorManagerInternal = sensorManagerInternal;
@@ -3459,12 +3381,12 @@
 
         @Override
         public Display getDisplay(int displayId) {
-            return mDisplays.get(displayId);
+            return mDisplay;
         }
 
         @Override
         public Display[] getDisplays() {
-            return mDisplays.values().toArray(new Display[0]);
+            return new Display[] { mDisplay };
         }
 
         @Override
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index be29163..cbc8538 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -46,6 +46,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 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;
@@ -61,6 +62,7 @@
 import android.app.ActivityManagerInternal;
 import android.app.AlarmManager;
 import android.app.IActivityManager;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.Sensor;
@@ -128,6 +130,8 @@
     @Mock
     private ConnectivityManager mConnectivityManager;
     @Mock
+    private ContentResolver mContentResolver;
+    @Mock
     private IActivityManager mIActivityManager;
     @Mock
     private LocationManager mLocationManager;
@@ -332,7 +336,7 @@
                         anyString(), any(Executor.class),
                         any(DeviceConfig.OnPropertiesChangedListener.class)));
         doAnswer((Answer<DeviceConfig.Properties>) invocationOnMock
-                -> mock(DeviceConfig.Properties.class))
+                -> new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_DEVICE_IDLE).build())
                 .when(() -> DeviceConfig.getProperties(
                         anyString(), ArgumentMatchers.<String>any()));
         when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
@@ -347,6 +351,7 @@
         mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper());
         mAnyMotionDetector = new AnyMotionDetectorForTest();
         mInjector = new InjectorForTest(getContext());
+        doNothing().when(mContentResolver).registerContentObserver(any(), anyBoolean(), any());
 
         doReturn(mWearModeManagerInternal)
                 .when(() -> LocalServices.getService(WearModeManagerInternal.class));
@@ -366,7 +371,8 @@
         mDeviceIdleController.setLightEnabledForTest(true);
 
         // Get the same Constants object that mDeviceIdleController got.
-        mConstants = mInjector.getConstants(mDeviceIdleController);
+        mConstants = mInjector.getConstants(mDeviceIdleController,
+                mInjector.getHandler(mDeviceIdleController), mContentResolver);
 
         final ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor =
                 ArgumentCaptor.forClass(TelephonyCallback.class);
@@ -2164,9 +2170,8 @@
     public void testStationaryDetection_QuickDozeOff() {
         setQuickDozeEnabled(false);
         enterDeepState(STATE_IDLE);
-        // Regular progression through states, so time should have increased appropriately.
-        mInjector.nowElapsed += mConstants.IDLE_AFTER_INACTIVE_TIMEOUT + mConstants.SENSING_TIMEOUT
-                + mConstants.LOCATING_TIMEOUT;
+        // Indicate that enough time has passed for the device to be considered stationary.
+        mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT;
 
         StationaryListenerForTest stationaryListener = new StationaryListenerForTest();
 
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 21e3b34..b39cd04 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -3397,6 +3397,8 @@
                 bOptions.getTemporaryAppAllowlistType());
         assertEquals(PowerExemptionManager.REASON_TIMEZONE_CHANGED,
                 bOptions.getTemporaryAppAllowlistReasonCode());
+        assertEquals(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT,
+                bOptions.getDeliveryGroupPolicy());
     }
 
     @Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index 3364545..918bc5d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -1665,7 +1665,8 @@
         enqueueBroadcast(makeBroadcastRecord(airplane, callerApp,
                 List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_RED))));
         enqueueBroadcast(makeOrderedBroadcastRecord(timezoneSecond, callerApp,
-                List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN)),
+                List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE),
+                        makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN)),
                 resultToSecond, null));
 
         waitForIdle();
@@ -1681,6 +1682,11 @@
                 anyInt(), anyInt(), any());
 
         // We deliver second broadcast to app
+        timezoneSecond.setClassName(PACKAGE_BLUE, CLASS_BLUE);
+        inOrder.verify(blueThread).scheduleReceiver(
+                argThat(filterAndExtrasEquals(timezoneSecond)), any(), any(),
+                anyInt(), any(), any(), eq(true), eq(false), anyInt(),
+                anyInt(), anyInt(), any());
         timezoneSecond.setClassName(PACKAGE_BLUE, CLASS_GREEN);
         inOrder.verify(blueThread).scheduleReceiver(
                 argThat(filterAndExtrasEquals(timezoneSecond)), any(), any(),
@@ -1797,9 +1803,15 @@
 
         waitForIdle();
 
-        verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, airplane);
-        verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane);
-        verifyScheduleRegisteredReceiver(never(), receiverYellowApp, airplane);
+        if (mImpl == Impl.MODERN) {
+            verifyScheduleRegisteredReceiver(times(2), receiverGreenApp, airplane);
+            verifyScheduleRegisteredReceiver(times(2), receiverBlueApp, airplane);
+            verifyScheduleRegisteredReceiver(times(1), receiverYellowApp, airplane);
+        } else {
+            verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, airplane);
+            verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane);
+            verifyScheduleRegisteredReceiver(never(), receiverYellowApp, airplane);
+        }
     }
 
     @Test
@@ -1830,6 +1842,39 @@
     }
 
     @Test
+    public void testReplacePending_existingDiffReceivers() throws Exception {
+        final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED);
+        final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN);
+        final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE);
+        final BroadcastFilter receiverGreen = makeRegisteredReceiver(receiverGreenApp);
+        final BroadcastFilter receiverBlue = makeRegisteredReceiver(receiverBlueApp);
+
+        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED)
+                .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+        final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+
+        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of(
+                withPriority(receiverGreen, 5))));
+        enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, List.of(
+                withPriority(receiverGreen, 10),
+                withPriority(receiverBlue, 5))));
+        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of(
+                withPriority(receiverBlue, 10),
+                withPriority(receiverGreen, 5))));
+
+        waitForIdle();
+
+        verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick);
+        verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, timeTick);
+        if (mImpl == Impl.MODERN) {
+            verifyScheduleRegisteredReceiver(times(2), receiverGreenApp, airplane);
+        } else {
+            verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, airplane);
+        }
+        verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane);
+    }
+
+    @Test
     public void testIdleAndBarrier() throws Exception {
         final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED);
         final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN);
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUpgradeTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUpgradeTest.java
index 92d1118..4f672f8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUpgradeTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUpgradeTest.java
@@ -19,6 +19,7 @@
 import static android.app.AppOpsManager.OP_SCHEDULE_EXACT_ALARM;
 import static android.app.AppOpsManager.OP_USE_FULL_SCREEN_INTENT;
 import static android.app.AppOpsManager._NUM_OP;
+import static android.companion.virtual.VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -208,8 +209,8 @@
     private void assertSameModes(AppOpsCheckingServiceImpl testService, int op1, int op2) {
         for (int uid : testService.getUidsWithNonDefaultModes()) {
             assertEquals(
-                    testService.getUidMode(uid, op1),
-                    testService.getUidMode(uid, op2)
+                    testService.getUidMode(uid, PERSISTENT_DEVICE_ID_DEFAULT, op1),
+                    testService.getUidMode(uid, PERSISTENT_DEVICE_ID_DEFAULT, op2)
             );
         }
         for (UserPackage pkg : testService.getPackagesWithNonDefaultModes()) {
@@ -275,7 +276,9 @@
                 } else {
                     expectedMode = previousMode;
                 }
-                int mode = testService.getUidMode(uid, OP_SCHEDULE_EXACT_ALARM);
+                int mode =
+                        testService.getUidMode(
+                                uid, PERSISTENT_DEVICE_ID_DEFAULT, OP_SCHEDULE_EXACT_ALARM);
                 assertEquals(expectedMode, mode);
             }
         }
@@ -284,7 +287,9 @@
         int[] unrelatedUidsInFile = {10225, 10178};
 
         for (int uid : unrelatedUidsInFile) {
-            int mode = testService.getUidMode(uid, OP_SCHEDULE_EXACT_ALARM);
+            int mode =
+                    testService.getUidMode(
+                            uid, PERSISTENT_DEVICE_ID_DEFAULT, OP_SCHEDULE_EXACT_ALARM);
             assertEquals(AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM), mode);
         }
     }
@@ -331,7 +336,9 @@
                 final int uid = UserHandle.getUid(userId, appId);
                 final int expectedMode = AppOpsManager.opToDefaultMode(OP_USE_FULL_SCREEN_INTENT);
                 synchronized (testService) {
-                    int mode = testService.getUidMode(uid, OP_USE_FULL_SCREEN_INTENT);
+                    int mode =
+                            testService.getUidMode(
+                                    uid, PERSISTENT_DEVICE_ID_DEFAULT, OP_USE_FULL_SCREEN_INTENT);
                     assertEquals(expectedMode, mode);
                 }
             }
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java
index c84797f..940469f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java
@@ -53,7 +53,6 @@
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 import java.util.ArrayDeque;
@@ -75,14 +74,10 @@
     private static final String SYSTEM_PACKAGE_NAME = "android";
     private static final String NON_SYSTEM_PACKAGE_NAME = "package";
 
-    @Mock
-    private BackupDataInput mBackupDataInput;
-    @Mock
-    private BackupDataOutput mBackupDataOutput;
-    @Mock
-    private UserBackupManagerService mBackupManagerService;
-    @Mock
-    private TransportConnection mTransportConnection;
+    @Mock private BackupDataInput mBackupDataInput;
+    @Mock private BackupDataOutput mBackupDataOutput;
+    @Mock private UserBackupManagerService mBackupManagerService;
+    @Mock private TransportConnection mTransportConnection;
 
     private Set<String> mExcludedkeys = new HashSet<>();
     private Map<String, String> mBackupData = new HashMap<>();
@@ -93,8 +88,8 @@
     private PerformUnifiedRestoreTask mRestoreTask;
 
     @Rule
-    public TestableDeviceConfig.TestableDeviceConfigRule
-            mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
+    public TestableDeviceConfig.TestableDeviceConfigRule mDeviceConfigRule =
+            new TestableDeviceConfig.TestableDeviceConfigRule();
 
     private Context mContext;
 
@@ -107,30 +102,21 @@
         mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
 
         mBackupDataSource = new ArrayDeque<>(mBackupData.keySet());
-        when(mBackupDataInput.readNextHeader()).then(new Answer<Boolean>() {
-            @Override
-            public Boolean answer(InvocationOnMock invocation) throws Throwable {
-                return !mBackupDataSource.isEmpty();
-            }
-        });
-        when(mBackupDataInput.getKey()).then(new Answer<String>() {
-            @Override
-            public String answer(InvocationOnMock invocation) throws Throwable {
-                return mBackupDataSource.poll();
-            }
-        });
+        when(mBackupDataInput.readNextHeader())
+                .then((Answer<Boolean>) invocation -> !mBackupDataSource.isEmpty());
+        when(mBackupDataInput.getKey())
+                .then((Answer<String>) invocation -> mBackupDataSource.poll());
         when(mBackupDataInput.getDataSize()).thenReturn(0);
 
         mBackupDataDump = new HashSet<>();
         ArgumentCaptor<String> keyCaptor = ArgumentCaptor.forClass(String.class);
-        when(mBackupDataOutput.writeEntityHeader(keyCaptor.capture(), anyInt())).then(
-                new Answer<Void>() {
-                    @Override
-                    public Void answer(InvocationOnMock invocation) throws Throwable {
-                        mBackupDataDump.add(keyCaptor.getValue());
-                        return null;
-                    }
-                });
+        when(mBackupDataOutput.writeEntityHeader(keyCaptor.capture(), anyInt()))
+                .then(
+                        (Answer<Void>)
+                                invocation -> {
+                                    mBackupDataDump.add(keyCaptor.getValue());
+                                    return null;
+                                });
 
         mRestoreTask = new PerformUnifiedRestoreTask(mBackupManagerService, mTransportConnection);
     }
@@ -148,8 +134,8 @@
 
     @Test
     public void testFilterExcludedKeys() throws Exception {
-        when(mBackupManagerService.getExcludedRestoreKeys(eq(PACKAGE_NAME))).thenReturn(
-                mExcludedkeys);
+        when(mBackupManagerService.getExcludedRestoreKeys(eq(PACKAGE_NAME)))
+                .thenReturn(mExcludedkeys);
 
         mRestoreTask.filterExcludedKeys(PACKAGE_NAME, mBackupDataInput, mBackupDataOutput);
 
@@ -162,46 +148,45 @@
     @Test
     public void testGetExcludedKeysForPackage_alwaysReturnsLatestKeys() {
         Set<String> firstExcludedKeys = new HashSet<>(Collections.singletonList(EXCLUDED_KEY_1));
-        when(mBackupManagerService.getExcludedRestoreKeys(eq(PACKAGE_NAME))).thenReturn(
-                firstExcludedKeys);
+        when(mBackupManagerService.getExcludedRestoreKeys(eq(PACKAGE_NAME)))
+                .thenReturn(firstExcludedKeys);
         assertEquals(firstExcludedKeys, mRestoreTask.getExcludedKeysForPackage(PACKAGE_NAME));
 
-
-        Set<String> secondExcludedKeys = new HashSet<>(Arrays.asList(EXCLUDED_KEY_1,
-                EXCLUDED_KEY_2));
-        when(mBackupManagerService.getExcludedRestoreKeys(eq(PACKAGE_NAME))).thenReturn(
-                secondExcludedKeys);
+        Set<String> secondExcludedKeys =
+                new HashSet<>(Arrays.asList(EXCLUDED_KEY_1, EXCLUDED_KEY_2));
+        when(mBackupManagerService.getExcludedRestoreKeys(eq(PACKAGE_NAME)))
+                .thenReturn(secondExcludedKeys);
         assertEquals(secondExcludedKeys, mRestoreTask.getExcludedKeysForPackage(PACKAGE_NAME));
     }
 
     @Test
     public void testStageBackupData_stageForNonSystemPackageWithKeysToExclude() {
-        when(mBackupManagerService.getExcludedRestoreKeys(eq(NON_SYSTEM_PACKAGE_NAME))).thenReturn(
-                mExcludedkeys);
+        when(mBackupManagerService.getExcludedRestoreKeys(eq(NON_SYSTEM_PACKAGE_NAME)))
+                .thenReturn(mExcludedkeys);
 
         assertTrue(mRestoreTask.shouldStageBackupData(NON_SYSTEM_PACKAGE_NAME));
     }
 
     @Test
     public void testStageBackupData_stageForNonSystemPackageWithNoKeysToExclude() {
-        when(mBackupManagerService.getExcludedRestoreKeys(any())).thenReturn(
-                Collections.emptySet());
+        when(mBackupManagerService.getExcludedRestoreKeys(any()))
+                .thenReturn(Collections.emptySet());
 
         assertTrue(mRestoreTask.shouldStageBackupData(NON_SYSTEM_PACKAGE_NAME));
     }
 
     @Test
     public void testStageBackupData_doNotStageForSystemPackageWithNoKeysToExclude() {
-        when(mBackupManagerService.getExcludedRestoreKeys(any())).thenReturn(
-                Collections.emptySet());
+        when(mBackupManagerService.getExcludedRestoreKeys(any()))
+                .thenReturn(Collections.emptySet());
 
         assertFalse(mRestoreTask.shouldStageBackupData(SYSTEM_PACKAGE_NAME));
     }
 
     @Test
     public void testStageBackupData_stageForSystemPackageWithKeysToExclude() {
-        when(mBackupManagerService.getExcludedRestoreKeys(eq(SYSTEM_PACKAGE_NAME))).thenReturn(
-                mExcludedkeys);
+        when(mBackupManagerService.getExcludedRestoreKeys(eq(SYSTEM_PACKAGE_NAME)))
+                .thenReturn(mExcludedkeys);
 
         assertTrue(mRestoreTask.shouldStageBackupData(SYSTEM_PACKAGE_NAME));
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java
new file mode 100644
index 0000000..c5e6824
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location.gnss;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+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 android.app.AlarmManager;
+import android.app.AppOpsManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.location.GnssCapabilities;
+import android.location.LocationManager;
+import android.location.LocationManagerInternal;
+import android.location.flags.Flags;
+import android.location.provider.ProviderRequest;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.modules.utils.testing.ExtendedMockitoRule;
+import com.android.server.LocalServices;
+import com.android.server.location.gnss.hal.FakeGnssHal;
+import com.android.server.location.gnss.hal.GnssNative;
+import com.android.server.location.injector.Injector;
+import com.android.server.location.injector.TestInjector;
+import com.android.server.timedetector.TimeDetectorInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.quality.Strictness;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+@Presubmit
+@androidx.test.filters.SmallTest
+@RunWith(AndroidJUnit4.class)
+public class GnssLocationProviderTest {
+
+    @Rule
+    public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
+            .setStrictness(Strictness.WARN)
+            .mockStatic(Settings.Global.class)
+            .build();
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+    private @Mock Context mContext;
+    private @Mock LocationManagerInternal mLocationManagerInternal;
+    private @Mock LocationManager mLocationManager;
+    private @Mock TimeDetectorInternal mTimeDetectorInternal;
+    private @Mock GnssConfiguration mMockConfiguration;
+    private @Mock GnssMetrics mGnssMetrics;
+    private @Mock PowerManager mPowerManager;
+    private @Mock TelephonyManager mTelephonyManager;
+    private @Mock AppOpsManager mAppOpsManager;
+    private @Mock AlarmManager mAlarmManager;
+    private @Mock PowerManager.WakeLock mWakeLock;
+    private @Mock ContentResolver mContentResolver;
+    private @Mock UserManager mUserManager;
+    private @Mock UserHandle mUserHandle;
+    private Set<UserHandle> mUserHandleSet = new HashSet<>();
+
+    private GnssNative mGnssNative;
+
+    private GnssLocationProvider mTestProvider;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        doReturn("mypackage").when(mContext).getPackageName();
+        doReturn("attribution").when(mContext).getAttributionTag();
+        doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
+        doReturn(mPowerManager).when(mContext).getSystemService("power");
+        doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
+        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
+        doReturn(mAlarmManager).when(mContext).getSystemService(Context.ALARM_SERVICE);
+        doReturn(mLocationManager).when(mContext).getSystemService(LocationManager.class);
+        doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+        mUserHandleSet.add(mUserHandle);
+        doReturn(true).when(mLocationManager).isLocationEnabledForUser(eq(mUserHandle));
+        doReturn(mUserHandleSet).when(mUserManager).getVisibleUsers();
+        doReturn(mContentResolver).when(mContext).getContentResolver();
+        doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
+        LocalServices.addService(LocationManagerInternal.class, mLocationManagerInternal);
+        LocalServices.addService(TimeDetectorInternal.class, mTimeDetectorInternal);
+        FakeGnssHal fakeGnssHal = new FakeGnssHal();
+        GnssNative.setGnssHalForTest(fakeGnssHal);
+        Injector injector = new TestInjector(mContext);
+        mGnssNative = spy(Objects.requireNonNull(
+                GnssNative.create(injector, mMockConfiguration)));
+        doReturn(true).when(mGnssNative).init();
+        GnssCapabilities gnssCapabilities = new GnssCapabilities.Builder().setHasScheduling(
+                true).build();
+        doReturn(gnssCapabilities).when(mGnssNative).getCapabilities();
+
+        mTestProvider = new GnssLocationProvider(mContext, mGnssNative, mGnssMetrics);
+        mGnssNative.register();
+    }
+
+    @After
+    public void tearDown() {
+        LocalServices.removeServiceForTest(LocationManagerInternal.class);
+        LocalServices.removeServiceForTest(TimeDetectorInternal.class);
+    }
+
+    @Test
+    public void testStartNavigating() {
+        ProviderRequest providerRequest = new ProviderRequest.Builder().setIntervalMillis(
+                0).build();
+
+        mTestProvider.onSetRequest(providerRequest);
+        verify(mGnssNative).start();
+    }
+
+    @Test
+    public void testUpdateRequirements_sameRequest() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_GNSS_CALL_STOP_BEFORE_SET_POSITION_MODE);
+        ProviderRequest providerRequest = new ProviderRequest.Builder().setIntervalMillis(
+                0).build();
+
+        mTestProvider.onSetRequest(providerRequest);
+        verify(mGnssNative).start();
+
+        // set the same request
+        mTestProvider.onSetRequest(providerRequest);
+        verify(mGnssNative, never()).stop();
+        verify(mGnssNative, times(1)).start();
+    }
+
+    @Test
+    public void testUpdateRequirements_differentRequest() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_GNSS_CALL_STOP_BEFORE_SET_POSITION_MODE);
+        ProviderRequest providerRequest = new ProviderRequest.Builder().setIntervalMillis(
+                0).build();
+
+        mTestProvider.onSetRequest(providerRequest);
+        verify(mGnssNative).start();
+
+        // set a different request
+        providerRequest = new ProviderRequest.Builder().setIntervalMillis(2000).build();
+        mTestProvider.onSetRequest(providerRequest);
+        verify(mGnssNative).stop();
+        verify(mGnssNative, times(2)).start();
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
index 931b38d..f8fe97e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
@@ -22,12 +22,14 @@
 import android.content.pm.PackageManager.PERMISSION_GRANTED
 import android.content.pm.UserInfo
 import android.os.Build
+import android.os.UserHandle
 import android.os.UserHandle.USER_SYSTEM
 import android.util.Log
 import com.android.server.testutils.any
 import com.android.server.testutils.spy
 import com.android.server.testutils.whenever
 import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertFalse
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -177,4 +179,13 @@
 
         assertThat(result).isEqualTo(PackageManager.DELETE_FAILED_INTERNAL_ERROR)
     }
+
+    @Test
+    fun deletePackageLIFWithNonExistantPackage_isFalse() {
+        val dph = DeletePackageHelper(mPms, mock(RemovePackageHelper::class.java),
+                                      mock(BroadcastHelper::class.java))
+        val result = dph.deletePackageLIF("a.nonexistent.package", UserHandle.of(USER_SYSTEM), true,
+                                          intArrayOf(0), 0, PackageRemovedInfo(), true)
+        assertFalse(result)
+    }
 }
diff --git a/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java b/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java
index 8e328ca..0e815d0 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java
@@ -49,8 +49,11 @@
 import android.app.AlarmManager;
 import android.app.IActivityManager;
 import android.app.IForegroundServiceObserver;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
@@ -68,7 +71,7 @@
 import android.test.mock.MockContentResolver;
 import android.util.ArraySet;
 
-import androidx.test.InstrumentationRegistry;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.internal.util.test.BroadcastInterceptingContext;
 import com.android.internal.util.test.FakeSettingsProvider;
@@ -85,9 +88,11 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
@@ -145,7 +150,8 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        mContextSpy = spy(new BroadcastInterceptingContext(InstrumentationRegistry.getContext()));
+        mContextSpy = spy(new BroadcastInterceptingContext(InstrumentationRegistry
+                .getInstrumentation().getTargetContext()));
         when(mContextSpy.getPackageManager()).thenReturn(mPackageManagerMock);
         when(mContextSpy.getSystemService(AlarmManager.class)).thenReturn(mAlarmManagerMock);
         when(mContextSpy.getSystemService(UserManager.class)).thenReturn(mUserManagerMock);
@@ -395,26 +401,65 @@
         setLowPowerStandbySupportedConfig(true);
         mController.systemReady();
 
+        TestReceiver receiver = new TestReceiver();
+        mContextSpy.registerReceiver(receiver,
+                new IntentFilter(PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED));
+
         BroadcastInterceptingContext.FutureIntent futureIntent = mContextSpy.nextBroadcastIntent(
                 PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
         mController.setEnabled(false);
         futureIntent.assertNotReceived();
+        assertThat(receiver.receivedCount).isEqualTo(0);
+        receiver.reset();
 
         futureIntent = mContextSpy.nextBroadcastIntent(
                 PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
         mController.setEnabled(true);
         assertThat(futureIntent.get(1, TimeUnit.SECONDS)).isNotNull();
+        assertThat(receiver.receivedCount).isEqualTo(1);
+        receiver.reset();
 
         futureIntent = mContextSpy.nextBroadcastIntent(
                 PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
         mController.setEnabled(true);
         futureIntent.assertNotReceived();
+        assertThat(receiver.receivedCount).isEqualTo(0);
+        receiver.reset();
 
         futureIntent = mContextSpy.nextBroadcastIntent(
                 PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
-
         mController.setEnabled(false);
         assertThat(futureIntent.get(1, TimeUnit.SECONDS)).isNotNull();
+        assertThat(receiver.receivedCount).isEqualTo(1);
+        receiver.reset();
+    }
+
+    @Test
+    public void testLowPowerStandbyEnabled_EnabledChangedExplicitBroadcastSent() throws Exception {
+        setLowPowerStandbySupportedConfig(true);
+        List<PackageInfo> packagesHoldingPermission = new ArrayList<>();
+
+        when(mPackageManagerMock.getPackagesHoldingPermissions(Mockito.any(),
+                Mockito.anyInt())).thenReturn(packagesHoldingPermission);
+
+        PackageInfo testInfo = new PackageInfo();
+        testInfo.packageName = mContextSpy.getPackageName();
+        packagesHoldingPermission.add(testInfo);
+        mController.systemReady();
+        TestReceiver receiver = new TestReceiver();
+        mContextSpy.registerReceiver(receiver,
+                new IntentFilter(PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED));
+
+        mController.setEnabled(false);
+        assertThat(receiver.receivedCount).isEqualTo(0);
+        receiver.reset();
+
+        mController.setEnabled(true);
+        // Since we added a package manually to the packages that are allowed to
+        // manage LPS, the interceptor should have intercepted two broadcasts, one
+        // implicit via registration and one explicit to the package added above.
+        assertThat(receiver.receivedCount).isEqualTo(2);
+        receiver.reset();
     }
 
     @Test
@@ -906,4 +951,19 @@
         LocalServices.removeServiceForTest(clazz);
         LocalServices.addService(clazz, mock);
     }
+
+    public static class TestReceiver extends BroadcastReceiver {
+        public int receivedCount = 0;
+
+        /**
+         * Resets the count of this receiver
+         */
+        public void reset() {
+            receivedCount = 0;
+        }
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            receivedCount++;
+        }
+    }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/AggregatedPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AggregatedPowerStatsTest.java
index 2003d04..ca7de7c 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/AggregatedPowerStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AggregatedPowerStatsTest.java
@@ -90,6 +90,10 @@
 
     private AggregatedPowerStats prepareAggregatePowerStats() {
         AggregatedPowerStats stats = new AggregatedPowerStats(mAggregatedPowerStatsConfig);
+
+        PowerStats ps = new PowerStats(mPowerComponentDescriptor);
+        stats.addPowerStats(ps, 0);
+
         stats.addClockUpdate(1000, 456);
         stats.setDuration(789);
 
@@ -100,7 +104,6 @@
         stats.setUidState(APP_2, AggregatedPowerStatsConfig.STATE_PROCESS_STATE,
                 BatteryConsumer.PROCESS_STATE_FOREGROUND, 2000);
 
-        PowerStats ps = new PowerStats(mPowerComponentDescriptor);
         ps.stats[0] = 100;
         ps.stats[1] = 987;
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java
index 663af5d..9c2834d 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryExternalStatsWorkerTest.java
@@ -215,7 +215,7 @@
 
     public class TestBatteryStatsImpl extends BatteryStatsImpl {
         public TestBatteryStatsImpl(Context context) {
-            super(Clock.SYSTEM_CLOCK, null);
+            super(Clock.SYSTEM_CLOCK, null, null, null);
             mPowerProfile = new PowerProfile(context, true /* forTest */);
 
             SparseArray<int[]> cpusByPolicy = new SparseArray<>();
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java
index 55ffa1a..f9f32b2 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java
@@ -37,6 +37,8 @@
 import static org.mockito.Mockito.when;
 
 import android.os.BatteryStats;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.UserHandle;
 import android.util.SparseArray;
 import android.util.SparseLongArray;
@@ -97,6 +99,7 @@
     BatteryStatsImpl.UserInfoProvider mUserInfoProvider;
 
     private MockClock mClocks;
+    private PowerStatsUidResolver mPowerStatsUidResolver;
     private MockBatteryStatsImpl mBatteryStatsImpl;
     private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
 
@@ -105,7 +108,9 @@
         MockitoAnnotations.initMocks(this);
 
         mClocks = new MockClock();
-        mBatteryStatsImpl = new MockBatteryStatsImpl(mClocks)
+        Handler handler = new Handler(Looper.getMainLooper());
+        mPowerStatsUidResolver = new PowerStatsUidResolver();
+        mBatteryStatsImpl = new MockBatteryStatsImpl(mClocks, null, handler, mPowerStatsUidResolver)
                 .setTestCpuScalingPolicies()
                 .setKernelCpuUidUserSysTimeReader(mCpuUidUserSysTimeReader)
                 .setKernelCpuUidFreqTimeReader(mCpuUidFreqTimeReader)
@@ -374,7 +379,7 @@
 
         // PRECONDITIONS
         final int ownerUid = UserHandle.getUid(testUserId, FIRST_APPLICATION_UID + 42);
-        mBatteryStatsImpl.addIsolatedUidLocked(isolatedUid, ownerUid);
+        mPowerStatsUidResolver.noteIsolatedUidAdded(isolatedUid, ownerUid);
         final long[][] deltasUs = {
                 {9379, 3332409833484L}, {493247, 723234}, {3247819, 123348}
         };
@@ -965,7 +970,7 @@
 
         // PRECONDITIONS
         final int ownerUid = UserHandle.getUid(testUserId, FIRST_APPLICATION_UID + 42);
-        mBatteryStatsImpl.addIsolatedUidLocked(isolatedUid, ownerUid);
+        mPowerStatsUidResolver.noteIsolatedUidAdded(isolatedUid, ownerUid);
         final long[][] deltasMs = {
                 {3, 12, 55, 100, 32},
                 {32483274, 232349349, 123, 2398, 0},
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
index 5ebc6ca..8d51592 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
@@ -39,14 +39,22 @@
 import android.app.ActivityManager;
 import android.bluetooth.BluetoothActivityEnergyInfo;
 import android.bluetooth.UidTraffic;
+import android.content.Context;
+import android.os.BatteryConsumer;
+import android.os.BatteryManager;
 import android.os.BatteryStats;
+import android.os.BatteryUsageStats;
 import android.os.BluetoothBatteryStats;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Parcel;
 import android.os.WakeLockStats;
 import android.os.WorkSource;
 import android.util.SparseArray;
 import android.view.Display;
 
+import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -65,6 +73,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.io.File;
+import java.time.Instant;
 import java.util.List;
 
 @LargeTest
@@ -93,6 +103,11 @@
 
     private final MockClock mMockClock = new MockClock();
     private MockBatteryStatsImpl mBatteryStatsImpl;
+    private Handler mHandler;
+    private PowerStatsStore mPowerStatsStore;
+    private BatteryUsageStatsProvider mBatteryUsageStatsProvider;
+    @Mock
+    private PowerStatsExporter mPowerStatsExporter;
 
     @Before
     public void setUp() {
@@ -103,12 +118,23 @@
         when(mKernelSingleUidTimeReader.singleUidCpuTimesAvailable()).thenReturn(true);
         when(mKernelWakelockReader.readKernelWakelockStats(
                 any(KernelWakelockStats.class))).thenReturn(mKernelWakelockStats);
-        mBatteryStatsImpl = new MockBatteryStatsImpl(mMockClock)
+        HandlerThread bgThread = new HandlerThread("bg thread");
+        bgThread.start();
+        mHandler = new Handler(bgThread.getLooper());
+        mBatteryStatsImpl = new MockBatteryStatsImpl(mMockClock, null, mHandler)
                 .setPowerProfile(mPowerProfile)
                 .setCpuScalingPolicies(mCpuScalingPolicies)
                 .setKernelCpuUidFreqTimeReader(mKernelUidCpuFreqTimeReader)
                 .setKernelSingleUidTimeReader(mKernelSingleUidTimeReader)
                 .setKernelWakelockReader(mKernelWakelockReader);
+
+        final Context context = InstrumentationRegistry.getContext();
+        File systemDir = context.getCacheDir();
+        mPowerStatsStore = new PowerStatsStore(systemDir, mHandler,
+                new AggregatedPowerStatsConfig());
+        mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mPowerStatsExporter,
+                mPowerProfile, mBatteryStatsImpl.getCpuScalingPolicies(), mPowerStatsStore,
+                mMockClock);
     }
 
     @Test
@@ -754,4 +780,76 @@
         parcel.recycle();
         return info;
     }
+
+    @Test
+    public void storeBatteryUsageStatsOnReset() {
+        mBatteryStatsImpl.forceRecordAllHistory();
+
+        mMockClock.currentTime = Instant.parse("2023-01-02T03:04:05.00Z").toEpochMilli();
+        mMockClock.realtime = 7654321;
+
+        synchronized (mBatteryStatsImpl) {
+            mBatteryStatsImpl.setOnBatteryLocked(mMockClock.realtime, mMockClock.uptime, true,
+                    BatteryManager.BATTERY_STATUS_DISCHARGING, 50, 0);
+            // Will not save to PowerStatsStore because "saveBatteryUsageStatsOnReset" has not
+            // been called yet.
+            mBatteryStatsImpl.resetAllStatsAndHistoryLocked(
+                    BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+        }
+
+        assertThat(mPowerStatsStore.getTableOfContents()).isEmpty();
+
+        mBatteryStatsImpl.saveBatteryUsageStatsOnReset(mBatteryUsageStatsProvider,
+                mPowerStatsStore);
+
+        synchronized (mBatteryStatsImpl) {
+            mBatteryStatsImpl.noteFlashlightOnLocked(42, mMockClock.realtime, mMockClock.uptime);
+        }
+
+        mMockClock.realtime += 60000;
+        mMockClock.currentTime += 60000;
+
+        synchronized (mBatteryStatsImpl) {
+            mBatteryStatsImpl.noteFlashlightOffLocked(42, mMockClock.realtime, mMockClock.uptime);
+        }
+
+        mMockClock.realtime += 60000;
+        mMockClock.currentTime += 60000;
+
+        // Battery stats reset should have the side-effect of saving accumulated battery usage stats
+        synchronized (mBatteryStatsImpl) {
+            mBatteryStatsImpl.resetAllStatsAndHistoryLocked(
+                    BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+        }
+
+        // Await completion
+        ConditionVariable done = new ConditionVariable();
+        mHandler.post(done::open);
+        done.block();
+
+        List<PowerStatsSpan.Metadata> contents = mPowerStatsStore.getTableOfContents();
+        assertThat(contents).hasSize(1);
+
+        PowerStatsSpan.Metadata metadata = contents.get(0);
+
+        PowerStatsSpan span = mPowerStatsStore.loadPowerStatsSpan(metadata.getId(),
+                BatteryUsageStatsSection.TYPE);
+        assertThat(span).isNotNull();
+
+        List<PowerStatsSpan.TimeFrame> timeFrames = span.getMetadata().getTimeFrames();
+        assertThat(timeFrames).hasSize(1);
+        assertThat(timeFrames.get(0).startMonotonicTime).isEqualTo(7654321);
+        assertThat(timeFrames.get(0).duration).isEqualTo(120000);
+
+        List<PowerStatsSpan.Section> sections = span.getSections();
+        assertThat(sections).hasSize(1);
+
+        PowerStatsSpan.Section section = sections.get(0);
+        assertThat(section.getType()).isEqualTo(BatteryUsageStatsSection.TYPE);
+        BatteryUsageStats bus = ((BatteryUsageStatsSection) section).getBatteryUsageStats();
+        assertThat(bus.getAggregateBatteryConsumer(
+                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
+                .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
+                .isEqualTo(60000);
+    }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java
index 7ef1a3f..24c67f8 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java
@@ -35,6 +35,8 @@
 import android.os.BatteryStats;
 import android.os.BatteryStats.HistoryItem;
 import android.os.BatteryStats.Uid.Sensor;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.WorkSource;
@@ -155,7 +157,9 @@
     @SmallTest
     public void testNoteStartWakeLocked_isolatedUid() throws Exception {
         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
-        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+        PowerStatsUidResolver uidResolver = new PowerStatsUidResolver();
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks, null,
+                new Handler(Looper.getMainLooper()), uidResolver);
 
         int pid = 10;
         String name = "name";
@@ -165,7 +169,7 @@
         isolatedWorkChain.addNode(ISOLATED_UID, name);
 
         // Map ISOLATED_UID to UID.
-        bi.addIsolatedUidLocked(ISOLATED_UID, UID);
+        uidResolver.noteIsolatedUidAdded(ISOLATED_UID, UID);
 
         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
@@ -195,7 +199,9 @@
     @SmallTest
     public void testNoteStartWakeLocked_isolatedUidRace() throws Exception {
         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
-        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+        PowerStatsUidResolver uidResolver = new PowerStatsUidResolver();
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks, null,
+                new Handler(Looper.getMainLooper()), uidResolver);
 
         int pid = 10;
         String name = "name";
@@ -205,7 +211,7 @@
         isolatedWorkChain.addNode(ISOLATED_UID, name);
 
         // Map ISOLATED_UID to UID.
-        bi.addIsolatedUidLocked(ISOLATED_UID, UID);
+        uidResolver.noteIsolatedUidAdded(ISOLATED_UID, UID);
 
         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
@@ -216,7 +222,7 @@
         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
 
         clocks.realtime = clocks.uptime = 150;
-        bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime);
+        uidResolver.releaseIsolatedUid(ISOLATED_UID);
 
         clocks.realtime = clocks.uptime = 220;
         bi.noteStopWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName,
@@ -237,8 +243,9 @@
     @SmallTest
     public void testNoteLongPartialWakelockStart_isolatedUid() throws Exception {
         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
-        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
-
+        PowerStatsUidResolver uidResolver = new PowerStatsUidResolver();
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks, null,
+                new Handler(Looper.getMainLooper()), uidResolver);
 
         bi.setRecordAllHistoryLocked(true);
         bi.forceRecordAllHistory();
@@ -251,7 +258,7 @@
         isolatedWorkChain.addNode(ISOLATED_UID, name);
 
         // Map ISOLATED_UID to UID.
-        bi.addIsolatedUidLocked(ISOLATED_UID, UID);
+        uidResolver.noteIsolatedUidAdded(ISOLATED_UID, UID);
 
         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
@@ -290,8 +297,9 @@
     @SmallTest
     public void testNoteLongPartialWakelockStart_isolatedUidRace() throws Exception {
         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
-        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
-
+        PowerStatsUidResolver uidResolver = new PowerStatsUidResolver();
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks, null,
+                new Handler(Looper.getMainLooper()), uidResolver);
 
         bi.setRecordAllHistoryLocked(true);
         bi.forceRecordAllHistory();
@@ -304,7 +312,7 @@
         isolatedWorkChain.addNode(ISOLATED_UID, name);
 
         // Map ISOLATED_UID to UID.
-        bi.addIsolatedUidLocked(ISOLATED_UID, UID);
+        uidResolver.noteIsolatedUidAdded(ISOLATED_UID, UID);
 
         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
@@ -314,7 +322,7 @@
         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
 
         clocks.realtime = clocks.uptime = 150;
-        bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime);
+        uidResolver.releaseIsolatedUid(ISOLATED_UID);
 
         clocks.realtime = clocks.uptime = 220;
         bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
index b1da1fc..2e0ba00 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
@@ -28,9 +28,7 @@
 import android.os.BatteryStats;
 import android.os.BatteryUsageStats;
 import android.os.BatteryUsageStatsQuery;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
+import android.os.ConditionVariable;
 import android.os.Parcel;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
@@ -40,7 +38,6 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.os.BatteryStatsHistoryIterator;
-import com.android.internal.os.MonotonicClock;
 import com.android.internal.os.PowerProfile;
 
 import org.junit.Rule;
@@ -72,10 +69,11 @@
         BatteryStatsImpl batteryStats = prepareBatteryStats();
 
         Context context = InstrumentationRegistry.getContext();
-        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, batteryStats);
+        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, null,
+                mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(), null, mMockClock);
 
         final BatteryUsageStats batteryUsageStats =
-                provider.getBatteryUsageStats(BatteryUsageStatsQuery.DEFAULT);
+                provider.getBatteryUsageStats(batteryStats, BatteryUsageStatsQuery.DEFAULT);
 
         final List<UidBatteryConsumer> uidBatteryConsumers =
                 batteryUsageStats.getUidBatteryConsumers();
@@ -84,6 +82,15 @@
                 .isEqualTo(20 * MINUTE_IN_MS);
         assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND))
                 .isEqualTo(40 * MINUTE_IN_MS);
+        assertThat(uidBatteryConsumer
+                .getTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_FOREGROUND))
+                .isEqualTo(20 * MINUTE_IN_MS);
+        assertThat(uidBatteryConsumer
+                .getTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_BACKGROUND))
+                .isEqualTo(20 * MINUTE_IN_MS);
+        assertThat(uidBatteryConsumer
+                .getTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE))
+                .isEqualTo(20 * MINUTE_IN_MS);
         assertThat(uidBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO))
                 .isWithin(PRECISION).of(2.0);
         assertThat(
@@ -99,10 +106,11 @@
         BatteryStatsImpl batteryStats = prepareBatteryStats();
 
         Context context = InstrumentationRegistry.getContext();
-        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, batteryStats);
+        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, null,
+                mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(), null, mMockClock);
 
         final BatteryUsageStats batteryUsageStats =
-                provider.getBatteryUsageStats(
+                provider.getBatteryUsageStats(batteryStats,
                         new BatteryUsageStatsQuery.Builder()
                                 .includePowerComponents(
                                         new int[]{BatteryConsumer.POWER_COMPONENT_AUDIO})
@@ -204,10 +212,11 @@
         }
 
         Context context = InstrumentationRegistry.getContext();
-        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, batteryStats);
+        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, null,
+                mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(), null, mMockClock);
 
         final BatteryUsageStats batteryUsageStats =
-                provider.getBatteryUsageStats(
+                provider.getBatteryUsageStats(batteryStats,
                         new BatteryUsageStatsQuery.Builder().includeBatteryHistory().build());
 
         Parcel in = Parcel.obtain();
@@ -292,11 +301,11 @@
         }
 
         Context context = InstrumentationRegistry.getContext();
-        BatteryUsageStatsProvider
-                provider = new BatteryUsageStatsProvider(context, batteryStats);
+        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, null,
+                mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(), null, mMockClock);
 
         final BatteryUsageStats batteryUsageStats =
-                provider.getBatteryUsageStats(
+                provider.getBatteryUsageStats(batteryStats,
                         new BatteryUsageStatsQuery.Builder().includeBatteryHistory().build());
 
         Parcel parcel = Parcel.obtain();
@@ -352,27 +361,22 @@
 
     @Test
     public void shouldUpdateStats() {
-        Context context = InstrumentationRegistry.getContext();
-        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context,
-                mStatsRule.getBatteryStats());
-
         final List<BatteryUsageStatsQuery> queries = List.of(
                 new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(1000).build(),
                 new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(2000).build()
         );
 
-        mStatsRule.setTime(10500, 0);
-        assertThat(provider.shouldUpdateStats(queries, 10000)).isFalse();
+        assertThat(BatteryUsageStatsProvider.shouldUpdateStats(queries,
+                10500, 10000)).isFalse();
 
-        mStatsRule.setTime(11500, 0);
-        assertThat(provider.shouldUpdateStats(queries, 10000)).isTrue();
+        assertThat(BatteryUsageStatsProvider.shouldUpdateStats(queries,
+                11500, 10000)).isTrue();
     }
 
     @Test
     public void testAggregateBatteryStats() {
         Context context = InstrumentationRegistry.getContext();
         BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
-        MonotonicClock monotonicClock = new MonotonicClock(0, mStatsRule.getMockClock());
 
         setTime(5 * MINUTE_IN_MS);
         synchronized (batteryStats) {
@@ -381,14 +385,17 @@
 
         PowerStatsStore powerStatsStore = new PowerStatsStore(
                 new File(context.getCacheDir(), "BatteryUsageStatsProviderTest"),
-                new TestHandler(), null);
+                mStatsRule.getHandler(), null);
+        powerStatsStore.reset();
 
-        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context,
-                batteryStats, powerStatsStore);
+        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, null,
+                mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(), powerStatsStore,
+                mMockClock);
 
-        batteryStats.setBatteryResetListener(reason ->
-                powerStatsStore.storeBatteryUsageStats(monotonicClock.monotonicTime(),
-                        provider.getBatteryUsageStats(BatteryUsageStatsQuery.DEFAULT)));
+        batteryStats.saveBatteryUsageStatsOnReset(provider, powerStatsStore);
+        synchronized (batteryStats) {
+            batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+        }
 
         synchronized (batteryStats) {
             batteryStats.noteFlashlightOnLocked(APP_UID,
@@ -441,11 +448,16 @@
         }
         setTime(95 * MINUTE_IN_MS);
 
+        // Await completion
+        ConditionVariable done = new ConditionVariable();
+        mStatsRule.getHandler().post(done::open);
+        done.block();
+
         // Include the first and the second snapshot, but not the third or current
         BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder()
                 .aggregateSnapshots(20 * MINUTE_IN_MS, 60 * MINUTE_IN_MS)
                 .build();
-        final BatteryUsageStats stats = provider.getBatteryUsageStats(query);
+        final BatteryUsageStats stats = provider.getBatteryUsageStats(batteryStats, query);
 
         assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
         assertThat(stats.getStatsEndTimestamp()).isEqualTo(55 * MINUTE_IN_MS);
@@ -499,30 +511,19 @@
         when(powerStatsStore.loadPowerStatsSpan(1, BatteryUsageStatsSection.TYPE))
                 .thenReturn(span1);
 
-        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context,
-                batteryStats, powerStatsStore);
+        BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, null,
+                mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(), powerStatsStore,
+                mMockClock);
 
         BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder()
                 .aggregateSnapshots(0, 3000)
                 .build();
-        final BatteryUsageStats stats = provider.getBatteryUsageStats(query);
+        final BatteryUsageStats stats = provider.getBatteryUsageStats(batteryStats, query);
         assertThat(stats.getCustomPowerComponentNames())
                 .isEqualTo(batteryStats.getCustomEnergyConsumerNames());
         assertThat(stats.getStatsDuration()).isEqualTo(1234);
     }
 
-    private static class TestHandler extends Handler {
-        TestHandler() {
-            super(Looper.getMainLooper());
-        }
-
-        @Override
-        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
-            msg.getCallback().run();
-            return true;
-        }
-    }
-
     private static final Random sRandom = new Random();
 
     /**
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
index 0b10954..e61dd0b 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
@@ -28,6 +28,8 @@
 import android.os.BatteryStats;
 import android.os.BatteryUsageStats;
 import android.os.BatteryUsageStatsQuery;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.UidBatteryConsumer;
 import android.os.UserBatteryConsumer;
 import android.util.SparseArray;
@@ -57,6 +59,7 @@
     private final PowerProfile mPowerProfile;
     private final MockClock mMockClock = new MockClock();
     private final MockBatteryStatsImpl mBatteryStats;
+    private final Handler mHandler;
 
     private BatteryUsageStats mBatteryUsageStats;
     private boolean mScreenOn;
@@ -73,10 +76,13 @@
     }
 
     public BatteryUsageStatsRule(long currentTime, File historyDir) {
+        HandlerThread bgThread = new HandlerThread("bg thread");
+        bgThread.start();
+        mHandler = new Handler(bgThread.getLooper());
         mContext = InstrumentationRegistry.getContext();
         mPowerProfile = spy(new PowerProfile(mContext, true /* forTest */));
         mMockClock.currentTime = currentTime;
-        mBatteryStats = new MockBatteryStatsImpl(mMockClock, historyDir);
+        mBatteryStats = new MockBatteryStatsImpl(mMockClock, historyDir, mHandler);
         mBatteryStats.setPowerProfile(mPowerProfile);
 
         mCpusByPolicy.put(0, new int[]{0, 1, 2, 3});
@@ -92,6 +98,10 @@
         return mMockClock;
     }
 
+    public Handler getHandler() {
+        return mHandler;
+    }
+
     public BatteryUsageStatsRule setTestPowerProfile(@XmlRes int xmlId) {
         mPowerProfile.forceInitForTesting(mContext, xmlId);
         return this;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
index 07c486c..079ea2c7 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
@@ -193,14 +193,14 @@
         for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
             if (uidBatteryConsumer.getUid() == APP_UID1) {
                 assertUidBatteryConsumer(uidBatteryConsumer, 2124, null,
-                        5321, 7432, 423, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 745,
+                        5321, 6900, 532, 423, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 745,
                         POWER_MODEL_UNDEFINED,
                         956, 1167, 1478,
                         true, 3554, 3776, 3998, 444, 3554, 15542, 3776, 17762, 3998, 19982,
                         444, 1110);
             } else if (uidBatteryConsumer.getUid() == APP_UID2) {
                 assertUidBatteryConsumer(uidBatteryConsumer, 1332, "bar",
-                        1111, 2222, 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
+                        1111, 2220, 2, 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
                         BatteryConsumer.POWER_MODEL_POWER_PROFILE,
                         555, 666, 777,
                         true, 1777, 1888, 1999, 321, 1777, 7771, 1888, 8881, 1999, 9991,
@@ -269,7 +269,7 @@
                         .setStatsEndTimestamp(3000);
 
         addUidBatteryConsumer(builder, batteryStats, APP_UID1, "foo",
-                1000, 2000,
+                1000, 1500, 500,
                 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
                 BatteryConsumer.POWER_MODEL_POWER_PROFILE, 500, 600, 800,
                 1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
@@ -312,13 +312,13 @@
                 .setStatsEndTimestamp(5000);
 
         addUidBatteryConsumer(builder, batteryStats, APP_UID1, null,
-                4321, 5432,
+                4321, 5400, 32,
                 123, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 345, POWER_MODEL_ENERGY_CONSUMPTION,
                 456, 567, 678,
                 1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
 
         addUidBatteryConsumer(builder, batteryStats, APP_UID2, "bar",
-                1111, 2222,
+                1111, 2220, 2,
                 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
                 BatteryConsumer.POWER_MODEL_POWER_PROFILE, 555, 666, 777,
                 1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
@@ -338,7 +338,8 @@
 
     private void addUidBatteryConsumer(BatteryUsageStats.Builder builder,
             MockBatteryStatsImpl batteryStats, int uid, String packageWithHighestDrain,
-            int timeInStateForeground, int timeInStateBackground, double screenPower,
+            int timeInProcessStateForeground, int timeInProcessStateBackground,
+            int timeInProcessStateForegroundService, double screenPower,
             int screenPowerModel, double cpuPower, int cpuPowerModel, double customComponentPower,
             int cpuDuration, int customComponentDuration, double cpuPowerForeground,
             int cpuDurationForeground, double cpuPowerBackground, int cpuDurationBackground,
@@ -348,8 +349,10 @@
                 builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid);
         uidBuilder
                 .setPackageWithHighestDrain(packageWithHighestDrain)
-                .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, timeInStateForeground)
-                .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, timeInStateBackground)
+                .setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND, timeInProcessStateForeground)
+                .setTimeInProcessStateMs(PROCESS_STATE_BACKGROUND, timeInProcessStateBackground)
+                .setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE,
+                        timeInProcessStateForegroundService)
                 .setConsumedPower(
                         BatteryConsumer.POWER_COMPONENT_SCREEN, screenPower, screenPowerModel)
                 .setConsumedPower(
@@ -446,7 +449,7 @@
         for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
             if (uidBatteryConsumer.getUid() == APP_UID1) {
                 assertUidBatteryConsumer(uidBatteryConsumer, 1200, "foo",
-                        1000, 2000, 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
+                        1000, 1500, 500, 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
                         BatteryConsumer.POWER_MODEL_POWER_PROFILE,
                         500, 600, 800,
                         true, 1777, 1888, 1999, 123, 1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
@@ -496,8 +499,9 @@
     }
 
     private void assertUidBatteryConsumer(UidBatteryConsumer uidBatteryConsumer,
-            double consumedPower, String packageWithHighestDrain, int timeInStateForeground,
-            int timeInStateBackground, int screenPower, int screenPowerModel, double cpuPower,
+            double consumedPower, String packageWithHighestDrain, int timeInProcessStateForeground,
+            int timeInProcessStateBackground, int timeInProcessStateForegroundService,
+            int screenPower, int screenPowerModel, double cpuPower,
             int cpuPowerModel, double customComponentPower, int cpuDuration,
             int customComponentDuration, boolean processStateDataIncluded,
             double totalPowerForeground, double totalPowerBackground, double totalPowerFgs,
@@ -509,9 +513,16 @@
         assertThat(uidBatteryConsumer.getPackageWithHighestDrain()).isEqualTo(
                 packageWithHighestDrain);
         assertThat(uidBatteryConsumer.getTimeInStateMs(
-                UidBatteryConsumer.STATE_FOREGROUND)).isEqualTo(timeInStateForeground);
+                UidBatteryConsumer.STATE_FOREGROUND)).isEqualTo(timeInProcessStateForeground);
         assertThat(uidBatteryConsumer.getTimeInStateMs(
-                UidBatteryConsumer.STATE_BACKGROUND)).isEqualTo(timeInStateBackground);
+                UidBatteryConsumer.STATE_BACKGROUND)).isEqualTo(
+                        timeInProcessStateBackground + timeInProcessStateForegroundService);
+        assertThat(uidBatteryConsumer.getTimeInProcessStateMs(
+                PROCESS_STATE_FOREGROUND)).isEqualTo(timeInProcessStateForeground);
+        assertThat(uidBatteryConsumer.getTimeInProcessStateMs(
+                PROCESS_STATE_BACKGROUND)).isEqualTo(timeInProcessStateBackground);
+        assertThat(uidBatteryConsumer.getTimeInProcessStateMs(
+                PROCESS_STATE_FOREGROUND_SERVICE)).isEqualTo(timeInProcessStateForegroundService);
         assertThat(uidBatteryConsumer.getConsumedPower(
                 BatteryConsumer.POWER_COMPONENT_SCREEN)).isEqualTo(screenPower);
         assertThat(uidBatteryConsumer.getPowerModel(
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuAggregatedPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuAggregatedPowerStatsProcessorTest.java
index 79084cc..8ca4ff6 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuAggregatedPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuAggregatedPowerStatsProcessorTest.java
@@ -192,7 +192,7 @@
 
     private static class MockPowerComponentAggregatedPowerStats extends
             PowerComponentAggregatedPowerStats {
-        private final CpuPowerStatsCollector.StatsArrayLayout mStatsLayout;
+        private final CpuPowerStatsCollector.CpuStatsArrayLayout mStatsLayout;
         private final PowerStats.Descriptor mDescriptor;
         private HashMap<String, long[]> mDeviceStats = new HashMap<>();
         private HashMap<String, long[]> mUidStats = new HashMap<>();
@@ -203,10 +203,10 @@
         MockPowerComponentAggregatedPowerStats(AggregatedPowerStatsConfig.PowerComponent config,
                 boolean useEnergyConsumers) {
             super(config);
-            mStatsLayout = new CpuPowerStatsCollector.StatsArrayLayout();
+            mStatsLayout = new CpuPowerStatsCollector.CpuStatsArrayLayout();
             mStatsLayout.addDeviceSectionCpuTimeByScalingStep(3);
             mStatsLayout.addDeviceSectionCpuTimeByCluster(2);
-            mStatsLayout.addDeviceSectionUptime();
+            mStatsLayout.addDeviceSectionUsageDuration();
             if (useEnergyConsumers) {
                 mStatsLayout.addDeviceSectionEnergyConsumers(2);
             }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java
index bc211df..64d5414 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
@@ -56,6 +57,9 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class CpuPowerStatsCollectorTest {
+    private static final int ISOLATED_UID = 99123;
+    private static final int UID_1 = 42;
+    private static final int UID_2 = 99;
     private Context mContext;
     private final MockClock mMockClock = new MockClock();
     private final HandlerThread mHandlerThread = new HandlerThread("test");
@@ -63,6 +67,8 @@
     private PowerStats mCollectedStats;
     private PowerProfile mPowerProfile;
     @Mock
+    private PowerStatsUidResolver mUidResolver;
+    @Mock
     private CpuPowerStatsCollector.KernelCpuStatsReader mMockKernelCpuStatsReader;
     @Mock
     private PowerStatsInternal mPowerStatsInternal;
@@ -76,6 +82,14 @@
         mHandlerThread.start();
         mHandler = mHandlerThread.getThreadHandler();
         when(mMockKernelCpuStatsReader.nativeIsSupportedFeature()).thenReturn(true);
+        when(mUidResolver.mapUid(anyInt())).thenAnswer(invocation -> {
+            int uid = invocation.getArgument(0);
+            if (uid == ISOLATED_UID) {
+                return UID_2;
+            } else {
+                return uid;
+            }
+        });
     }
 
     @Test
@@ -156,14 +170,14 @@
         assertThat(descriptor.name).isEqualTo("cpu");
         assertThat(descriptor.statsArrayLength).isEqualTo(13);
         assertThat(descriptor.uidStatsArrayLength).isEqualTo(5);
-        CpuPowerStatsCollector.StatsArrayLayout layout =
-                new CpuPowerStatsCollector.StatsArrayLayout();
+        CpuPowerStatsCollector.CpuStatsArrayLayout layout =
+                new CpuPowerStatsCollector.CpuStatsArrayLayout();
         layout.fromExtras(descriptor.extras);
 
         long[] deviceStats = new long[descriptor.statsArrayLength];
         layout.setTimeByScalingStep(deviceStats, 2, 42);
         layout.setConsumedEnergy(deviceStats, 1, 43);
-        layout.setUptime(deviceStats, 44);
+        layout.setUsageDuration(deviceStats, 44);
         layout.setDevicePowerEstimate(deviceStats, 45);
 
         long[] uidStats = new long[descriptor.uidStatsArrayLength];
@@ -173,10 +187,10 @@
         assertThat(layout.getCpuScalingStepCount()).isEqualTo(7);
         assertThat(layout.getTimeByScalingStep(deviceStats, 2)).isEqualTo(42);
 
-        assertThat(layout.getCpuClusterEnergyConsumerCount()).isEqualTo(2);
+        assertThat(layout.getEnergyConsumerCount()).isEqualTo(2);
         assertThat(layout.getConsumedEnergy(deviceStats, 1)).isEqualTo(43);
 
-        assertThat(layout.getUptime(deviceStats)).isEqualTo(44);
+        assertThat(layout.getUsageDuration(deviceStats)).isEqualTo(44);
 
         assertThat(layout.getDevicePowerEstimate(deviceStats)).isEqualTo(45);
 
@@ -195,14 +209,15 @@
         mockEnergyConsumers();
 
         CpuPowerStatsCollector collector = createCollector(8, 0);
-        CpuPowerStatsCollector.StatsArrayLayout layout =
-                new CpuPowerStatsCollector.StatsArrayLayout();
+        CpuPowerStatsCollector.CpuStatsArrayLayout layout =
+                new CpuPowerStatsCollector.CpuStatsArrayLayout();
         layout.fromExtras(collector.getPowerStatsDescriptor().extras);
 
         mockKernelCpuStats(new long[]{1111, 2222, 3333},
                 new SparseArray<>() {{
-                    put(42, new long[]{100, 200});
-                    put(99, new long[]{300, 600});
+                    put(UID_1, new long[]{100, 200});
+                    put(UID_2, new long[]{100, 150});
+                    put(ISOLATED_UID, new long[]{200, 450});
                 }}, 0, 1234);
 
         mMockClock.uptime = 1000;
@@ -219,19 +234,19 @@
         assertThat(layout.getConsumedEnergy(mCollectedStats.stats, 0)).isEqualTo(0);
         assertThat(layout.getConsumedEnergy(mCollectedStats.stats, 1)).isEqualTo(0);
 
-        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(42), 0))
+        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(UID_1), 0))
                 .isEqualTo(100);
-        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(42), 1))
+        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(UID_1), 1))
                 .isEqualTo(200);
-        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(99), 0))
+        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(UID_2), 0))
                 .isEqualTo(300);
-        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(99), 1))
+        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(UID_2), 1))
                 .isEqualTo(600);
 
         mockKernelCpuStats(new long[]{5555, 4444, 3333},
                 new SparseArray<>() {{
-                    put(42, new long[]{123, 234});
-                    put(99, new long[]{345, 678});
+                    put(UID_1, new long[]{123, 234});
+                    put(ISOLATED_UID, new long[]{245, 528});
                 }}, 1234, 3421);
 
         mMockClock.uptime = 2000;
@@ -249,13 +264,13 @@
         // 700 * 1000 / 3500
         assertThat(layout.getConsumedEnergy(mCollectedStats.stats, 1)).isEqualTo(200);
 
-        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(42), 0))
+        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(UID_1), 0))
                 .isEqualTo(23);
-        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(42), 1))
+        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(UID_1), 1))
                 .isEqualTo(34);
-        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(99), 0))
+        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(UID_2), 0))
                 .isEqualTo(45);
-        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(99), 1))
+        assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(UID_2), 1))
                 .isEqualTo(78);
     }
 
@@ -282,9 +297,9 @@
     private CpuPowerStatsCollector createCollector(int defaultCpuPowerBrackets,
             int defaultCpuPowerBracketsPerEnergyConsumer) {
         CpuPowerStatsCollector collector = new CpuPowerStatsCollector(mCpuScalingPolicies,
-                mPowerProfile, mHandler, mMockKernelCpuStatsReader, () -> mPowerStatsInternal,
-                () -> 3500, 60_000, mMockClock, defaultCpuPowerBrackets,
-                defaultCpuPowerBracketsPerEnergyConsumer);
+                mPowerProfile, mHandler, mMockKernelCpuStatsReader, mUidResolver,
+                () -> mPowerStatsInternal, () -> 3500, 60_000, mMockClock,
+                defaultCpuPowerBrackets, defaultCpuPowerBracketsPerEnergyConsumer);
         collector.addConsumer(stats -> mCollectedStats = stats);
         collector.setEnabled(true);
         return collector;
@@ -375,8 +390,8 @@
     }
 
     private static int[] getScalingStepToPowerBracketMap(CpuPowerStatsCollector collector) {
-        CpuPowerStatsCollector.StatsArrayLayout layout =
-                new CpuPowerStatsCollector.StatsArrayLayout();
+        CpuPowerStatsCollector.CpuStatsArrayLayout layout =
+                new CpuPowerStatsCollector.CpuStatsArrayLayout();
         layout.fromExtras(collector.getPowerStatsDescriptor().extras);
         return layout.getScalingStepToPowerBracketMap();
     }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
index 4150972a..fb71ac8 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
@@ -61,16 +61,23 @@
     }
 
     MockBatteryStatsImpl(Clock clock, File historyDirectory) {
-        super(clock, historyDirectory);
+        this(clock, historyDirectory, new Handler(Looper.getMainLooper()));
+    }
+
+    MockBatteryStatsImpl(Clock clock, File historyDirectory, Handler handler) {
+        this(clock, historyDirectory, handler, new PowerStatsUidResolver());
+    }
+
+    MockBatteryStatsImpl(Clock clock, File historyDirectory, Handler handler,
+            PowerStatsUidResolver powerStatsUidResolver) {
+        super(clock, historyDirectory, handler, powerStatsUidResolver);
         initTimersAndCounters();
         setMaxHistoryBuffer(128 * 1024);
 
         setExternalStatsSyncLocked(mExternalStatsSync);
         informThatAllExternalStatsAreFlushed();
 
-        // A no-op handler.
-        mHandler = new Handler(Looper.getMainLooper()) {
-        };
+        mHandler = handler;
 
         mCpuUidFreqTimeReader = mock(KernelCpuUidFreqTimeReader.class);
         mKernelWakelockReader = null;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsAggregatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsAggregatorTest.java
index b52fc8a..6704987 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsAggregatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsAggregatorTest.java
@@ -76,9 +76,18 @@
 
     @Test
     public void stateUpdates() {
+        PowerStats.Descriptor descriptor =
+                new PowerStats.Descriptor(TEST_POWER_COMPONENT, "majorDrain", 1, 1,
+                        new PersistableBundle());
+        PowerStats powerStats = new PowerStats(descriptor);
+
         mClock.currentTime = 1222156800000L;    // An important date in world history
 
         mHistory.forceRecordAllHistory();
+        powerStats.stats = new long[]{0};
+        powerStats.uidStats.put(TEST_UID, new long[]{0});
+        mHistory.recordPowerStats(mClock.realtime, mClock.uptime, powerStats);
+
         mHistory.recordBatteryState(mClock.realtime, mClock.uptime, 10, /* plugged */ true);
         mHistory.recordStateStartEvent(mClock.realtime, mClock.uptime,
                 BatteryStats.HistoryItem.STATE_SCREEN_ON_FLAG);
@@ -87,10 +96,6 @@
 
         advance(1000);
 
-        PowerStats.Descriptor descriptor =
-                new PowerStats.Descriptor(TEST_POWER_COMPONENT, "majorDrain", 1, 1,
-                        new PersistableBundle());
-        PowerStats powerStats = new PowerStats(descriptor);
         powerStats.stats = new long[]{10000};
         powerStats.uidStats.put(TEST_UID, new long[]{1234});
         mHistory.recordPowerStats(mClock.realtime, mClock.uptime, powerStats);
@@ -181,17 +186,21 @@
 
     @Test
     public void incompatiblePowerStats() {
+        PowerStats.Descriptor descriptor =
+                new PowerStats.Descriptor(TEST_POWER_COMPONENT, "majorDrain", 1, 1,
+                        new PersistableBundle());
+        PowerStats powerStats = new PowerStats(descriptor);
+
         mHistory.forceRecordAllHistory();
+        powerStats.stats = new long[]{0};
+        powerStats.uidStats.put(TEST_UID, new long[]{0});
+        mHistory.recordPowerStats(mClock.realtime, mClock.uptime, powerStats);
         mHistory.recordBatteryState(mClock.realtime, mClock.uptime, 10, /* plugged */ true);
         mHistory.recordProcessStateChange(mClock.realtime, mClock.uptime, TEST_UID,
                 BatteryConsumer.PROCESS_STATE_FOREGROUND);
 
         advance(1000);
 
-        PowerStats.Descriptor descriptor =
-                new PowerStats.Descriptor(TEST_POWER_COMPONENT, "majorDrain", 1, 1,
-                        new PersistableBundle());
-        PowerStats powerStats = new PowerStats(descriptor);
         powerStats.stats = new long[]{10000};
         powerStats.uidStats.put(TEST_UID, new long[]{1234});
         mHistory.recordPowerStats(mClock.realtime, mClock.uptime, powerStats);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java
new file mode 100644
index 0000000..3c48262
--- /dev/null
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power.stats;
+
+import static androidx.test.InstrumentationRegistry.getContext;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.mock;
+
+import android.os.AggregateBatteryConsumer;
+import android.os.BatteryConsumer;
+import android.os.BatteryStats;
+import android.os.BatteryUsageStats;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.PersistableBundle;
+import android.os.UidBatteryConsumer;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.os.BatteryStatsHistory;
+import com.android.internal.os.MonotonicClock;
+import com.android.internal.os.PowerProfile;
+import com.android.internal.os.PowerStats;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class PowerStatsExporterTest {
+
+    private static final int APP_UID1 = 42;
+    private static final int APP_UID2 = 84;
+    private static final double TOLERANCE = 0.01;
+
+    @Rule
+    public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
+            .setAveragePower(PowerProfile.POWER_CPU_ACTIVE, 720)
+            .setCpuScalingPolicy(0, new int[]{0}, new int[]{100})
+            .setAveragePowerForCpuScalingPolicy(0, 360)
+            .setAveragePowerForCpuScalingStep(0, 0, 300)
+            .setCpuPowerBracketCount(1)
+            .setCpuPowerBracket(0, 0, 0);
+
+    private MockClock mClock = new MockClock();
+    private MonotonicClock mMonotonicClock = new MonotonicClock(0, mClock);
+    private PowerStatsStore mPowerStatsStore;
+    private PowerStatsAggregator mPowerStatsAggregator;
+    private BatteryStatsHistory mHistory;
+    private CpuPowerStatsCollector.CpuStatsArrayLayout mCpuStatsArrayLayout;
+    private PowerStats.Descriptor mPowerStatsDescriptor;
+
+    @Before
+    public void setup() {
+        File storeDirectory = new File(getContext().getCacheDir(), getClass().getSimpleName());
+        clearDirectory(storeDirectory);
+
+        AggregatedPowerStatsConfig config = new AggregatedPowerStatsConfig();
+        config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_CPU)
+                .trackDeviceStates(AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN)
+                .trackUidStates(AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN,
+                        AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
+                .setProcessor(
+                        new CpuAggregatedPowerStatsProcessor(mStatsRule.getPowerProfile(),
+                                mStatsRule.getCpuScalingPolicies()));
+
+        mPowerStatsStore = new PowerStatsStore(storeDirectory, new TestHandler(), config);
+        mHistory = new BatteryStatsHistory(Parcel.obtain(), storeDirectory, 0, 10000,
+                mock(BatteryStatsHistory.HistoryStepDetailsCalculator.class), mClock,
+                mMonotonicClock, null);
+        mPowerStatsAggregator = new PowerStatsAggregator(config, mHistory);
+
+        mCpuStatsArrayLayout = new CpuPowerStatsCollector.CpuStatsArrayLayout();
+        mCpuStatsArrayLayout.addDeviceSectionCpuTimeByScalingStep(1);
+        mCpuStatsArrayLayout.addDeviceSectionCpuTimeByCluster(1);
+        mCpuStatsArrayLayout.addDeviceSectionPowerEstimate();
+        mCpuStatsArrayLayout.addUidSectionCpuTimeByPowerBracket(new int[]{0});
+        mCpuStatsArrayLayout.addUidSectionPowerEstimate();
+        PersistableBundle extras = new PersistableBundle();
+        mCpuStatsArrayLayout.toExtras(extras);
+
+        mPowerStatsDescriptor = new PowerStats.Descriptor(BatteryConsumer.POWER_COMPONENT_CPU,
+                mCpuStatsArrayLayout.getDeviceStatsArrayLength(),
+                mCpuStatsArrayLayout.getUidStatsArrayLength(), extras);
+    }
+
+    @Test
+    public void breakdownByProcState_fullRange() throws Exception {
+        BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
+                new String[0], /* includePowerModels */ false,
+                /* includeProcessStateData */ true, /* powerThreshold */ 0);
+        exportAggregatedPowerStats(builder, 1000, 10000);
+
+        BatteryUsageStats actual = builder.build();
+        String message = "Actual BatteryUsageStats: " + actual;
+
+        assertDevicePowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 25.53);
+        assertAllAppsPowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 25.53);
+
+        assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_ANY, 13.5);
+        assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND, 7.47);
+        assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_BACKGROUND, 6.03);
+
+        assertUidPowerEstimate(message, actual, APP_UID2, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_ANY, 12.03);
+        assertUidPowerEstimate(message, actual, APP_UID2, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE, 12.03);
+
+        actual.close();
+    }
+
+    @Test
+    public void breakdownByProcState_subRange() throws Exception {
+        BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
+                new String[0], /* includePowerModels */ false,
+                /* includeProcessStateData */ true, /* powerThreshold */ 0);
+        exportAggregatedPowerStats(builder, 3700, 6700);
+
+        BatteryUsageStats actual = builder.build();
+        String message = "Actual BatteryUsageStats: " + actual;
+
+        assertDevicePowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 15.4);
+        assertAllAppsPowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 15.4);
+
+        assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_ANY, 4.06);
+        assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND, 1.35);
+        assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_BACKGROUND, 2.70);
+
+        assertUidPowerEstimate(message, actual, APP_UID2, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_ANY, 11.33);
+        assertUidPowerEstimate(message, actual, APP_UID2, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE, 11.33);
+
+        actual.close();
+    }
+
+    @Test
+    public void combinedProcessStates() throws Exception {
+        BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
+                new String[0], /* includePowerModels */ false,
+                /* includeProcessStateData */ false, /* powerThreshold */ 0);
+        exportAggregatedPowerStats(builder, 1000, 10000);
+
+        BatteryUsageStats actual = builder.build();
+        String message = "Actual BatteryUsageStats: " + actual;
+
+        assertDevicePowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 25.53);
+        assertAllAppsPowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 25.53);
+
+        assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_ANY, 13.5);
+        assertUidPowerEstimate(message, actual, APP_UID2, BatteryConsumer.POWER_COMPONENT_CPU,
+                BatteryConsumer.PROCESS_STATE_ANY, 12.03);
+        UidBatteryConsumer uidScope = actual.getUidBatteryConsumers().stream()
+                .filter(us -> us.getUid() == APP_UID1).findFirst().orElse(null);
+        // There shouldn't be any per-procstate data
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> uidScope.getConsumedPower(new BatteryConsumer.Dimensions(
+                        BatteryConsumer.POWER_COMPONENT_CPU,
+                        BatteryConsumer.PROCESS_STATE_FOREGROUND)));
+
+
+        actual.close();
+    }
+
+    private void recordBatteryHistory() {
+        PowerStats powerStats = new PowerStats(mPowerStatsDescriptor);
+        long[] uidStats1 = new long[mCpuStatsArrayLayout.getUidStatsArrayLength()];
+        powerStats.uidStats.put(APP_UID1, uidStats1);
+        long[] uidStats2 = new long[mCpuStatsArrayLayout.getUidStatsArrayLength()];
+        powerStats.uidStats.put(APP_UID2, uidStats2);
+
+        mHistory.forceRecordAllHistory();
+
+        mHistory.startRecordingHistory(1000, 1000, false);
+        mHistory.recordPowerStats(1000, 1000, powerStats);
+        mHistory.recordBatteryState(1000, 1000, 70, /* plugged */ false);
+        mHistory.recordStateStartEvent(1000, 1000, BatteryStats.HistoryItem.STATE_SCREEN_ON_FLAG);
+        mHistory.recordProcessStateChange(1000, 1000, APP_UID1,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND);
+        mHistory.recordProcessStateChange(1000, 1000, APP_UID2,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
+
+        mCpuStatsArrayLayout.setTimeByScalingStep(powerStats.stats, 0, 11111);
+        mCpuStatsArrayLayout.setUidTimeByPowerBracket(uidStats1, 0, 10000);
+        mCpuStatsArrayLayout.setUidTimeByPowerBracket(uidStats2, 0, 1111);
+        mHistory.recordPowerStats(1000, 1000, powerStats);
+
+        mCpuStatsArrayLayout.setTimeByScalingStep(powerStats.stats, 0, 12345);
+        mCpuStatsArrayLayout.setUidTimeByPowerBracket(uidStats1, 0, 9876);
+        mCpuStatsArrayLayout.setUidTimeByPowerBracket(uidStats2, 0, 2469);
+        mHistory.recordPowerStats(3000, 3000, powerStats);
+
+        mPowerStatsAggregator.aggregatePowerStats(0, 3500, stats -> {
+            mPowerStatsStore.storeAggregatedPowerStats(stats);
+        });
+
+        mHistory.recordProcessStateChange(4000, 4000, APP_UID1,
+                BatteryConsumer.PROCESS_STATE_BACKGROUND);
+
+        mHistory.recordStateStopEvent(4000, 4000, BatteryStats.HistoryItem.STATE_SCREEN_ON_FLAG);
+
+        mCpuStatsArrayLayout.setTimeByScalingStep(powerStats.stats, 0, 54321);
+        mCpuStatsArrayLayout.setUidTimeByPowerBracket(uidStats1, 0, 14321);
+        mCpuStatsArrayLayout.setUidTimeByPowerBracket(uidStats2, 0, 40000);
+        mHistory.recordPowerStats(6000, 6000, powerStats);
+
+        mPowerStatsAggregator.aggregatePowerStats(3500, 6500, stats -> {
+            mPowerStatsStore.storeAggregatedPowerStats(stats);
+        });
+
+        mHistory.recordStateStartEvent(7000, 7000, BatteryStats.HistoryItem.STATE_SCREEN_ON_FLAG);
+        mHistory.recordProcessStateChange(7000, 7000, APP_UID1,
+                BatteryConsumer.PROCESS_STATE_FOREGROUND);
+        mHistory.recordProcessStateChange(7000, 7000, APP_UID2,
+                BatteryConsumer.PROCESS_STATE_UNSPECIFIED);
+
+        mCpuStatsArrayLayout.setTimeByScalingStep(powerStats.stats, 0, 23456);
+        mCpuStatsArrayLayout.setUidTimeByPowerBracket(uidStats1, 0, 23456);
+        mCpuStatsArrayLayout.setUidTimeByPowerBracket(uidStats2, 0, 0);
+        mHistory.recordPowerStats(8000, 8000, powerStats);
+
+        assertThat(mPowerStatsStore.getTableOfContents()).hasSize(2);
+    }
+
+    private void exportAggregatedPowerStats(BatteryUsageStats.Builder builder,
+            int monotonicStartTime, int monotonicEndTime) {
+        recordBatteryHistory();
+        PowerStatsExporter exporter = new PowerStatsExporter(mPowerStatsStore,
+                mPowerStatsAggregator, /* batterySessionTimeSpanSlackMillis */ 0);
+        exporter.exportAggregatedPowerStats(builder, monotonicStartTime, monotonicEndTime);
+    }
+
+    private void assertDevicePowerEstimate(String message, BatteryUsageStats bus, int componentId,
+            double expected) {
+        AggregateBatteryConsumer consumer = bus.getAggregateBatteryConsumer(
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
+        assertWithMessage(message).that(consumer.getConsumedPower(componentId))
+                .isWithin(TOLERANCE).of(expected);
+    }
+
+    private void assertAllAppsPowerEstimate(String message, BatteryUsageStats bus, int componentId,
+            double expected) {
+        AggregateBatteryConsumer consumer = bus.getAggregateBatteryConsumer(
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
+        assertWithMessage(message).that(consumer.getConsumedPower(componentId))
+                .isWithin(TOLERANCE).of(expected);
+    }
+
+    private void assertUidPowerEstimate(String message, BatteryUsageStats bus, int uid,
+            int componentId, int processState, double expected) {
+        List<UidBatteryConsumer> uidScopes = bus.getUidBatteryConsumers();
+        final UidBatteryConsumer uidScope = uidScopes.stream()
+                .filter(us -> us.getUid() == uid).findFirst().orElse(null);
+        assertWithMessage(message).that(uidScope).isNotNull();
+        assertWithMessage(message).that(uidScope.getConsumedPower(
+                new BatteryConsumer.Dimensions(componentId, processState)))
+                .isWithin(TOLERANCE).of(expected);
+    }
+
+    private void clearDirectory(File dir) {
+        if (dir.exists()) {
+            for (File child : dir.listFiles()) {
+                if (child.isDirectory()) {
+                    clearDirectory(child);
+                }
+                child.delete();
+            }
+        }
+    }
+
+    private static class TestHandler extends Handler {
+        TestHandler() {
+            super(Looper.getMainLooper());
+        }
+
+        @Override
+        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+            msg.getCallback().run();
+            return true;
+        }
+    }
+}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java
index 0e58787..7257a94 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java
@@ -27,9 +27,6 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.os.BatteryConsumer;
-import android.os.BatteryManager;
-import android.os.BatteryUsageStats;
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -59,13 +56,13 @@
     private MockClock mClock = new MockClock();
     private MonotonicClock mMonotonicClock = new MonotonicClock(0, mClock);
     private MockBatteryStatsImpl mBatteryStats;
-    private BatteryUsageStatsProvider mBatteryUsageStatsProvider;
     private PowerStatsScheduler mPowerStatsScheduler;
     private PowerProfile mPowerProfile;
     private PowerStatsAggregator mPowerStatsAggregator;
     private AggregatedPowerStatsConfig mAggregatedPowerStatsConfig;
 
     @Before
+    @SuppressWarnings("GuardedBy")
     public void setup() {
         final Context context = InstrumentationRegistry.getContext();
 
@@ -83,11 +80,10 @@
         mPowerProfile = mock(PowerProfile.class);
         when(mPowerProfile.getAveragePower(PowerProfile.POWER_FLASHLIGHT)).thenReturn(1000000.0);
         mBatteryStats = new MockBatteryStatsImpl(mClock).setPowerProfile(mPowerProfile);
-        mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mBatteryStats);
         mPowerStatsAggregator = mock(PowerStatsAggregator.class);
         mPowerStatsScheduler = new PowerStatsScheduler(context, mPowerStatsAggregator,
                 TimeUnit.MINUTES.toMillis(30), TimeUnit.HOURS.toMillis(1), mPowerStatsStore, mClock,
-                mMonotonicClock, mHandler, mBatteryStats, mBatteryUsageStatsProvider);
+                mMonotonicClock, mHandler, mBatteryStats);
     }
 
     @Test
@@ -176,70 +172,6 @@
     }
 
     @Test
-    public void storeBatteryUsageStatsOnReset() {
-        mBatteryStats.forceRecordAllHistory();
-        synchronized (mBatteryStats) {
-            mBatteryStats.setOnBatteryLocked(mClock.realtime, mClock.uptime, true,
-                    BatteryManager.BATTERY_STATUS_DISCHARGING, 50, 0);
-        }
-
-        mPowerStatsScheduler.start(/* schedulePeriodicPowerStatsCollection */false);
-
-        assertThat(mPowerStatsStore.getTableOfContents()).isEmpty();
-
-        mPowerStatsScheduler.start(true);
-
-        synchronized (mBatteryStats) {
-            mBatteryStats.noteFlashlightOnLocked(42, mClock.realtime, mClock.uptime);
-        }
-
-        mClock.realtime += 60000;
-        mClock.currentTime += 60000;
-
-        synchronized (mBatteryStats) {
-            mBatteryStats.noteFlashlightOffLocked(42, mClock.realtime, mClock.uptime);
-        }
-
-        mClock.realtime += 60000;
-        mClock.currentTime += 60000;
-
-        // Battery stats reset should have the side-effect of saving accumulated battery usage stats
-        synchronized (mBatteryStats) {
-            mBatteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
-        }
-
-        // Await completion
-        ConditionVariable done = new ConditionVariable();
-        mHandler.post(done::open);
-        done.block();
-
-        List<PowerStatsSpan.Metadata> contents = mPowerStatsStore.getTableOfContents();
-        assertThat(contents).hasSize(1);
-
-        PowerStatsSpan.Metadata metadata = contents.get(0);
-
-        PowerStatsSpan span = mPowerStatsStore.loadPowerStatsSpan(metadata.getId(),
-                BatteryUsageStatsSection.TYPE);
-        assertThat(span).isNotNull();
-
-        List<PowerStatsSpan.TimeFrame> timeFrames = span.getMetadata().getTimeFrames();
-        assertThat(timeFrames).hasSize(1);
-        assertThat(timeFrames.get(0).startMonotonicTime).isEqualTo(7654321);
-        assertThat(timeFrames.get(0).duration).isEqualTo(120000);
-
-        List<PowerStatsSpan.Section> sections = span.getSections();
-        assertThat(sections).hasSize(1);
-
-        PowerStatsSpan.Section section = sections.get(0);
-        assertThat(section.getType()).isEqualTo(BatteryUsageStatsSection.TYPE);
-        BatteryUsageStats bus = ((BatteryUsageStatsSection) section).getBatteryUsageStats();
-        assertThat(bus.getAggregateBatteryConsumer(
-                        BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
-                .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
-                .isEqualTo(60000);
-    }
-
-    @Test
     public void alignToWallClock() {
         // Expect the aligned value to be adjusted by 1 min 30 sec - rounded to the next 15 min
         assertThat(PowerStatsScheduler.alignToWallClock(123, TimeUnit.MINUTES.toMillis(15),
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsUidResolverTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsUidResolverTest.java
new file mode 100644
index 0000000..60b2541
--- /dev/null
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsUidResolverTest.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.power.stats;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class PowerStatsUidResolverTest {
+
+    private final PowerStatsUidResolver mResolver = new PowerStatsUidResolver();
+    @Mock
+    PowerStatsUidResolver.Listener mListener;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void addAndRemoveIsolatedUid() {
+        mResolver.addListener(mListener);
+        mResolver.noteIsolatedUidAdded(42, 314);
+        verify(mListener).onIsolatedUidAdded(42, 314);
+        assertThat(mResolver.mapUid(42)).isEqualTo(314);
+
+        mResolver.noteIsolatedUidRemoved(42, 314);
+        verify(mListener).onBeforeIsolatedUidRemoved(42, 314);
+        verify(mListener).onAfterIsolatedUidRemoved(42, 314);
+        assertThat(mResolver.mapUid(42)).isEqualTo(42);
+
+        verifyNoMoreInteractions(mListener);
+    }
+
+    @Test
+    public void retainAndRemoveIsolatedUid() {
+        mResolver.addListener(mListener);
+        mResolver.noteIsolatedUidAdded(42, 314);
+        verify(mListener).onIsolatedUidAdded(42, 314);
+        assertThat(mResolver.mapUid(42)).isEqualTo(314);
+
+        mResolver.retainIsolatedUid(42);
+
+        mResolver.noteIsolatedUidRemoved(42, 314);
+        verify(mListener).onBeforeIsolatedUidRemoved(42, 314);
+        assertThat(mResolver.mapUid(42)).isEqualTo(314);
+        verifyNoMoreInteractions(mListener);
+
+        mResolver.releaseIsolatedUid(42);
+        verify(mListener).onAfterIsolatedUidRemoved(42, 314);
+        assertThat(mResolver.mapUid(42)).isEqualTo(42);
+
+        verifyNoMoreInteractions(mListener);
+    }
+
+    @Test
+    public void removeUidsInRange() {
+        mResolver.noteIsolatedUidAdded(1, 314);
+        mResolver.noteIsolatedUidAdded(2, 314);
+        mResolver.noteIsolatedUidAdded(3, 314);
+        mResolver.noteIsolatedUidAdded(4, 314);
+        mResolver.noteIsolatedUidAdded(6, 314);
+        mResolver.noteIsolatedUidAdded(8, 314);
+        mResolver.noteIsolatedUidAdded(10, 314);
+
+        mResolver.addListener(mListener);
+
+        mResolver.releaseUidsInRange(4, 4);     // Single
+        verify(mListener).onAfterIsolatedUidRemoved(4, 314);
+        verifyNoMoreInteractions(mListener);
+
+        // Now: [1, 2, 3, 6, 8, 10]
+
+        mResolver.releaseUidsInRange(2, 3);     // Inclusive
+        verify(mListener).onAfterIsolatedUidRemoved(2, 314);
+        verify(mListener).onAfterIsolatedUidRemoved(3, 314);
+        verifyNoMoreInteractions(mListener);
+
+        // Now: [1, 6, 8, 10]
+
+        mResolver.releaseUidsInRange(5, 9);     // Exclusive
+        verify(mListener).onAfterIsolatedUidRemoved(6, 314);
+        verify(mListener).onAfterIsolatedUidRemoved(8, 314);
+        verifyNoMoreInteractions(mListener);
+
+        // Now: [1, 10]
+
+        mResolver.releaseUidsInRange(5, 9);     // Empty
+        verifyNoMoreInteractions(mListener);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java b/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java
index 1002fba..88ca029 100644
--- a/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/PinnerServiceTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.spy;
 
 import android.app.ActivityManagerInternal;
+import android.app.pinner.PinnedFileStat;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
@@ -47,22 +48,19 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import java.io.BufferedReader;
 import java.io.CharArrayWriter;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.io.StringReader;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.util.Optional;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 @SmallTest
@@ -138,6 +136,13 @@
             protected void publishBinderService(PinnerService service, Binder binderService) {
                 // Suppress this for testing, it's not needed and causes conflitcs.
             }
+
+            @Override
+            protected PinnerService.PinnedFile pinFileInternal(String fileToPin,
+                    int maxBytesToPin, boolean attemptPinIntrospection) {
+                return new PinnerService.PinnedFile(-1,
+                        maxBytesToPin, fileToPin, maxBytesToPin);
+            }
         };
     }
 
@@ -202,20 +207,27 @@
         return cw.toString();
     }
 
-    private int getPinnedSize(PinnerService pinnerService) throws Exception {
-        return getPinnedSizeImpl(pinnerService, "Total size: ");
+    private long getPinnedSize(PinnerService pinnerService) {
+        long totalBytesPinned = 0;
+        for (PinnedFileStat stat : pinnerService.getPinnerStats()) {
+            totalBytesPinned += stat.getBytesPinned();
+        }
+        return totalBytesPinned;
     }
 
-    private int getPinnedAnonSize(PinnerService pinnerService) throws Exception {
-        return getPinnedSizeImpl(pinnerService, "Pinned anon region: ");
+    private int getPinnedAnonSize(PinnerService pinnerService) {
+        List<PinnedFileStat> anonStats = pinnerService.getPinnerStats().stream()
+                .filter(pf -> pf.getGroupName().equals(PinnerService.ANON_REGION_STAT_NAME))
+                .toList();
+        int totalAnon = 0;
+        for (PinnedFileStat anonStat : anonStats) {
+            totalAnon += anonStat.getBytesPinned();
+        }
+        return totalAnon;
     }
 
-    private int getPinnedSizeImpl(PinnerService pinnerService, String sizeToken) throws Exception {
-        String dumpOutput = getPinnerServiceDump(pinnerService);
-        BufferedReader bufReader = new BufferedReader(new StringReader(dumpOutput));
-        Optional<Integer> size = bufReader.lines().filter(s -> s.contains(sizeToken))
-                .map(s -> Integer.valueOf(s.substring(sizeToken.length()))).findAny();
-        return size.orElse(-1);
+    private long getTotalPinnedFiles(PinnerService pinnerService) {
+        return pinnerService.getPinnerStats().stream().count();
     }
 
     private void setDeviceConfigPinnedAnonSize(long size) {
@@ -227,7 +239,6 @@
     }
 
     @Test
-    @Ignore("b/309853498, pinning home app can fail with ENOMEM")
     public void testPinHomeApp() throws Exception {
         // Enable HOME app pinning
         mContext.getOrCreateTestableResources()
@@ -245,15 +256,13 @@
         ArrayMap<Integer, Object> pinnedApps = getPinnedApps(pinnerService);
         assertThat(pinnedApps.get(KEY_HOME)).isNotNull();
 
-        // Check if dump() reports total pinned bytes
-        int totalPinnedSizeBytes = getPinnedSize(pinnerService);
-        assertThat(totalPinnedSizeBytes).isGreaterThan(0);
+        assertThat(getPinnedSize(pinnerService)).isGreaterThan(0);
+        assertThat(getTotalPinnedFiles(pinnerService)).isGreaterThan(0);
 
         unpinAll(pinnerService);
     }
 
     @Test
-    @Ignore("b/309853498, pinning home app can fail with ENOMEM")
     public void testPinHomeAppOnBootCompleted() throws Exception {
         // Enable HOME app pinning
         mContext.getOrCreateTestableResources()
@@ -271,9 +280,7 @@
         ArrayMap<Integer, Object> pinnedApps = getPinnedApps(pinnerService);
         assertThat(pinnedApps.get(KEY_HOME)).isNotNull();
 
-        // Check if dump() reports total pinned bytes
-        int totalPinnedSizeBytes = getPinnedSize(pinnerService);
-        assertThat(totalPinnedSizeBytes).isGreaterThan(0);
+        assertThat(getPinnedSize(pinnerService)).isGreaterThan(0);
 
         unpinAll(pinnerService);
     }
@@ -294,12 +301,24 @@
         ArrayMap<Integer, Object> pinnedApps = getPinnedApps(pinnerService);
         assertThat(pinnedApps).isEmpty();
 
-        // Check if dump() reports total pinned bytes
-        int totalPinnedSizeBytes = getPinnedSize(pinnerService);
+        long totalPinnedSizeBytes = getPinnedSize(pinnerService);
         assertThat(totalPinnedSizeBytes).isEqualTo(0);
 
         int pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService);
-        assertThat(pinnedAnonSizeBytes).isEqualTo(-1);
+        assertThat(pinnedAnonSizeBytes).isEqualTo(0);
+
+        unpinAll(pinnerService);
+    }
+
+    @Test
+    public void testPinFile() throws Exception {
+        PinnerService pinnerService = new PinnerService(mContext, mInjector);
+        pinnerService.onStart();
+
+        pinnerService.pinFile("test_file", 4096, null, "my_group");
+
+        assertThat(getPinnedSize(pinnerService)).isGreaterThan(0);
+        assertThat(getTotalPinnedFiles(pinnerService)).isGreaterThan(0);
 
         unpinAll(pinnerService);
     }
@@ -341,11 +360,8 @@
         waitForPinnerService(pinnerService);
         // An empty anon region should clear the associated status entry.
         pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService);
-        assertThat(pinnedAnonSizeBytes).isEqualTo(-1);
+        assertThat(pinnedAnonSizeBytes).isEqualTo(0);
 
         unpinAll(pinnerService);
     }
-
-    // TODO: Add test to check that the pages we expect to be pinned are actually pinned
-
 }
diff --git a/services/tests/servicestests/src/com/android/server/SecurityStateTest.java b/services/tests/servicestests/src/com/android/server/SecurityStateTest.java
new file mode 100644
index 0000000..fc91e47
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/SecurityStateTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static android.os.SecurityStateManager.KEY_KERNEL_VERSION;
+import static android.os.SecurityStateManager.KEY_SYSTEM_SPL;
+import static android.os.SecurityStateManager.KEY_VENDOR_SPL;
+
+import static com.android.server.SecurityStateManagerService.KERNEL_RELEASE_PATTERN;
+import static com.android.server.SecurityStateManagerService.VENDOR_SECURITY_PATCH_PROPERTY_KEY;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.os.VintfRuntimeInfo;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.regex.Matcher;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class SecurityStateTest {
+    @Rule
+    public MockitoRule mockitoRule = MockitoJUnit.rule();
+
+    @Mock
+    private Context mMockContext;
+
+    @Mock
+    private PackageManager mMockPackageManager;
+
+    @Mock
+    private Resources mMockResources;
+
+    private static final String DEFAULT_MODULE_METADATA_PROVIDER = "com.android.modulemetadata";
+    private static final String DEFAULT_MODULE_METADATA_PROVIDER_VERSION = "2023-12-01";
+    private static final String DEFAULT_SECURITY_STATE_PACKAGE = "com.google.android.gms";
+    private static final String DEFAULT_SECURITY_STATE_PACKAGE_VERSION = "2023-12-05";
+    private static final String[] SECURITY_STATE_PACKAGES =
+            new String[]{DEFAULT_SECURITY_STATE_PACKAGE};
+
+    @Before
+    public void setUp() throws Exception {
+        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+        when(mMockContext.getResources()).thenReturn(mMockResources);
+        when(mMockContext.getString(R.string.config_defaultModuleMetadataProvider))
+                .thenReturn(DEFAULT_MODULE_METADATA_PROVIDER);
+        when(mMockPackageManager.getPackageInfo(anyString(), anyInt()))
+                .thenReturn(new PackageInfo());
+        PackageInfo moduleMetadataPackageInfo = new PackageInfo();
+        moduleMetadataPackageInfo.versionName = DEFAULT_MODULE_METADATA_PROVIDER_VERSION;
+        when(mMockPackageManager.getPackageInfo(DEFAULT_MODULE_METADATA_PROVIDER, 0))
+                .thenReturn(moduleMetadataPackageInfo);
+        PackageInfo securityStatePackageInfo = new PackageInfo();
+        securityStatePackageInfo.versionName = DEFAULT_SECURITY_STATE_PACKAGE_VERSION;
+        when(mMockPackageManager.getPackageInfo(DEFAULT_SECURITY_STATE_PACKAGE, 0))
+                .thenReturn(securityStatePackageInfo);
+        when(mMockResources.getStringArray(R.array.config_securityStatePackages))
+                .thenReturn(SECURITY_STATE_PACKAGES);
+    }
+
+    @Test
+    public void testGetGlobalSecurityState_returnsBundle() {
+        SecurityStateManagerService securityState = new SecurityStateManagerService(mMockContext);
+
+        Bundle bundle = securityState.getGlobalSecurityState();
+
+        assertEquals(bundle.getString(KEY_SYSTEM_SPL), Build.VERSION.SECURITY_PATCH);
+        assertEquals(bundle.getString(KEY_VENDOR_SPL),
+                SystemProperties.get(VENDOR_SECURITY_PATCH_PROPERTY_KEY, ""));
+        Matcher matcher = KERNEL_RELEASE_PATTERN.matcher(VintfRuntimeInfo.getKernelVersion());
+        String kernelVersion = "";
+        if (matcher.matches()) {
+            kernelVersion = matcher.group(1);
+        }
+        assertEquals(bundle.getString(KEY_KERNEL_VERSION), kernelVersion);
+        assertEquals(bundle.getString(DEFAULT_MODULE_METADATA_PROVIDER),
+                DEFAULT_MODULE_METADATA_PROVIDER_VERSION);
+        assertEquals(bundle.getString(DEFAULT_SECURITY_STATE_PACKAGE),
+                DEFAULT_SECURITY_STATE_PACKAGE_VERSION);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/WatchdogTest.java b/services/tests/servicestests/src/com/android/server/WatchdogTest.java
new file mode 100644
index 0000000..34ac47e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/WatchdogTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.os.Handler;
+import android.os.SimpleClock;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.Watchdog.HandlerChecker;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.ZoneOffset;
+
+/** Test class for {@link Watchdog}. */
+@RunWith(AndroidJUnit4.class)
+public class WatchdogTest {
+    private static final int TIMEOUT_MS = 10;
+
+    private TestClock mClock;
+    private Handler mHandler;
+    private HandlerChecker mChecker;
+
+    @Before
+    public void setUp() {
+        mClock = new TestClock();
+        mHandler = mock(Handler.class);
+        mChecker =
+                new HandlerChecker(mHandler, "monitor thread", new Object(), mClock) {
+                    @Override
+                    public boolean isHandlerPolling() {
+                        return false;
+                    }
+                };
+    }
+
+    @Test
+    public void checkerPausedUntilResume() {
+        Watchdog.Monitor monitor = mock(Watchdog.Monitor.class);
+        mChecker.addMonitorLocked(monitor);
+
+        mChecker.pauseLocked("pausing");
+        mChecker.scheduleCheckLocked(TIMEOUT_MS);
+        verifyNoMoreInteractions(mHandler);
+        assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+
+        mChecker.resumeLocked("resuming");
+        mChecker.scheduleCheckLocked(10);
+        assertEquals(Watchdog.WAITING, mChecker.getCompletionStateLocked());
+    }
+
+    @Test
+    public void checkerPausedUntilDeadline() {
+        Watchdog.Monitor monitor = mock(Watchdog.Monitor.class);
+        mChecker.addMonitorLocked(monitor);
+
+        mChecker.pauseForLocked(10, "pausing");
+        mChecker.scheduleCheckLocked(TIMEOUT_MS);
+        verifyNoMoreInteractions(mHandler);
+        assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+
+        mClock.advanceBy(5);
+        verifyNoMoreInteractions(mHandler);
+        assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+
+        // Above the 10s timeout. Watchdog should not be paused anymore.
+        mClock.advanceBy(6);
+        mChecker.scheduleCheckLocked(TIMEOUT_MS);
+        assertEquals(Watchdog.WAITING, mChecker.getCompletionStateLocked());
+    }
+
+    @Test
+    public void checkerPausedDuringScheduledRun() {
+        Watchdog.Monitor monitor = mock(Watchdog.Monitor.class);
+        mChecker.addMonitorLocked(monitor);
+
+        mChecker.scheduleCheckLocked(TIMEOUT_MS);
+        mClock.advanceBy(5);
+        mChecker.pauseForLocked(10, "pausing");
+        verifyNoMoreInteractions(mHandler);
+        assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+
+        // Above the 10s timeout. Watchdog should not be paused anymore.
+        mClock.advanceBy(11);
+        mChecker.scheduleCheckLocked(TIMEOUT_MS);
+        assertEquals(Watchdog.WAITING, mChecker.getCompletionStateLocked());
+    }
+
+    @Test
+    public void blockedThread() {
+        mChecker.scheduleCheckLocked(TIMEOUT_MS);
+        assertEquals(mChecker.getCompletionStateLocked(), Watchdog.WAITING);
+
+        mClock.advanceBy(6);
+        assertEquals(Watchdog.WAITED_UNTIL_PRE_WATCHDOG, mChecker.getCompletionStateLocked());
+
+        // Above the 10s timeout.
+        mClock.advanceBy(6);
+        assertEquals(Watchdog.OVERDUE, mChecker.getCompletionStateLocked());
+    }
+
+    @Test
+    public void checkNothingBlocked() {
+        Watchdog.Monitor monitor = mock(Watchdog.Monitor.class);
+        mChecker.addMonitorLocked(monitor);
+
+        mChecker.scheduleCheckLocked(TIMEOUT_MS);
+        // scheduleCheckLocked calls #postAtFrontOfQueue which will call mChecker.run().
+        mChecker.run();
+        assertEquals(Watchdog.COMPLETED, mChecker.getCompletionStateLocked());
+        verify(monitor).monitor();
+    }
+
+    private static class TestClock extends SimpleClock {
+        long mNowMillis = 1;
+
+        TestClock() {
+            super(ZoneOffset.UTC);
+        }
+
+        @Override
+        public long millis() {
+            return mNowMillis;
+        }
+
+        public void advanceBy(long millis) {
+            mNowMillis += millis;
+        }
+    }
+}
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 82efdd3..800350a 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -85,9 +85,9 @@
 import com.android.server.LocalServices;
 import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener;
 import com.android.server.accessibility.magnification.FullScreenMagnificationController;
+import com.android.server.accessibility.magnification.MagnificationConnectionManager;
 import com.android.server.accessibility.magnification.MagnificationController;
 import com.android.server.accessibility.magnification.MagnificationProcessor;
-import com.android.server.accessibility.magnification.WindowMagnificationManager;
 import com.android.server.accessibility.test.MessageCapturingHandler;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal;
@@ -156,7 +156,7 @@
     @Mock private UserManagerInternal mMockUserManagerInternal;
     @Mock private IBinder mMockBinder;
     @Mock private IAccessibilityServiceClient mMockServiceClient;
-    @Mock private WindowMagnificationManager mMockWindowMagnificationMgr;
+    @Mock private MagnificationConnectionManager mMockMagnificationConnectionManager;
     @Mock private MagnificationController mMockMagnificationController;
     @Mock private FullScreenMagnificationController mMockFullScreenMagnificationController;
     @Mock private ProxyManager mProxyManager;
@@ -180,8 +180,8 @@
                 UserManagerInternal.class, mMockUserManagerInternal);
         mInputFilter = Mockito.mock(FakeInputFilter.class);
 
-        when(mMockMagnificationController.getWindowMagnificationMgr()).thenReturn(
-                mMockWindowMagnificationMgr);
+        when(mMockMagnificationController.getMagnificationConnectionManager()).thenReturn(
+                mMockMagnificationConnectionManager);
         when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn(
                 mMockFullScreenMagnificationController);
         when(mMockMagnificationController.supportWindowMagnification()).thenReturn(true);
@@ -530,7 +530,7 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr).requestConnection(true);
+        verify(mMockMagnificationConnectionManager).requestConnection(true);
     }
 
     @SmallTest
@@ -547,7 +547,7 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr).requestConnection(true);
+        verify(mMockMagnificationConnectionManager).requestConnection(true);
     }
 
     @SmallTest
@@ -565,7 +565,7 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr).requestConnection(false);
+        verify(mMockMagnificationConnectionManager).requestConnection(false);
     }
 
     @SmallTest
@@ -583,7 +583,7 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr).requestConnection(true);
+        verify(mMockMagnificationConnectionManager).requestConnection(true);
     }
 
     @SmallTest
@@ -602,7 +602,7 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr).requestConnection(false);
+        verify(mMockMagnificationConnectionManager).requestConnection(false);
     }
 
     @SmallTest
@@ -616,7 +616,7 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr).requestConnection(true);
+        verify(mMockMagnificationConnectionManager).requestConnection(true);
     }
 
     @SmallTest
@@ -630,7 +630,8 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr, atLeastOnce()).removeMagnificationButton(anyInt());
+        verify(mMockMagnificationConnectionManager, atLeastOnce())
+                .removeMagnificationButton(anyInt());
     }
 
     @SmallTest
@@ -644,7 +645,7 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr, never()).removeMagnificationButton(anyInt());
+        verify(mMockMagnificationConnectionManager, never()).removeMagnificationButton(anyInt());
     }
 
     @SmallTest
@@ -659,7 +660,8 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr, atLeastOnce()).removeMagnificationButton(anyInt());
+        verify(mMockMagnificationConnectionManager, atLeastOnce())
+                .removeMagnificationButton(anyInt());
     }
 
     @SmallTest
@@ -674,7 +676,7 @@
         // Invokes client change to trigger onUserStateChanged.
         mA11yms.onClientChangeLocked(/* serviceInfoChanged= */false);
 
-        verify(mMockWindowMagnificationMgr, never()).removeMagnificationButton(anyInt());
+        verify(mMockMagnificationConnectionManager, never()).removeMagnificationButton(anyInt());
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java
index a02807f..7829fcc 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java
@@ -39,9 +39,9 @@
 import android.graphics.Region;
 
 import com.android.server.accessibility.magnification.FullScreenMagnificationController;
+import com.android.server.accessibility.magnification.MagnificationConnectionManager;
 import com.android.server.accessibility.magnification.MagnificationController;
 import com.android.server.accessibility.magnification.MagnificationProcessor;
-import com.android.server.accessibility.magnification.WindowMagnificationManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -66,21 +66,21 @@
     @Mock
     private FullScreenMagnificationController mMockFullScreenMagnificationController;
     @Mock
-    private WindowMagnificationManager mMockWindowMagnificationManager;
+    private MagnificationConnectionManager mMockMagnificationConnectionManager;
     FullScreenMagnificationControllerStub mFullScreenMagnificationControllerStub;
-    WindowMagnificationManagerStub mWindowMagnificationManagerStub;
+    MagnificationManagerStub mMagnificationManagerStub;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
         mFullScreenMagnificationControllerStub = new FullScreenMagnificationControllerStub(
                 mMockFullScreenMagnificationController);
-        mWindowMagnificationManagerStub = new WindowMagnificationManagerStub(
-                mMockWindowMagnificationManager);
+        mMagnificationManagerStub = new MagnificationManagerStub(
+                mMockMagnificationConnectionManager);
         when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn(
                 mMockFullScreenMagnificationController);
-        when(mMockMagnificationController.getWindowMagnificationMgr()).thenReturn(
-                mMockWindowMagnificationManager);
+        when(mMockMagnificationController.getMagnificationConnectionManager()).thenReturn(
+                mMockMagnificationConnectionManager);
         mMagnificationProcessor = new MagnificationProcessor(mMockMagnificationController);
     }
 
@@ -194,7 +194,7 @@
         doAnswer((invocation) -> {
             ((Region) invocation.getArguments()[1]).set(region);
             return null;
-        }).when(mMockWindowMagnificationManager).getMagnificationSourceBounds(eq(TEST_DISPLAY),
+        }).when(mMockMagnificationConnectionManager).getMagnificationSourceBounds(eq(TEST_DISPLAY),
                 any());
 
         final Region result = new Region();
@@ -286,7 +286,7 @@
 
         mMagnificationProcessor.resetCurrentMagnification(TEST_DISPLAY, /* animate= */false);
 
-        verify(mMockWindowMagnificationManager).disableWindowMagnification(TEST_DISPLAY, false,
+        verify(mMockMagnificationConnectionManager).disableWindowMagnification(TEST_DISPLAY, false,
                 null);
     }
 
@@ -296,7 +296,7 @@
         mMagnificationProcessor.resetAllIfNeeded(connectionId);
 
         verify(mMockFullScreenMagnificationController).resetAllIfNeeded(eq(connectionId));
-        verify(mMockWindowMagnificationManager).resetAllIfNeeded(eq(connectionId));
+        verify(mMockMagnificationConnectionManager).resetAllIfNeeded(eq(connectionId));
     }
 
     @Test
@@ -450,7 +450,7 @@
                 .setActivated(false).build();
         mMagnificationProcessor.setMagnificationConfig(TEST_DISPLAY, config, false, SERVICE_ID);
 
-        verify(mMockWindowMagnificationManager)
+        verify(mMockMagnificationConnectionManager)
                 .disableWindowMagnification(eq(TEST_DISPLAY), anyBoolean());
     }
 
@@ -481,11 +481,11 @@
             mFullScreenMagnificationControllerStub.resetAndStubMethods();
             mMockFullScreenMagnificationController.setScaleAndCenter(displayId, config.getScale(),
                     config.getCenterX(), config.getCenterY(), false, SERVICE_ID);
-            mWindowMagnificationManagerStub.deactivateIfNeed();
+            mMagnificationManagerStub.deactivateIfNeed();
         } else if (config.getMode() == MAGNIFICATION_MODE_WINDOW) {
-            mWindowMagnificationManagerStub.resetAndStubMethods();
-            mMockWindowMagnificationManager.enableWindowMagnification(displayId, config.getScale(),
-                    config.getCenterX(), config.getCenterY());
+            mMagnificationManagerStub.resetAndStubMethods();
+            mMockMagnificationConnectionManager.enableWindowMagnification(
+                    displayId, config.getScale(), config.getCenterX(), config.getCenterY());
             mFullScreenMagnificationControllerStub.deactivateIfNeed();
         }
     }
@@ -568,26 +568,26 @@
         }
     }
 
-    private static class WindowMagnificationManagerStub {
-        private final WindowMagnificationManager mWindowMagnificationManager;
+    private static class MagnificationManagerStub {
+        private final MagnificationConnectionManager mMagnificationConnectionManager;
         private float mScale = 1.0f;
         private float mCenterX = 0;
         private float mCenterY = 0;
         private boolean mIsEnabled = false;
 
-        WindowMagnificationManagerStub(
-                WindowMagnificationManager windowMagnificationManager) {
-            mWindowMagnificationManager = windowMagnificationManager;
+        MagnificationManagerStub(
+                MagnificationConnectionManager magnificationConnectionManager) {
+            mMagnificationConnectionManager = magnificationConnectionManager;
         }
 
         private void stubMethods() {
-            doAnswer(invocation -> mScale).when(mWindowMagnificationManager).getScale(
+            doAnswer(invocation -> mScale).when(mMagnificationConnectionManager).getScale(
                     TEST_DISPLAY);
-            doAnswer(invocation -> mCenterX).when(mWindowMagnificationManager).getCenterX(
+            doAnswer(invocation -> mCenterX).when(mMagnificationConnectionManager).getCenterX(
                     TEST_DISPLAY);
-            doAnswer(invocation -> mCenterY).when(mWindowMagnificationManager).getCenterY(
+            doAnswer(invocation -> mCenterY).when(mMagnificationConnectionManager).getCenterY(
                     TEST_DISPLAY);
-            doAnswer(invocation -> mIsEnabled).when(mWindowMagnificationManager)
+            doAnswer(invocation -> mIsEnabled).when(mMagnificationConnectionManager)
                     .isWindowMagnifierEnabled(TEST_DISPLAY);
 
             Answer enableWindowMagnificationStubAnswer = invocation -> {
@@ -598,10 +598,10 @@
                 return true;
             };
             doAnswer(enableWindowMagnificationStubAnswer).when(
-                    mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY),
+                    mMagnificationConnectionManager).enableWindowMagnification(eq(TEST_DISPLAY),
                     anyFloat(), anyFloat(), anyFloat());
             doAnswer(enableWindowMagnificationStubAnswer).when(
-                    mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY),
+                    mMagnificationConnectionManager).enableWindowMagnification(eq(TEST_DISPLAY),
                     anyFloat(), anyFloat(), anyFloat(), any(), anyInt());
 
             Answer disableWindowMagnificationStubAnswer = invocation -> {
@@ -609,15 +609,15 @@
                 return true;
             };
             doAnswer(disableWindowMagnificationStubAnswer).when(
-                    mWindowMagnificationManager).disableWindowMagnification(eq(TEST_DISPLAY),
+                    mMagnificationConnectionManager).disableWindowMagnification(eq(TEST_DISPLAY),
                     anyBoolean());
             doAnswer(disableWindowMagnificationStubAnswer).when(
-                    mWindowMagnificationManager).disableWindowMagnification(eq(TEST_DISPLAY),
+                    mMagnificationConnectionManager).disableWindowMagnification(eq(TEST_DISPLAY),
                     anyBoolean(), any());
         }
 
         public void resetAndStubMethods() {
-            Mockito.reset(mWindowMagnificationManager);
+            Mockito.reset(mMagnificationConnectionManager);
             stubMethods();
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index fd2cf6d..3b39160 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -540,18 +540,23 @@
         twoFingerTap();
 
         assertIn(STATE_ACTIVATED);
+        verify(mMockMagnificationLogger, never()).logMagnificationTripleTap(anyBoolean());
+        verify(mMockMagnificationLogger).logMagnificationTwoFingerTripleTap(true);
     }
 
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
     public void testTwoFingerTripleTap_StateIsActivated_shouldInIdle() {
         goFromStateIdleTo(STATE_ACTIVATED);
+        reset(mMockMagnificationLogger);
 
         twoFingerTap();
         twoFingerTap();
         twoFingerTap();
 
         assertIn(STATE_IDLE);
+        verify(mMockMagnificationLogger, never()).logMagnificationTripleTap(anyBoolean());
+        verify(mMockMagnificationLogger).logMagnificationTwoFingerTripleTap(false);
     }
 
     @Test
@@ -564,6 +569,8 @@
         twoFingerTapAndHold();
 
         assertIn(STATE_NON_ACTIVATED_ZOOMED_TMP);
+        verify(mMockMagnificationLogger, never()).logMagnificationTripleTap(anyBoolean());
+        verify(mMockMagnificationLogger).logMagnificationTwoFingerTripleTap(true);
     }
 
     @Test
@@ -576,6 +583,8 @@
         twoFingerSwipeAndHold();
 
         assertIn(STATE_NON_ACTIVATED_ZOOMED_TMP);
+        verify(mMockMagnificationLogger, never()).logMagnificationTripleTap(anyBoolean());
+        verify(mMockMagnificationLogger).logMagnificationTwoFingerTripleTap(true);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
new file mode 100644
index 0000000..3843e25
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
@@ -0,0 +1,854 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility.magnification;
+
+import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY;
+import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY_2;
+
+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.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import static java.lang.Float.NaN;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.test.mock.MockContentResolver;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
+import android.view.accessibility.IWindowMagnificationConnectionCallback;
+import android.view.accessibility.MagnificationAnimationCallback;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.FlakyTest;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.LocalServices;
+import com.android.server.accessibility.AccessibilityTraceManager;
+import com.android.server.statusbar.StatusBarManagerInternal;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+
+/**
+ * Tests for WindowMagnificationManager.
+ */
+public class MagnificationConnectionManagerTest {
+
+    private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM;
+    private static final int SERVICE_ID = 1;
+
+    private MockWindowMagnificationConnection mMockConnection;
+    @Mock
+    private Context mContext;
+    @Mock
+    private AccessibilityTraceManager mMockTrace;
+    @Mock
+    private StatusBarManagerInternal mMockStatusBarManagerInternal;
+    @Mock
+    private MagnificationAnimationCallback mAnimationCallback;
+    @Mock
+    private MagnificationConnectionManager.Callback mMockCallback;
+    private MockContentResolver mResolver;
+    private MagnificationConnectionManager mMagnificationConnectionManager;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+        LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
+        LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal);
+        mResolver = new MockContentResolver();
+        mMockConnection = new MockWindowMagnificationConnection();
+        mMagnificationConnectionManager = new MagnificationConnectionManager(mContext, new Object(),
+                mMockCallback, mMockTrace, new MagnificationScaleProvider(mContext));
+
+        when(mContext.getContentResolver()).thenReturn(mResolver);
+        stubSetConnection(false);
+
+        mResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        Settings.Secure.putFloatForUser(mResolver,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.5f,
+                CURRENT_USER_ID);
+    }
+
+    private void stubSetConnection(boolean needDelay) {
+        doAnswer((InvocationOnMock invocation) -> {
+            final boolean connect = (Boolean) invocation.getArguments()[0];
+            // Simulates setConnection() called by another process.
+            if (needDelay) {
+                final Context context = ApplicationProvider.getApplicationContext();
+                context.getMainThreadHandler().postDelayed(
+                        () -> {
+                            mMagnificationConnectionManager.setConnection(
+                                    connect ? mMockConnection.getConnection() : null);
+                        }, 10);
+            } else {
+                mMagnificationConnectionManager.setConnection(
+                        connect ? mMockConnection.getConnection() : null);
+            }
+            return true;
+        }).when(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(anyBoolean());
+    }
+
+    @Test
+    public void setConnection_connectionIsNull_wrapperIsNullAndLinkToDeath() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        assertTrue(mMagnificationConnectionManager.isConnected());
+        verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0));
+    }
+
+    @Test
+    public void setConnection_connectionIsNull_setMirrorWindowCallbackAndHasWrapper()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+        assertTrue(mMagnificationConnectionManager.isConnected());
+        verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0));
+        verify(mMockConnection.getConnection()).setConnectionCallback(
+                any(IWindowMagnificationConnectionCallback.class));
+    }
+
+    @Test
+    public void binderDied_hasConnection_wrapperIsNullAndUnlinkToDeath() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+        mMockConnection.getDeathRecipient().binderDied();
+
+        assertFalse(mMagnificationConnectionManager.isConnected());
+        verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(),
+                0);
+    }
+
+    /**
+     * This test simulates {@link MagnificationConnectionManager#setConnection} is called by thread
+     * A and then the former connection is called by thread B. In this situation we should keep the
+     * new connection.
+     */
+    @Test
+    public void setSecondConnectionAndFormerConnectionBinderDead_hasWrapperAndNotCallUnlinkToDeath()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        MockWindowMagnificationConnection secondConnection =
+                new MockWindowMagnificationConnection();
+
+        mMagnificationConnectionManager.setConnection(secondConnection.getConnection());
+        mMockConnection.getDeathRecipient().binderDied();
+
+        assertTrue(mMagnificationConnectionManager.isConnected());
+        verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(), 0);
+        verify(secondConnection.asBinder(), never()).unlinkToDeath(
+                secondConnection.getDeathRecipient(), 0);
+    }
+
+    @Test
+    public void setNullConnection_hasConnection_wrapperIsNull() throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+        mMagnificationConnectionManager.setConnection(null);
+
+        assertFalse(mMagnificationConnectionManager.isConnected());
+        verify(mMockConnection.getConnection()).setConnectionCallback(null);
+    }
+
+    @Test
+    public void enableWithAnimation_hasConnection_enableWindowMagnification()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f);
+
+        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f),
+                eq(200f), eq(300f), eq(0f), eq(0f), notNull());
+    }
+
+    @Test
+    public void enableWithCallback_hasConnection_enableWindowMagnification()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f,
+                mAnimationCallback, SERVICE_ID);
+
+        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f),
+                eq(200f), eq(300f), eq(0f), eq(0f),
+                any(IRemoteMagnificationAnimationCallback.class));
+        verify(mAnimationCallback).onResult(true);
+    }
+
+    @Test
+    public void disable_hasConnectionAndEnabled_disableWindowMagnification()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
+
+        mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
+
+        verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY),
+                notNull());
+    }
+
+    @Test
+    public void disableWithCallback_hasConnectionAndEnabled_disableWindowMagnification()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
+
+        mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false,
+                mAnimationCallback);
+
+        verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY),
+                any(IRemoteMagnificationAnimationCallback.class));
+        verify(mAnimationCallback).onResult(true);
+    }
+
+    @Test
+    public void isWindowMagnifierEnabled_hasConnectionAndEnabled_returnExpectedValue() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN);
+
+        assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+    }
+
+    @Test
+    public void getPersistedScale() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+        assertEquals(mMagnificationConnectionManager.getPersistedScale(TEST_DISPLAY), 2.5f);
+    }
+
+    @Test
+    public void persistScale_setValue_expectedValueInProvider() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN);
+        mMagnificationConnectionManager.setScale(TEST_DISPLAY, 2.5f);
+
+        mMagnificationConnectionManager.persistScale(TEST_DISPLAY);
+
+        assertEquals(Settings.Secure.getFloatForUser(mResolver,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f,
+                CURRENT_USER_ID), 2.5f);
+    }
+
+    @Test
+    public void persistScale_setValueWhenScaleIsOne_nothingChanged() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        final float persistedScale =
+                mMagnificationConnectionManager.getPersistedScale(TEST_DISPLAY);
+
+        mMagnificationConnectionManager.setScale(TEST_DISPLAY, 1.0f);
+        mMagnificationConnectionManager.persistScale(TEST_DISPLAY);
+
+        assertEquals(Settings.Secure.getFloatForUser(mResolver,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f,
+                CURRENT_USER_ID), persistedScale);
+    }
+
+    @Test
+    public void scaleSetterGetter_enabledOnTestDisplay_expectedValue() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN);
+
+        mMagnificationConnectionManager.setScale(TEST_DISPLAY, 2.5f);
+
+        assertEquals(mMagnificationConnectionManager.getScale(TEST_DISPLAY), 2.5f);
+    }
+
+    @Test
+    public void scaleSetterGetter_scaleIsOutOfRang_getNormalizeValue() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN);
+
+        mMagnificationConnectionManager.setScale(TEST_DISPLAY, 10.0f);
+
+        assertEquals(mMagnificationConnectionManager.getScale(TEST_DISPLAY),
+                MagnificationScaleProvider.MAX_SCALE);
+    }
+
+    @FlakyTest(bugId = 297879435)
+    @Test
+    public void logTrackingTypingFocus_processScroll_logDuration() {
+        MagnificationConnectionManager spyMagnificationConnectionManager = spy(
+                mMagnificationConnectionManager);
+        spyMagnificationConnectionManager.enableWindowMagnification(
+                TEST_DISPLAY, 3.0f, 50f, 50f);
+        spyMagnificationConnectionManager.onImeWindowVisibilityChanged(
+                TEST_DISPLAY, /* shown */ true);
+
+        spyMagnificationConnectionManager.processScroll(TEST_DISPLAY, 10f, 10f);
+
+        verify(spyMagnificationConnectionManager).logTrackingTypingFocus(anyLong());
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnifier()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        final Region outRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+        final Rect requestedRect = outRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+        mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
+    }
+
+
+    @Test
+    public void onRectangleOnScreenRequested_trackingDisabledByScroll_withoutMovingMagnifier()
+            throws RemoteException {
+        final float distanceX = 10f;
+        final float distanceY = 10f;
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        final Region outRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+        final Rect requestedRect = outRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+        mMagnificationConnectionManager.processScroll(TEST_DISPLAY, distanceX, distanceY);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_requestRectangleInBound_withoutMovingMagnifier()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        final Region outRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+        final Rect requestedRect = outRegion.getBounds();
+        requestedRect.inset(-10, -10);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
+    }
+    @Test
+    public void onRectangleOnScreenRequested_imeVisibilityDefaultInvisible_withoutMovingMagnifier()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        final Region outRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+        final Rect requestedRect = outRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnifier()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        final Region outRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+        final Rect requestedRect = outRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
+                eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
+                any(IRemoteMagnificationAnimationCallback.class));
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_imeInvisible_withoutMovingMagnifier()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        final Region outRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+        final Rect requestedRect = outRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, false);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnifier()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        final Region outRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+        final Rect requestedRect = outRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
+                eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
+                any(IRemoteMagnificationAnimationCallback.class));
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnifier() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        final Region beforeRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
+        final Rect requestedRect = beforeRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+        mMagnificationConnectionManager.setMagnificationFollowTypingEnabled(false);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        final Region afterRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
+        assertEquals(afterRegion, beforeRegion);
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_trackingDisabled_withoutMovingMagnifier() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        mMagnificationConnectionManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
+        final Region beforeRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
+        final Rect requestedRect = beforeRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        final Region afterRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
+        assertEquals(afterRegion, beforeRegion);
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_trackingDisabledAndEnabledMagnifier_movingMagnifier()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mMagnificationConnectionManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        mMagnificationConnectionManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
+        final Region beforeRegion = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
+        final Rect requestedRect = beforeRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+        mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
+        // Enabling a window magnifier again will turn on the tracking typing focus functionality.
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, NaN, NaN, NaN);
+
+        mMagnificationConnectionManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
+                eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
+                any(IRemoteMagnificationAnimationCallback.class));
+    }
+
+    @Test
+    public void moveWindowMagnifier_enabled_invokeConnectionMethod() throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN);
+
+        mMagnificationConnectionManager.moveWindowMagnification(TEST_DISPLAY, 200, 300);
+        verify(mMockConnection.getConnection()).moveWindowMagnifier(TEST_DISPLAY, 200, 300);
+    }
+
+    @Test
+    public void showMagnificationButton_hasConnection_invokeConnectionMethod()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+        mMagnificationConnectionManager.showMagnificationButton(TEST_DISPLAY,
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+        verify(mMockConnection.getConnection()).showMagnificationButton(TEST_DISPLAY,
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+
+        mMagnificationConnectionManager.removeMagnificationButton(TEST_DISPLAY);
+        verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY);
+    }
+
+    @Test
+    public void removeMagnificationSettingsPanel_hasConnection_invokeConnectionMethod()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+        mMagnificationConnectionManager.removeMagnificationSettingsPanel(TEST_DISPLAY);
+        verify(mMockConnection.getConnection()).removeMagnificationSettingsPanel(TEST_DISPLAY);
+    }
+
+    @Test
+    public void onUserMagnificationScaleChanged_hasConnection_invokeConnectionMethod()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+        final float testScale = 3f;
+        mMagnificationConnectionManager.onUserMagnificationScaleChanged(
+                CURRENT_USER_ID, TEST_DISPLAY, testScale);
+        verify(mMockConnection.getConnection()).onUserMagnificationScaleChanged(
+                eq(CURRENT_USER_ID), eq(TEST_DISPLAY), eq(testScale));
+    }
+
+    @Test
+    public void pointersInWindow_magnifierEnabled_returnCorrectValue() throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+        mMockConnection.getConnectionCallback().onWindowMagnifierBoundsChanged(TEST_DISPLAY,
+                new Rect(0, 0, 500, 500));
+        PointF[] pointersLocation = new PointF[2];
+        pointersLocation[0] = new PointF(600, 700);
+        pointersLocation[1] = new PointF(300, 400);
+        MotionEvent event = generatePointersDownEvent(pointersLocation);
+
+        assertEquals(mMagnificationConnectionManager.pointersInWindow(TEST_DISPLAY, event), 1);
+    }
+
+    @Test
+    public void onPerformScaleAction_magnifierEnabled_notifyAction() throws RemoteException {
+        final float newScale = 4.0f;
+        final boolean updatePersistence = true;
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+
+        mMockConnection.getConnectionCallback().onPerformScaleAction(
+                TEST_DISPLAY, newScale, updatePersistence);
+
+        verify(mMockCallback).onPerformScaleAction(
+                eq(TEST_DISPLAY), eq(newScale), eq(updatePersistence));
+    }
+
+    @Test
+    public void onAccessibilityActionPerformed_magnifierEnabled_notifyAction()
+            throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+
+        mMockConnection.getConnectionCallback().onAccessibilityActionPerformed(TEST_DISPLAY);
+
+        verify(mMockCallback).onAccessibilityActionPerformed(eq(TEST_DISPLAY));
+    }
+
+    @Test
+    public void binderDied_windowMagnifierIsEnabled_resetState() throws RemoteException {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
+
+        mMockConnection.getDeathRecipient().binderDied();
+
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+    }
+
+    @Test
+    public void
+            requestConnectionToNull_disableAllMagnifiersAndRequestWindowMagnificationConnection()
+            throws RemoteException {
+        assertTrue(mMagnificationConnectionManager.requestConnection(true));
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
+
+        assertTrue(mMagnificationConnectionManager.requestConnection(false));
+
+        verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null);
+        verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(false);
+    }
+
+    @Test
+    public void requestConnection_requestWindowMagnificationConnection() throws RemoteException {
+        assertTrue(mMagnificationConnectionManager.requestConnection(true));
+        verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(true);
+    }
+
+    @Test
+    public void isConnected_requestConnection_expectedValue() throws RemoteException {
+        mMagnificationConnectionManager.requestConnection(true);
+        assertTrue(mMagnificationConnectionManager.isConnected());
+
+        mMagnificationConnectionManager.requestConnection(false);
+        assertFalse(mMagnificationConnectionManager.isConnected());
+    }
+
+    @Test
+    public void requestConnection_registerAndUnregisterBroadcastReceiver() {
+        assertTrue(mMagnificationConnectionManager.requestConnection(true));
+        verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
+
+        assertTrue(mMagnificationConnectionManager.requestConnection(false));
+        verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
+    }
+
+    @Test
+    public void requestConnectionToNull_expectedGetterResults() {
+        mMagnificationConnectionManager.requestConnection(true);
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1);
+
+        mMagnificationConnectionManager.requestConnection(false);
+
+        assertEquals(1f, mMagnificationConnectionManager.getScale(TEST_DISPLAY), 0);
+        assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY)));
+        assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY)));
+        final Region bounds = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds);
+        assertTrue(bounds.isEmpty());
+    }
+
+    @Test
+    public void enableWindowMagnification_connecting_invokeConnectionMethodAfterConnected()
+            throws RemoteException {
+        stubSetConnection(true);
+        mMagnificationConnectionManager.requestConnection(true);
+
+        assertTrue(mMagnificationConnectionManager.enableWindowMagnification(
+                TEST_DISPLAY, 3f, 1, 1));
+
+        // Invoke enableWindowMagnification if the connection is connected.
+        verify(mMockConnection.getConnection()).enableWindowMagnification(
+                eq(TEST_DISPLAY), eq(3f),
+                eq(1f), eq(1f), eq(0f), eq(0f), notNull());
+    }
+
+    @Test
+    public void resetAllMagnification_enabledBySameId_windowMagnifiersDisabled() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+                100f, 200f, null,
+                MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY_2, 3f,
+                100f, 200f, null,
+                MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
+        assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+        assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
+
+        mMagnificationConnectionManager.resetAllIfNeeded(SERVICE_ID);
+
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
+    }
+
+    @Test
+    public void resetAllMagnification_enabledByDifferentId_windowMagnifierDisabled() {
+        final int serviceId2 = SERVICE_ID + 1;
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+                100f, 200f, null,
+                MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY_2, 3f,
+                100f, 200f, null,
+                MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER, serviceId2);
+        assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+        assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
+
+        mMagnificationConnectionManager.resetAllIfNeeded(SERVICE_ID);
+
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+        assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
+    }
+
+    @Test
+    public void onScreenOff_windowMagnifierIsEnabled_removeButtonAndDisableWindowMagnification()
+            throws RemoteException {
+        mMagnificationConnectionManager.requestConnection(true);
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN);
+
+        mMagnificationConnectionManager.mScreenStateReceiver.onReceive(mContext,
+                new Intent(Intent.ACTION_SCREEN_OFF));
+
+        verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY);
+        verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null);
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+    }
+
+    @Test
+    public void centerGetter_enabledOnTestDisplay_expectedValues() {
+        mMagnificationConnectionManager.requestConnection(true);
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f);
+
+        assertEquals(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 100f);
+        assertEquals(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 200f);
+    }
+
+    @Test
+    public void centerGetter_enabledOnTestDisplayWindowAtCenter_expectedValues()
+            throws RemoteException {
+        mMagnificationConnectionManager.requestConnection(true);
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+                100f, 200f, MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER);
+
+        assertEquals(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 100f);
+        assertEquals(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 200f);
+
+        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f),
+                eq(100f), eq(200f), eq(0f), eq(0f), notNull());
+    }
+
+    @Test
+    public void centerGetter_enabledOnTestDisplayWindowAtLeftTop_expectedValues()
+            throws RemoteException {
+        mMagnificationConnectionManager.requestConnection(true);
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+                100f, 200f, MagnificationConnectionManager.WINDOW_POSITION_AT_TOP_LEFT);
+
+        assertEquals(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 100f);
+        assertEquals(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 200f);
+
+        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f),
+                eq(100f), eq(200f), eq(-1f), eq(-1f), notNull());
+    }
+
+    @Test
+    public void magnifierGetters_disabled_expectedValues() {
+        mMagnificationConnectionManager.requestConnection(true);
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f,
+                100f, 200f, MagnificationConnectionManager.WINDOW_POSITION_AT_CENTER);
+
+        mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
+
+        assertEquals(1f, mMagnificationConnectionManager.getScale(TEST_DISPLAY), 0);
+        assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterX(TEST_DISPLAY)));
+        assertTrue(Float.isNaN(mMagnificationConnectionManager.getCenterY(TEST_DISPLAY)));
+        final Region bounds = new Region();
+        mMagnificationConnectionManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds);
+        assertTrue(bounds.isEmpty());
+    }
+
+    @Test
+    public void onDisplayRemoved_enabledOnTestDisplay_disabled() {
+        mMagnificationConnectionManager.requestConnection(true);
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f);
+
+        mMagnificationConnectionManager.onDisplayRemoved(TEST_DISPLAY);
+
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+    }
+
+    @Test
+    public void onWindowMagnificationActivationState_magnifierEnabled_notifyActivatedState() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+
+        verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, true);
+    }
+
+    @Test
+    public void onWindowMagnificationActivationState_magnifierDisabled_notifyDeactivatedState() {
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
+        mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
+
+        verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, false);
+
+        Mockito.reset(mMockCallback);
+        mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
+
+        verify(mMockCallback, never()).onWindowMagnificationActivationState(eq(TEST_DISPLAY),
+                anyBoolean());
+    }
+
+    private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) {
+        final int len = pointersLocation.length;
+
+        final MotionEvent.PointerProperties[] pp = new MotionEvent.PointerProperties[len];
+        for (int i = 0; i < len; i++) {
+            MotionEvent.PointerProperties pointerProperty = new MotionEvent.PointerProperties();
+            pointerProperty.id = i;
+            pointerProperty.toolType = MotionEvent.TOOL_TYPE_FINGER;
+            pp[i] = pointerProperty;
+        }
+
+        final MotionEvent.PointerCoords[] pc = new MotionEvent.PointerCoords[len];
+        for (int i = 0; i < len; i++) {
+            MotionEvent.PointerCoords pointerCoord = new MotionEvent.PointerCoords();
+            pointerCoord.x = pointersLocation[i].x;
+            pointerCoord.y = pointersLocation[i].y;
+            pc[i] = pointerCoord;
+        }
+
+        return MotionEvent.obtain(
+                /* downTime */ SystemClock.uptimeMillis(),
+                /* eventTime */ SystemClock.uptimeMillis(),
+                /* action */ MotionEvent.ACTION_POINTER_DOWN,
+                /* pointerCount */ pc.length,
+                /* pointerProperties */ pp,
+                /* pointerCoords */ pc,
+                /* metaState */ 0,
+                /* buttonState */ 0,
+                /* xPrecision */ 1.0f,
+                /* yPrecision */ 1.0f,
+                /* deviceId */ 0,
+                /* edgeFlags */ 0,
+                /* source */ InputDevice.SOURCE_TOUCHSCREEN,
+                /* flags */ 0);
+    }
+
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java
index cfd0289..8f85f11 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java
@@ -39,7 +39,7 @@
 /**
  * Tests for MagnificationConnectionWrapper. We don't test {@code
  * MagnificationConnectionWrapper#linkToDeath(IBinder.DeathRecipient)} since it's tested in
- * {@link WindowMagnificationManagerTest}.
+ * {@link MagnificationConnectionManagerTest}.
  */
 public class MagnificationConnectionWrapperTest {
 
@@ -73,9 +73,9 @@
     }
 
     @Test
-    public void setScale() throws RemoteException {
-        mConnectionWrapper.setScale(TEST_DISPLAY, 3.0f);
-        verify(mConnection).setScale(TEST_DISPLAY, 3.0f);
+    public void setScaleForWindowMagnification() throws RemoteException {
+        mConnectionWrapper.setScaleForWindowMagnification(TEST_DISPLAY, 3.0f);
+        verify(mConnection).setScaleForWindowMagnification(TEST_DISPLAY, 3.0f);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index d4c6fad..e8cdf35 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -131,7 +131,7 @@
     private ArgumentCaptor<MagnificationAnimationCallback> mCallbackArgumentCaptor;
 
     private MockWindowMagnificationConnection mMockConnection;
-    private WindowMagnificationManager mWindowMagnificationManager;
+    private MagnificationConnectionManager mMagnificationConnectionManager;
     private MockContentResolver mMockResolver;
     private MagnificationController mMagnificationController;
     private final WindowMagnificationMgrCallbackDelegate
@@ -205,13 +205,14 @@
         ));
         mScreenMagnificationController.register(TEST_DISPLAY);
 
-        mWindowMagnificationManager = spy(new WindowMagnificationManager(mContext, globalLock,
-                mWindowMagnificationCallbackDelegate, mTraceManager, mScaleProvider));
+        mMagnificationConnectionManager = spy(
+                new MagnificationConnectionManager(mContext, globalLock,
+                        mWindowMagnificationCallbackDelegate, mTraceManager, mScaleProvider));
         mMockConnection = new MockWindowMagnificationConnection(true);
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
 
         mMagnificationController = spy(new MagnificationController(mService, globalLock, mContext,
-                mScreenMagnificationController, mWindowMagnificationManager, mScaleProvider,
+                mScreenMagnificationController, mMagnificationConnectionManager, mScaleProvider,
                 ConcurrentUtils.DIRECT_EXECUTOR));
         mMagnificationController.setMagnificationCapabilities(
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
@@ -254,8 +255,10 @@
         mCallbackArgumentCaptor.getValue().onResult(true);
         mMockConnection.invokeCallbacks();
         verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
-        assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0);
-        assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0);
+        assertEquals(MAGNIFIED_CENTER_X,
+                mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 0);
+        assertEquals(MAGNIFIED_CENTER_Y,
+                mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 0);
     }
 
     @Test
@@ -297,8 +300,10 @@
 
         mMockConnection.invokeCallbacks();
         verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
-        assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0);
-        assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0);
+        assertEquals(MAGNIFIED_CENTER_X,
+                mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 0);
+        assertEquals(MAGNIFIED_CENTER_Y,
+                mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 0);
     }
 
     @Test
@@ -316,7 +321,7 @@
         // The first time is triggered when window mode is activated.
         // The second time is triggered when activating the window mode again.
         // The third time is triggered when the transition is completed.
-        verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_WINDOW));
     }
 
@@ -330,7 +335,7 @@
                 mTransitionCallBack);
         mMockConnection.invokeCallbacks();
 
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
         verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY,
                 DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
                 true, MAGNIFICATION_GESTURE_HANDLER_ID);
@@ -350,7 +355,7 @@
                 mTransitionCallBack);
         mMockConnection.invokeCallbacks();
 
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
         verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE,
                 magnificationBounds.exactCenterX(), magnificationBounds.exactCenterY(), true,
                 MAGNIFICATION_GESTURE_HANDLER_ID);
@@ -386,11 +391,11 @@
                 mTransitionCallBack);
 
         // Enable window magnification while animating.
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE,
+        mMagnificationConnectionManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE,
                 Float.NaN, Float.NaN, null, TEST_SERVICE_ID);
         mMockConnection.invokeCallbacks();
 
-        assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+        assertTrue(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
         verify(mScreenMagnificationController, never()).setScaleAndCenter(TEST_DISPLAY,
                 DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
                 true, MAGNIFICATION_GESTURE_HANDLER_ID);
@@ -408,8 +413,10 @@
 
         verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY), eq(false));
         mMockConnection.invokeCallbacks();
-        assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0);
-        assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0);
+        assertEquals(MAGNIFIED_CENTER_X,
+                mMagnificationConnectionManager.getCenterX(TEST_DISPLAY), 0);
+        assertEquals(MAGNIFIED_CENTER_Y,
+                mMagnificationConnectionManager.getCenterY(TEST_DISPLAY), 0);
     }
 
     @Test
@@ -438,7 +445,7 @@
                 animate, TEST_SERVICE_ID);
         mMockConnection.invokeCallbacks();
 
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
         verify(mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY),
                 eq(DEFAULT_SCALE), eq(MAGNIFIED_CENTER_X), eq(MAGNIFIED_CENTER_Y),
                 any(MagnificationAnimationCallback.class), eq(TEST_SERVICE_ID));
@@ -564,7 +571,7 @@
         mMagnificationController.onDisplayRemoved(TEST_DISPLAY);
 
         verify(mScreenMagnificationController).onDisplayRemoved(TEST_DISPLAY);
-        verify(mWindowMagnificationManager).onDisplayRemoved(TEST_DISPLAY);
+        verify(mMagnificationConnectionManager).onDisplayRemoved(TEST_DISPLAY);
         verify(mScaleProvider).onDisplayRemoved(TEST_DISPLAY);
     }
 
@@ -573,7 +580,7 @@
         mMagnificationController.updateUserIdIfNeeded(SECOND_USER_ID);
 
         verify(mScreenMagnificationController).resetAllIfNeeded(false);
-        verify(mWindowMagnificationManager).disableAllWindowMagnifiers();
+        verify(mMagnificationConnectionManager).disableAllWindowMagnifiers();
         verify(mScaleProvider).onUserChanged(SECOND_USER_ID);
     }
 
@@ -584,7 +591,7 @@
         mMagnificationController.onRequestMagnificationSpec(TEST_DISPLAY, TEST_SERVICE_ID);
         mMockConnection.invokeCallbacks();
 
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
+        assertFalse(mMagnificationConnectionManager.isWindowMagnifierEnabled(TEST_DISPLAY));
     }
 
     @Test
@@ -594,11 +601,11 @@
 
         // The first time is trigger when fullscreen mode is activated.
         // The second time is triggered when magnification spec is changed.
-        verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_FULLSCREEN));
         // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
         // in current capability and mode, and the magnification is activated.
-        verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -625,8 +632,8 @@
 
         mMagnificationController.onPerformScaleAction(TEST_DISPLAY, newScale, updatePersistence);
 
-        verify(mWindowMagnificationManager).setScale(eq(TEST_DISPLAY), eq(newScale));
-        verify(mWindowMagnificationManager, never()).persistScale(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager).setScale(eq(TEST_DISPLAY), eq(newScale));
+        verify(mMagnificationConnectionManager, never()).persistScale(eq(TEST_DISPLAY));
     }
 
     @Test
@@ -669,7 +676,7 @@
         assertEquals(config.getCenterY(), actualConfig.getCenterY(), 0);
         assertEquals(config.getScale(), actualConfig.getScale(), 0);
 
-        verify(mWindowMagnificationManager).onUserMagnificationScaleChanged(
+        verify(mMagnificationConnectionManager).onUserMagnificationScaleChanged(
                 /* userId= */ anyInt(), eq(TEST_DISPLAY), eq(config.getScale()));
     }
 
@@ -677,11 +684,11 @@
     public void onSourceBoundChanged_windowEnabled_notifyMagnificationChanged()
             throws RemoteException {
         setMagnificationEnabled(MODE_WINDOW);
-        reset(mWindowMagnificationManager);
+        reset(mMagnificationConnectionManager);
 
         mMagnificationController.onSourceBoundsChanged(TEST_DISPLAY, TEST_RECT);
 
-        verify(mWindowMagnificationManager).onUserMagnificationScaleChanged(
+        verify(mMagnificationConnectionManager).onUserMagnificationScaleChanged(
                 /* userId= */ anyInt(), eq(TEST_DISPLAY), eq(DEFAULT_SCALE));
     }
 
@@ -780,11 +787,11 @@
 
         // The first time is triggered when window mode is activated.
         // The second time is triggered when accessibility action performed.
-        verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_WINDOW));
         // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
         // in current capability and mode, and the magnification is activated.
-        verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -799,10 +806,11 @@
 
         // The first time is triggered when window mode is activated.
         // The second time is triggered when accessibility action performed.
-        verify(mWindowMagnificationManager, times(2)).removeMagnificationButton(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager, times(2))
+                .removeMagnificationButton(eq(TEST_DISPLAY));
         // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
         // in current capability and mode, and the magnification is activated.
-        verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -816,7 +824,7 @@
     public void deactivateWindowMagnification_windowActivated_triggerCallbackAndLogUsage()
             throws RemoteException {
         setMagnificationEnabled(MODE_WINDOW);
-        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, /* clear= */ true);
+        mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, /* clear= */ true);
 
         verify(mMagnificationController).onWindowMagnificationActivationState(
                 eq(TEST_DISPLAY), eq(false));
@@ -828,7 +836,7 @@
     public void setPreferenceMagnificationFollowTypingEnabled_setPrefDisabled_disableAll() {
         mMagnificationController.setMagnificationFollowTypingEnabled(false);
 
-        verify(mWindowMagnificationManager).setMagnificationFollowTypingEnabled(eq(false));
+        verify(mMagnificationConnectionManager).setMagnificationFollowTypingEnabled(eq(false));
         verify(mScreenMagnificationController).setMagnificationFollowTypingEnabled(eq(false));
     }
 
@@ -850,7 +858,7 @@
 
         verify(mScreenMagnificationController).onRectangleOnScreenRequested(eq(TEST_DISPLAY),
                 eq(TEST_RECT.left), eq(TEST_RECT.top), eq(TEST_RECT.right), eq(TEST_RECT.bottom));
-        verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
+        verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(),
                 anyInt(), anyInt(), anyInt(), anyInt());
     }
 
@@ -867,7 +875,7 @@
 
         verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested(anyInt(),
                 anyInt(), anyInt(), anyInt(), anyInt());
-        verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
+        verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(),
                 anyInt(), anyInt(), anyInt(), anyInt());
     }
 
@@ -880,7 +888,7 @@
 
         verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested(
                 eq(TEST_DISPLAY), anyInt(), anyInt(), anyInt(), anyInt());
-        verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
+        verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(),
                 anyInt(), anyInt(), anyInt(), anyInt());
     }
 
@@ -895,7 +903,7 @@
 
         verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested(
                 eq(TEST_DISPLAY), anyInt(), anyInt(), anyInt(), anyInt());
-        verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
+        verify(mMagnificationConnectionManager, never()).onRectangleOnScreenRequested(anyInt(),
                 anyInt(), anyInt(), anyInt(), anyInt());
     }
 
@@ -970,7 +978,8 @@
 
         mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
 
-        verify(mWindowMagnificationManager).disableWindowMagnification(eq(TEST_DISPLAY), eq(false));
+        verify(mMagnificationConnectionManager)
+                .disableWindowMagnification(eq(TEST_DISPLAY), eq(false));
     }
 
     @Test
@@ -983,11 +992,11 @@
         // The first time is triggered when fullscreen mode is activated.
         // The second time is triggered when magnification spec is changed.
         // The third time is triggered when user interaction changed.
-        verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_FULLSCREEN));
         // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
         // in current capability and mode, and the magnification is activated.
-        verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -1001,11 +1010,11 @@
         // The first time is triggered when fullscreen mode is activated.
         // The second time is triggered when magnification spec is changed.
         // The third time is triggered when user interaction changed.
-        verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_FULLSCREEN));
         // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
         // in current capability and mode, and the magnification is activated.
-        verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -1018,11 +1027,11 @@
 
         // The first time is triggered when the window mode is activated.
         // The second time is triggered when user interaction changed.
-        verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_WINDOW));
         // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
         // in current capability and mode, and the magnification is activated.
-        verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -1035,11 +1044,11 @@
 
         // The first time is triggered when the window mode is activated.
         // The second time is triggered when user interaction changed.
-        verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_WINDOW));
         // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
         // in current capability and mode, and the magnification is activated.
-        verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -1053,11 +1062,11 @@
         mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN);
         mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN);
 
-        verify(mWindowMagnificationManager, never()).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, never()).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_FULLSCREEN));
         // The first time is triggered when fullscreen mode is activated.
         // The second time is triggered when magnification spec is changed.
-        verify(mWindowMagnificationManager, times(2)).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, times(2)).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -1071,9 +1080,9 @@
         mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN);
         mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN);
 
-        verify(mWindowMagnificationManager, never()).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, never()).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_FULLSCREEN));
-        verify(mWindowMagnificationManager, times(2)).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, times(2)).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -1082,11 +1091,11 @@
             throws RemoteException {
         setMagnificationEnabled(MODE_WINDOW);
 
-        verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_WINDOW));
         // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
         // in current capability and mode, and the magnification is activated.
-        verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -1100,11 +1109,11 @@
         // The first time is triggered when fullscreen mode is activated.
         // The second time is triggered when magnification spec is changed.
         // The third time is triggered when fullscreen mode activation state is updated.
-        verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_FULLSCREEN));
         // Never call removeMagnificationSettingsPanel if it is allowed to show the settings panel
         // in current capability and mode, and the magnification is activated.
-        verify(mWindowMagnificationManager, never()).removeMagnificationSettingsPanel(
+        verify(mMagnificationConnectionManager, never()).removeMagnificationSettingsPanel(
                 eq(TEST_DISPLAY));
     }
 
@@ -1113,10 +1122,10 @@
             throws RemoteException {
         setMagnificationEnabled(MODE_WINDOW);
 
-        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+        mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
 
-        verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
-        verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager).removeMagnificationButton(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
     }
 
     @Test
@@ -1126,8 +1135,8 @@
         setMagnificationEnabled(MODE_FULLSCREEN);
         mScreenMagnificationController.reset(TEST_DISPLAY, /* animate= */ true);
 
-        verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
-        verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager).removeMagnificationButton(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
     }
 
     @Test
@@ -1142,10 +1151,10 @@
         // The first time is triggered when fullscreen mode is activated.
         // The second time is triggered when magnification spec is changed.
         // The third time is triggered when the disable-magnification callback is triggered.
-        verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_FULLSCREEN));
         // It is triggered when the disable-magnification callback is triggered.
-        verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
     }
 
     @Test
@@ -1163,10 +1172,10 @@
 
         // The first time is triggered when window mode is activated.
         // The second time is triggered when the disable-magnification callback is triggered.
-        verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
+        verify(mMagnificationConnectionManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
                 eq(MODE_WINDOW));
         // It is triggered when the disable-magnification callback is triggered.
-        verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
     }
 
     @Test
@@ -1174,9 +1183,9 @@
             throws RemoteException {
         setMagnificationEnabled(MODE_WINDOW);
 
-        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+        mMagnificationConnectionManager.disableWindowMagnification(TEST_DISPLAY, false);
 
-        verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
     }
 
     @Test
@@ -1185,7 +1194,7 @@
         setMagnificationEnabled(MODE_FULLSCREEN);
         mScreenMagnificationController.reset(TEST_DISPLAY, /* animate= */ true);
 
-        verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+        verify(mMagnificationConnectionManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
     }
 
     @Test
@@ -1260,17 +1269,17 @@
 
     private void activateMagnifier(int displayId, int mode, float centerX, float centerY)
             throws RemoteException {
-        final boolean windowMagnifying = mWindowMagnificationManager.isWindowMagnifierEnabled(
+        final boolean windowMagnifying = mMagnificationConnectionManager.isWindowMagnifierEnabled(
                 displayId);
         if (windowMagnifying) {
-            mWindowMagnificationManager.disableWindowMagnification(displayId, false);
+            mMagnificationConnectionManager.disableWindowMagnification(displayId, false);
             mMockConnection.invokeCallbacks();
         }
         if (mode == MODE_FULLSCREEN) {
             mScreenMagnificationController.setScaleAndCenter(displayId, DEFAULT_SCALE, centerX,
                     centerY, true, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
         } else {
-            mWindowMagnificationManager.enableWindowMagnification(displayId, DEFAULT_SCALE,
+            mMagnificationConnectionManager.enableWindowMagnification(displayId, DEFAULT_SCALE,
                     centerX, centerY, null, TEST_SERVICE_ID);
             mMockConnection.invokeCallbacks();
         }
@@ -1304,10 +1313,10 @@
     }
 
     private static class WindowMagnificationMgrCallbackDelegate implements
-            WindowMagnificationManager.Callback {
-        private WindowMagnificationManager.Callback mCallback;
+            MagnificationConnectionManager.Callback {
+        private MagnificationConnectionManager.Callback mCallback;
 
-        public void setDelegate(WindowMagnificationManager.Callback callback) {
+        public void setDelegate(MagnificationConnectionManager.Callback callback) {
             mCallback = callback;
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
index 612a091..c4be51f 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
@@ -92,7 +92,7 @@
     public final TestableContext mContext = new TestableContext(
             InstrumentationRegistry.getInstrumentation().getContext());
 
-    private WindowMagnificationManager mWindowMagnificationManager;
+    private MagnificationConnectionManager mMagnificationConnectionManager;
     private MockWindowMagnificationConnection mMockConnection;
     private SpyWindowMagnificationGestureHandler mWindowMagnificationGestureHandler;
     private WindowMagnificationGestureHandler mMockWindowMagnificationGestureHandler;
@@ -104,23 +104,23 @@
     @Before
     public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
-        mWindowMagnificationManager = new WindowMagnificationManager(mContext, new Object(),
-                mock(WindowMagnificationManager.Callback.class), mMockTrace,
+        mMagnificationConnectionManager = new MagnificationConnectionManager(mContext, new Object(),
+                mock(MagnificationConnectionManager.Callback.class), mMockTrace,
                 new MagnificationScaleProvider(mContext));
         mMockConnection = new MockWindowMagnificationConnection();
         mWindowMagnificationGestureHandler = new SpyWindowMagnificationGestureHandler(
-                mContext, mWindowMagnificationManager, mMockTrace, mMockCallback,
+                mContext, mMagnificationConnectionManager, mMockTrace, mMockCallback,
                 /** detectSingleFingerTripleTap= */ true, /** detectTwoFingerTripleTap= */ true,
                 /** detectShortcutTrigger= */ true, DISPLAY_0);
         mMockWindowMagnificationGestureHandler =
                 mWindowMagnificationGestureHandler.getMockGestureHandler();
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationGestureHandler.setNext(strictMock(EventStreamTransformation.class));
     }
 
     @After
     public void tearDown() {
-        mWindowMagnificationManager.disableWindowMagnification(DISPLAY_0, true);
+        mMagnificationConnectionManager.disableWindowMagnification(DISPLAY_0, true);
     }
 
     @Test
@@ -378,7 +378,7 @@
             }
             break;
             case STATE_SHOW_MAGNIFIER_SHORTCUT: {
-                mWindowMagnificationManager.disableWindowMagnification(DISPLAY_0, false);
+                mMagnificationConnectionManager.disableWindowMagnification(DISPLAY_0, false);
             }
             break;
             case STATE_TWO_FINGERS_DOWN: {
@@ -423,7 +423,7 @@
     }
 
     private boolean isWindowMagnifierEnabled(int displayId) {
-        return mWindowMagnificationManager.isWindowMagnifierEnabled(displayId);
+        return mMagnificationConnectionManager.isWindowMagnifierEnabled(displayId);
     }
 
     private static String stateToString(int state) {
@@ -495,13 +495,14 @@
         private final WindowMagnificationGestureHandler mMockWindowMagnificationGestureHandler;
 
         SpyWindowMagnificationGestureHandler(@UiContext Context context,
-                WindowMagnificationManager windowMagnificationMgr,
+                MagnificationConnectionManager magnificationConnectionManager,
                 AccessibilityTraceManager trace,
                 Callback callback,
                 boolean detectSingleFingerTripleTap, boolean detectTwoFingerTripleTap,
                 boolean detectShortcutTrigger, int displayId) {
-            super(context, windowMagnificationMgr, trace, callback, detectSingleFingerTripleTap,
-                    detectTwoFingerTripleTap, detectShortcutTrigger, displayId);
+            super(context, magnificationConnectionManager, trace, callback,
+                    detectSingleFingerTripleTap, detectTwoFingerTripleTap,
+                    detectShortcutTrigger, displayId);
             mMockWindowMagnificationGestureHandler = mock(WindowMagnificationGestureHandler.class);
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
deleted file mode 100644
index 24ad976..0000000
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.accessibility.magnification;
-
-import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY;
-import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY_2;
-
-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.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.notNull;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
-import static java.lang.Float.NaN;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.test.mock.MockContentResolver;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.accessibility.IRemoteMagnificationAnimationCallback;
-import android.view.accessibility.IWindowMagnificationConnectionCallback;
-import android.view.accessibility.MagnificationAnimationCallback;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.FlakyTest;
-
-import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.server.LocalServices;
-import com.android.server.accessibility.AccessibilityTraceManager;
-import com.android.server.statusbar.StatusBarManagerInternal;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-
-/**
- * Tests for WindowMagnificationManager.
- */
-public class WindowMagnificationManagerTest {
-
-    private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM;
-    private static final int SERVICE_ID = 1;
-
-    private MockWindowMagnificationConnection mMockConnection;
-    @Mock
-    private Context mContext;
-    @Mock
-    private AccessibilityTraceManager mMockTrace;
-    @Mock
-    private StatusBarManagerInternal mMockStatusBarManagerInternal;
-    @Mock
-    private MagnificationAnimationCallback mAnimationCallback;
-    @Mock
-    private WindowMagnificationManager.Callback mMockCallback;
-    private MockContentResolver mResolver;
-    private WindowMagnificationManager mWindowMagnificationManager;
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
-        LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal);
-        mResolver = new MockContentResolver();
-        mMockConnection = new MockWindowMagnificationConnection();
-        mWindowMagnificationManager = new WindowMagnificationManager(mContext, new Object(),
-                mMockCallback, mMockTrace, new MagnificationScaleProvider(mContext));
-
-        when(mContext.getContentResolver()).thenReturn(mResolver);
-        stubSetConnection(false);
-
-        mResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
-        Settings.Secure.putFloatForUser(mResolver,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.5f,
-                CURRENT_USER_ID);
-    }
-
-    private void stubSetConnection(boolean needDelay) {
-        doAnswer((InvocationOnMock invocation) -> {
-            final boolean connect = (Boolean) invocation.getArguments()[0];
-            // Simulates setConnection() called by another process.
-            if (needDelay) {
-                final Context context = ApplicationProvider.getApplicationContext();
-                context.getMainThreadHandler().postDelayed(
-                        () -> {
-                            mWindowMagnificationManager.setConnection(
-                                    connect ? mMockConnection.getConnection() : null);
-                        }, 10);
-            } else {
-                mWindowMagnificationManager.setConnection(
-                        connect ? mMockConnection.getConnection() : null);
-            }
-            return true;
-        }).when(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(anyBoolean());
-    }
-
-    @Test
-    public void setConnection_connectionIsNull_wrapperIsNullAndLinkToDeath() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        assertNotNull(mWindowMagnificationManager.mConnectionWrapper);
-        verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0));
-    }
-
-    @Test
-    public void setConnection_connectionIsNull_setMirrorWindowCallbackAndHasWrapper()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-
-        assertNotNull(mWindowMagnificationManager.mConnectionWrapper);
-        verify(mMockConnection.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0));
-        verify(mMockConnection.getConnection()).setConnectionCallback(
-                any(IWindowMagnificationConnectionCallback.class));
-    }
-
-    @Test
-    public void binderDied_hasConnection_wrapperIsNullAndUnlinkToDeath() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-
-        mMockConnection.getDeathRecipient().binderDied();
-
-        assertNull(mWindowMagnificationManager.mConnectionWrapper);
-        verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(),
-                0);
-    }
-
-    /**
-     * This test simulates {@link WindowMagnificationManager#setConnection} is called by thread A
-     * and then the former connection is called by thread B. In this situation we should keep the
-     * new connection.
-     */
-    @Test
-    public void setSecondConnectionAndFormerConnectionBinderDead_hasWrapperAndNotCallUnlinkToDeath()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        MockWindowMagnificationConnection secondConnection =
-                new MockWindowMagnificationConnection();
-
-        mWindowMagnificationManager.setConnection(secondConnection.getConnection());
-        mMockConnection.getDeathRecipient().binderDied();
-
-        assertNotNull(mWindowMagnificationManager.mConnectionWrapper);
-        verify(mMockConnection.asBinder()).unlinkToDeath(mMockConnection.getDeathRecipient(), 0);
-        verify(secondConnection.asBinder(), never()).unlinkToDeath(
-                secondConnection.getDeathRecipient(), 0);
-    }
-
-    @Test
-    public void setNullConnection_hasConnection_wrapperIsNull() throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-
-        mWindowMagnificationManager.setConnection(null);
-
-        assertNull(mWindowMagnificationManager.mConnectionWrapper);
-        verify(mMockConnection.getConnection()).setConnectionCallback(null);
-    }
-
-    @Test
-    public void enableWithAnimation_hasConnection_enableWindowMagnification()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f);
-
-        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f),
-                eq(200f), eq(300f), eq(0f), eq(0f), notNull());
-    }
-
-    @Test
-    public void enableWithCallback_hasConnection_enableWindowMagnification()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f,
-                mAnimationCallback, SERVICE_ID);
-
-        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f),
-                eq(200f), eq(300f), eq(0f), eq(0f),
-                any(IRemoteMagnificationAnimationCallback.class));
-        verify(mAnimationCallback).onResult(true);
-    }
-
-    @Test
-    public void disable_hasConnectionAndEnabled_disableWindowMagnification()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
-
-        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
-
-        verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY),
-                notNull());
-    }
-
-    @Test
-    public void disableWithCallback_hasConnectionAndEnabled_disableWindowMagnification()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
-
-        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false,
-                mAnimationCallback);
-
-        verify(mMockConnection.getConnection()).disableWindowMagnification(eq(TEST_DISPLAY),
-                any(IRemoteMagnificationAnimationCallback.class));
-        verify(mAnimationCallback).onResult(true);
-    }
-
-    @Test
-    public void isWindowMagnifierEnabled_hasConnectionAndEnabled_returnExpectedValue() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
-
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN);
-
-        assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
-    }
-
-    @Test
-    public void getPersistedScale() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-
-        assertEquals(mWindowMagnificationManager.getPersistedScale(TEST_DISPLAY), 2.5f);
-    }
-
-    @Test
-    public void persistScale_setValue_expectedValueInProvider() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN);
-        mWindowMagnificationManager.setScale(TEST_DISPLAY, 2.5f);
-
-        mWindowMagnificationManager.persistScale(TEST_DISPLAY);
-
-        assertEquals(Settings.Secure.getFloatForUser(mResolver,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f,
-                CURRENT_USER_ID), 2.5f);
-    }
-
-    @Test
-    public void persistScale_setValueWhenScaleIsOne_nothingChanged() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        final float persistedScale = mWindowMagnificationManager.getPersistedScale(TEST_DISPLAY);
-
-        mWindowMagnificationManager.setScale(TEST_DISPLAY, 1.0f);
-        mWindowMagnificationManager.persistScale(TEST_DISPLAY);
-
-        assertEquals(Settings.Secure.getFloatForUser(mResolver,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f,
-                CURRENT_USER_ID), persistedScale);
-    }
-
-    @Test
-    public void scaleSetterGetter_enabledOnTestDisplay_expectedValue() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN);
-
-        mWindowMagnificationManager.setScale(TEST_DISPLAY, 2.5f);
-
-        assertEquals(mWindowMagnificationManager.getScale(TEST_DISPLAY), 2.5f);
-    }
-
-    @Test
-    public void scaleSetterGetter_scaleIsOutOfRang_getNormalizeValue() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN);
-
-        mWindowMagnificationManager.setScale(TEST_DISPLAY, 10.0f);
-
-        assertEquals(mWindowMagnificationManager.getScale(TEST_DISPLAY),
-                MagnificationScaleProvider.MAX_SCALE);
-    }
-
-    @FlakyTest(bugId = 297879435)
-    @Test
-    public void logTrackingTypingFocus_processScroll_logDuration() {
-        WindowMagnificationManager spyWindowMagnificationManager = spy(mWindowMagnificationManager);
-        spyWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        spyWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, /* shown */ true);
-
-        spyWindowMagnificationManager.processScroll(TEST_DISPLAY, 10f, 10f);
-
-        verify(spyWindowMagnificationManager).logTrackingTypingFocus(anyLong());
-    }
-
-    @Test
-    public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnifier()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        final Region outRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
-        final Rect requestedRect = outRegion.getBounds();
-        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-        mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        verify(mMockConnection.getConnection(), never())
-                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
-    }
-
-
-    @Test
-    public void onRectangleOnScreenRequested_trackingDisabledByScroll_withoutMovingMagnifier()
-            throws RemoteException {
-        final float distanceX = 10f;
-        final float distanceY = 10f;
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        final Region outRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
-        final Rect requestedRect = outRegion.getBounds();
-        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-        mWindowMagnificationManager.processScroll(TEST_DISPLAY, distanceX, distanceY);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        verify(mMockConnection.getConnection(), never())
-                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
-    }
-
-    @Test
-    public void onRectangleOnScreenRequested_requestRectangleInBound_withoutMovingMagnifier()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        final Region outRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
-        final Rect requestedRect = outRegion.getBounds();
-        requestedRect.inset(-10, -10);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        verify(mMockConnection.getConnection(), never())
-                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
-    }
-    @Test
-    public void onRectangleOnScreenRequested_imeVisibilityDefaultInvisible_withoutMovingMagnifier()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        final Region outRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
-        final Rect requestedRect = outRegion.getBounds();
-        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        verify(mMockConnection.getConnection(), never())
-                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
-    }
-
-    @Test
-    public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnifier()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        final Region outRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
-        final Rect requestedRect = outRegion.getBounds();
-        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
-                eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
-                any(IRemoteMagnificationAnimationCallback.class));
-    }
-
-    @Test
-    public void onRectangleOnScreenRequested_imeInvisible_withoutMovingMagnifier()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        final Region outRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
-        final Rect requestedRect = outRegion.getBounds();
-        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, false);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        verify(mMockConnection.getConnection(), never())
-                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
-    }
-
-    @Test
-    public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnifier()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        final Region outRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
-        final Rect requestedRect = outRegion.getBounds();
-        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
-                eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
-                any(IRemoteMagnificationAnimationCallback.class));
-    }
-
-    @Test
-    public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnifier() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        final Region beforeRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
-        final Rect requestedRect = beforeRegion.getBounds();
-        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-        mWindowMagnificationManager.setMagnificationFollowTypingEnabled(false);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        final Region afterRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
-        assertEquals(afterRegion, beforeRegion);
-    }
-
-    @Test
-    public void onRectangleOnScreenRequested_trackingDisabled_withoutMovingMagnifier() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
-        final Region beforeRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
-        final Rect requestedRect = beforeRegion.getBounds();
-        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        final Region afterRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
-        assertEquals(afterRegion, beforeRegion);
-    }
-
-    @Test
-    public void onRectangleOnScreenRequested_trackingDisabledAndEnabledMagnifier_movingMagnifier()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
-        mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
-        final Region beforeRegion = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
-        final Rect requestedRect = beforeRegion.getBounds();
-        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
-        // Enabling a window magnifier again will turn on the tracking typing focus functionality.
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, NaN, NaN, NaN);
-
-        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
-                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
-
-        verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
-                eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
-                any(IRemoteMagnificationAnimationCallback.class));
-    }
-
-    @Test
-    public void moveWindowMagnifier_enabled_invokeConnectionMethod() throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN);
-
-        mWindowMagnificationManager.moveWindowMagnification(TEST_DISPLAY, 200, 300);
-        verify(mMockConnection.getConnection()).moveWindowMagnifier(TEST_DISPLAY, 200, 300);
-    }
-
-    @Test
-    public void showMagnificationButton_hasConnection_invokeConnectionMethod()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-
-        mWindowMagnificationManager.showMagnificationButton(TEST_DISPLAY,
-                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-        verify(mMockConnection.getConnection()).showMagnificationButton(TEST_DISPLAY,
-                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-
-        mWindowMagnificationManager.removeMagnificationButton(TEST_DISPLAY);
-        verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY);
-    }
-
-    @Test
-    public void removeMagnificationSettingsPanel_hasConnection_invokeConnectionMethod()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-
-        mWindowMagnificationManager.removeMagnificationSettingsPanel(TEST_DISPLAY);
-        verify(mMockConnection.getConnection()).removeMagnificationSettingsPanel(TEST_DISPLAY);
-    }
-
-    @Test
-    public void onUserMagnificationScaleChanged_hasConnection_invokeConnectionMethod()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-
-        final float testScale = 3f;
-        mWindowMagnificationManager.onUserMagnificationScaleChanged(
-                CURRENT_USER_ID, TEST_DISPLAY, testScale);
-        verify(mMockConnection.getConnection()).onUserMagnificationScaleChanged(
-                eq(CURRENT_USER_ID), eq(TEST_DISPLAY), eq(testScale));
-    }
-
-    @Test
-    public void pointersInWindow_magnifierEnabled_returnCorrectValue() throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
-        mMockConnection.getConnectionCallback().onWindowMagnifierBoundsChanged(TEST_DISPLAY,
-                new Rect(0, 0, 500, 500));
-        PointF[] pointersLocation = new PointF[2];
-        pointersLocation[0] = new PointF(600, 700);
-        pointersLocation[1] = new PointF(300, 400);
-        MotionEvent event = generatePointersDownEvent(pointersLocation);
-
-        assertEquals(mWindowMagnificationManager.pointersInWindow(TEST_DISPLAY, event), 1);
-    }
-
-    @Test
-    public void onPerformScaleAction_magnifierEnabled_notifyAction() throws RemoteException {
-        final float newScale = 4.0f;
-        final boolean updatePersistence = true;
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
-
-        mMockConnection.getConnectionCallback().onPerformScaleAction(
-                TEST_DISPLAY, newScale, updatePersistence);
-
-        verify(mMockCallback).onPerformScaleAction(
-                eq(TEST_DISPLAY), eq(newScale), eq(updatePersistence));
-    }
-
-    @Test
-    public void onAccessibilityActionPerformed_magnifierEnabled_notifyAction()
-            throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
-
-        mMockConnection.getConnectionCallback().onAccessibilityActionPerformed(TEST_DISPLAY);
-
-        verify(mMockCallback).onAccessibilityActionPerformed(eq(TEST_DISPLAY));
-    }
-
-    @Test
-    public void binderDied_windowMagnifierIsEnabled_resetState() throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
-
-        mMockConnection.getDeathRecipient().binderDied();
-
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
-    }
-
-    @Test
-    public void
-            requestConnectionToNull_disableAllMagnifiersAndRequestWindowMagnificationConnection()
-            throws RemoteException {
-        assertTrue(mWindowMagnificationManager.requestConnection(true));
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
-
-        assertTrue(mWindowMagnificationManager.requestConnection(false));
-
-        verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null);
-        verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(false);
-    }
-
-    @Test
-    public void requestConnection_requestWindowMagnificationConnection() throws RemoteException {
-        assertTrue(mWindowMagnificationManager.requestConnection(true));
-        verify(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(true);
-    }
-
-    @Test
-    public void isConnected_requestConnection_expectedValue() throws RemoteException {
-        mWindowMagnificationManager.requestConnection(true);
-        assertTrue(mWindowMagnificationManager.isConnected());
-
-        mWindowMagnificationManager.requestConnection(false);
-        assertFalse(mWindowMagnificationManager.isConnected());
-    }
-
-    @Test
-    public void requestConnection_registerAndUnregisterBroadcastReceiver() {
-        assertTrue(mWindowMagnificationManager.requestConnection(true));
-        verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
-
-        assertTrue(mWindowMagnificationManager.requestConnection(false));
-        verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
-    }
-
-    @Test
-    public void requestConnectionToNull_expectedGetterResults() {
-        mWindowMagnificationManager.requestConnection(true);
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1);
-
-        mWindowMagnificationManager.requestConnection(false);
-
-        assertEquals(1f, mWindowMagnificationManager.getScale(TEST_DISPLAY), 0);
-        assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterX(TEST_DISPLAY)));
-        assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterY(TEST_DISPLAY)));
-        final Region bounds = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds);
-        assertTrue(bounds.isEmpty());
-    }
-
-    @Test
-    public void enableWindowMagnification_connecting_invokeConnectionMethodAfterConnected()
-            throws RemoteException {
-        stubSetConnection(true);
-        mWindowMagnificationManager.requestConnection(true);
-
-        assertTrue(mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1));
-
-        // Invoke enableWindowMagnification if the connection is connected.
-        verify(mMockConnection.getConnection()).enableWindowMagnification(
-                eq(TEST_DISPLAY), eq(3f),
-                eq(1f), eq(1f), eq(0f), eq(0f), notNull());
-    }
-
-    @Test
-    public void resetAllMagnification_enabledBySameId_windowMagnifiersDisabled() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
-                100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY_2, 3f,
-                100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
-        assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
-        assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
-
-        mWindowMagnificationManager.resetAllIfNeeded(SERVICE_ID);
-
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
-    }
-
-    @Test
-    public void resetAllMagnification_enabledByDifferentId_windowMagnifierDisabled() {
-        final int serviceId2 = SERVICE_ID + 1;
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
-                100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID);
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY_2, 3f,
-                100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, serviceId2);
-        assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
-        assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
-
-        mWindowMagnificationManager.resetAllIfNeeded(SERVICE_ID);
-
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
-        assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2));
-    }
-
-    @Test
-    public void onScreenOff_windowMagnifierIsEnabled_removeButtonAndDisableWindowMagnification()
-            throws RemoteException {
-        mWindowMagnificationManager.requestConnection(true);
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.5f, NaN, NaN);
-
-        mWindowMagnificationManager.mScreenStateReceiver.onReceive(mContext,
-                new Intent(Intent.ACTION_SCREEN_OFF));
-
-        verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY);
-        verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY, null);
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
-    }
-
-    @Test
-    public void centerGetter_enabledOnTestDisplay_expectedValues() {
-        mWindowMagnificationManager.requestConnection(true);
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f);
-
-        assertEquals(mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 100f);
-        assertEquals(mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 200f);
-    }
-
-    @Test
-    public void centerGetter_enabledOnTestDisplayWindowAtCenter_expectedValues()
-            throws RemoteException {
-        mWindowMagnificationManager.requestConnection(true);
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
-                100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER);
-
-        assertEquals(mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 100f);
-        assertEquals(mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 200f);
-
-        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f),
-                eq(100f), eq(200f), eq(0f), eq(0f), notNull());
-    }
-
-    @Test
-    public void centerGetter_enabledOnTestDisplayWindowAtLeftTop_expectedValues()
-            throws RemoteException {
-        mWindowMagnificationManager.requestConnection(true);
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
-                100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_TOP_LEFT);
-
-        assertEquals(mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 100f);
-        assertEquals(mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 200f);
-
-        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f),
-                eq(100f), eq(200f), eq(-1f), eq(-1f), notNull());
-    }
-
-    @Test
-    public void magnifierGetters_disabled_expectedValues() {
-        mWindowMagnificationManager.requestConnection(true);
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
-                100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER);
-
-        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
-
-        assertEquals(1f, mWindowMagnificationManager.getScale(TEST_DISPLAY), 0);
-        assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterX(TEST_DISPLAY)));
-        assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterY(TEST_DISPLAY)));
-        final Region bounds = new Region();
-        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds);
-        assertTrue(bounds.isEmpty());
-    }
-
-    @Test
-    public void onDisplayRemoved_enabledOnTestDisplay_disabled() {
-        mWindowMagnificationManager.requestConnection(true);
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 100f, 200f);
-
-        mWindowMagnificationManager.onDisplayRemoved(TEST_DISPLAY);
-
-        assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
-    }
-
-    @Test
-    public void onWindowMagnificationActivationState_magnifierEnabled_notifyActivatedState() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
-
-        verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, true);
-    }
-
-    @Test
-    public void onWindowMagnificationActivationState_magnifierDisabled_notifyDeactivatedState() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
-        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
-
-        verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, false);
-
-        Mockito.reset(mMockCallback);
-        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
-
-        verify(mMockCallback, never()).onWindowMagnificationActivationState(eq(TEST_DISPLAY),
-                anyBoolean());
-    }
-
-    private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) {
-        final int len = pointersLocation.length;
-
-        final MotionEvent.PointerProperties[] pp = new MotionEvent.PointerProperties[len];
-        for (int i = 0; i < len; i++) {
-            MotionEvent.PointerProperties pointerProperty = new MotionEvent.PointerProperties();
-            pointerProperty.id = i;
-            pointerProperty.toolType = MotionEvent.TOOL_TYPE_FINGER;
-            pp[i] = pointerProperty;
-        }
-
-        final MotionEvent.PointerCoords[] pc = new MotionEvent.PointerCoords[len];
-        for (int i = 0; i < len; i++) {
-            MotionEvent.PointerCoords pointerCoord = new MotionEvent.PointerCoords();
-            pointerCoord.x = pointersLocation[i].x;
-            pointerCoord.y = pointersLocation[i].y;
-            pc[i] = pointerCoord;
-        }
-
-        return MotionEvent.obtain(
-                /* downTime */ SystemClock.uptimeMillis(),
-                /* eventTime */ SystemClock.uptimeMillis(),
-                /* action */ MotionEvent.ACTION_POINTER_DOWN,
-                /* pointerCount */ pc.length,
-                /* pointerProperties */ pp,
-                /* pointerCoords */ pc,
-                /* metaState */ 0,
-                /* buttonState */ 0,
-                /* xPrecision */ 1.0f,
-                /* yPrecision */ 1.0f,
-                /* deviceId */ 0,
-                /* edgeFlags */ 0,
-                /* source */ InputDevice.SOURCE_TOUCHSCREEN,
-                /* flags */ 0);
-    }
-
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java
index 749b07d..9c8276a 100644
--- a/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/LoudnessCodecHelperTest.java
@@ -19,6 +19,16 @@
 import static android.media.AudioPlaybackConfiguration.PLAYER_UPDATE_DEVICE_ID;
 import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_4;
 import static android.media.LoudnessCodecInfo.CodecMetadataType.CODEC_METADATA_TYPE_MPEG_D;
+import static android.media.MediaFormat.KEY_AAC_DRC_EFFECT_TYPE;
+import static android.media.MediaFormat.KEY_AAC_DRC_HEAVY_COMPRESSION;
+import static android.media.MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL;
+
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_LARGE;
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_MEDIUM;
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_SMALL;
+import static com.android.server.audio.LoudnessCodecHelper.SPL_RANGE_UNKNOWN;
+
+import static junit.framework.Assert.assertEquals;
 
 import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -34,11 +44,15 @@
 import android.media.LoudnessCodecInfo;
 import android.media.PlayerBase;
 import android.os.IBinder;
+import android.os.PersistableBundle;
 import android.platform.test.annotations.Presubmit;
 import android.util.Log;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.server.audio.LoudnessCodecHelper.DeviceSplRange;
+import com.android.server.audio.LoudnessCodecHelper.LoudnessCodecInputProperties;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -84,8 +98,7 @@
         mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
 
         mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
-                List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true,
-                        CODEC_METADATA_TYPE_MPEG_4)));
+                List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4)));
 
         verify(mDispatcher).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid), any());
     }
@@ -96,8 +109,7 @@
         mLoudnessHelper.unregisterLoudnessCodecUpdatesDispatcher(mDispatcher);
 
         mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
-                List.of(getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/false,
-                        CODEC_METADATA_TYPE_MPEG_D)));
+                List.of(getLoudnessInfo(/*isDownmixing=*/false, CODEC_METADATA_TYPE_MPEG_D)));
 
         verify(mDispatcher, times(0)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid),
                 any());
@@ -108,11 +120,9 @@
         mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
 
         mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
-                List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true,
-                        CODEC_METADATA_TYPE_MPEG_4)));
-        mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid,
-                getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true,
-                        CODEC_METADATA_TYPE_MPEG_D));
+                List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4)));
+        mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid, /*mediaCodecHash=*/222,
+                getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D));
 
         verify(mDispatcher, times(2)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid),
                 any());
@@ -124,11 +134,10 @@
         mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
 
         mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
-                List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true,
+                List.of(getLoudnessInfo(/*isDownmixing=*/true,
                         CODEC_METADATA_TYPE_MPEG_4)));
-        mLoudnessHelper.addLoudnessCodecInfo(newPiid,
-                getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true,
-                        CODEC_METADATA_TYPE_MPEG_D));
+        mLoudnessHelper.addLoudnessCodecInfo(newPiid, /*mediaCodecHash=*/222,
+                getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D));
 
         verify(mDispatcher, times(1)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid),
                 any());
@@ -140,12 +149,10 @@
         mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
 
         mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid,
-                List.of(getLoudnessInfo(/*mediaCodecHash=*/111, /*isDownmixing=*/true,
-                        CODEC_METADATA_TYPE_MPEG_4)));
+                List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4)));
         //does not trigger dispatch since active apc list does not contain newPiid
         mLoudnessHelper.startLoudnessCodecUpdates(newPiid,
-                List.of(getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true,
-                        CODEC_METADATA_TYPE_MPEG_D)));
+                List.of(getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D)));
         verify(mDispatcher, times(1)).dispatchLoudnessCodecParameterChange(eq(mInitialApcPiid),
                 any());
 
@@ -157,9 +164,8 @@
     @Test
     public void updateCodecParameters_noStartedPiids_noDispatch() throws Exception {
         mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
-        mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid,
-                getLoudnessInfo(/*mediaCodecHash=*/222, /*isDownmixing=*/true,
-                        CODEC_METADATA_TYPE_MPEG_D));
+        mLoudnessHelper.addLoudnessCodecInfo(mInitialApcPiid, /*mediaCodecHash=*/222,
+                getLoudnessInfo(/*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_D));
 
         mLoudnessHelper.updateCodecParameters(getApcListForPiids(mInitialApcPiid));
 
@@ -170,8 +176,8 @@
 
     @Test
     public void updateCodecParameters_removedCodecInfo_noDispatch() throws Exception {
-        final LoudnessCodecInfo info = getLoudnessInfo(/*mediaCodecHash=*/111,
-                /*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4);
+        final LoudnessCodecInfo info = getLoudnessInfo(/*isDownmixing=*/true,
+                CODEC_METADATA_TYPE_MPEG_4);
         mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
 
         mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, List.of(info));
@@ -186,8 +192,8 @@
 
     @Test
     public void updateCodecParameters_stoppedPiids_noDispatch() throws Exception {
-        final LoudnessCodecInfo info = getLoudnessInfo(/*mediaCodecHash=*/111,
-                /*isDownmixing=*/true, CODEC_METADATA_TYPE_MPEG_4);
+        final LoudnessCodecInfo info = getLoudnessInfo(/*isDownmixing=*/true,
+                CODEC_METADATA_TYPE_MPEG_4);
         mLoudnessHelper.registerLoudnessCodecUpdatesDispatcher(mDispatcher);
 
         mLoudnessHelper.startLoudnessCodecUpdates(mInitialApcPiid, List.of(info));
@@ -200,6 +206,108 @@
                 any());
     }
 
+    @Test
+    public void checkParcelableBundle_forMpeg4CodecInputProperties() {
+        PersistableBundle loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+                SPL_RANGE_SMALL).createLoudnessParameters();
+        assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+                SPL_RANGE_SMALL).createLoudnessParameters();
+        assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+                SPL_RANGE_MEDIUM).createLoudnessParameters();
+        assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+                SPL_RANGE_MEDIUM).createLoudnessParameters();
+        assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+                SPL_RANGE_LARGE).createLoudnessParameters();
+        assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+                SPL_RANGE_LARGE).createLoudnessParameters();
+        assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/true,
+                SPL_RANGE_UNKNOWN).createLoudnessParameters();
+        assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(1, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_4, /*isDownmixing*/false,
+                SPL_RANGE_UNKNOWN).createLoudnessParameters();
+        assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(0, loudnessParameters.getInt(KEY_AAC_DRC_HEAVY_COMPRESSION));
+    }
+
+    @Test
+    public void checkParcelableBundle_forMpegDCodecInputProperties() {
+        PersistableBundle loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+                SPL_RANGE_SMALL).createLoudnessParameters();
+        assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(3, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+                SPL_RANGE_SMALL).createLoudnessParameters();
+        assertEquals(64, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(3, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+                SPL_RANGE_MEDIUM).createLoudnessParameters();
+        assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+                SPL_RANGE_MEDIUM).createLoudnessParameters();
+        assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+                SPL_RANGE_LARGE).createLoudnessParameters();
+        assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+                SPL_RANGE_LARGE).createLoudnessParameters();
+        assertEquals(124, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/true,
+                SPL_RANGE_UNKNOWN).createLoudnessParameters();
+        assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+
+        loudnessParameters = createInputProperties(
+                CODEC_METADATA_TYPE_MPEG_D, /*isDownmixing*/false,
+                SPL_RANGE_UNKNOWN).createLoudnessParameters();
+        assertEquals(96, loudnessParameters.getInt(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL));
+        assertEquals(6, loudnessParameters.getInt(KEY_AAC_DRC_EFFECT_TYPE));
+    }
+
     private List<AudioPlaybackConfiguration> getApcListForPiids(int... piids) {
         final ArrayList<AudioPlaybackConfiguration> apcList = new ArrayList<>();
 
@@ -220,11 +328,15 @@
         return apcList;
     }
 
-    private static LoudnessCodecInfo getLoudnessInfo(int mediaCodecHash, boolean isDownmixing,
-            int metadataType) {
+    private static LoudnessCodecInputProperties createInputProperties(
+            int metadataType, boolean isDownmixing, @DeviceSplRange int splRange) {
+        return new LoudnessCodecInputProperties.Builder().setMetadataType(
+                metadataType).setIsDownmixing(isDownmixing).setDeviceSplRange(splRange).build();
+    }
+
+    private static LoudnessCodecInfo getLoudnessInfo(boolean isDownmixing, int metadataType) {
         LoudnessCodecInfo info = new LoudnessCodecInfo();
         info.isDownmixing = isDownmixing;
-        info.mediaCodecHashCode = mediaCodecHash;
         info.metadataType = metadataType;
 
         return info;
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index b5ba322..9213601a 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -413,18 +413,24 @@
     public void getDeviceIdForDisplayId_invalidDisplayId_returnsDefault() {
         assertThat(mVdm.getDeviceIdForDisplayId(Display.INVALID_DISPLAY))
                 .isEqualTo(DEVICE_ID_DEFAULT);
+        assertThat(mLocalService.getDeviceIdForDisplayId(Display.INVALID_DISPLAY))
+                .isEqualTo(DEVICE_ID_DEFAULT);
     }
 
     @Test
     public void getDeviceIdForDisplayId_defaultDisplayId_returnsDefault() {
         assertThat(mVdm.getDeviceIdForDisplayId(Display.DEFAULT_DISPLAY))
                 .isEqualTo(DEVICE_ID_DEFAULT);
+        assertThat(mLocalService.getDeviceIdForDisplayId(Display.DEFAULT_DISPLAY))
+                .isEqualTo(DEVICE_ID_DEFAULT);
     }
 
     @Test
     public void getDeviceIdForDisplayId_nonExistentDisplayId_returnsDefault() {
         assertThat(mVdm.getDeviceIdForDisplayId(NON_EXISTENT_DISPLAY_ID))
                 .isEqualTo(DEVICE_ID_DEFAULT);
+        assertThat(mLocalService.getDeviceIdForDisplayId(NON_EXISTENT_DISPLAY_ID))
+                .isEqualTo(DEVICE_ID_DEFAULT);
     }
 
     @Test
@@ -433,6 +439,8 @@
 
         assertThat(mVdm.getDeviceIdForDisplayId(DISPLAY_ID_1))
                 .isEqualTo(mDeviceImpl.getDeviceId());
+        assertThat(mLocalService.getDeviceIdForDisplayId(DISPLAY_ID_1))
+                .isEqualTo(mDeviceImpl.getDeviceId());
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java
index 01922e0..edfe1b4 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java
@@ -40,6 +40,7 @@
 import android.testing.TestableLooper;
 import android.view.Surface;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -77,6 +78,11 @@
         when(mVirtualCameraServiceMock.registerCamera(any(), any())).thenReturn(true);
     }
 
+    @After
+    public void tearDown() throws Exception {
+        mVirtualCameraController.close();
+    }
+
     @Test
     public void registerCamera_registersCamera() throws Exception {
         mVirtualCameraController.registerCamera(createVirtualCameraConfig(
@@ -95,6 +101,8 @@
     public void unregisterCamera_unregistersCamera() throws Exception {
         VirtualCameraConfig config = createVirtualCameraConfig(
                 CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT, CAMERA_DISPLAY_NAME_RES_ID_1);
+        mVirtualCameraController.registerCamera(config);
+
         mVirtualCameraController.unregisterCamera(config);
 
         verify(mVirtualCameraServiceMock).unregisterCamera(any());
@@ -107,9 +115,10 @@
         mVirtualCameraController.registerCamera(createVirtualCameraConfig(
                 CAMERA_WIDTH_2, CAMERA_HEIGHT_2, CAMERA_FORMAT, CAMERA_DISPLAY_NAME_RES_ID_2));
 
+        mVirtualCameraController.close();
+
         ArgumentCaptor<VirtualCameraConfiguration> configurationCaptor =
                 ArgumentCaptor.forClass(VirtualCameraConfiguration.class);
-        mVirtualCameraController.close();
         verify(mVirtualCameraServiceMock, times(2)).registerCamera(any(),
                 configurationCaptor.capture());
         List<VirtualCameraConfiguration> virtualCameraConfigurations =
diff --git a/services/tests/servicestests/src/com/android/server/media/AudioPoliciesDeviceRouteControllerTest.java b/services/tests/servicestests/src/com/android/server/media/AudioPoliciesDeviceRouteControllerTest.java
deleted file mode 100644
index 5aef7a3..0000000
--- a/services/tests/servicestests/src/com/android/server/media/AudioPoliciesDeviceRouteControllerTest.java
+++ /dev/null
@@ -1,247 +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.media;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.media.AudioManager;
-import android.media.AudioRoutesInfo;
-import android.media.IAudioRoutesObserver;
-import android.media.MediaRoute2Info;
-import android.os.RemoteException;
-
-import com.android.internal.R;
-import com.android.server.audio.AudioService;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(JUnit4.class)
-public class AudioPoliciesDeviceRouteControllerTest {
-
-    private static final String ROUTE_NAME_DEFAULT = "default";
-    private static final String ROUTE_NAME_DOCK = "dock";
-    private static final String ROUTE_NAME_HEADPHONES = "headphones";
-
-    private static final int VOLUME_SAMPLE_1 = 25;
-
-    @Mock
-    private Context mContext;
-    @Mock
-    private Resources mResources;
-    @Mock
-    private AudioManager mAudioManager;
-    @Mock
-    private AudioService mAudioService;
-    @Mock
-    private DeviceRouteController.OnDeviceRouteChangedListener mOnDeviceRouteChangedListener;
-
-    @Captor
-    private ArgumentCaptor<IAudioRoutesObserver.Stub> mAudioRoutesObserverCaptor;
-
-    private AudioPoliciesDeviceRouteController mController;
-
-    private IAudioRoutesObserver.Stub mAudioRoutesObserver;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mResources.getText(anyInt())).thenReturn(ROUTE_NAME_DEFAULT);
-
-        // Setting built-in speaker as default speaker.
-        AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
-        audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_SPEAKER;
-        when(mAudioService.startWatchingRoutes(mAudioRoutesObserverCaptor.capture()))
-                .thenReturn(audioRoutesInfo);
-
-        mController = new AudioPoliciesDeviceRouteController(
-                mContext, mAudioManager, mAudioService, mOnDeviceRouteChangedListener);
-
-        mAudioRoutesObserver = mAudioRoutesObserverCaptor.getValue();
-    }
-
-    @Test
-    public void getDeviceRoute_noSelectedRoutes_returnsDefaultDevice() {
-        MediaRoute2Info route2Info = mController.getSelectedRoute();
-
-        assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_DEFAULT);
-        assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_BUILTIN_SPEAKER);
-    }
-
-    @Test
-    public void getDeviceRoute_audioRouteHasChanged_returnsRouteFromAudioService() {
-        when(mResources.getText(R.string.default_audio_route_name_headphones))
-                .thenReturn(ROUTE_NAME_HEADPHONES);
-
-        AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
-        audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
-        callAudioRoutesObserver(audioRoutesInfo);
-
-        MediaRoute2Info route2Info = mController.getSelectedRoute();
-        assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_HEADPHONES);
-        assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADPHONES);
-    }
-
-    @Test
-    public void getDeviceRoute_selectDevice_returnsSelectedRoute() {
-        when(mResources.getText(R.string.default_audio_route_name_dock_speakers))
-                .thenReturn(ROUTE_NAME_DOCK);
-
-        mController.selectRoute(MediaRoute2Info.TYPE_DOCK);
-
-        MediaRoute2Info route2Info = mController.getSelectedRoute();
-        assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_DOCK);
-        assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_DOCK);
-    }
-
-    @Test
-    public void getDeviceRoute_hasSelectedAndAudioServiceRoutes_returnsSelectedRoute() {
-        when(mResources.getText(R.string.default_audio_route_name_headphones))
-                .thenReturn(ROUTE_NAME_HEADPHONES);
-        when(mResources.getText(R.string.default_audio_route_name_dock_speakers))
-                .thenReturn(ROUTE_NAME_DOCK);
-
-        AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
-        audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
-        callAudioRoutesObserver(audioRoutesInfo);
-
-        mController.selectRoute(MediaRoute2Info.TYPE_DOCK);
-
-        MediaRoute2Info route2Info = mController.getSelectedRoute();
-        assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_DOCK);
-        assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_DOCK);
-    }
-
-    @Test
-    public void getDeviceRoute_unselectRoute_returnsAudioServiceRoute() {
-        when(mResources.getText(R.string.default_audio_route_name_headphones))
-                .thenReturn(ROUTE_NAME_HEADPHONES);
-        when(mResources.getText(R.string.default_audio_route_name_dock_speakers))
-                .thenReturn(ROUTE_NAME_DOCK);
-
-        mController.selectRoute(MediaRoute2Info.TYPE_DOCK);
-
-        AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
-        audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
-        callAudioRoutesObserver(audioRoutesInfo);
-
-        mController.selectRoute(null);
-
-        MediaRoute2Info route2Info = mController.getSelectedRoute();
-        assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_HEADPHONES);
-        assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADPHONES);
-    }
-
-    @Test
-    public void getDeviceRoute_selectRouteFails_returnsAudioServiceRoute() {
-        when(mResources.getText(R.string.default_audio_route_name_headphones))
-                .thenReturn(ROUTE_NAME_HEADPHONES);
-
-        AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
-        audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
-        callAudioRoutesObserver(audioRoutesInfo);
-
-        mController.selectRoute(MediaRoute2Info.TYPE_BLUETOOTH_A2DP);
-
-        MediaRoute2Info route2Info = mController.getSelectedRoute();
-        assertThat(route2Info.getName()).isEqualTo(ROUTE_NAME_HEADPHONES);
-        assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADPHONES);
-    }
-
-    @Test
-    public void selectRoute_selectWiredRoute_returnsTrue() {
-        assertThat(mController.selectRoute(MediaRoute2Info.TYPE_HDMI)).isTrue();
-    }
-
-    @Test
-    public void selectRoute_selectBluetoothRoute_returnsFalse() {
-        assertThat(mController.selectRoute(MediaRoute2Info.TYPE_BLUETOOTH_A2DP)).isFalse();
-    }
-
-    @Test
-    public void selectRoute_unselectRoute_returnsTrue() {
-        assertThat(mController.selectRoute(null)).isTrue();
-    }
-
-    @Test
-    public void updateVolume_noSelectedRoute_deviceRouteVolumeChanged() {
-        when(mResources.getText(R.string.default_audio_route_name_headphones))
-                .thenReturn(ROUTE_NAME_HEADPHONES);
-
-        AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
-        audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
-        callAudioRoutesObserver(audioRoutesInfo);
-
-        mController.updateVolume(VOLUME_SAMPLE_1);
-
-        MediaRoute2Info route2Info = mController.getSelectedRoute();
-        assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_WIRED_HEADPHONES);
-        assertThat(route2Info.getVolume()).isEqualTo(VOLUME_SAMPLE_1);
-    }
-
-    @Test
-    public void updateVolume_connectSelectedRouteLater_selectedRouteVolumeChanged() {
-        when(mResources.getText(R.string.default_audio_route_name_headphones))
-                .thenReturn(ROUTE_NAME_HEADPHONES);
-        when(mResources.getText(R.string.default_audio_route_name_dock_speakers))
-                .thenReturn(ROUTE_NAME_DOCK);
-
-        AudioRoutesInfo audioRoutesInfo = new AudioRoutesInfo();
-        audioRoutesInfo.mainType = AudioRoutesInfo.MAIN_HEADPHONES;
-        callAudioRoutesObserver(audioRoutesInfo);
-
-        mController.updateVolume(VOLUME_SAMPLE_1);
-
-        mController.selectRoute(MediaRoute2Info.TYPE_DOCK);
-
-        MediaRoute2Info route2Info = mController.getSelectedRoute();
-        assertThat(route2Info.getType()).isEqualTo(MediaRoute2Info.TYPE_DOCK);
-        assertThat(route2Info.getVolume()).isEqualTo(VOLUME_SAMPLE_1);
-    }
-
-    /**
-     * Simulates {@link IAudioRoutesObserver.Stub#dispatchAudioRoutesChanged(AudioRoutesInfo)}
-     * from {@link AudioService}. This happens when there is a wired route change,
-     * like a wired headset being connected.
-     *
-     * @param audioRoutesInfo updated state of connected wired device
-     */
-    private void callAudioRoutesObserver(AudioRoutesInfo audioRoutesInfo) {
-        try {
-            // this is a captured observer implementation
-            // from WiredRoutesController's AudioService#startWatchingRoutes call
-            mAudioRoutesObserver.dispatchAudioRoutesChanged(audioRoutesInfo);
-        } catch (RemoteException exception) {
-            // Should not happen since the object is mocked.
-            assertWithMessage("An unexpected RemoteException happened.").fail();
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java b/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java
index 14b121d..0961b7d 100644
--- a/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/DeviceRouteControllerTest.java
@@ -19,6 +19,7 @@
 import static com.android.media.flags.Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER;
 
 import android.content.Context;
+import android.os.Looper;
 import android.platform.test.annotations.RequiresFlagsDisabled;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
@@ -56,7 +57,8 @@
     @RequiresFlagsDisabled(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER)
     public void createInstance_audioPoliciesFlagIsDisabled_createsLegacyController() {
         DeviceRouteController deviceRouteController =
-                DeviceRouteController.createInstance(mContext, mOnDeviceRouteChangedListener);
+                DeviceRouteController.createInstance(
+                        mContext, Looper.getMainLooper(), mOnDeviceRouteChangedListener);
 
         Truth.assertThat(deviceRouteController).isInstanceOf(LegacyDeviceRouteController.class);
     }
@@ -65,7 +67,8 @@
     @RequiresFlagsEnabled(FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER)
     public void createInstance_audioPoliciesFlagIsEnabled_createsAudioPoliciesController() {
         DeviceRouteController deviceRouteController =
-                DeviceRouteController.createInstance(mContext, mOnDeviceRouteChangedListener);
+                DeviceRouteController.createInstance(
+                        mContext, Looper.getMainLooper(), mOnDeviceRouteChangedListener);
 
         Truth.assertThat(deviceRouteController)
                 .isInstanceOf(AudioPoliciesDeviceRouteController.class);
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index c7d80ed..8933c6c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -23,6 +23,7 @@
 import static org.junit.Assume.assumeTrue;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertThrows;
+import static org.testng.Assert.assertTrue;
 
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
@@ -31,6 +32,7 @@
 import android.content.pm.UserInfo;
 import android.content.pm.UserProperties;
 import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -219,6 +221,8 @@
                 .isEqualTo(cloneUserProperties.isCredentialShareableWithParent());
         assertThrows(SecurityException.class, cloneUserProperties::getDeleteAppWithParent);
         assertThrows(SecurityException.class, cloneUserProperties::getAlwaysVisible);
+        compareDrawables(mUserManager.getUserBadge(),
+                Resources.getSystem().getDrawable(userTypeDetails.getBadgePlain()));
 
         // Verify clone user parent
         assertThat(mUserManager.getProfileParent(mainUserId)).isNull();
@@ -335,7 +339,8 @@
                 .isEqualTo(privateProfileUserProperties
                         .isAuthAlwaysRequiredToDisableQuietMode());
         assertThrows(SecurityException.class, privateProfileUserProperties::getDeleteAppWithParent);
-
+        compareDrawables(mUserManager.getUserBadge(),
+                Resources.getSystem().getDrawable(userTypeDetails.getBadgePlain()));
         // Verify private profile parent
         assertThat(mUserManager.getProfileParent(mainUserId)).isNull();
         UserInfo parentProfileInfo = mUserManager.getProfileParent(userInfo.id);
@@ -955,6 +960,8 @@
                 .isEqualTo(userTypeDetails.getBadgeNoBackground());
         assertThat(mUserManager.getUserStatusBarIconResId(userId))
                 .isEqualTo(userTypeDetails.getStatusBarIcon());
+        compareDrawables(mUserManager.getUserBadge(),
+                Resources.getSystem().getDrawable(userTypeDetails.getBadgePlain()));
 
         final int badgeIndex = userInfo.profileBadge;
         assertThat(mUserManager.getUserBadgeColor(userId)).isEqualTo(
@@ -1762,4 +1769,10 @@
                 .getBoolean(com.android.internal.R.bool.config_isMainUserPermanentAdmin);
     }
 
+    private void compareDrawables(Drawable actual, Drawable expected){
+        assertEquals(actual.getIntrinsicWidth(), expected.getIntrinsicWidth());
+        assertEquals(actual.getIntrinsicHeight(), expected.getIntrinsicHeight());
+        assertEquals(actual.getLevel(), expected.getLevel());
+    }
+
 }
diff --git a/services/tests/servicestests/src/com/android/server/usage/IntervalStatsTests.java b/services/tests/servicestests/src/com/android/server/usage/IntervalStatsTests.java
index 2be3f1e8..517f483 100644
--- a/services/tests/servicestests/src/com/android/server/usage/IntervalStatsTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/IntervalStatsTests.java
@@ -21,8 +21,11 @@
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 
+import android.app.usage.Flags;
 import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManager;
 import android.content.res.Configuration;
+import android.os.PersistableBundle;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -99,6 +102,17 @@
                 case UsageEvents.Event.LOCUS_ID_SET:
                     event.mLocusId = "locus" + (i % 7); //"random" locus
                     break;
+                case UsageEvents.Event.USER_INTERACTION:
+                    if (Flags.userInteractionTypeApi()) {
+                        // "random" user interaction extras.
+                        PersistableBundle extras = new PersistableBundle();
+                        extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY,
+                                "fake.namespace.category" + (i % 13));
+                        extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION,
+                                "fakeaction" + (i % 13));
+                        event.mExtras = extras;
+                    }
+                    break;
             }
 
             intervalStats.addEvent(event);
diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
index 6ae2658..cd29c80 100644
--- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
+++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
@@ -24,11 +24,13 @@
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
+import android.app.usage.Flags;
 import android.app.usage.UsageEvents.Event;
 import android.app.usage.UsageStats;
 import android.app.usage.UsageStatsManager;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.os.PersistableBundle;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.AtomicFile;
 import android.util.LongSparseArray;
@@ -183,6 +185,17 @@
                 case Event.LOCUS_ID_SET:
                     event.mLocusId = "locus" + (i % 7); //"random" locus
                     break;
+                case Event.USER_INTERACTION:
+                    if (Flags.userInteractionTypeApi()) {
+                        // "random" user interaction extras.
+                        PersistableBundle extras = new PersistableBundle();
+                        extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY,
+                                "fake.namespace.category" + (i % 13));
+                        extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION,
+                                "fakeaction" + (i % 13));
+                        event.mExtras = extras;
+                    }
+                    break;
             }
 
             mIntervalStats.addEvent(event);
@@ -295,6 +308,18 @@
                         assertEquals(e1.mLocusIdToken, e2.mLocusIdToken,
                                 "Usage event " + debugId);
                         break;
+                    case Event.USER_INTERACTION:
+                        if (Flags.userInteractionTypeApi()) {
+                            PersistableBundle extras1 = e1.getExtras();
+                            PersistableBundle extras2 = e2.getExtras();
+                            assertEquals(extras1.getString(UsageStatsManager.EXTRA_EVENT_CATEGORY),
+                                    extras2.getString(UsageStatsManager.EXTRA_EVENT_CATEGORY),
+                                    "Usage event " + debugId);
+                            assertEquals(extras1.getString(UsageStatsManager.EXTRA_EVENT_ACTION),
+                                    extras2.getString(UsageStatsManager.EXTRA_EVENT_ACTION),
+                                    "Usage event " + debugId);
+                        }
+                        break;
                 }
                 // fallthrough
             case 4: // test fields added in version 4
diff --git a/services/tests/servicestests/src/com/android/server/utils/UserSettingDeviceConfigMediatorTest.java b/services/tests/servicestests/src/com/android/server/utils/UserSettingDeviceConfigMediatorTest.java
new file mode 100644
index 0000000..377e4c3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/utils/UserSettingDeviceConfigMediatorTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.utils;
+
+import static org.junit.Assert.assertEquals;
+
+import android.provider.DeviceConfig;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests for {@link UserSettingDeviceConfigMediator}
+ */
+@RunWith(AndroidJUnit4.class)
+public class UserSettingDeviceConfigMediatorTest {
+    @Test
+    public void testDeviceConfigOnly() {
+        UserSettingDeviceConfigMediator mediator =
+                new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
+
+        DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder("test")
+                .setInt("int", 1)
+                .setFloat("float", .5f)
+                .setBoolean("boolean", true)
+                .setLong("long", 123456789)
+                .setString("string", "abc123")
+                .build();
+
+        mediator.setDeviceConfigProperties(properties);
+
+        assertEquals(1, mediator.getInt("int", 123));
+        assertEquals(123, mediator.getInt("invalidKey", 123));
+        assertEquals(.5f, mediator.getFloat("float", .8f), 0.001);
+        assertEquals(.8f, mediator.getFloat("invalidKey", .8f), 0.001);
+        assertEquals(true, mediator.getBoolean("boolean", false));
+        assertEquals(true, mediator.getBoolean("invalidKey", true));
+        assertEquals(123456789, mediator.getLong("long", 987654321));
+        assertEquals(987654321, mediator.getInt("invalidKey", 987654321));
+        assertEquals("abc123", mediator.getString("string", "xyz987"));
+        assertEquals("xyz987", mediator.getString("invalidKey", "xyz987"));
+
+        // Clear the properties
+        mediator.setDeviceConfigProperties(null);
+
+        assertEquals(123, mediator.getInt("int", 123));
+        assertEquals(123, mediator.getInt("invalidKey", 123));
+        assertEquals(.8f, mediator.getFloat("float", .8f), 0.001);
+        assertEquals(.8f, mediator.getFloat("invalidKey", .8f), 0.001);
+        assertEquals(false, mediator.getBoolean("boolean", false));
+        assertEquals(true, mediator.getBoolean("invalidKey", true));
+        assertEquals(987654321, mediator.getLong("long", 987654321));
+        assertEquals(987654321, mediator.getInt("invalidKey", 987654321));
+        assertEquals("xyz987", mediator.getString("string", "xyz987"));
+        assertEquals("xyz987", mediator.getString("invalidKey", "xyz987"));
+    }
+
+    @Test
+    public void testSettingsOnly() {
+        UserSettingDeviceConfigMediator mediator =
+                new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
+
+        String settings = "int=1,float=.5f,boolean=true,long=123456789,string=abc123";
+
+        mediator.setSettingsString(settings);
+
+        assertEquals(1, mediator.getInt("int", 123));
+        assertEquals(123, mediator.getInt("invalidKey", 123));
+        assertEquals(.5f, mediator.getFloat("float", .8f), 0.001);
+        assertEquals(.8f, mediator.getFloat("invalidKey", .8f), 0.001);
+        assertEquals(true, mediator.getBoolean("boolean", false));
+        assertEquals(true, mediator.getBoolean("invalidKey", true));
+        assertEquals(123456789, mediator.getLong("long", 987654321));
+        assertEquals(987654321, mediator.getInt("invalidKey", 987654321));
+        assertEquals("abc123", mediator.getString("string", "xyz987"));
+        assertEquals("xyz987", mediator.getString("invalidKey", "xyz987"));
+
+        // Clear the settings
+        mediator.setSettingsString(null);
+
+        assertEquals(123, mediator.getInt("int", 123));
+        assertEquals(123, mediator.getInt("invalidKey", 123));
+        assertEquals(.8f, mediator.getFloat("float", .8f), 0.001);
+        assertEquals(.8f, mediator.getFloat("invalidKey", .8f), 0.001);
+        assertEquals(false, mediator.getBoolean("boolean", false));
+        assertEquals(true, mediator.getBoolean("invalidKey", true));
+        assertEquals(987654321, mediator.getLong("long", 987654321));
+        assertEquals(987654321, mediator.getInt("invalidKey", 987654321));
+        assertEquals("xyz987", mediator.getString("string", "xyz987"));
+        assertEquals("xyz987", mediator.getString("invalidKey", "xyz987"));
+    }
+
+    @Test
+    public void testSettingsOverridesAll() {
+        UserSettingDeviceConfigMediator mediator =
+                new UserSettingDeviceConfigMediator.SettingsOverridesAllMediator(',');
+
+        String settings = "int=1,float=.5f,boolean=true,long=123456789,string=abc123,"
+                + "intOnlyInSettings=9,floatOnlyInSettings=.25f,booleanOnlyInSettings=true,"
+                + "longOnlyInSettings=53771465,stringOnlyInSettings=settingsString";
+        DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder("test")
+                .setInt("int", 10)
+                .setInt("intOnlyInDeviceConfig", 9001)
+                .setFloat("float", .7f)
+                .setFloat("floatOnlyInDeviceConfig", .9f)
+                .setBoolean("boolean", false)
+                .setBoolean("booleanOnlyInDeviceConfig", true)
+                .setLong("long", 60000001)
+                .setLong("longOnlyInDeviceConfig", 7357)
+                .setString("string", "xyz987")
+                .setString("stringOnlyInDeviceConfig", "deviceConfigString")
+                .build();
+
+        mediator.setSettingsString(settings);
+        mediator.setDeviceConfigProperties(properties);
+
+        // Since settings overrides all, anything in DeviceConfig should be ignored,
+        // even if settings doesn't have a value for it.
+        assertEquals(1, mediator.getInt("int", 123));
+        assertEquals(9, mediator.getInt("intOnlyInSettings", 123));
+        assertEquals(123, mediator.getInt("intOnlyInDeviceConfig", 123));
+        assertEquals(.5f, mediator.getFloat("float", .8f), 0.001);
+        assertEquals(.25f, mediator.getFloat("floatOnlyInSettings", .8f), 0.001);
+        assertEquals(.8f, mediator.getFloat("floatOnlyInDeviceConfig", .8f), 0.001);
+        assertEquals(true, mediator.getBoolean("boolean", false));
+        assertEquals(true, mediator.getBoolean("booleanOnlyInSettings", false));
+        assertEquals(false, mediator.getBoolean("booleanOnlyInDeviceConfig", false));
+        assertEquals(123456789, mediator.getLong("long", 987654321));
+        assertEquals(53771465, mediator.getLong("longOnlyInSettings", 987654321));
+        assertEquals(987654321, mediator.getLong("longOnlyInDeviceConfig", 987654321));
+        assertEquals("abc123", mediator.getString("string", "default"));
+        assertEquals("settingsString", mediator.getString("stringOnlyInSettings", "default"));
+        assertEquals("default", mediator.getString("stringOnlyInDeviceConfig", "default"));
+
+        // Nothing in settings, do DeviceConfig can be used.
+        mediator.setSettingsString("");
+
+        assertEquals(10, mediator.getInt("int", 123));
+        assertEquals(123, mediator.getInt("intOnlyInSettings", 123));
+        assertEquals(9001, mediator.getInt("intOnlyInDeviceConfig", 123));
+        assertEquals(.7f, mediator.getFloat("float", .8f), 0.001);
+        assertEquals(.8f, mediator.getFloat("floatOnlyInSettings", .8f), 0.001);
+        assertEquals(.9f, mediator.getFloat("floatOnlyInDeviceConfig", .8f), 0.001);
+        assertEquals(false, mediator.getBoolean("boolean", false));
+        assertEquals(false, mediator.getBoolean("booleanOnlyInSettings", false));
+        assertEquals(true, mediator.getBoolean("booleanOnlyInDeviceConfig", false));
+        assertEquals(60000001, mediator.getLong("long", 987654321));
+        assertEquals(987654321, mediator.getLong("longOnlyInSettings", 987654321));
+        assertEquals(7357, mediator.getLong("longOnlyInDeviceConfig", 987654321));
+        assertEquals("xyz987", mediator.getString("string", "default"));
+        assertEquals("default", mediator.getString("stringOnlyInSettings", "default"));
+        assertEquals("deviceConfigString",
+                mediator.getString("stringOnlyInDeviceConfig", "default"));
+
+        // Nothing in settings, do DeviceConfig can be used.
+        mediator.setSettingsString(null);
+
+        assertEquals(10, mediator.getInt("int", 123));
+        assertEquals(123, mediator.getInt("intOnlyInSettings", 123));
+        assertEquals(9001, mediator.getInt("intOnlyInDeviceConfig", 123));
+        assertEquals(.7f, mediator.getFloat("float", .8f), 0.001);
+        assertEquals(.8f, mediator.getFloat("floatOnlyInSettings", .8f), 0.001);
+        assertEquals(.9f, mediator.getFloat("floatOnlyInDeviceConfig", .8f), 0.001);
+        assertEquals(false, mediator.getBoolean("boolean", false));
+        assertEquals(false, mediator.getBoolean("booleanOnlyInSettings", false));
+        assertEquals(true, mediator.getBoolean("booleanOnlyInDeviceConfig", false));
+        assertEquals(60000001, mediator.getLong("long", 987654321));
+        assertEquals(987654321, mediator.getLong("longOnlyInSettings", 987654321));
+        assertEquals(7357, mediator.getLong("longOnlyInDeviceConfig", 987654321));
+        assertEquals("xyz987", mediator.getString("string", "default"));
+        assertEquals("default", mediator.getString("stringOnlyInSettings", "default"));
+        assertEquals("deviceConfigString",
+                mediator.getString("stringOnlyInDeviceConfig", "default"));
+    }
+
+    @Test
+    public void testSettingsOverridesIndividual() {
+        UserSettingDeviceConfigMediator mediator =
+                new UserSettingDeviceConfigMediator.SettingsOverridesIndividualMediator(',');
+
+        String settings = "int=1,float=.5f,boolean=true,long=123456789,string=abc123,"
+                + "intOnlyInSettings=9,floatOnlyInSettings=.25f,booleanOnlyInSettings=true,"
+                + "longOnlyInSettings=53771465,stringOnlyInSettings=settingsString";
+        DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder("test")
+                .setInt("int", 10)
+                .setInt("intOnlyInDeviceConfig", 9001)
+                .setFloat("float", .7f)
+                .setFloat("floatOnlyInDeviceConfig", .9f)
+                .setBoolean("boolean", false)
+                .setBoolean("booleanOnlyInDeviceConfig", true)
+                .setLong("long", 60000001)
+                .setLong("longOnlyInDeviceConfig", 7357)
+                .setString("string", "xyz987")
+                .setString("stringOnlyInDeviceConfig", "deviceConfigString")
+                .build();
+
+        mediator.setSettingsString(settings);
+        mediator.setDeviceConfigProperties(properties);
+
+        // Since settings overrides individual, anything in DeviceConfig that doesn't exist in
+        // settings should be used.
+        assertEquals(1, mediator.getInt("int", 123));
+        assertEquals(9, mediator.getInt("intOnlyInSettings", 123));
+        assertEquals(9001, mediator.getInt("intOnlyInDeviceConfig", 123));
+        assertEquals(.5f, mediator.getFloat("float", .8f), 0.001);
+        assertEquals(.25f, mediator.getFloat("floatOnlyInSettings", .8f), 0.001);
+        assertEquals(.9f, mediator.getFloat("floatOnlyInDeviceConfig", .8f), 0.001);
+        assertEquals(true, mediator.getBoolean("boolean", false));
+        assertEquals(true, mediator.getBoolean("booleanOnlyInSettings", false));
+        assertEquals(true, mediator.getBoolean("booleanOnlyInDeviceConfig", false));
+        assertEquals(123456789, mediator.getLong("long", 987654321));
+        assertEquals(53771465, mediator.getLong("longOnlyInSettings", 987654321));
+        assertEquals(7357, mediator.getLong("longOnlyInDeviceConfig", 987654321));
+        assertEquals("abc123", mediator.getString("string", "default"));
+        assertEquals("settingsString", mediator.getString("stringOnlyInSettings", "default"));
+        assertEquals("deviceConfigString",
+                mediator.getString("stringOnlyInDeviceConfig", "default"));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index d000605..32082e3 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -28,6 +28,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.test.suitebuilder.annotation.MediumTest;
@@ -1449,4 +1450,21 @@
         checkPreparationPhasesForPackage(currentSdkPackage.packageName,
                 1 /* first preparation phase */);
     }
+
+    @Test
+    @RequiresFlagsEnabled("android.webkit.update_service_v2")
+    public void testDefaultWebViewPackageIsTheFirstAvailableByDefault() {
+        String nonDefaultPackage = "nonDefaultPackage";
+        String defaultPackage1 = "defaultPackage1";
+        String defaultPackage2 = "defaultPackage2";
+        WebViewProviderInfo[] packages =
+                new WebViewProviderInfo[] {
+                    new WebViewProviderInfo(nonDefaultPackage, "", false, false, null),
+                    new WebViewProviderInfo(defaultPackage1, "", true, false, null),
+                    new WebViewProviderInfo(defaultPackage2, "", true, false, null)
+                };
+        setupWithPackages(packages);
+        assertEquals(
+                defaultPackage1, mWebViewUpdateServiceImpl.getDefaultWebViewPackage().packageName);
+    }
 }
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 09ffe71..ee08fd2 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -28,6 +28,7 @@
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_CAN_COLORIZE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
 import static android.app.Notification.FLAG_NO_CLEAR;
 import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
@@ -320,6 +321,11 @@
     private static final int SECONDARY_DISPLAY_ID = 42;
     private static final int TEST_PROFILE_USERHANDLE = 12;
 
+    private static final String ACTION_NOTIFICATION_TIMEOUT =
+            NotificationManagerService.class.getSimpleName() + ".TIMEOUT";
+    private static final String EXTRA_KEY = "key";
+    private static final String SCHEME_TIMEOUT = "timeout";
+
     private final int mUid = Binder.getCallingUid();
     private final @UserIdInt int mUserId = UserHandle.getUserId(mUid);
 
@@ -442,6 +448,7 @@
     MultiRateLimiter mToastRateLimiter;
     BroadcastReceiver mPackageIntentReceiver;
     BroadcastReceiver mUserSwitchIntentReceiver;
+    BroadcastReceiver mNotificationTimeoutReceiver;
     NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
     TestableNotificationManagerService.StrongAuthTrackerFake mStrongAuthTracker;
 
@@ -677,6 +684,8 @@
         verify(mContext, atLeastOnce()).registerReceiverAsUser(broadcastReceiverCaptor.capture(),
                 any(), intentFilterCaptor.capture(), any(), any());
         verify(mContext, atLeastOnce()).registerReceiver(broadcastReceiverCaptor.capture(),
+                intentFilterCaptor.capture(), anyInt());
+        verify(mContext, atLeastOnce()).registerReceiver(broadcastReceiverCaptor.capture(),
                 intentFilterCaptor.capture());
         List<BroadcastReceiver> broadcastReceivers = broadcastReceiverCaptor.getAllValues();
         List<IntentFilter> intentFilters = intentFilterCaptor.getAllValues();
@@ -695,9 +704,14 @@
                     mUserSwitchIntentReceiver = broadcastReceivers.get(i);
                 }
             }
+            if (filter.hasAction(ACTION_NOTIFICATION_TIMEOUT)
+                    && filter.hasDataScheme(SCHEME_TIMEOUT)) {
+                mNotificationTimeoutReceiver = broadcastReceivers.get(i);
+            }
         }
         assertNotNull("package intent receiver should exist", mPackageIntentReceiver);
         assertNotNull("User-switch receiver should exist", mUserSwitchIntentReceiver);
+        assertNotNull("Notification timeout receiver should exist", mNotificationTimeoutReceiver);
 
         // Pretend the shortcut exists
         List<ShortcutInfo> shortcutInfos = new ArrayList<>();
@@ -2430,6 +2444,59 @@
     }
 
     @Test
+    public void testCancelWithTagDoesNotCancelLifetimeExtended() throws Exception {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+        final NotificationRecord notif = generateNotificationRecord(null);
+        notif.getSbn().getNotification().flags =
+                Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+        mService.addNotification(notif);
+        final StatusBarNotification sbn = notif.getSbn();
+
+        assertThat(mBinderService.getActiveNotifications(sbn.getPackageName()).length).isEqualTo(1);
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
+
+        mBinderService.cancelNotificationWithTag(PKG, PKG, sbn.getTag(), sbn.getId(),
+                sbn.getUserId());
+        waitForIdle();
+
+        assertThat(mBinderService.getActiveNotifications(sbn.getPackageName()).length).isEqualTo(1);
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
+
+        mSetFlagsRule.disableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+        mBinderService.cancelNotificationWithTag(PKG, PKG, sbn.getTag(), sbn.getId(),
+                sbn.getUserId());
+        waitForIdle();
+
+        assertThat(mBinderService.getActiveNotifications(sbn.getPackageName()).length).isEqualTo(0);
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testCancelAllDoesNotCancelLifetimeExtended() throws Exception {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+        // Adds a lifetime extended notification.
+        final NotificationRecord notif = generateNotificationRecord(mTestNotificationChannel, 1,
+                null, false);
+        notif.getSbn().getNotification().flags =
+                Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+        mService.addNotification(notif);
+        // Adds a second, non-lifetime extended notification.
+        final NotificationRecord notifCancelable = generateNotificationRecord(
+                mTestNotificationChannel, 2, null, false);
+        mService.addNotification(notifCancelable);
+        // Verify that both notifications have been posted and are active.
+        assertThat(mBinderService.getActiveNotifications(PKG).length).isEqualTo(2);
+
+        mBinderService.cancelAllNotifications(PKG, notif.getSbn().getUserId());
+        waitForIdle();
+
+        // The non-lifetime extended notification, with id = 2, has been cancelled.
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        assertThat(notifs.length).isEqualTo(1);
+        assertThat(notifs[0].getId()).isEqualTo(1);
+    }
+
+    @Test
     public void testCancelNotificationWithTag_fromApp_cannotCancelFgsChild()
             throws Exception {
         when(mAmi.applyForegroundServiceNotification(
@@ -2832,6 +2899,24 @@
     }
 
     @Test
+    public void testCancelNotificationsFromListener_clearAll_NoClearLifetimeExt()
+            throws Exception {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+
+        final NotificationRecord notif = generateNotificationRecord(
+                mTestNotificationChannel, 1, null, false);
+        notif.getNotification().flags = FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+        mService.addNotification(notif);
+
+        mService.getBinderService().cancelNotificationsFromListener(null, null);
+        waitForIdle();
+
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(notif.getSbn().getPackageName());
+        assertThat(notifs.length).isEqualTo(1);
+    }
+
+    @Test
     public void testCancelNotificationsFromListener_byKey_GroupWithOngoingParent()
             throws Exception {
         final NotificationRecord parent = generateNotificationRecord(
@@ -3036,6 +3121,22 @@
     }
 
     @Test
+    public void testCancelNotificationsFromListener_byKey_NoClearLifetimeExt()
+            throws Exception {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+        final NotificationRecord notif = generateNotificationRecord(
+                mTestNotificationChannel, 3, null, false);
+        notif.getNotification().flags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+        mService.addNotification(notif);
+        String[] keys = {notif.getSbn().getKey()};
+        mService.getBinderService().cancelNotificationsFromListener(null, keys);
+        waitForIdle();
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(notif.getSbn().getPackageName());
+        assertEquals(1, notifs.length);
+    }
+
+    @Test
     public void testGroupInstanceIds() throws Exception {
         final NotificationRecord group1 = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group1", true);
@@ -5298,6 +5399,79 @@
                 anyInt());
     }
 
+    private void simulateNotificationTimeoutBroadcast(String notificationKey) {
+        final Bundle extras = new Bundle();
+        extras.putString(EXTRA_KEY, notificationKey);
+        final Intent intent = new Intent(ACTION_NOTIFICATION_TIMEOUT);
+        intent.putExtras(extras);
+        mNotificationTimeoutReceiver.onReceive(getContext(), intent);
+    }
+
+    @Test
+    public void testTimeout_CancelsNotification() throws Exception {
+        final NotificationRecord notif = generateNotificationRecord(
+                mTestNotificationChannel, 1, null, false);
+        mService.addNotification(notif);
+
+        simulateNotificationTimeoutBroadcast(notif.getKey());
+        waitForIdle();
+
+        // Check that the notification was cancelled.
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertThat(notifsAfter.length).isEqualTo(0);
+        assertThat(mService.getNotificationRecord(notif.getKey())).isNull();
+    }
+
+    @Test
+    public void testTimeout_NoCancelForegroundServiceNotification() throws Exception {
+        // Creates a notification with FLAG_FOREGROUND_SERVICE
+        final NotificationRecord notif = generateNotificationRecord(null);
+        notif.getSbn().getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
+        mService.addNotification(notif);
+
+        simulateNotificationTimeoutBroadcast(notif.getKey());
+        waitForIdle();
+
+        // Check that the notification was not cancelled.
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertThat(notifsAfter.length).isEqualTo(1);
+        assertThat(mService.getNotificationRecord(notif.getKey())).isEqualTo(notif);
+    }
+
+    @Test
+    public void testTimeout_NoCancelUserInitJobNotification() throws Exception {
+        // Create a notification with FLAG_USER_INITIATED_JOB
+        final NotificationRecord notif = generateNotificationRecord(null);
+        notif.getSbn().getNotification().flags = Notification.FLAG_USER_INITIATED_JOB;
+        mService.addNotification(notif);
+
+        simulateNotificationTimeoutBroadcast(notif.getKey());
+        waitForIdle();
+
+        // Check that the notification was not cancelled.
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertThat(notifsAfter.length).isEqualTo(1);
+        assertThat(mService.getNotificationRecord(notif.getKey())).isEqualTo(notif);
+    }
+
+    @Test
+    public void testTimeout_NoCancelLifetimeExtensionNotification() throws Exception {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+        // Create a notification with FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY
+        final NotificationRecord notif = generateNotificationRecord(null);
+        notif.getSbn().getNotification().flags =
+                Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+        mService.addNotification(notif);
+
+        simulateNotificationTimeoutBroadcast(notif.getKey());
+        waitForIdle();
+
+        // Check that the notification was not cancelled.
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertThat(notifsAfter.length).isEqualTo(1);
+        assertThat(mService.getNotificationRecord(notif.getKey())).isEqualTo(notif);
+    }
+
     @Test
     public void testBumpFGImportance_channelChangePreOApp() throws Exception {
         String preOPkg = PKG_N_MR1;
@@ -7913,6 +8087,7 @@
 
     @Test
     public void testOnNotificationSmartReplySent() {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
         final int replyIndex = 2;
         final String reply = "Hello";
         final boolean modifiedBeforeSending = true;
@@ -7930,6 +8105,10 @@
         assertEquals(1, mNotificationRecordLogger.numCalls());
         assertEquals(NotificationRecordLogger.NotificationEvent.NOTIFICATION_SMART_REPLIED,
                 mNotificationRecordLogger.event(0));
+        // Check that r.recordSmartReplied was called.
+        assertThat(r.getSbn().getNotification().flags & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY)
+                .isGreaterThan(0);
+        assertThat(r.getStats().hasSmartReplied()).isTrue();
     }
 
     @Test
@@ -13116,6 +13295,20 @@
                 eq("package"), anyString(), anyInt(), anyBoolean());
     }
 
+    @Test
+    public void testFixNotification_clearsLifetimeExtendedFlag() throws Exception {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setFlag(FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY, true)
+                .build();
+
+        assertThat(n.flags & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isGreaterThan(0);
+
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+
+        assertThat(n.flags & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isEqualTo(0);
+    }
+
     private NotificationRecord createAndPostNotification(Notification.Builder nb, String testName)
             throws RemoteException {
         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, testName, mUid, 0,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index f83a1df..670d097 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -29,6 +29,8 @@
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
@@ -44,6 +46,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
+import android.app.Flags;
 import android.app.Notification;
 import android.app.Notification.Builder;
 import android.app.NotificationChannel;
@@ -64,6 +67,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.Vibrator;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.service.notification.Adjustment;
 import android.service.notification.StatusBarNotification;
@@ -80,6 +84,7 @@
 import com.android.server.uri.UriGrantsManagerInternal;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -122,6 +127,9 @@
     private static final NotificationRecord.Light CUSTOM_LIGHT =
             new NotificationRecord.Light(1, 2, 3);
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -651,6 +659,7 @@
 
     @Test
     public void testNotificationStats() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, groupId /* group */);
@@ -690,6 +699,37 @@
 
         record.recordDirectReplied();
         assertTrue(record.getStats().hasDirectReplied());
+
+        record.recordSmartReplied();
+        assertThat(record.getStats().hasSmartReplied()).isTrue();
+    }
+
+    @Test
+    public void testDirectRepliedAddsLifetimeExtensionFlag() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, groupId /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        record.recordDirectReplied();
+        assertThat(record.getSbn().getNotification().flags
+                & Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isGreaterThan(0);
+    }
+
+    @Test
+    public void testSmartRepliedAddsLifetimeExtensionFlag() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, groupId /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        record.recordSmartReplied();
+        assertThat(record.getSbn().getNotification().flags
+                & Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isGreaterThan(0);
     }
 
     @Test
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index f2a1fe8..c3074bb 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -93,8 +93,6 @@
                   android:showWhenLocked="true"/>
         <activity android:name="android.view.cts.surfacevalidator.CapturedActivity"/>
 
-        <activity android:name="com.android.server.wm.SurfaceControlViewHostTests$TestActivity" />
-
         <activity android:name="com.android.server.wm.SurfaceSyncGroupTests$TestActivity"
             android:screenOrientation="locked"
             android:turnScreenOn="true"
@@ -122,6 +120,13 @@
         <activity android:name="com.android.server.wm.ActivityRecordInputSinkTests$TestActivity"
                   android:exported="true">
         </activity>
+
+        <activity android:name="com.android.server.wm.utils.TestActivity"
+            android:screenOrientation="locked"
+            android:turnScreenOn="true"
+            android:showWhenLocked="true"
+            android:theme="@style/WhiteBackgroundTheme"
+            android:exported="true" />
     </application>
 
     <instrumentation
diff --git a/services/tests/wmtests/AndroidTest.xml b/services/tests/wmtests/AndroidTest.xml
index f8ebead..46e87dc 100644
--- a/services/tests/wmtests/AndroidTest.xml
+++ b/services/tests/wmtests/AndroidTest.xml
@@ -30,4 +30,8 @@
         <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false" />
     </test>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="settings put secure immersive_mode_confirmations confirmed" />
+    </target_preparer>
 </configuration>
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 2c35cf0..8d236ed 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
@@ -110,24 +110,6 @@
     }
 
     /**
-     * META + SPACE to switch keyboard layout.
-     */
-    @Test
-    public void testMetaSpace() {
-        sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SPACE}, 0);
-        mPhoneWindowManager.assertSwitchKeyboardLayout(1);
-    }
-
-    /**
-     * META + SHIFT + SPACE to switch keyboard layout backwards.
-     */
-    @Test
-    public void testMetaShiftSpace() {
-        sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_SPACE}, 0);
-        mPhoneWindowManager.assertSwitchKeyboardLayout(-1);
-    }
-
-    /**
      * CTRL + ALT + Z to enable accessibility service.
      */
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
index 71098aa..6853c4c 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
@@ -30,13 +30,13 @@
 import com.android.internal.annotations.Keep;
 import com.android.server.input.KeyboardMetricsCollector.KeyboardLogEvent;
 
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import junitparams.JUnitParamsRunner;
-import junitparams.Parameters;
-
 @Presubmit
 @MediumTest
 @RunWith(JUnitParamsRunner.class)
@@ -44,6 +44,7 @@
 
     private static final int VENDOR_ID = 0x123;
     private static final int PRODUCT_ID = 0x456;
+    private static final int DEVICE_BUS = 0x789;
     private static final int META_KEY = KeyEvent.KEYCODE_META_LEFT;
     private static final int META_ON = MODIFIER.get(KeyEvent.KEYCODE_META_LEFT);
     private static final int ALT_KEY = KeyEvent.KEYCODE_ALT_LEFT;
@@ -71,8 +72,8 @@
                         KeyboardLogEvent.RECENT_APPS, KeyEvent.KEYCODE_TAB, ALT_ON},
                 {"BACK key -> Go back", new int[]{KeyEvent.KEYCODE_BACK}, KeyboardLogEvent.BACK,
                         KeyEvent.KEYCODE_BACK, 0},
-                {"Meta + `(grave) -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_GRAVE},
-                        KeyboardLogEvent.BACK, KeyEvent.KEYCODE_GRAVE, META_ON},
+                {"Meta + Escape -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_ESCAPE},
+                        KeyboardLogEvent.BACK, KeyEvent.KEYCODE_ESCAPE, META_ON},
                 {"Meta + Left arrow -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_DPAD_LEFT},
                         KeyboardLogEvent.BACK, KeyEvent.KEYCODE_DPAD_LEFT, META_ON},
                 {"Meta + Del -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_DEL},
@@ -132,13 +133,6 @@
                 {"LANGUAGE_SWITCH key -> Switch Keyboard Language",
                         new int[]{KeyEvent.KEYCODE_LANGUAGE_SWITCH},
                         KeyboardLogEvent.LANGUAGE_SWITCH, KeyEvent.KEYCODE_LANGUAGE_SWITCH, 0},
-                {"Meta + Space -> Switch Keyboard Language",
-                        new int[]{META_KEY, KeyEvent.KEYCODE_SPACE},
-                        KeyboardLogEvent.LANGUAGE_SWITCH, KeyEvent.KEYCODE_SPACE, META_ON},
-                {"Meta + Shift + Space -> Switch Keyboard Language",
-                        new int[]{META_KEY, SHIFT_KEY, KeyEvent.KEYCODE_SPACE},
-                        KeyboardLogEvent.LANGUAGE_SWITCH, KeyEvent.KEYCODE_SPACE,
-                        META_ON | SHIFT_ON},
                 {"META key -> Open App Drawer in Accessibility mode", new int[]{META_KEY},
                         KeyboardLogEvent.ACCESSIBILITY_ALL_APPS, META_KEY, META_ON},
                 {"Meta + Alt -> Toggle CapsLock", new int[]{META_KEY, ALT_KEY},
@@ -298,7 +292,7 @@
     @Before
     public void setUp() {
         setUpPhoneWindowManager(/*supportSettingsUpdate*/ true);
-        mPhoneWindowManager.overrideKeyEventSource(VENDOR_ID, PRODUCT_ID);
+        mPhoneWindowManager.overrideKeyEventSource(VENDOR_ID, PRODUCT_ID, DEVICE_BUS);
         mPhoneWindowManager.overrideLaunchHome();
         mPhoneWindowManager.overrideSearchKeyBehavior(
                 PhoneWindowManager.SEARCH_BEHAVIOR_TARGET_ACTIVITY);
@@ -318,7 +312,8 @@
             int expectedKey, int expectedModifierState) {
         sendKeyCombination(testKeys, 0 /* duration */);
         mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
-                expectedKey, expectedModifierState, "Failed while executing " + testName);
+                expectedKey, expectedModifierState, DEVICE_BUS,
+                "Failed while executing " + testName);
     }
 
     @Test
@@ -328,7 +323,8 @@
         mPhoneWindowManager.overrideLongPressOnHomeBehavior(longPressOnHomeBehavior);
         sendLongPressKeyCombination(testKeys);
         mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
-                expectedKey, expectedModifierState, "Failed while executing " + testName);
+                expectedKey, expectedModifierState, DEVICE_BUS,
+                "Failed while executing " + testName);
     }
 
     @Test
@@ -340,7 +336,8 @@
         sendKeyCombination(testKeys, 0 /* duration */);
         sendKeyCombination(testKeys, 0 /* duration */);
         mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
-                expectedKey, expectedModifierState, "Failed while executing " + testName);
+                expectedKey, expectedModifierState, DEVICE_BUS,
+                "Failed while executing " + testName);
     }
 
     @Test
@@ -351,6 +348,7 @@
         mPhoneWindowManager.overrideShortPressOnSettingsBehavior(shortPressOnSettingsBehavior);
         sendKeyCombination(testKeys, 0 /* duration */);
         mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
-                expectedKey, expectedModifierState, "Failed while executing " + testName);
+                expectedKey, expectedModifierState, DEVICE_BUS,
+                "Failed while executing " + testName);
     }
 }
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 7788b33..43c4745 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -483,10 +483,15 @@
         doReturn(mPackageManager).when(mContext).getPackageManager();
     }
 
-    void overrideKeyEventSource(int vendorId, int productId) {
-        InputDevice device = new InputDevice.Builder().setId(1).setVendorId(vendorId).setProductId(
-                productId).setSources(InputDevice.SOURCE_KEYBOARD).setKeyboardType(
-                InputDevice.KEYBOARD_TYPE_ALPHABETIC).build();
+    void overrideKeyEventSource(int vendorId, int productId, int deviceBus) {
+        InputDevice device = new InputDevice.Builder()
+                .setId(1)
+                .setVendorId(vendorId)
+                .setProductId(productId)
+                .setDeviceBus(deviceBus)
+                .setSources(InputDevice.SOURCE_KEYBOARD)
+                .setKeyboardType(InputDevice.KEYBOARD_TYPE_ALPHABETIC)
+                .build();
         doReturn(mInputManager).when(mContext).getSystemService(eq(InputManager.class));
         doReturn(device).when(mInputManager).getInputDevice(anyInt());
     }
@@ -682,11 +687,11 @@
     }
 
     void assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent,
-            int expectedKey, int expectedModifierState, String errorMsg) {
+            int expectedKey, int expectedModifierState, int deviceBus, String errorMsg) {
         mTestLooper.dispatchAll();
         verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
                         vendorId, productId, logEvent.getIntValue(), new int[]{expectedKey},
-                        expectedModifierState), description(errorMsg));
+                        expectedModifierState, deviceBus), description(errorMsg));
     }
 
     void assertSwitchToRecent(int persistentId) throws RemoteException {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index 9f58491..9efbe35 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -25,8 +25,6 @@
 import static com.android.server.wm.utils.LastCallVerifier.lastCall;
 
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -36,11 +34,14 @@
 
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 
 import com.android.server.testutils.StubTransaction;
 import com.android.server.wm.utils.MockAnimationAdapter;
+import com.android.window.flags.Flags;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -122,7 +123,8 @@
         }
     }
 
-    static class MockAnimationAdapterFactory extends SmoothDimmer.AnimationAdapterFactory {
+    static class MockAnimationAdapterFactory extends DimmerAnimationHelper.AnimationAdapterFactory {
+        @Override
         public AnimationAdapter get(LocalAnimationAdapter.AnimationSpec alphaAnimationSpec,
                 SurfaceAnimationRunner runner) {
             return sTestAnimation;
@@ -175,8 +177,8 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
     public void testDimBelowWithChildSurfaceCreatesSurfaceBelowChild_Smooth() {
-        assumeTrue(Dimmer.DIMMER_REFACTOR);
         final float alpha = 0.7f;
         final int blur = 50;
         mHost.addChild(mChild, 0);
@@ -195,8 +197,8 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
     public void testDimBelowWithChildSurfaceCreatesSurfaceBelowChild_Legacy() {
-        assumeFalse(Dimmer.DIMMER_REFACTOR);
         final float alpha = 0.7f;
         mHost.addChild(mChild, 0);
         mDimmer.adjustAppearance(mChild, alpha, 20);
@@ -210,8 +212,8 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
     public void testDimBelowWithChildSurfaceDestroyedWhenReset_Smooth() {
-        assumeTrue(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
 
         final float alpha = 0.8f;
@@ -230,8 +232,8 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
     public void testDimBelowWithChildSurfaceDestroyedWhenReset_Legacy() {
-        assumeFalse(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
 
         final float alpha = 0.8f;
@@ -290,8 +292,8 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
     public void testRemoveDimImmediately_Smooth() {
-        assumeTrue(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
         mDimmer.adjustAppearance(mChild, 1, 2);
         mDimmer.adjustRelativeLayer(mChild, -1);
@@ -310,8 +312,8 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
     public void testRemoveDimImmediately_Legacy() {
-        assumeFalse(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
         mDimmer.adjustAppearance(mChild, 1, 0);
         mDimmer.adjustRelativeLayer(mChild, -1);
@@ -330,8 +332,8 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
     public void testDimmerWithBlurUpdatesTransaction_Legacy() {
-        assumeFalse(Dimmer.DIMMER_REFACTOR);
         mHost.addChild(mChild, 0);
 
         final int blurRadius = 50;
@@ -344,4 +346,120 @@
         verify(mHost.getPendingTransaction()).setBackgroundBlurRadius(dimLayer, blurRadius);
         verify(mHost.getPendingTransaction()).setRelativeLayer(dimLayer, mChild.mControl, -1);
     }
+
+    /**
+     * mChild is requesting the dim values to be set directly. In this case, dim won't play the
+     * standard animation, but directly apply mChild's requests to the dim surface
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
+    public void testContainerDimsOpeningAnimationByItself() {
+        mHost.addChild(mChild, 0);
+
+        mDimmer.resetDimStates();
+        mDimmer.adjustAppearance(mChild, 0.1f, 0);
+        mDimmer.adjustRelativeLayer(mChild, -1);
+        SurfaceControl dimLayer = mDimmer.getDimLayer();
+        mDimmer.updateDims(mTransaction);
+
+        mDimmer.resetDimStates();
+        mDimmer.adjustAppearance(mChild, 0.2f, 0);
+        mDimmer.adjustRelativeLayer(mChild, -1);
+        mDimmer.updateDims(mTransaction);
+
+        mDimmer.resetDimStates();
+        mDimmer.adjustAppearance(mChild, 0.3f, 0);
+        mDimmer.adjustRelativeLayer(mChild, -1);
+        mDimmer.updateDims(mTransaction);
+
+        verify(mTransaction).setAlpha(dimLayer, 0.2f);
+        verify(mTransaction).setAlpha(dimLayer, 0.3f);
+        verify(sTestAnimation, times(1)).startAnimation(
+                any(SurfaceControl.class), any(SurfaceControl.Transaction.class),
+                anyInt(), any(SurfaceAnimator.OnAnimationFinishedCallback.class));
+    }
+
+    /**
+     * Same as testContainerDimsOpeningAnimationByItself, but this is a more specific case in which
+     * alpha is animated to 0. This corner case is needed to verify that the layer is removed anyway
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
+    public void testContainerDimsClosingAnimationByItself() {
+        mHost.addChild(mChild, 0);
+
+        mDimmer.resetDimStates();
+        mDimmer.adjustAppearance(mChild, 0.2f, 0);
+        mDimmer.adjustRelativeLayer(mChild, -1);
+        SurfaceControl dimLayer = mDimmer.getDimLayer();
+        mDimmer.updateDims(mTransaction);
+
+        mDimmer.resetDimStates();
+        mDimmer.adjustAppearance(mChild, 0.1f, 0);
+        mDimmer.adjustRelativeLayer(mChild, -1);
+        mDimmer.updateDims(mTransaction);
+
+        mDimmer.resetDimStates();
+        mDimmer.adjustAppearance(mChild, 0f, 0);
+        mDimmer.adjustRelativeLayer(mChild, -1);
+        mDimmer.updateDims(mTransaction);
+
+        mDimmer.resetDimStates();
+        mDimmer.updateDims(mTransaction);
+        verify(mTransaction).remove(dimLayer);
+    }
+
+    /**
+     * Check the handover of the dim between two windows and the consequent dim animation in between
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
+    public void testMultipleContainersDimmingConsecutively() {
+        TestWindowContainer first = mChild;
+        TestWindowContainer second = new TestWindowContainer(mWm);
+        mHost.addChild(first, 0);
+        mHost.addChild(second, 1);
+
+        mDimmer.adjustAppearance(first, 0.5f, 0);
+        mDimmer.adjustRelativeLayer(first, -1);
+        SurfaceControl dimLayer = mDimmer.getDimLayer();
+        mDimmer.updateDims(mTransaction);
+
+        mDimmer.resetDimStates();
+        mDimmer.adjustAppearance(second, 0.9f, 0);
+        mDimmer.adjustRelativeLayer(second, -1);
+        mDimmer.updateDims(mTransaction);
+
+        verify(sTestAnimation, times(2)).startAnimation(
+                any(SurfaceControl.class), any(SurfaceControl.Transaction.class),
+                anyInt(), any(SurfaceAnimator.OnAnimationFinishedCallback.class));
+        verify(mTransaction).setAlpha(dimLayer, 0.5f);
+        verify(mTransaction).setAlpha(dimLayer, 0.9f);
+    }
+
+    /**
+     * Two windows are trying to modify the dim at the same time, but only the last request before
+     * updateDims will be satisfied
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_INTRODUCE_SMOOTHER_DIMMER)
+    public void testMultipleContainersDimmingAtTheSameTime() {
+        TestWindowContainer first = mChild;
+        TestWindowContainer second = new TestWindowContainer(mWm);
+        mHost.addChild(first, 0);
+        mHost.addChild(second, 1);
+
+        mDimmer.adjustAppearance(first, 0.5f, 0);
+        mDimmer.adjustRelativeLayer(first, -1);
+        SurfaceControl dimLayer = mDimmer.getDimLayer();
+        mDimmer.adjustAppearance(second, 0.9f, 0);
+        mDimmer.adjustRelativeLayer(second, -1);
+        mDimmer.updateDims(mTransaction);
+
+        verify(sTestAnimation, times(1)).startAnimation(
+                any(SurfaceControl.class), any(SurfaceControl.Transaction.class),
+                anyInt(), any(SurfaceAnimator.OnAnimationFinishedCallback.class));
+        verify(mTransaction, never()).setAlpha(dimLayer, 0.5f);
+        verify(mTransaction).setAlpha(dimLayer, 0.9f);
+    }
 }
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 5a43498..0608cf4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -362,6 +362,8 @@
         // Ensure a task has moved over.
         ensureTaskPlacement(task, activity);
         assertTrue(task.inPinnedWindowingMode());
+        assertFalse("Entering PiP activity must not affect SysUiFlags",
+                activity.canAffectSystemUiFlags());
 
         // The activity with fixed orientation should not apply letterbox when entering PiP.
         final int requestedOrientation = task.getConfiguration().orientation
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java
index 8119fd4..3b9ed26 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java
@@ -23,15 +23,14 @@
 
 import static org.junit.Assert.assertTrue;
 
-import android.app.Activity;
 import android.app.Instrumentation;
 import android.content.res.Configuration;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
+import android.server.wm.BuildUtils;
 import android.view.Gravity;
 import android.view.IWindow;
 import android.view.SurfaceControl;
@@ -46,12 +45,12 @@
 import android.widget.FrameLayout;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
 
 import com.android.server.wm.utils.CommonUtils;
+import com.android.server.wm.utils.TestActivity;
 
 import org.junit.After;
 import org.junit.Before;
@@ -59,11 +58,14 @@
 import org.junit.runner.RunWith;
 
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 @Presubmit
 @SmallTest
 @RunWith(WindowTestRunner.class)
 public class SurfaceControlViewHostTests {
+    private static final long WAIT_TIME_S = 5L * BuildUtils.HW_TIMEOUT_MULTIPLIER;
+
     private static final String TAG = "SurfaceControlViewHostTests";
 
     private final ActivityTestRule<TestActivity> mActivityRule = new ActivityTestRule<>(
@@ -76,6 +78,8 @@
     private SurfaceControlViewHost mScvh1;
     private SurfaceControlViewHost mScvh2;
 
+    private SurfaceView mSurfaceView;
+
     @Before
     public void setUp() throws Exception {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -96,15 +100,17 @@
         mView1 = new Button(mActivity);
         mView2 = new Button(mActivity);
 
-        mInstrumentation.runOnMainSync(() -> {
-            try {
-                mActivity.attachToSurfaceView(sc);
-            } catch (InterruptedException e) {
-            }
+        CountDownLatch svReadyLatch = new CountDownLatch(1);
+        mActivity.runOnUiThread(() -> addSurfaceView(svReadyLatch));
+        assertTrue("Failed to wait for SV to get created",
+                svReadyLatch.await(WAIT_TIME_S, TimeUnit.SECONDS));
+        new SurfaceControl.Transaction().reparent(sc, mSurfaceView.getSurfaceControl())
+                .show(sc).apply();
 
+        mInstrumentation.runOnMainSync(() -> {
             TestWindowlessWindowManager wwm = new TestWindowlessWindowManager(
                     mActivity.getResources().getConfiguration(), sc,
-                    mActivity.mSurfaceView.getHostToken());
+                    mSurfaceView.getHostToken());
 
             mScvh1 = new SurfaceControlViewHost(mActivity, mActivity.getDisplay(),
                     wwm, "requestFocusWithMultipleWindows");
@@ -135,7 +141,7 @@
         }
         assertTrue("Failed to wait for view2", wasVisible);
 
-        IWindow window = IWindow.Stub.asInterface(mActivity.mSurfaceView.getWindowToken());
+        IWindow window = IWindow.Stub.asInterface(mSurfaceView.getWindowToken());
 
         WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(window,
                 mScvh1.getInputTransferToken(), true);
@@ -162,43 +168,30 @@
         }
     }
 
-    public static class TestActivity extends Activity implements SurfaceHolder.Callback {
-        private SurfaceView mSurfaceView;
-        private final CountDownLatch mSvReadyLatch = new CountDownLatch(1);
+    private void addSurfaceView(CountDownLatch svReadyLatch) {
+        final FrameLayout content = mActivity.getParentLayout();
+        mSurfaceView = new SurfaceView(mActivity);
+        mSurfaceView.setZOrderOnTop(true);
+        final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(500, 500,
+                Gravity.LEFT | Gravity.TOP);
+        mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
+            @Override
+            public void surfaceCreated(@NonNull SurfaceHolder holder) {
+                svReadyLatch.countDown();
+            }
 
-        @Override
-        protected void onCreate(@Nullable Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            final FrameLayout content = new FrameLayout(this);
-            mSurfaceView = new SurfaceView(this);
-            mSurfaceView.setBackgroundColor(Color.BLACK);
-            mSurfaceView.setZOrderOnTop(true);
-            final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(500, 500,
-                    Gravity.LEFT | Gravity.TOP);
-            content.addView(mSurfaceView, lp);
-            setContentView(content);
-            mSurfaceView.getHolder().addCallback(this);
-        }
+            @Override
+            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
+                    int height) {
 
-        @Override
-        public void surfaceCreated(@NonNull SurfaceHolder holder) {
-            mSvReadyLatch.countDown();
-        }
+            }
 
-        @Override
-        public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
-                int height) {
-        }
+            @Override
+            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
 
-        @Override
-        public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
-        }
-
-        public void attachToSurfaceView(SurfaceControl sc) throws InterruptedException {
-            mSvReadyLatch.await();
-            new SurfaceControl.Transaction().reparent(sc, mSurfaceView.getSurfaceControl())
-                    .show(sc).apply();
-        }
+            }
+        });
+        content.addView(mSurfaceView, lp);
     }
 }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java
index 3cb4a1d..e65a9fe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java
@@ -19,6 +19,8 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 
 import android.os.Handler;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.testing.DexmakerShareClassLoaderRule;
 
@@ -39,6 +41,9 @@
     public final SystemServicesTestRule mSystemServicesTestRule = new SystemServicesTestRule(
             this::onBeforeSystemServicesCreated);
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @WindowTestRunner.MethodWrapperRule
     public final WindowManagerGlobalLockRule mLockRule =
             new WindowManagerGlobalLockRule(mSystemServicesTestRule);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index b1def8d..51f0404 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -444,7 +444,9 @@
         SurfaceAnimationThread.dispose();
         AnimationThread.dispose();
         UiThread.dispose();
-        mInputChannel.dispose();
+        if (mInputChannel != null) {
+            mInputChannel.dispose();
+        }
 
         tearDownLocalServices();
         // Reset priority booster because animation thread has been changed.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index 8a90f12..06f29c2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -25,7 +25,9 @@
 import static android.view.WindowManager.TRANSIT_NONE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE;
 import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE;
 import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_BOTTOM_OF_TASK;
 import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
 import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_TOP_OF_TASK;
@@ -1759,6 +1761,40 @@
     }
 
     @Test
+    public void testApplyTransaction_createTaskFragmentDecorSurface() {
+        // TODO(b/293654166) remove system organizer requirement once security review is cleared.
+        mController.unregisterOrganizer(mIOrganizer);
+        mController.registerOrganizerInternal(mIOrganizer, true /* isSystemOrganizer */);
+        final Task task = createTask(mDisplayContent);
+
+        final TaskFragment tf = createTaskFragment(task);
+        final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+                OP_TYPE_CREATE_TASK_FRAGMENT_DECOR_SURFACE).build();
+        mTransaction.addTaskFragmentOperation(tf.getFragmentToken(), operation);
+
+        assertApplyTransactionAllowed(mTransaction);
+
+        verify(task).moveOrCreateDecorSurfaceFor(tf);
+    }
+
+    @Test
+    public void testApplyTransaction_removeTaskFragmentDecorSurface() {
+        // TODO(b/293654166) remove system organizer requirement once security review is cleared.
+        mController.unregisterOrganizer(mIOrganizer);
+        mController.registerOrganizerInternal(mIOrganizer, true /* isSystemOrganizer */);
+        final Task task = createTask(mDisplayContent);
+        final TaskFragment tf = createTaskFragment(task);
+
+        final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+                OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE).build();
+        mTransaction.addTaskFragmentOperation(tf.getFragmentToken(), operation);
+
+        assertApplyTransactionAllowed(mTransaction);
+
+        verify(task).removeDecorSurface();
+    }
+
+    @Test
     public void testApplyTransaction_reorderToBottomOfTask_failsIfNotSystemOrganizer() {
         testApplyTransaction_reorder_failsIfNotSystemOrganizer_common(
                 OP_TYPE_REORDER_TO_BOTTOM_OF_TASK);
@@ -1966,7 +2002,8 @@
     /** Setups the mock Task as the parent of the given TaskFragment. */
     private static void setupMockParent(TaskFragment taskFragment, Task mockParent) {
         doReturn(mockParent).when(taskFragment).getTask();
-        doReturn(new TaskFragmentParentInfo(new Configuration(), DEFAULT_DISPLAY, true, true))
+        doReturn(new TaskFragmentParentInfo(
+                new Configuration(), DEFAULT_DISPLAY, true, true, null /* decorSurface */))
                 .when(mockParent).getTaskFragmentParentInfo();
 
         // Task needs to be visible
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 5e531b4..da7612b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -63,6 +63,7 @@
 import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 
 import android.app.ActivityManager;
@@ -82,6 +83,7 @@
 import android.util.Xml;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.SurfaceControl;
 import android.window.TaskFragmentOrganizer;
 
 import androidx.test.filters.MediumTest;
@@ -1619,6 +1621,185 @@
         assertFalse(task.isDragResizing());
     }
 
+    @Test
+    public void testMoveOrCreateDecorSurface() {
+        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+        final Task task =  new TaskBuilder(mSupervisor).setCreateActivity(true).build();
+        final ActivityRecord activity = task.getTopMostActivity();
+        final TaskFragment fragment = createTaskFragmentWithEmbeddedActivity(task, organizer);
+        doNothing().when(task).sendTaskFragmentParentInfoChangedIfNeeded();
+
+        // Decor surface should not be present initially.
+        assertNull(task.mDecorSurfaceContainer);
+        assertNull(task.getDecorSurface());
+        assertNull(task.getTaskFragmentParentInfo().getDecorSurface());
+
+        // Decor surface should be created.
+        clearInvocations(task);
+        task.moveOrCreateDecorSurfaceFor(fragment);
+
+        assertNotNull(task.mDecorSurfaceContainer);
+        assertNotNull(task.getDecorSurface());
+        verify(task).sendTaskFragmentParentInfoChangedIfNeeded();
+        assertNotNull(task.getTaskFragmentParentInfo().getDecorSurface());
+        assertEquals(fragment, task.mDecorSurfaceContainer.mOwnerTaskFragment);
+
+        // Decor surface should be removed.
+        clearInvocations(task);
+        task.removeDecorSurface();
+
+        assertNull(task.mDecorSurfaceContainer);
+        assertNull(task.getDecorSurface());
+        verify(task).sendTaskFragmentParentInfoChangedIfNeeded();
+        assertNull(task.getTaskFragmentParentInfo().getDecorSurface());
+    }
+
+    @Test
+    public void testMoveOrCreateDecorSurface_whenOwnerTaskFragmentRemoved() {
+        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+        final Task task =  new TaskBuilder(mSupervisor).setCreateActivity(true).build();
+        final ActivityRecord activity = task.getTopMostActivity();
+        final TaskFragment fragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer);
+        final TaskFragment fragment2 = createTaskFragmentWithEmbeddedActivity(task, organizer);
+        doNothing().when(task).sendTaskFragmentParentInfoChangedIfNeeded();
+
+        task.moveOrCreateDecorSurfaceFor(fragment1);
+
+        assertNotNull(task.mDecorSurfaceContainer);
+        assertNotNull(task.getDecorSurface());
+        assertEquals(fragment1, task.mDecorSurfaceContainer.mOwnerTaskFragment);
+
+        // Transfer ownership
+        task.moveOrCreateDecorSurfaceFor(fragment2);
+
+        assertNotNull(task.mDecorSurfaceContainer);
+        assertNotNull(task.getDecorSurface());
+        assertEquals(fragment2, task.mDecorSurfaceContainer.mOwnerTaskFragment);
+
+        // Safe surface should be removed when the owner TaskFragment is removed.
+        task.removeChild(fragment2);
+
+        verify(task).removeDecorSurface();
+        assertNull(task.mDecorSurfaceContainer);
+        assertNull(task.getDecorSurface());
+    }
+
+    @Test
+    public void testAssignChildLayers_decorSurfacePlacement() {
+        final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+        final Task task =  new TaskBuilder(mSupervisor).setCreateActivity(true).build();
+        final ActivityRecord unembeddedActivity = task.getTopMostActivity();
+
+        final TaskFragment fragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer);
+        final TaskFragment fragment2 = createTaskFragmentWithEmbeddedActivity(task, organizer);
+        final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
+
+        doNothing().when(task).sendTaskFragmentParentInfoChangedIfNeeded();
+        spyOn(unembeddedActivity);
+        spyOn(fragment1);
+        spyOn(fragment2);
+
+        // Initially, the decor surface should not be placed.
+        task.assignChildLayers(t);
+        verify(unembeddedActivity).assignLayer(t, 0);
+        verify(fragment1).assignLayer(t, 1);
+        verify(fragment2).assignLayer(t, 2);
+
+        clearInvocations(t);
+        clearInvocations(unembeddedActivity);
+        clearInvocations(fragment1);
+        clearInvocations(fragment2);
+
+        // The decor surface should be placed just above the owner TaskFragment.
+        doReturn(true).when(unembeddedActivity).isUid(task.effectiveUid);
+        doReturn(true).when(fragment1).isAllowedToBeEmbeddedInTrustedMode();
+        doReturn(true).when(fragment2).isAllowedToBeEmbeddedInTrustedMode();
+        doReturn(true).when(fragment1).isVisible();
+
+        task.moveOrCreateDecorSurfaceFor(fragment1);
+        task.assignChildLayers(t);
+
+        verify(unembeddedActivity).assignLayer(t, 0);
+        verify(fragment1).assignLayer(t, 1);
+        verify(t).setLayer(task.mDecorSurfaceContainer.mContainerSurface, 2);
+        verify(fragment2).assignLayer(t, 3);
+        verify(t).setVisibility(task.mDecorSurfaceContainer.mContainerSurface, true);
+        verify(t, never()).setLayer(eq(task.getDecorSurface()), anyInt());
+
+        clearInvocations(t);
+        clearInvocations(unembeddedActivity);
+        clearInvocations(fragment1);
+        clearInvocations(fragment2);
+
+        // The decor surface should be invisible if the owner TaskFragment is invisible.
+        doReturn(true).when(unembeddedActivity).isUid(task.effectiveUid);
+        doReturn(true).when(fragment1).isAllowedToBeEmbeddedInTrustedMode();
+        doReturn(true).when(fragment2).isAllowedToBeEmbeddedInTrustedMode();
+        doReturn(false).when(fragment1).isVisible();
+
+        task.assignChildLayers(t);
+
+        verify(unembeddedActivity).assignLayer(t, 0);
+        verify(fragment1).assignLayer(t, 1);
+        verify(t).setLayer(task.mDecorSurfaceContainer.mContainerSurface, 2);
+        verify(fragment2).assignLayer(t, 3);
+        verify(t).setVisibility(task.mDecorSurfaceContainer.mContainerSurface, false);
+        verify(t, never()).setLayer(eq(task.getDecorSurface()), anyInt());
+
+        clearInvocations(t);
+        clearInvocations(unembeddedActivity);
+        clearInvocations(fragment1);
+        clearInvocations(fragment2);
+
+        // The decor surface should be placed on below activity from a different UID.
+        doReturn(false).when(unembeddedActivity).isUid(task.effectiveUid);
+        doReturn(true).when(fragment1).isAllowedToBeEmbeddedInTrustedMode();
+        doReturn(true).when(fragment2).isAllowedToBeEmbeddedInTrustedMode();
+        doReturn(true).when(fragment1).isVisible();
+
+        task.assignChildLayers(t);
+
+        verify(t).setLayer(task.mDecorSurfaceContainer.mContainerSurface, 0);
+        verify(unembeddedActivity).assignLayer(t, 1);
+        verify(fragment1).assignLayer(t, 2);
+        verify(fragment2).assignLayer(t, 3);
+        verify(t).setVisibility(task.mDecorSurfaceContainer.mContainerSurface, true);
+        verify(t, never()).setLayer(eq(task.getDecorSurface()), anyInt());
+
+        clearInvocations(t);
+        clearInvocations(unembeddedActivity);
+        clearInvocations(fragment1);
+        clearInvocations(fragment2);
+
+        // The decor surface should be placed below untrusted embedded TaskFragment.
+        doReturn(true).when(unembeddedActivity).isUid(task.effectiveUid);
+        doReturn(true).when(fragment1).isAllowedToBeEmbeddedInTrustedMode();
+        doReturn(false).when(fragment2).isAllowedToBeEmbeddedInTrustedMode();
+        doReturn(true).when(fragment1).isVisible();
+
+        task.assignChildLayers(t);
+
+        verify(unembeddedActivity).assignLayer(t, 0);
+        verify(fragment1).assignLayer(t, 1);
+        verify(t).setLayer(task.mDecorSurfaceContainer.mContainerSurface, 2);
+        verify(fragment2).assignLayer(t, 3);
+        verify(t).setVisibility(task.mDecorSurfaceContainer.mContainerSurface, true);
+        verify(t, never()).setLayer(eq(task.getDecorSurface()), anyInt());
+
+        clearInvocations(t);
+        clearInvocations(unembeddedActivity);
+        clearInvocations(fragment1);
+        clearInvocations(fragment2);
+
+        // The decor surface should not be placed after removal.
+        task.removeDecorSurface();
+        task.assignChildLayers(t);
+
+        verify(unembeddedActivity).assignLayer(t, 0);
+        verify(fragment1).assignLayer(t, 1);
+        verify(fragment2).assignLayer(t, 2);
+    }
+
     private Task getTestTask() {
         return new TaskBuilder(mSupervisor).setCreateActivity(true).build();
     }
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 dade3b9..71447e7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -2015,6 +2015,9 @@
         transition.collect(leafTaskA);
         rootTaskA.moveToFront("test", leafTaskA);
 
+        // Test has order changes, a shallow check of order changes
+        assertTrue(transition.hasOrderChanges());
+
         // All the tasks were already visible, so there shouldn't be any changes
         ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(
                 participants, changes);
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/TestActivity.java b/services/tests/wmtests/src/com/android/server/wm/utils/TestActivity.java
new file mode 100644
index 0000000..c12dcdd
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/TestActivity.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.systemBars;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.os.Bundle;
+import android.view.WindowInsetsController;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+
+import androidx.annotation.Nullable;
+
+/**
+ * TestActivity that will ensure it dismisses keyguard and shows as a fullscreen activity.
+ */
+public class TestActivity extends Activity {
+    private static final int sTypeMask = systemBars() | displayCutout();
+    private FrameLayout mParentLayout;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mParentLayout = new FrameLayout(this);
+        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
+                FrameLayout.LayoutParams.MATCH_PARENT,
+                FrameLayout.LayoutParams.MATCH_PARENT);
+        setContentView(mParentLayout, layoutParams);
+
+        WindowInsetsController windowInsetsController = getWindow().getInsetsController();
+        windowInsetsController.hide(sTypeMask);
+        WindowManager.LayoutParams params = getWindow().getAttributes();
+        params.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        getWindow().setAttributes(params);
+        getWindow().setDecorFitsSystemWindows(false);
+
+        final KeyguardManager keyguardManager = getInstrumentation().getContext().getSystemService(
+                KeyguardManager.class);
+        if (keyguardManager != null && keyguardManager.isKeyguardLocked()) {
+            keyguardManager.requestDismissKeyguard(this, null);
+        }
+    }
+
+    public FrameLayout getParentLayout() {
+        return mParentLayout;
+    }
+}
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index bfb159f..dce4818 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -31,6 +31,7 @@
 import static android.app.usage.UsageEvents.Event.LOCUS_ID_SET;
 import static android.app.usage.UsageEvents.Event.NOTIFICATION_INTERRUPTION;
 import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE;
+import static android.app.usage.UsageEvents.Event.USER_INTERACTION;
 import static android.app.usage.UsageEvents.Event.SCREEN_INTERACTIVE;
 import static android.app.usage.UsageEvents.Event.SCREEN_NON_INTERACTIVE;
 import static android.app.usage.UsageEvents.Event.SHORTCUT_INVOCATION;
@@ -42,7 +43,9 @@
 import android.app.usage.EventStats;
 import android.app.usage.UsageEvents.Event;
 import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
 import android.content.res.Configuration;
+import android.os.PersistableBundle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -575,6 +578,23 @@
                         continue;
                     }
                     break;
+                case USER_INTERACTION:
+                    if (event.mUserInteractionExtrasToken != null) {
+                        String category = packagesTokenData.getString(packageToken,
+                                event.mUserInteractionExtrasToken.mCategoryToken);
+                        String action = packagesTokenData.getString(packageToken,
+                                event.mUserInteractionExtrasToken.mActionToken);
+                        if (TextUtils.isEmpty(category) || TextUtils.isEmpty(action)) {
+                            this.events.remove(i);
+                            dataOmitted = true;
+                            continue;
+                        }
+                        event.mExtras = new PersistableBundle();
+                        event.mExtras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, category);
+                        event.mExtras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, action);
+                        event.mUserInteractionExtrasToken = null;
+                    }
+                    break;
             }
         }
         if (dataOmitted) {
@@ -692,13 +712,30 @@
                                 event.mPackage, event.mLocusId);
                     }
                     break;
+                case USER_INTERACTION:
+                    if (event.mExtras != null && event.mExtras.size() != 0) {
+                        final String category = event.mExtras.getString(
+                                UsageStatsManager.EXTRA_EVENT_CATEGORY);
+                        final String action = event.mExtras.getString(
+                                UsageStatsManager.EXTRA_EVENT_ACTION);
+                        if (!TextUtils.isEmpty(category) && !TextUtils.isEmpty(action)) {
+                            event.mUserInteractionExtrasToken =
+                                    new Event.UserInteractionEventExtrasToken();
+                            event.mUserInteractionExtrasToken.mCategoryToken =
+                                    packagesTokenData.getTokenOrAdd(packageToken, event.mPackage,
+                                            category);
+                            event.mUserInteractionExtrasToken.mActionToken =
+                                    packagesTokenData.getTokenOrAdd(packageToken, event.mPackage,
+                                            action);
+                        }
+                    }
+                    break;
             }
         }
     }
 
     /**
      * Obfuscates the data in this instance of interval stats.
-     *
      * @hide
      */
     public void obfuscateData(PackagesTokenData packagesTokenData) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java b/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java
index 8138747..d865345 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java
@@ -17,8 +17,10 @@
 
 import android.app.usage.ConfigurationStats;
 import android.app.usage.UsageEvents;
+import android.app.usage.UsageEvents.Event.UserInteractionEventExtrasToken;
 import android.app.usage.UsageStats;
 import android.content.res.Configuration;
+import android.os.PersistableBundle;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -26,6 +28,8 @@
 import android.util.proto.ProtoInputStream;
 import android.util.proto.ProtoOutputStream;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -282,6 +286,16 @@
                     event.mLocusIdToken = proto.readInt(
                             EventObfuscatedProto.LOCUS_ID_TOKEN) - 1;
                     break;
+                case (int) EventObfuscatedProto.INTERACTION_EXTRAS:
+                    try {
+                        final long interactionExtrasToken = proto.start(
+                                EventObfuscatedProto.INTERACTION_EXTRAS);
+                        event.mUserInteractionExtrasToken = parseUserInteractionEventExtras(proto);
+                        proto.end(interactionExtrasToken);
+                    } catch (IOException e) {
+                        Slog.e(TAG, "Unable to read some user interaction extras from proto.", e);
+                    }
+                    break;
                 case ProtoInputStream.NO_MORE_FIELDS:
                     return event.mPackageToken == PackagesTokenData.UNASSIGNED_TOKEN ? null : event;
             }
@@ -386,7 +400,7 @@
     }
 
     private static void writeEvent(ProtoOutputStream proto, final long statsBeginTime,
-            final UsageEvents.Event event) throws IllegalArgumentException {
+            final UsageEvents.Event event) throws IOException, IllegalArgumentException {
         proto.write(EventObfuscatedProto.PACKAGE_TOKEN, event.mPackageToken + 1);
         if (event.mClassToken != PackagesTokenData.UNASSIGNED_TOKEN) {
             proto.write(EventObfuscatedProto.CLASS_TOKEN, event.mClassToken + 1);
@@ -429,6 +443,12 @@
                             event.mNotificationChannelIdToken + 1);
                 }
                 break;
+            case UsageEvents.Event.USER_INTERACTION:
+                if (event.mUserInteractionExtrasToken != null) {
+                    writeUserInteractionEventExtras(proto, EventObfuscatedProto.INTERACTION_EXTRAS,
+                            event.mUserInteractionExtrasToken);
+                }
+                break;
         }
     }
 
@@ -703,6 +723,9 @@
                 case (int) PendingEventProto.TASK_ROOT_CLASS:
                     event.mTaskRootClass = proto.readString(PendingEventProto.TASK_ROOT_CLASS);
                     break;
+                case (int) PendingEventProto.EXTRAS:
+                    event.mExtras = parsePendingEventExtras(proto, PendingEventProto.EXTRAS);
+                    break;
                 case ProtoInputStream.NO_MORE_FIELDS:
                     // Handle default values for certain events types
                     switch (event.mEventType) {
@@ -757,7 +780,7 @@
     }
 
     private static void writePendingEvent(ProtoOutputStream proto, UsageEvents.Event event)
-            throws IllegalArgumentException {
+            throws IOException, IllegalArgumentException {
         proto.write(PendingEventProto.PACKAGE_NAME, event.mPackage);
         if (event.mClass != null) {
             proto.write(PendingEventProto.CLASS_NAME, event.mClass);
@@ -794,6 +817,11 @@
                             event.mNotificationChannelId);
                 }
                 break;
+            case UsageEvents.Event.USER_INTERACTION:
+                if (event.mExtras != null && event.mExtras.size() != 0) {
+                    writePendingEventExtras(proto, PendingEventProto.EXTRAS, event.mExtras);
+                }
+                break;
         }
     }
 
@@ -888,4 +916,52 @@
             proto.end(token);
         }
     }
+
+    private static UserInteractionEventExtrasToken parseUserInteractionEventExtras(
+            ProtoInputStream proto) throws IOException {
+        UserInteractionEventExtrasToken interactionExtrasToken =
+                new UserInteractionEventExtrasToken();
+        while (true) {
+            switch (proto.nextField()) {
+                case (int) ObfuscatedUserInteractionExtrasProto.CATEGORY_TOKEN:
+                    interactionExtrasToken.mCategoryToken = proto.readInt(
+                            ObfuscatedUserInteractionExtrasProto.CATEGORY_TOKEN) - 1;
+                    break;
+                case (int) ObfuscatedUserInteractionExtrasProto.ACTION_TOKEN:
+                    interactionExtrasToken.mActionToken = proto.readInt(
+                            ObfuscatedUserInteractionExtrasProto.ACTION_TOKEN) - 1;
+                    break;
+                case ProtoInputStream.NO_MORE_FIELDS:
+                    return interactionExtrasToken;
+            }
+        }
+    }
+
+    static void writeUserInteractionEventExtras(ProtoOutputStream proto, long fieldId,
+            UserInteractionEventExtrasToken interactionExtras) {
+        final long token = proto.start(fieldId);
+        proto.write(ObfuscatedUserInteractionExtrasProto.CATEGORY_TOKEN,
+                interactionExtras.mCategoryToken + 1);
+        proto.write(ObfuscatedUserInteractionExtrasProto.ACTION_TOKEN,
+                interactionExtras.mActionToken + 1);
+        proto.end(token);
+    }
+
+    /**
+     * Populates the extra details for pending interaction event from the protobuf stream.
+     */
+    private static PersistableBundle parsePendingEventExtras(ProtoInputStream proto, long fieldId)
+            throws IOException {
+        return PersistableBundle.readFromStream(new ByteArrayInputStream(proto.readBytes(fieldId)));
+    }
+
+    /**
+     * Write the extra details for pending interaction event to a protobuf stream.
+     */
+    static void writePendingEventExtras(ProtoOutputStream proto, long fieldId,
+            PersistableBundle eventExtras) throws IOException {
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        eventExtras.writeToStream(baos);
+        proto.write(fieldId, baos.toByteArray());
+    }
 }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 4c56f33..0e1e0c8 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -83,6 +83,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -91,6 +92,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -193,6 +195,11 @@
 
     private static final char TOKEN_DELIMITER = '/';
 
+    // The maximum length for extras {@link UsageStatsManager#EXTRA_EVENT_CATEGORY},
+    // {@link UsageStatsManager#EXTRA_EVENT_ACTION} in a {@link UsageEvents.Event#mExtras}.
+    // The value will be truncated at this limit.
+    private static final int MAX_TEXT_LENGTH = 127;
+
     // Handler message types.
     static final int MSG_REPORT_EVENT = 0;
     static final int MSG_FLUSH_TO_DISK = 1;
@@ -1814,6 +1821,13 @@
         mHandler.removeMessages(MSG_FLUSH_TO_DISK);
     }
 
+    private String getTrimmedString(String input) {
+        if (input != null && input.length() > MAX_TEXT_LENGTH) {
+            return input.substring(0, MAX_TEXT_LENGTH);
+        }
+        return input;
+    }
+
     /**
      * Called by the Binder stub.
      */
@@ -2253,6 +2267,32 @@
             }
         }
 
+        private void reportUserInteractionInnerHelper(String packageName, @UserIdInt int userId,
+                PersistableBundle extras) {
+            if (Flags.reportUsageStatsPermission()) {
+                if (!canReportUsageStats()) {
+                    throw new SecurityException(
+                        "Only the system or holders of the REPORT_USAGE_STATS"
+                            + " permission are allowed to call reportUserInteraction");
+                }
+            } else {
+                if (!isCallingUidSystem()) {
+                    throw new SecurityException("Only system is allowed to call"
+                        + " reportUserInteraction");
+                }
+            }
+
+            // Verify if this package exists before reporting an event for it.
+            if (mPackageManagerInternal.getPackageUid(packageName, 0, userId) < 0) {
+                throw new IllegalArgumentException("Package " + packageName + "not exist!");
+            }
+
+            final Event event = new Event(USER_INTERACTION, SystemClock.elapsedRealtime());
+            event.mPackage = packageName;
+            event.mExtras = extras;
+            reportEventOrAddToQueue(userId, event);
+        }
+
         @Override
         public ParceledListSlice<UsageStats> queryUsageStats(int bucketType, long beginTime,
                 long endTime, String callingPackage, int userId) {
@@ -2686,23 +2726,36 @@
 
         @Override
         public void reportUserInteraction(String packageName, int userId) {
+            reportUserInteractionInnerHelper(packageName, userId, null);
+        }
+
+        @Override
+        public void reportUserInteractionWithBundle(String packageName, @UserIdInt int userId,
+                PersistableBundle extras) {
             Objects.requireNonNull(packageName);
-            if (Flags.reportUsageStatsPermission()) {
-                if (!canReportUsageStats()) {
-                    throw new SecurityException(
-                        "Only the system or holders of the REPORT_USAGE_STATS"
-                            + " permission are allowed to call reportUserInteraction");
-                }
-            } else {
-                if (!isCallingUidSystem()) {
-                    throw new SecurityException("Only system is allowed to call"
-                            + " reportUserInteraction");
-                }
+            if (extras == null || extras.size() == 0) {
+                throw new IllegalArgumentException("Emtry extras!");
             }
 
-            final Event event = new Event(USER_INTERACTION, SystemClock.elapsedRealtime());
-            event.mPackage = packageName;
-            reportEventOrAddToQueue(userId, event);
+            // Only category/action are allowed now, other unknown keys will be trimmed.
+            // Also, empty category/action is not meanful.
+            String category = extras.getString(UsageStatsManager.EXTRA_EVENT_CATEGORY);
+            if (TextUtils.isEmpty(category)) {
+                throw new IllegalArgumentException("Empty "
+                        + UsageStatsManager.EXTRA_EVENT_CATEGORY);
+            }
+            String action = extras.getString(UsageStatsManager.EXTRA_EVENT_ACTION);
+            if (TextUtils.isEmpty(action)) {
+                throw new IllegalArgumentException("Empty "
+                        + UsageStatsManager.EXTRA_EVENT_ACTION);
+            }
+
+            PersistableBundle extrasCopy = new PersistableBundle();
+            extrasCopy.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY,
+                    getTrimmedString(category));
+            extrasCopy.putString(UsageStatsManager.EXTRA_EVENT_ACTION, getTrimmedString(action));
+
+            reportUserInteractionInnerHelper(packageName, userId, extrasCopy);
         }
 
         @Override
@@ -3160,6 +3213,24 @@
         }
 
         @Override
+        public void reportUserInteractionEvent(@NonNull String pkgName, @UserIdInt int userId,
+                @NonNull PersistableBundle extras) {
+            if (extras != null && extras.size() != 0) {
+                // Truncate the value if necessary.
+                String category = extras.getString(UsageStatsManager.EXTRA_EVENT_CATEGORY);
+                String action = extras.getString(UsageStatsManager.EXTRA_EVENT_ACTION);
+                extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY,
+                        getTrimmedString(category));
+                extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, getTrimmedString(action));
+            }
+
+            Event event = new Event(USER_INTERACTION, SystemClock.elapsedRealtime());
+            event.mPackage = pkgName;
+            event.mExtras = extras;
+            reportEventOrAddToQueue(userId, event);
+        }
+
+        @Override
         public boolean isAppIdle(String packageName, int uidForAppId, int userId) {
             return mAppStandby.isAppIdleFiltered(packageName, uidForAppId,
                     userId, SystemClock.elapsedRealtime());
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 9b67ab6..3bc7752 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -1110,6 +1110,10 @@
         if (event.mNotificationChannelId != null) {
             pw.printPair("channelId", event.mNotificationChannelId);
         }
+
+        if ((event.mEventType == Event.USER_INTERACTION) && (event.mExtras != null)) {
+            pw.print(event.mExtras.toString());
+        }
         pw.printHexPair("flags", event.mFlags);
         pw.println();
     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index b098e82..dc8b5a1 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -179,6 +179,31 @@
     private final SparseArray<DetectorSession> mDetectorSessions =
             new SparseArray<>();
 
+    /** Listens to changes to voice activation op. */
+    private final AppOpsManager.OnOpChangedListener mOnOpChangedListener =
+            new AppOpsManager.OnOpChangedListener() {
+                @Override
+                public void onOpChanged(String op, String packageName) {
+                    if (op.equals(AppOpsManager.OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO)) {
+                        AppOpsManager appOpsManager =
+                                mContext.getSystemService(AppOpsManager.class);
+                        synchronized (mLock) {
+                            int checkOp = appOpsManager.unsafeCheckOpNoThrow(
+                                    AppOpsManager.OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO,
+                                    mVoiceInteractorIdentity.uid,
+                                    mVoiceInteractorIdentity.packageName);
+                            // Voice activation app op disabled, safely shutdown hotword detection.
+                            if (checkOp == AppOpsManager.MODE_ERRORED) {
+                                Slog.i(TAG, "Shutdown hotword detection service on voice "
+                                        + "activation op disabled.");
+                                safelyShutdownHotwordDetectionOnVoiceActivationDisabledLocked();
+                            }
+                        }
+                    }
+                }
+            };
+
+
     HotwordDetectionConnection(Object lock, Context context, int voiceInteractionServiceUid,
             Identity voiceInteractorIdentity, ComponentName hotwordDetectionServiceName,
             ComponentName visualQueryDetectionServiceName, int userId,
@@ -216,6 +241,10 @@
 
         mLastRestartInstant = Instant.now();
 
+        AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
+        appOpsManager.startWatchingMode(AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO,
+                mVoiceInteractorIdentity.packageName, mOnOpChangedListener);
+
         if (mReStartPeriodSeconds <= 0) {
             mCancellationTaskFuture = null;
         } else {
@@ -299,7 +328,11 @@
         }
         if (mAudioFlinger != null) {
             mAudioFlinger.unlinkToDeath(mAudioServerDeathRecipient, /* flags= */ 0);
+            mAudioFlinger = null;
         }
+        // Unregister the on op mode changed listener.
+        AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
+        appOpsManager.stopWatchingMode(mOnOpChangedListener);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -553,6 +586,51 @@
         }
     }
 
+    /**
+     * Shutdowns down hotword detection service, swallowing exceptions.
+     *
+     * Called when voice activation app-op has been disabled.
+     */
+    @SuppressWarnings("GuardedBy")
+    void safelyShutdownHotwordDetectionOnVoiceActivationDisabledLocked() {
+        Slog.v(TAG, "safelyShutdownHotwordDetectionOnVoiceActivationDisabled");
+        try {
+            clearDebugHotwordLoggingTimeoutLocked();
+            mRemoteExceptionListener = null;
+            runForEachDetectorSessionLocked((session) -> {
+                if (!(session instanceof VisualQueryDetectorSession)) {
+                    // Inform all detector sessions that they got destroyed due to voice activation
+                    // op being disabled.
+                    session.reportErrorLocked(
+                            new HotwordDetectionServiceFailure(
+                                    HotwordDetectionServiceFailure
+                                            .ERROR_CODE_SHUTDOWN_HDS_ON_VOICE_ACTIVATION_OP_DISABLED,
+                                    "Shutdown hotword detection service on voice "
+                                            + "activation op disabled!"));
+                    session.destroyLocked();
+                }
+            });
+
+            // Remove hotword detection sessions.
+            mDetectorSessions.delete(HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP);
+            mDetectorSessions.delete(HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE);
+
+            mDebugHotwordLogging = false;
+            unbindHotwordDetectionService();
+            if (mCancellationTaskFuture != null) {
+                mCancellationTaskFuture.cancel(/* mayInterruptIfRunning= */ true);
+            }
+            if (mAudioFlinger != null) {
+                mAudioFlinger.unlinkToDeath(mAudioServerDeathRecipient, /* flags= */ 0);
+                mAudioFlinger = null;
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Swallowing error while shutting down hotword detection."
+                    + "Error message: " + e.getMessage());
+        }
+    }
+
+
     static final class SoundTriggerCallback extends IRecognitionStatusCallback.Stub {
         private final HotwordDetectionConnection mHotwordDetectionConnection;
         private final IHotwordRecognitionStatusCallback mExternalCallback;
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index ede4885..1e68687 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -252,6 +252,7 @@
      *
      * The default value is true.
      */
+    @FlaggedApi(Flags.FLAG_SHOW_CALL_ID_AND_CALL_WAITING_IN_ADDITIONAL_SETTINGS_MENU)
     public static final String KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL =
             "additional_settings_caller_id_visibility_bool";
 
@@ -261,6 +262,7 @@
      *
      * The default value is true.
      */
+    @FlaggedApi(Flags.FLAG_SHOW_CALL_ID_AND_CALL_WAITING_IN_ADDITIONAL_SETTINGS_MENU)
     public static final String KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL =
             "additional_settings_call_waiting_visibility_bool";
 
@@ -3349,12 +3351,42 @@
     /**
      * Determines whether we should show a notification when the phone established a data
      * connection in roaming network, to warn users about possible roaming charges.
+     *
+     * @see #KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_EXCLUDED_MCCS_STRING_ARRAY
+     * @see #KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_INCLUDED_MCC_MNCS_STRING_ARRAY
      * @hide
      */
     public static final String KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL =
             "show_data_connected_roaming_notification";
 
     /**
+     * Determines what MCCs are exceptions for the value of
+     * {@link #KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL}.
+     * An empty list indicates that there are no exceptions.
+     *
+     * @see #KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL
+     * @see #KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_INCLUDED_MCC_MNCS_STRING_ARRAY
+     * @hide
+     */
+    public static final String
+            KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_EXCLUDED_MCCS_STRING_ARRAY =
+            "data_connected_roaming_notification_excluded_mccs_string_array";
+
+    /**
+     * Determines what MCC+MNCs are exceptions for the MCCs specified in
+     * {@link #KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_EXCLUDED_MCCS_STRING_ARRAY}, meaning the
+     * value for the MCC+MNC is {@link #KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL}.
+     * An empty list indicates that there are no MNC-specific exceptions.
+     *
+     * @see #KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL
+     * @see #KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_EXCLUDED_MCCS_STRING_ARRAY
+     * @hide
+     */
+    public static final String
+            KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_INCLUDED_MCC_MNCS_STRING_ARRAY =
+            "data_connected_roaming_notification_included_mcc_mncs_string_array";
+
+    /**
      * A list of 4 LTE RSRP thresholds above which a signal level is considered POOR,
      * MODERATE, GOOD, or EXCELLENT, to be used in SignalStrength reporting.
      *
@@ -10336,6 +10368,11 @@
         sDefaults.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
         sDefaults.putBoolean(KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL, false);
+        sDefaults.putStringArray(KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_EXCLUDED_MCCS_STRING_ARRAY,
+                new String[0]);
+        sDefaults.putStringArray(
+                KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_INCLUDED_MCC_MNCS_STRING_ARRAY,
+                new String[0]);
         sDefaults.putIntArray(KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
                 // Boundaries: [-140 dBm, -44 dBm]
                 new int[] {
diff --git a/telephony/java/android/telephony/CellularIdentifierDisclosure.java b/telephony/java/android/telephony/CellularIdentifierDisclosure.java
new file mode 100644
index 0000000..7b2db6d
--- /dev/null
+++ b/telephony/java/android/telephony/CellularIdentifierDisclosure.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * A single occurrence of a cellular identifier being disclosed in the clear before a security
+ * context is established.
+ *
+ * @hide
+ */
+public final class CellularIdentifierDisclosure implements Parcelable {
+    private static final String TAG = "CellularIdentifierDisclosure";
+
+    private @NasProtocolMessage int mNasProtocolMessage;
+    private @CellularIdentifier int mCellularIdentifier;
+    private String mPlmn;
+    private boolean mIsEmergency;
+
+    public CellularIdentifierDisclosure(@NasProtocolMessage int nasProtocolMessage,
+            @CellularIdentifier int cellularIdentifier, String plmn, boolean isEmergency) {
+        mNasProtocolMessage = nasProtocolMessage;
+        mCellularIdentifier = cellularIdentifier;
+        mPlmn = plmn;
+        mIsEmergency = isEmergency;
+    }
+
+    private CellularIdentifierDisclosure(Parcel in) {
+        readFromParcel(in);
+    }
+
+    public @NasProtocolMessage int getNasProtocolMessage() {
+        return mNasProtocolMessage;
+    }
+
+    public @CellularIdentifier int getCellularIdentifier() {
+        return mCellularIdentifier;
+    }
+
+    public String getPlmn() {
+        return mPlmn;
+    }
+
+    public boolean isEmergency() {
+        return mIsEmergency;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mNasProtocolMessage);
+        out.writeInt(mCellularIdentifier);
+        out.writeBoolean(mIsEmergency);
+        out.writeString8(mPlmn);
+    }
+
+    public static final Parcelable.Creator<CellularIdentifierDisclosure> CREATOR =
+            new Parcelable.Creator<CellularIdentifierDisclosure>() {
+                public CellularIdentifierDisclosure createFromParcel(Parcel in) {
+                    return new CellularIdentifierDisclosure(in);
+                }
+
+                public CellularIdentifierDisclosure[] newArray(int size) {
+                    return new CellularIdentifierDisclosure[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        return TAG + ":{ mNasProtocolMessage = " + mNasProtocolMessage
+                + " mCellularIdentifier = " + mCellularIdentifier + " mIsEmergency = "
+                + mIsEmergency + " mPlmn = " + mPlmn;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof CellularIdentifierDisclosure)) return false;
+        CellularIdentifierDisclosure that = (CellularIdentifierDisclosure) o;
+        return mNasProtocolMessage == that.mNasProtocolMessage
+                && mCellularIdentifier == that.mCellularIdentifier
+                && mIsEmergency == that.mIsEmergency && mPlmn.equals(that.mPlmn);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mNasProtocolMessage, mCellularIdentifier, mIsEmergency,
+                mPlmn);
+    }
+
+    private void readFromParcel(@NonNull Parcel in) {
+        mNasProtocolMessage = in.readInt();
+        mCellularIdentifier = in.readInt();
+        mIsEmergency = in.readBoolean();
+        mPlmn = in.readString8();
+    }
+
+    public static final int NAS_PROTOCOL_MESSAGE_UNKNOWN = 0;
+    public static final int NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST = 1;
+    public static final int NAS_PROTOCOL_MESSAGE_IDENTITY_RESPONSE = 2;
+    public static final int NAS_PROTOCOL_MESSAGE_DETACH_REQUEST = 3;
+    public static final int NAS_PROTOCOL_MESSAGE_TRACKING_AREA_UPDATE_REQUEST = 4;
+    public static final int NAS_PROTOCOL_MESSAGE_LOCATION_UPDATE_REQUEST = 5;
+    public static final int NAS_PROTOCOL_MESSAGE_AUTHENTICATION_AND_CIPHERING_RESPONSE = 6;
+    public static final int NAS_PROTOCOL_MESSAGE_REGISTRATION_REQUEST = 7;
+    public static final int NAS_PROTOCOL_MESSAGE_DEREGISTRATION_REQUEST = 8;
+    public static final int NAS_PROTOCOL_MESSAGE_CM_REESTABLISHMENT_REQUEST = 9;
+    public static final int NAS_PROTOCOL_MESSAGE_CM_SERVICE_REQUEST = 10;
+    public static final int NAS_PROTOCOL_MESSAGE_IMSI_DETACH_INDICATION = 11;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"NAS_PROTOCOL_MESSAGE_"}, value = {NAS_PROTOCOL_MESSAGE_UNKNOWN,
+            NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST, NAS_PROTOCOL_MESSAGE_IDENTITY_RESPONSE,
+            NAS_PROTOCOL_MESSAGE_DETACH_REQUEST, NAS_PROTOCOL_MESSAGE_TRACKING_AREA_UPDATE_REQUEST,
+            NAS_PROTOCOL_MESSAGE_LOCATION_UPDATE_REQUEST,
+            NAS_PROTOCOL_MESSAGE_AUTHENTICATION_AND_CIPHERING_RESPONSE,
+            NAS_PROTOCOL_MESSAGE_REGISTRATION_REQUEST, NAS_PROTOCOL_MESSAGE_DEREGISTRATION_REQUEST,
+            NAS_PROTOCOL_MESSAGE_CM_REESTABLISHMENT_REQUEST,
+            NAS_PROTOCOL_MESSAGE_CM_SERVICE_REQUEST, NAS_PROTOCOL_MESSAGE_IMSI_DETACH_INDICATION})
+    public @interface NasProtocolMessage {
+    }
+
+    public static final int CELLULAR_IDENTIFIER_UNKNOWN = 0;
+    public static final int CELLULAR_IDENTIFIER_IMSI = 1;
+    public static final int CELLULAR_IDENTIFIER_IMEI = 2;
+    public static final int CELLULAR_IDENTIFIER_SUCI = 3;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"CELLULAR_IDENTIFIER_"}, value = {CELLULAR_IDENTIFIER_UNKNOWN,
+            CELLULAR_IDENTIFIER_IMSI, CELLULAR_IDENTIFIER_IMEI, CELLULAR_IDENTIFIER_SUCI})
+    public @interface CellularIdentifier {
+    }
+}
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index b528866..54ceaed 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -34,6 +35,8 @@
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.util.Log;
 
+import com.android.internal.telephony.flags.Flags;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Map;
@@ -77,9 +80,11 @@
     /** @hide */
     @IntDef(prefix = {"SUGGESTED_ACTION_"},
             value = {
-            SUGGESTED_ACTION_NONE,
-            SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK,
-            SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT
+                SUGGESTED_ACTION_NONE,
+                SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK,
+                SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+                SUGGESTED_ACTION_TRIGGER_RAT_BLOCK,
+                SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface SuggestedAction {}
@@ -109,6 +114,27 @@
     @SystemApi
     public static final int SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT = 2;
 
+    /**
+     * Indicates that the IMS registration on current RAT failed multiple times.
+     * The radio shall block the current RAT and search for other available RATs in the
+     * background. If no other RAT is available that meets the carrier requirements, the
+     * radio may remain on the current RAT for internet service. The radio clears all
+     * RATs marked as unavailable if the IMS service is registered to the carrier network.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(Flags.FLAG_ADD_RAT_RELATED_SUGGESTED_ACTION_TO_IMS_REGISTRATION)
+    int SUGGESTED_ACTION_TRIGGER_RAT_BLOCK = 3;
+
+    /**
+     * Indicates that the radio clears all RATs marked as unavailable and tries to find
+     * an available RAT that meets the carrier requirements.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(Flags.FLAG_ADD_RAT_RELATED_SUGGESTED_ACTION_TO_IMS_REGISTRATION)
+    int SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK = 4;
+
     /**@hide*/
     // Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN
     // and WWAN are more accurate constants.
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 22320fd..2ff7413 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -54,6 +54,29 @@
     dist_group: "android",
 }
 
+java_library {
+    name: "android.test.mock.ravenwood",
+    srcs: [":android-test-mock-sources"],
+    visibility: [
+        "//frameworks/base",
+    ],
+}
+
+android_ravenwood_test {
+    name: "android.test.mock.ravenwood.tests",
+    libs: [
+        "android.test.mock.ravenwood",
+    ],
+    static_libs: [
+        "androidx.annotation_annotation",
+        "androidx.test.rules",
+    ],
+    srcs: [
+        "tests/**/*.java",
+    ],
+    auto_gen_config: true,
+}
+
 // Make the current.txt available for use by the cts/tests/signature tests.
 // ========================================================================
 filegroup {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt b/test-mock/tests/src/android/test/mock/MockContextTest.java
similarity index 69%
copy from packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
copy to test-mock/tests/src/android/test/mock/MockContextTest.java
index cc92f60..6e28267 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
+++ b/test-mock/tests/src/android/test/mock/MockContextTest.java
@@ -14,8 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.common
+package android.test.mock;
 
-enum class CredentialType {
-    UNKNOWN, PASSKEY, PASSWORD,
-}
\ No newline at end of file
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class MockContextTest {
+    @Test
+    public void testConstructor() {
+        new MockContext();
+    }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt b/test-mock/tests/src/android/test/mock/MockPackageManagerTest.java
similarity index 68%
copy from packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
copy to test-mock/tests/src/android/test/mock/MockPackageManagerTest.java
index cc92f60..5b860f1 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
+++ b/test-mock/tests/src/android/test/mock/MockPackageManagerTest.java
@@ -14,8 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.common
+package android.test.mock;
 
-enum class CredentialType {
-    UNKNOWN, PASSKEY, PASSWORD,
-}
\ No newline at end of file
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class MockPackageManagerTest {
+    @Test
+    public void testConstructor() {
+        new MockPackageManager();
+    }
+}
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java
index 4548a7d..60b5ce7 100644
--- a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java
@@ -235,13 +235,17 @@
         }
 
         public int setFrameRate(float frameRate) {
+            return setFrameRate(frameRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
+        }
+
+        public int setFrameRate(
+                float frameRate, @Surface.FrameRateCompatibility int compatibility) {
             Log.i(TAG,
                     String.format("Setting frame rate for %s: frameRate=%.2f", mName, frameRate));
 
             int rc = 0;
             try (SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()) {
-                transaction.setFrameRate(
-                        mSurfaceControl, frameRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
+                transaction.setFrameRate(mSurfaceControl, frameRate, compatibility);
                 transaction.apply();
             }
             return rc;
@@ -668,12 +672,34 @@
         }
     }
 
-    private void testSurfaceControlFrameRateCategoryInternal(int category)
-            throws InterruptedException {
+    private void testSurfaceControlFrameRateCompatibilityInternal(
+            @Surface.FrameRateCompatibility int compatibility) throws InterruptedException {
+        runOneSurfaceTest((TestSurface surface) -> {
+            Log.i(TAG,
+                    "**** Running testSurfaceControlFrameRateCompatibility with compatibility "
+                            + compatibility);
+
+            float expectedFrameRate = getExpectedFrameRateForCompatibility(compatibility);
+            int initialNumEvents = mModeChangedEvents.size();
+            surface.setFrameRate(30.f, compatibility);
+            verifyExactAndStableFrameRate(expectedFrameRate, surface);
+            verifyModeSwitchesDontChangeResolution(initialNumEvents, mModeChangedEvents.size());
+        });
+    }
+
+    public void testSurfaceControlFrameRateCompatibility(
+            @Surface.FrameRateCompatibility int compatibility) throws InterruptedException {
+        runTestsWithPreconditions(
+                () -> testSurfaceControlFrameRateCompatibilityInternal(compatibility),
+                "frame rate compatibility=" + compatibility);
+    }
+
+    private void testSurfaceControlFrameRateCategoryInternal(
+            @Surface.FrameRateCategory int category) throws InterruptedException {
         runOneSurfaceTest((TestSurface surface) -> {
             Log.i(TAG, "**** Running testSurfaceControlFrameRateCategory for category " + category);
 
-            float expectedFrameRate = getExpectedFrameRate(category);
+            float expectedFrameRate = getExpectedFrameRateForCategory(category);
             int initialNumEvents = mModeChangedEvents.size();
             surface.setFrameRateCategory(category);
             verifyCompatibleAndStableFrameRate(expectedFrameRate, surface);
@@ -681,7 +707,8 @@
         });
     }
 
-    public void testSurfaceControlFrameRateCategory(int category) throws InterruptedException {
+    public void testSurfaceControlFrameRateCategory(@Surface.FrameRateCategory int category)
+            throws InterruptedException {
         runTestsWithPreconditions(()
                 -> testSurfaceControlFrameRateCategoryInternal(category),
                 "frame rate category=" + category);
@@ -710,9 +737,15 @@
             float childFrameRate = Collections.max(frameRates);
             float parentFrameRate = childFrameRate / 2;
             int initialNumEvents = mModeChangedEvents.size();
-            parent.setFrameRate(parentFrameRate);
             parent.setFrameRateSelectionStrategy(parentStrategy);
-            child.setFrameRate(childFrameRate);
+
+            // For Self case, we want to test that child gets default behavior
+            if (parentStrategy == SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_SELF) {
+                parent.setFrameRateCategory(Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE);
+            } else {
+                parent.setFrameRate(parentFrameRate);
+                child.setFrameRate(childFrameRate);
+            }
 
             // Verify
             float expectedFrameRate =
@@ -738,7 +771,24 @@
                 "frame rate strategy=" + parentStrategy);
     }
 
-    private float getExpectedFrameRate(int category) {
+    private float getExpectedFrameRateForCompatibility(int compatibility) {
+        assumeTrue("**** testSurfaceControlFrameRateCompatibility SKIPPED for compatibility "
+                        + compatibility,
+                compatibility == Surface.FRAME_RATE_COMPATIBILITY_GTE);
+
+        Display display = getDisplay();
+        Optional<Float> expectedFrameRate = getRefreshRates(display.getMode(), display)
+                                                    .stream()
+                                                    .filter(rate -> rate >= 30.f)
+                                                    .min(Comparator.naturalOrder());
+
+        assumeTrue("**** testSurfaceControlFrameRateCompatibility SKIPPED because no refresh rate "
+                        + "is >= 30",
+                expectedFrameRate.isPresent());
+        return expectedFrameRate.get();
+    }
+
+    private float getExpectedFrameRateForCategory(int category) {
         Display display = getDisplay();
         List<Float> frameRates = getRefreshRates(display.getMode(), display);
 
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java
index bed9cff..4b56c10 100644
--- a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java
@@ -16,11 +16,8 @@
 
 package android.view.surfacecontroltests;
 
-import static org.junit.Assume.assumeTrue;
-
 import android.Manifest;
 import android.hardware.display.DisplayManager;
-import android.os.SystemProperties;
 import android.support.test.uiautomator.UiDevice;
 import android.view.Surface;
 import android.view.SurfaceControl;
@@ -54,10 +51,6 @@
 
         UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
 
-        // TODO(b/290634611): clean this up once SF new front end is enabled by default
-        assumeTrue(SystemProperties.getBoolean(
-                "persist.debug.sf.enable_layer_lifecycle_manager", false));
-
         uiDevice.wakeUp();
         uiDevice.executeShellCommand("wm dismiss-keyguard");
 
@@ -88,6 +81,12 @@
     }
 
     @Test
+    public void testSurfaceControlFrameRateCompatibilityGte() throws InterruptedException {
+        GraphicsActivity activity = mActivityRule.getActivity();
+        activity.testSurfaceControlFrameRateCompatibility(Surface.FRAME_RATE_COMPATIBILITY_GTE);
+    }
+
+    @Test
     public void testSurfaceControlFrameRateCategoryHigh() throws InterruptedException {
         GraphicsActivity activity = mActivityRule.getActivity();
         activity.testSurfaceControlFrameRateCategory(Surface.FRAME_RATE_CATEGORY_HIGH);
@@ -118,10 +117,11 @@
     }
 
     @Test
-    public void testSurfaceControlFrameRateSelectionStrategySelf() throws InterruptedException {
+    public void testSurfaceControlFrameRateSelectionStrategyPropagate()
+            throws InterruptedException {
         GraphicsActivity activity = mActivityRule.getActivity();
         activity.testSurfaceControlFrameRateSelectionStrategy(
-                SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_SELF);
+                SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_PROPAGATE);
     }
 
     @Test
@@ -131,4 +131,12 @@
         activity.testSurfaceControlFrameRateSelectionStrategy(
                 SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN);
     }
+
+    @Test
+    public void testSurfaceControlFrameRateSelectionStrategySelf()
+            throws InterruptedException {
+        GraphicsActivity activity = mActivityRule.getActivity();
+        activity.testSurfaceControlFrameRateSelectionStrategy(
+                SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_SELF);
+    }
 }
diff --git a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
index 44de6a6..9c33576 100644
--- a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
@@ -63,6 +63,7 @@
     deviceId: Int,
     vendorId: Int,
     productId: Int,
+    deviceBus: Int,
     languageTag: String,
     layoutType: String
 ): InputDevice =
@@ -75,6 +76,7 @@
         .setExternal(true)
         .setVendorId(vendorId)
         .setProductId(productId)
+        .setDeviceBus(deviceBus)
         .setKeyboardLanguageTag(languageTag)
         .setKeyboardLayoutType(layoutType)
         .build()
@@ -94,6 +96,7 @@
         const val ENGLISH_QWERTY_DEVICE_ID = 4
         const val DEFAULT_VENDOR_ID = 123
         const val DEFAULT_PRODUCT_ID = 456
+        const val DEFAULT_DEVICE_BUS = 789
         const val USER_ID = 4
         const val IME_ID = "ime_id"
         const val PACKAGE_NAME = "KeyboardLayoutManagerTests"
@@ -177,12 +180,14 @@
         Mockito.`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
             .thenReturn(inputManager)
 
-        keyboardDevice = createKeyboard(DEVICE_ID, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, "", "")
-        vendorSpecificKeyboardDevice = createKeyboard(VENDOR_SPECIFIC_DEVICE_ID, 1, 1, "", "")
+        keyboardDevice = createKeyboard(DEVICE_ID, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID,
+                DEFAULT_DEVICE_BUS, "", "")
+        vendorSpecificKeyboardDevice = createKeyboard(VENDOR_SPECIFIC_DEVICE_ID, 1, 1,
+                1, "", "")
         englishDvorakKeyboardDevice = createKeyboard(ENGLISH_DVORAK_DEVICE_ID, DEFAULT_VENDOR_ID,
-                DEFAULT_PRODUCT_ID, "en", "dvorak")
+                DEFAULT_PRODUCT_ID, DEFAULT_DEVICE_BUS, "en", "dvorak")
         englishQwertyKeyboardDevice = createKeyboard(ENGLISH_QWERTY_DEVICE_ID, DEFAULT_VENDOR_ID,
-                DEFAULT_PRODUCT_ID, "en", "qwerty")
+                DEFAULT_PRODUCT_ID, DEFAULT_DEVICE_BUS, "en", "qwerty")
         Mockito.`when`(iInputManager.inputDeviceIds)
             .thenReturn(intArrayOf(
                 DEVICE_ID,
@@ -861,7 +866,9 @@
                                 GERMAN_LAYOUT_NAME,
                                 KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
                                 "de-Latn",
-                                LAYOUT_TYPE_QWERTZ))
+                                LAYOUT_TYPE_QWERTZ),
+                            ),
+                        ArgumentMatchers.eq(keyboardDevice.deviceBus),
                 )
             }
         }
@@ -887,7 +894,8 @@
                                 ENGLISH_US_LAYOUT_NAME,
                                 KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE,
                                 "de-Latn",
-                                LAYOUT_TYPE_QWERTZ))
+                                LAYOUT_TYPE_QWERTZ)),
+                        ArgumentMatchers.eq(keyboardDevice.deviceBus),
                 )
             }
         }
@@ -911,7 +919,9 @@
                                 "Default",
                                 KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEFAULT,
                                 KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
-                                LAYOUT_TYPE_DEFAULT))
+                                LAYOUT_TYPE_DEFAULT),
+                            ),
+                        ArgumentMatchers.eq(keyboardDevice.deviceBus),
                 )
             }
         }
@@ -929,7 +939,8 @@
                         ArgumentMatchers.anyBoolean(),
                         ArgumentMatchers.anyInt(),
                         ArgumentMatchers.anyInt(),
-                        ArgumentMatchers.any(ByteArray::class.java)
+                        ArgumentMatchers.any(ByteArray::class.java),
+                        ArgumentMatchers.anyInt(),
                 )
             }, Mockito.times(0))
         }
@@ -972,8 +983,13 @@
     }
 
     private fun createByteArray(
-            expectedLanguageTag: String, expectedLayoutType: Int, expectedLayoutName: String,
-            expectedCriteria: Int, expectedImeLanguageTag: String, expectedImeLayoutType: Int): ByteArray {
+            expectedLanguageTag: String,
+            expectedLayoutType: Int,
+            expectedLayoutName: String,
+            expectedCriteria: Int,
+            expectedImeLanguageTag: String,
+            expectedImeLayoutType: Int
+    ): ByteArray {
         val proto = ProtoOutputStream()
         val keyboardLayoutConfigToken = proto.start(
                 KeyboardConfiguredProto.RepeatedKeyboardLayoutConfig.KEYBOARD_LAYOUT_CONFIG)
@@ -1001,7 +1017,7 @@
                 KeyboardConfiguredProto.KeyboardLayoutConfig.IME_LAYOUT_TYPE,
                 expectedImeLayoutType
         )
-        proto.end(keyboardLayoutConfigToken);
+        proto.end(keyboardLayoutConfigToken)
         return proto.bytes
     }
 
diff --git a/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt b/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
index 33ff09b..89a47b9 100644
--- a/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardMetricsCollectorTests.kt
@@ -30,6 +30,7 @@
     deviceId: Int,
     vendorId: Int,
     productId: Int,
+    deviceBus: Int,
     languageTag: String?,
     layoutType: String?
 ): InputDevice =
@@ -42,6 +43,7 @@
         .setExternal(true)
         .setVendorId(vendorId)
         .setProductId(productId)
+        .setDeviceBus(deviceBus)
         .setKeyboardLanguageTag(languageTag)
         .setKeyboardLayoutType(layoutType)
         .build()
@@ -67,6 +69,7 @@
         const val DEVICE_ID = 1
         const val DEFAULT_VENDOR_ID = 123
         const val DEFAULT_PRODUCT_ID = 456
+        const val DEFAULT_DEVICE_BUS = 789
     }
 
     @Test
@@ -77,6 +80,7 @@
                     DEVICE_ID,
                     DEFAULT_VENDOR_ID,
                     DEFAULT_PRODUCT_ID,
+                    DEFAULT_DEVICE_BUS,
                     null,
                     null
                 )
@@ -92,6 +96,7 @@
                     DEVICE_ID,
                     DEFAULT_VENDOR_ID,
                     DEFAULT_PRODUCT_ID,
+                    DEFAULT_DEVICE_BUS,
                     null,
                     null
                 )
@@ -107,6 +112,7 @@
                 DEVICE_ID,
                 DEFAULT_VENDOR_ID,
                 DEFAULT_PRODUCT_ID,
+                DEFAULT_DEVICE_BUS,
                 "de-CH",
                 "qwertz"
             )
@@ -135,6 +141,11 @@
             DEFAULT_PRODUCT_ID,
             event.productId
         )
+        assertEquals(
+             "KeyboardConfigurationEvent should pick device bus from provided InputDevice",
+             DEFAULT_DEVICE_BUS,
+             event.deviceBus
+        )
         assertTrue(event.isFirstConfiguration)
 
         assertEquals(
@@ -178,6 +189,7 @@
                 DEVICE_ID,
                 DEFAULT_VENDOR_ID,
                 DEFAULT_PRODUCT_ID,
+                DEFAULT_DEVICE_BUS,
                 "und", // Undefined language tag
                 "azerty"
             )
diff --git a/tests/Input/src/com/android/test/input/InputDeviceTest.java b/tests/Input/src/com/android/test/input/InputDeviceTest.java
index d075b5f..5434c82 100644
--- a/tests/Input/src/com/android/test/input/InputDeviceTest.java
+++ b/tests/Input/src/com/android/test/input/InputDeviceTest.java
@@ -51,6 +51,7 @@
         assertEquals(device.getName(), outDevice.getName());
         assertEquals(device.getVendorId(), outDevice.getVendorId());
         assertEquals(device.getProductId(), outDevice.getProductId());
+        assertEquals(device.getDeviceBus(), outDevice.getDeviceBus());
         assertEquals(device.getDescriptor(), outDevice.getDescriptor());
         assertEquals(device.isExternal(), outDevice.isExternal());
         assertEquals(device.getSources(), outDevice.getSources());
@@ -79,6 +80,7 @@
                 .setName("Test Device " + DEVICE_ID)
                 .setVendorId(44)
                 .setProductId(45)
+                .setDeviceBus(3)
                 .setDescriptor("descriptor")
                 .setExternal(true)
                 .setSources(InputDevice.SOURCE_HDMI)
diff --git a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
index 1dfd5c0..d0e5626 100644
--- a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
+++ b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
@@ -93,7 +93,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS)
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
     fun grantCannotActivelyUnlockDevice() {
         // On automotive, trust agents can actively unlock the device.
         assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE))
@@ -120,7 +120,7 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS)
+    @RequiresFlagsDisabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
     fun grantCouldCauseWrongDeviceLockedStateDueToBug() {
         // On automotive, trust agents can actively unlock the device.
         assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE))
diff --git a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
index 5a8f828..0121809 100644
--- a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
+++ b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
@@ -36,7 +36,8 @@
 class LockStateTrackingRule : TestRule {
     private val context: Context = getApplicationContext()
     private val windowManager = checkNotNull(WindowManagerGlobal.getWindowManagerService())
-    private val keyguardManager = context.getSystemService(KeyguardManager::class.java) as KeyguardManager
+    private val keyguardManager =
+            context.getSystemService(KeyguardManager::class.java) as KeyguardManager
 
     @Volatile lateinit var trustState: TrustState
         private set
@@ -63,7 +64,7 @@
         wait("not trusted") { trustState.trusted == false }
     }
 
-    // TODO(b/299298338) remove this when removing FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS
+    // TODO(b/299298338) remove this when removing FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2
     fun assertUnlockedButNotReally() {
         wait("device unlocked") { !keyguardManager.isDeviceLocked }
         wait("not trusted") { trustState.trusted == false }
@@ -87,7 +88,7 @@
             trustGrantedMessages: MutableList<String>
         ) {
             Log.d(TAG, "Device became trusted=$enabled")
-            trustState = trustState.copy(trusted=enabled)
+            trustState = trustState.copy(trusted = enabled)
         }
     }
 
diff --git a/tools/hoststubgen/README.md b/tools/hoststubgen/README.md
index b0a1262..3455b0a 100644
--- a/tools/hoststubgen/README.md
+++ b/tools/hoststubgen/README.md
@@ -2,19 +2,27 @@
 
 ## Overview
 
-This directory contains tools / sample code / investigation for host side test support.
+HostStubGen is a tool built for ravenwood. It can read an Android framework jar file
+(such as `framework-minus-apex.jar` or `framework-all.jar`) and
+converts them, so that they can be used on the Ravenwood environment.
 
+This directory contains the HostStubGen source code, tests and some library source files
+used at runtime.
+
+- HostStubGen itself is design to be agnostic to Android. It doesn't use any Android APIs
+(hidden or not). But it may use Android specific knowledge -- e.g. as of now,
+AndroidHeuristicsFilter has hardcoded heuristics to detect AIDL generated classes. 
+
+- `test-tiny-framework/` contains basic tests that are agnostic to Android.
+
+- More Android specific build files and code are stored in `frameworks/base/Ravenwood.bp`
+  `frameworks/base/ravenwood`.
 
 ## Directories and files
 
 - `hoststubgen/`
   Contains source code of the "hoststubgen" tool and relevant code
 
-  - `framework-policy-override.txt`
-    This file contains "policy overrides", which allows to control what goes to stub/impl without
-    having to touch the target java files. This allows quicker iteration, because you can skip
-    having to rebuild framework.jar.
-
   - `src/`
 
     HostStubGen tool source code.
@@ -26,14 +34,12 @@
 
   - `test-tiny-framework/` See `README.md` in it.
 
-  - `test-framework` See `README.md` in it.
+  - `test-framework`
+    This directory was used during the prototype phase, but now that we have real ravenwood tests,
+    this directory is obsolete and should be deleted.
+
 
 - `scripts`
-  - `run-host-test.sh`
-
-    Run a host side test. Use it instead of `atest` for now. (`atest` works "mostly" but it has
-    problems.)
-
   - `dump-jar.sh`
 
     A script to dump the content of `*.class` and `*.jar` files.
@@ -53,8 +59,8 @@
 
 ### Run the tests
 
-- Run all relevant tests and test scripts. Some of thests are still expected to fail,
-  but this should print "finished, with no unexpected failures" at the end.
+- Run all relevant tests and test scripts. All of it is expected to pass, and it'll print
+  "Ready to submit" at the end.
 
   However, because some of the script it executes depend on internal file paths to Soong's
   intermediate directory, some of it might fail when something changes in the build system.
@@ -74,3 +80,7 @@
   (or at least check it.)
 
  - The `HostStubGenTest-framework-test-host-test-lib` jar somehow contain all ASM classes? Figure out where the dependency is coming from.
+
+- At some point, we can move or delete all Android specific code to `frameworks/base/ravenwood`.
+  - `helper-framework-*-src` should be moved to `frameworks/base/ravenwood`
+  - `test-framework` should be deleted.
\ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/Android.bp b/tools/hoststubgen/hoststubgen/Android.bp
index 5949bca..d415dc5 100644
--- a/tools/hoststubgen/hoststubgen/Android.bp
+++ b/tools/hoststubgen/hoststubgen/Android.bp
@@ -274,6 +274,21 @@
     ],
 }
 
+java_library_host {
+    name: "hoststubgen-helper-libcore-runtime",
+    defaults: ["hoststubgen-for-prototype-only-java"],
+    srcs: [
+        "helper-framework-runtime-src/libcore-fake/**/*.java",
+    ],
+}
+
+java_host_for_device {
+    name: "hoststubgen-helper-libcore-runtime.ravenwood",
+    libs: [
+        "hoststubgen-helper-libcore-runtime",
+    ],
+}
+
 java_library {
     name: "hoststubgen-helper-framework-runtime.ravenwood",
     defaults: ["hoststubgen-for-prototype-only-java"],
@@ -286,6 +301,7 @@
     ],
     static_libs: [
         "core-xml-for-device",
+        "hoststubgen-helper-libcore-runtime.ravenwood",
     ],
 }
 
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/android/system/ErrnoException.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/android/system/ErrnoException.java
new file mode 100644
index 0000000..388156a
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/android/system/ErrnoException.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.system;
+
+import java.io.IOException;
+import java.net.SocketException;
+
+/**
+ * A checked exception thrown when {@link Os} methods fail. This exception contains the native
+ * errno value, for comparison against the constants in {@link OsConstants}, should sophisticated
+ * callers need to adjust their behavior based on the exact failure.
+ */
+public final class ErrnoException extends Exception {
+    private final String functionName;
+
+    /**
+     * The errno value, for comparison with the {@code E} constants in {@link OsConstants}.
+     */
+    public final int errno;
+
+    /**
+     * Constructs an instance with the given function name and errno value.
+     */
+    public ErrnoException(String functionName, int errno) {
+        this.functionName = functionName;
+        this.errno = errno;
+    }
+
+    /**
+     * Constructs an instance with the given function name, errno value, and cause.
+     */
+    public ErrnoException(String functionName, int errno, Throwable cause) {
+        super(cause);
+        this.functionName = functionName;
+        this.errno = errno;
+    }
+
+    /**
+     * Converts the stashed function name and errno value to a human-readable string.
+     * We do this here rather than in the constructor so that callers only pay for
+     * this if they need it.
+     */
+    @Override public String getMessage() {
+        return functionName + " failed: " + errno;
+    }
+
+    /**
+     * Throws an {@link IOException} with a message based on {@link #getMessage()} and with this
+     * instance as the cause.
+     *
+     * <p>This method always terminates by throwing the exception. Callers can write
+     * {@code throw e.rethrowAsIOException()} to make that clear to the compiler.
+     */
+    public IOException rethrowAsIOException() throws IOException {
+        IOException newException = new IOException(getMessage());
+        newException.initCause(this);
+        throw newException;
+    }
+
+    /**
+     * Throws a {@link SocketException} with a message based on {@link #getMessage()} and with this
+     * instance as the cause.
+     *
+     * <p>This method always terminates by throwing the exception. Callers can write
+     * {@code throw e.rethrowAsIOException()} to make that clear to the compiler.
+     */
+    public SocketException rethrowAsSocketException() throws SocketException {
+        throw new SocketException(getMessage());
+    }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/io/IoUtils.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/io/IoUtils.java
new file mode 100644
index 0000000..65c285e
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/io/IoUtils.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.Socket;
+
+/** @hide */
+public final class IoUtils {
+    private IoUtils() {
+    }
+
+    public static void closeQuietly(AutoCloseable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    public static void closeQuietly(Socket socket) {
+        if (socket != null) {
+            try {
+                socket.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    public static void deleteContents(File dir) throws IOException {
+        File[] files = dir.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    deleteContents(file);
+                }
+                file.delete();
+            }
+        }
+    }
+}
diff --git a/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh b/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh
index 85038be..d97dd7c 100755
--- a/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh
+++ b/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh
@@ -51,6 +51,8 @@
 
 HOSTSTUBGEN_OUT=$TEMP/output.txt
 
+EXTRA_ARGS=""
+
 # Because of `set -e`, we can't return non-zero from functions, so we store
 # HostStubGen result in it.
 HOSTSTUBGEN_RC=0
@@ -115,6 +117,7 @@
       --keep-static-initializer-annotation \
           android.hosttest.annotation.HostSideTestStaticInitializerKeep \
       $filter_arg \
+      $EXTRA_ARGS \
       |& tee $HOSTSTUBGEN_OUT
   HOSTSTUBGEN_RC=${PIPESTATUS[0]}
   echo "HostStubGen exited with $HOSTSTUBGEN_RC"
@@ -209,7 +212,6 @@
 com.unsupported.*
 "
 
-
 run_hoststubgen_for_failure "One specific class disallowed" \
     "TinyFrameworkClassAnnotations is not allowed to have Ravenwood annotations" \
     "
@@ -229,6 +231,10 @@
 
 STUB="" IMPL="" run_hoststubgen_for_success "No stub, no impl generation" ""
 
+EXTRA_ARGS="--in-jar abc" run_hoststubgen_for_failure "Duplicate arg" \
+    "Duplicate or conflicting argument found: --in-jar" \
+    ""
+
 
 echo "All tests passed"
 exit 0
\ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
index 3cdddc2..4e0cd09 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -22,7 +22,6 @@
 import com.android.hoststubgen.filters.DefaultHookInjectingFilter
 import com.android.hoststubgen.filters.FilterPolicy
 import com.android.hoststubgen.filters.ImplicitOutputFilter
-import com.android.hoststubgen.filters.KeepAllClassesFilter
 import com.android.hoststubgen.filters.OutputFilter
 import com.android.hoststubgen.filters.StubIntersectingFilter
 import com.android.hoststubgen.filters.createFilterFromTextPolicyFile
@@ -52,15 +51,15 @@
         val errors = HostStubGenErrors()
 
         // Load all classes.
-        val allClasses = loadClassStructures(options.inJar)
+        val allClasses = loadClassStructures(options.inJar.get)
 
         // Dump the classes, if specified.
-        options.inputJarDumpFile?.let {
+        options.inputJarDumpFile.ifSet {
             PrintWriter(it).use { pw -> allClasses.dump(pw) }
             log.i("Dump file created at $it")
         }
 
-        options.inputJarAsKeepAllFile?.let {
+        options.inputJarAsKeepAllFile.ifSet {
             PrintWriter(it).use {
                 pw -> allClasses.forEach {
                     classNode -> printAsTextPolicy(pw, classNode)
@@ -74,11 +73,11 @@
 
         // Transform the jar.
         convert(
-                options.inJar,
-                options.outStubJar,
-                options.outImplJar,
+                options.inJar.get,
+                options.outStubJar.get,
+                options.outImplJar.get,
                 filter,
-                options.enableClassChecker,
+                options.enableClassChecker.get,
                 allClasses,
                 errors,
         )
@@ -153,7 +152,7 @@
         // text-file based filter, which is handled by parseTextFilterPolicyFile.
 
         // The first filter is for the default policy from the command line options.
-        var filter: OutputFilter = ConstantFilter(options.defaultPolicy, "default-by-options")
+        var filter: OutputFilter = ConstantFilter(options.defaultPolicy.get, "default-by-options")
 
         // Next, we need a filter that resolves "class-wide" policies.
         // This is used when a member (methods, fields, nested classes) don't get any polices
@@ -163,16 +162,16 @@
 
         // Inject default hooks from options.
         filter = DefaultHookInjectingFilter(
-            options.defaultClassLoadHook,
-            options.defaultMethodCallHook,
+            options.defaultClassLoadHook.get,
+            options.defaultMethodCallHook.get,
             filter
         )
 
-        val annotationAllowedClassesFilter = options.annotationAllowedClassesFile.let { filename ->
-            if (filename == null) {
+        val annotationAllowedClassesFilter = options.annotationAllowedClassesFile.get.let { file ->
+            if (file == null) {
                 ClassFilter.newNullFilter(true) // Allow all classes
             } else {
-                ClassFilter.loadFromFile(filename, false)
+                ClassFilter.loadFromFile(file, false)
             }
         }
 
@@ -196,7 +195,7 @@
 
         // Next, "text based" filter, which allows to override polices without touching
         // the target code.
-        options.policyOverrideFile?.let {
+        options.policyOverrideFile.ifSet {
             filter = createFilterFromTextPolicyFile(it, allClasses, filter)
         }
 
@@ -212,11 +211,6 @@
         // Apply the implicit filter.
         filter = ImplicitOutputFilter(errors, allClasses, filter)
 
-        // Optionally keep all classes.
-        if (options.keepAllClasses) {
-            filter = KeepAllClassesFilter(filter)
-        }
-
         return filter
     }
 
@@ -245,7 +239,7 @@
             errors: HostStubGenErrors,
             ) {
         log.i("Converting %s into [stub: %s, impl: %s] ...", inJar, outStubJar, outImplJar)
-        log.i("Checker is %s", if (enableChecker) "enabled" else "disabled")
+        log.i("ASM CheckClassAdapter is %s", if (enableChecker) "enabled" else "disabled")
 
         val start = System.currentTimeMillis()
 
@@ -270,7 +264,7 @@
             }
         }
         val end = System.currentTimeMillis()
-        log.v("Done transforming the jar in %.1f second(s).", (end - start) / 1000.0)
+        log.i("Done transforming the jar in %.1f second(s).", (end - start) / 1000.0)
     }
 
     private fun <T> maybeWithZipOutputStream(filename: String?, block: (ZipOutputStream?) -> T): T {
@@ -422,9 +416,9 @@
             outVisitor = CheckClassAdapter(outVisitor)
         }
         val visitorOptions = BaseAdapter.Options(
-                enablePreTrace = options.enablePreTrace,
-                enablePostTrace = options.enablePostTrace,
-                enableNonStubMethodCallDetection = options.enableNonStubMethodCallDetection,
+                enablePreTrace = options.enablePreTrace.get,
+                enablePostTrace = options.enablePostTrace.get,
+                enableNonStubMethodCallDetection = options.enableNonStubMethodCallDetection.get,
                 errors = errors,
         )
         outVisitor = BaseAdapter.getVisitor(classInternalName, classes, outVisitor, filter,
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt
index 5e71a36..18065ba 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt
@@ -15,10 +15,12 @@
  */
 package com.android.hoststubgen
 
-import java.io.OutputStream
-import java.io.PrintStream
+import java.io.BufferedOutputStream
+import java.io.FileOutputStream
+import java.io.PrintWriter
+import java.io.Writer
 
-val log: HostStubGenLogger = HostStubGenLogger()
+val log: HostStubGenLogger = HostStubGenLogger().setConsoleLogLevel(LogLevel.Info)
 
 /** Logging level */
 enum class LogLevel {
@@ -30,15 +32,13 @@
     Debug,
 }
 
-/** Simple logging class. */
-class HostStubGenLogger(
-        private var out: PrintStream = System.out!!,
-        var level: LogLevel = LogLevel.Info,
-) {
-    companion object {
-        private val sNullPrintStream: PrintStream = PrintStream(OutputStream.nullOutputStream())
-    }
-
+/**
+ * Simple logging class.
+ *
+ * By default, it has no printers set. Use [setConsoleLogLevel] or [addFilePrinter] to actually
+ * write log.
+ */
+class HostStubGenLogger {
     private var indentLevel: Int = 0
         get() = field
         set(value) {
@@ -47,6 +47,56 @@
         }
     private var indent: String = ""
 
+    private val printers: MutableList<LogPrinter> = mutableListOf()
+
+    private var consolePrinter: LogPrinter? = null
+
+    private var maxLogLevel = LogLevel.None
+
+    private fun updateMaxLogLevel() {
+        maxLogLevel = LogLevel.None
+
+        printers.forEach {
+            if (maxLogLevel < it.logLevel) {
+                maxLogLevel = it.logLevel
+            }
+        }
+    }
+
+    private fun addPrinter(printer: LogPrinter) {
+        printers.add(printer)
+        updateMaxLogLevel()
+    }
+
+    private fun removePrinter(printer: LogPrinter) {
+        printers.remove(printer)
+        updateMaxLogLevel()
+    }
+
+    fun setConsoleLogLevel(level: LogLevel): HostStubGenLogger {
+        // If there's already a console log printer set, remove it, and then add a new one
+        consolePrinter?.let {
+            removePrinter(it)
+        }
+        val cp = StreamPrinter(level, PrintWriter(System.out))
+        addPrinter(cp)
+        consolePrinter = cp
+
+        return this
+    }
+
+    fun addFilePrinter(level: LogLevel, logFilename: String): HostStubGenLogger {
+        addPrinter(StreamPrinter(level, PrintWriter(BufferedOutputStream(
+            FileOutputStream(logFilename)))))
+
+        return this
+    }
+
+    /** Flush all the printers */
+    fun flush() {
+        printers.forEach { it.flush() }
+    }
+
     fun indent() {
         indentLevel++
     }
@@ -68,92 +118,71 @@
     }
 
     fun isEnabled(level: LogLevel): Boolean {
-        return level.ordinal <= this.level.ordinal
+        return level.ordinal <= maxLogLevel.ordinal
     }
 
-    private fun println(message: String) {
-        out.print(indent)
-        out.println(message)
+    private fun println(level: LogLevel, message: String) {
+        printers.forEach {
+            if (it.logLevel.ordinal >= level.ordinal) {
+                it.println(level, indent, message)
+            }
+        }
+    }
+
+    private fun println(level: LogLevel, format: String, vararg args: Any?) {
+        if (isEnabled(level)) {
+            println(level, String.format(format, *args))
+        }
     }
 
     /** Log an error. */
     fun e(message: String) {
-        if (level.ordinal < LogLevel.Error.ordinal) {
-            return
-        }
-        println(message)
+        println(LogLevel.Error, message)
     }
 
     /** Log an error. */
     fun e(format: String, vararg args: Any?) {
-        if (level.ordinal < LogLevel.Error.ordinal) {
-            return
-        }
-        e(String.format(format, *args))
+        println(LogLevel.Error, format, *args)
     }
 
     /** Log a warning. */
     fun w(message: String) {
-        if (level.ordinal < LogLevel.Warn.ordinal) {
-            return
-        }
-        println(message)
+        println(LogLevel.Warn, message)
     }
 
     /** Log a warning. */
     fun w(format: String, vararg args: Any?) {
-        if (level.ordinal < LogLevel.Warn.ordinal) {
-            return
-        }
-        w(String.format(format, *args))
+        println(LogLevel.Warn, format, *args)
     }
 
     /** Log an info message. */
     fun i(message: String) {
-        if (level.ordinal < LogLevel.Info.ordinal) {
-            return
-        }
-        println(message)
+        println(LogLevel.Info, message)
     }
 
-    /** Log a debug message. */
+    /** Log an info message. */
     fun i(format: String, vararg args: Any?) {
-        if (level.ordinal < LogLevel.Warn.ordinal) {
-            return
-        }
-        i(String.format(format, *args))
+        println(LogLevel.Info, format, *args)
     }
 
     /** Log a verbose message. */
     fun v(message: String) {
-        if (level.ordinal < LogLevel.Verbose.ordinal) {
-            return
-        }
-        println(message)
+        println(LogLevel.Verbose, message)
     }
 
     /** Log a verbose message. */
     fun v(format: String, vararg args: Any?) {
-        if (level.ordinal < LogLevel.Verbose.ordinal) {
-            return
-        }
-        v(String.format(format, *args))
+        println(LogLevel.Verbose, format, *args)
     }
 
     /** Log a debug message. */
     fun d(message: String) {
-        if (level.ordinal < LogLevel.Debug.ordinal) {
-            return
-        }
-        println(message)
+        println(LogLevel.Debug, message)
     }
 
     /** Log a debug message. */
     fun d(format: String, vararg args: Any?) {
-        if (level.ordinal < LogLevel.Warn.ordinal) {
-            return
-        }
-        d(String.format(format, *args))
+        println(LogLevel.Debug, format, *args)
     }
 
     inline fun forVerbose(block: () -> Unit) {
@@ -168,31 +197,65 @@
         }
     }
 
-    /** Return a stream for error. */
-    fun getErrorPrintStream(): PrintStream {
-        if (level.ordinal < LogLevel.Error.ordinal) {
-            return sNullPrintStream
-        }
-
-        // TODO Apply indent
-        return PrintStream(out)
+    /** Return a Writer for a given log level. */
+    fun getWriter(level: LogLevel): Writer {
+        return MultiplexingWriter(level)
     }
 
-    /** Return a stream for verbose messages. */
-    fun getVerbosePrintStream(): PrintStream {
-        if (level.ordinal < LogLevel.Verbose.ordinal) {
-            return sNullPrintStream
+    private inner class MultiplexingWriter(val level: LogLevel) : Writer() {
+        private inline fun forPrinters(callback: (LogPrinter) -> Unit) {
+            printers.forEach {
+                if (it.logLevel.ordinal >= level.ordinal) {
+                    callback(it)
+                }
+            }
         }
-        // TODO Apply indent
-        return PrintStream(out)
+
+        override fun close() {
+            flush()
+        }
+
+        override fun flush() {
+            forPrinters {
+                it.flush()
+            }
+        }
+
+        override fun write(cbuf: CharArray, off: Int, len: Int) {
+            // TODO Apply indent
+            forPrinters {
+                it.write(cbuf, off, len)
+            }
+        }
+    }
+}
+
+private interface LogPrinter {
+    val logLevel: LogLevel
+
+    fun println(logLevel: LogLevel, indent: String, message: String)
+
+    // TODO: This should be removed once MultiplexingWriter starts applying indent, at which point
+    // println() should be used instead.
+    fun write(cbuf: CharArray, off: Int, len: Int)
+
+    fun flush()
+}
+
+private class StreamPrinter(
+    override val logLevel: LogLevel,
+    val out: PrintWriter,
+) : LogPrinter {
+    override fun println(logLevel: LogLevel, indent: String, message: String) {
+        out.print(indent)
+        out.println(message)
     }
 
-    /** Return a stream for debug messages. */
-    fun getInfoPrintStream(): PrintStream {
-        if (level.ordinal < LogLevel.Info.ordinal) {
-            return sNullPrintStream
-        }
-        // TODO Apply indent
-        return PrintStream(out)
+    override fun write(cbuf: CharArray, off: Int, len: Int) {
+        out.write(cbuf, off, len)
     }
-}
\ No newline at end of file
+
+    override fun flush() {
+        out.flush()
+    }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
index 83f873d..d2ead18 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
@@ -21,21 +21,60 @@
 import java.io.FileReader
 
 /**
+ * A single value that can only set once.
+ */
+class SetOnce<T>(
+        private var value: T,
+) {
+    class SetMoreThanOnceException : Exception()
+
+    private var set = false
+
+    fun set(v: T) {
+        if (set) {
+            throw SetMoreThanOnceException()
+        }
+        if (v == null) {
+            throw NullPointerException("This shouldn't happen")
+        }
+        set = true
+        value = v
+    }
+
+    val get: T
+        get() = this.value
+
+    val isSet: Boolean
+        get() = this.set
+
+    fun <R> ifSet(block: (T & Any) -> R): R? {
+        if (isSet) {
+            return block(value!!)
+        }
+        return null
+    }
+
+    override fun toString(): String {
+        return "$value"
+    }
+}
+
+/**
  * Options that can be set from command line arguments.
  */
 class HostStubGenOptions(
         /** Input jar file*/
-        var inJar: String = "",
+        var inJar: SetOnce<String> = SetOnce(""),
 
         /** Output stub jar file */
-        var outStubJar: String? = null,
+        var outStubJar: SetOnce<String?> = SetOnce(null),
 
         /** Output implementation jar file */
-        var outImplJar: String? = null,
+        var outImplJar: SetOnce<String?> = SetOnce(null),
 
-        var inputJarDumpFile: String? = null,
+        var inputJarDumpFile: SetOnce<String?> = SetOnce(null),
 
-        var inputJarAsKeepAllFile: String? = null,
+        var inputJarAsKeepAllFile: SetOnce<String?> = SetOnce(null),
 
         var stubAnnotations: MutableSet<String> = mutableSetOf(),
         var keepAnnotations: MutableSet<String> = mutableSetOf(),
@@ -51,27 +90,24 @@
 
         var packageRedirects: MutableList<Pair<String, String>> = mutableListOf(),
 
-        var annotationAllowedClassesFile: String? = null,
+        var annotationAllowedClassesFile: SetOnce<String?> = SetOnce(null),
 
-        var defaultClassLoadHook: String? = null,
-        var defaultMethodCallHook: String? = null,
+        var defaultClassLoadHook: SetOnce<String?> = SetOnce(null),
+        var defaultMethodCallHook: SetOnce<String?> = SetOnce(null),
 
         var intersectStubJars: MutableSet<String> = mutableSetOf(),
 
-        var policyOverrideFile: String? = null,
+        var policyOverrideFile: SetOnce<String?> = SetOnce(null),
 
-        var defaultPolicy: FilterPolicy = FilterPolicy.Remove,
-        var keepAllClasses: Boolean = false,
+        var defaultPolicy: SetOnce<FilterPolicy> = SetOnce(FilterPolicy.Remove),
 
-        var logLevel: LogLevel = LogLevel.Info,
+        var cleanUpOnError: SetOnce<Boolean> = SetOnce(false),
 
-        var cleanUpOnError: Boolean = false,
+        var enableClassChecker: SetOnce<Boolean> = SetOnce(false),
+        var enablePreTrace: SetOnce<Boolean> = SetOnce(false),
+        var enablePostTrace: SetOnce<Boolean> = SetOnce(false),
 
-        var enableClassChecker: Boolean = false,
-        var enablePreTrace: Boolean = false,
-        var enablePostTrace: Boolean = false,
-
-        var enableNonStubMethodCallDetection: Boolean = false,
+        var enableNonStubMethodCallDetection: SetOnce<Boolean> = SetOnce(false),
 ) {
     companion object {
 
@@ -105,116 +141,133 @@
                 return name
             }
 
+            fun setLogFile(level: LogLevel, filename: String) {
+                log.addFilePrinter(level, filename)
+                log.i("$level log file: $filename")
+            }
+
             while (true) {
                 val arg = ai.nextArgOptional()
                 if (arg == null) {
                     break
                 }
 
-                when (arg) {
-                    // TODO: Write help
-                    "-h", "--h" -> TODO("Help is not implemented yet")
+                // Define some shorthands...
+                fun nextArg(): String = ai.nextArgRequired(arg)
+                fun SetOnce<String>.setNextStringArg(): String = nextArg().also { this.set(it) }
+                fun SetOnce<String?>.setNextStringArg(): String = nextArg().also { this.set(it) }
+                fun MutableSet<String>.addUniqueAnnotationArg(): String =
+                        nextArg().also { this += ensureUniqueAnnotation(it) }
 
-                    "-v", "--verbose" -> ret.logLevel = LogLevel.Verbose
-                    "-d", "--debug" -> ret.logLevel = LogLevel.Debug
-                    "-q", "--quiet" -> ret.logLevel = LogLevel.None
+                try {
+                    when (arg) {
+                        // TODO: Write help
+                        "-h", "--help" -> TODO("Help is not implemented yet")
 
-                    "--in-jar" -> ret.inJar = ai.nextArgRequired(arg).ensureFileExists()
-                    "--out-stub-jar" -> ret.outStubJar = ai.nextArgRequired(arg)
-                    "--out-impl-jar" -> ret.outImplJar = ai.nextArgRequired(arg)
+                        "-v", "--verbose" -> log.setConsoleLogLevel(LogLevel.Verbose)
+                        "-d", "--debug" -> log.setConsoleLogLevel(LogLevel.Debug)
+                        "-q", "--quiet" -> log.setConsoleLogLevel(LogLevel.None)
 
-                    "--policy-override-file" ->
-                        ret.policyOverrideFile = ai.nextArgRequired(arg).ensureFileExists()
+                        "--in-jar" -> ret.inJar.setNextStringArg().ensureFileExists()
+                        "--out-stub-jar" -> ret.outStubJar.setNextStringArg()
+                        "--out-impl-jar" -> ret.outImplJar.setNextStringArg()
 
-                    "--clean-up-on-error" -> ret.cleanUpOnError = true
-                    "--no-clean-up-on-error" -> ret.cleanUpOnError = false
+                        "--policy-override-file" ->
+                            ret.policyOverrideFile.setNextStringArg().ensureFileExists()
 
-                    "--default-remove" -> ret.defaultPolicy = FilterPolicy.Remove
-                    "--default-throw" -> ret.defaultPolicy = FilterPolicy.Throw
-                    "--default-keep" -> ret.defaultPolicy = FilterPolicy.Keep
-                    "--default-stub" -> ret.defaultPolicy = FilterPolicy.Stub
+                        "--clean-up-on-error" -> ret.cleanUpOnError.set(true)
+                        "--no-clean-up-on-error" -> ret.cleanUpOnError.set(false)
 
-                    "--keep-all-classes" -> ret.keepAllClasses = true
-                    "--no-keep-all-classes" -> ret.keepAllClasses = false
+                        "--default-remove" -> ret.defaultPolicy.set(FilterPolicy.Remove)
+                        "--default-throw" -> ret.defaultPolicy.set(FilterPolicy.Throw)
+                        "--default-keep" -> ret.defaultPolicy.set(FilterPolicy.Keep)
+                        "--default-stub" -> ret.defaultPolicy.set(FilterPolicy.Stub)
 
-                    "--stub-annotation" ->
-                        ret.stubAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--stub-annotation" ->
+                            ret.stubAnnotations.addUniqueAnnotationArg()
 
-                    "--keep-annotation" ->
-                        ret.keepAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--keep-annotation" ->
+                            ret.keepAnnotations.addUniqueAnnotationArg()
 
-                    "--stub-class-annotation" ->
-                        ret.stubClassAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--stub-class-annotation" ->
+                            ret.stubClassAnnotations.addUniqueAnnotationArg()
 
-                    "--keep-class-annotation" ->
-                        ret.keepClassAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--keep-class-annotation" ->
+                            ret.keepClassAnnotations.addUniqueAnnotationArg()
 
-                    "--throw-annotation" ->
-                        ret.throwAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--throw-annotation" ->
+                            ret.throwAnnotations.addUniqueAnnotationArg()
 
-                    "--remove-annotation" ->
-                        ret.removeAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--remove-annotation" ->
+                            ret.removeAnnotations.addUniqueAnnotationArg()
 
-                    "--substitute-annotation" ->
-                        ret.substituteAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--substitute-annotation" ->
+                            ret.substituteAnnotations.addUniqueAnnotationArg()
 
-                    "--native-substitute-annotation" ->
-                        ret.nativeSubstituteAnnotations +=
-                                ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--native-substitute-annotation" ->
+                            ret.nativeSubstituteAnnotations.addUniqueAnnotationArg()
 
-                    "--class-load-hook-annotation" ->
-                        ret.classLoadHookAnnotations +=
-                                ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--class-load-hook-annotation" ->
+                            ret.classLoadHookAnnotations.addUniqueAnnotationArg()
 
-                    "--keep-static-initializer-annotation" ->
-                        ret.keepStaticInitializerAnnotations +=
-                                ensureUniqueAnnotation(ai.nextArgRequired(arg))
+                        "--keep-static-initializer-annotation" ->
+                            ret.keepStaticInitializerAnnotations.addUniqueAnnotationArg()
 
-                    "--package-redirect" ->
-                        ret.packageRedirects += parsePackageRedirect(ai.nextArgRequired(arg))
+                        "--package-redirect" ->
+                            ret.packageRedirects += parsePackageRedirect(nextArg())
 
-                    "--annotation-allowed-classes-file" ->
-                        ret.annotationAllowedClassesFile = ai.nextArgRequired(arg)
+                        "--annotation-allowed-classes-file" ->
+                            ret.annotationAllowedClassesFile.setNextStringArg()
 
-                    "--default-class-load-hook" ->
-                        ret.defaultClassLoadHook = ai.nextArgRequired(arg)
+                        "--default-class-load-hook" ->
+                            ret.defaultClassLoadHook.setNextStringArg()
 
-                    "--default-method-call-hook" ->
-                        ret.defaultMethodCallHook = ai.nextArgRequired(arg)
+                        "--default-method-call-hook" ->
+                            ret.defaultMethodCallHook.setNextStringArg()
 
-                    "--intersect-stub-jar" ->
-                        ret.intersectStubJars += ai.nextArgRequired(arg).ensureFileExists()
+                        "--intersect-stub-jar" ->
+                            ret.intersectStubJars += nextArg().ensureFileExists()
 
-                    "--gen-keep-all-file" ->
-                        ret.inputJarAsKeepAllFile = ai.nextArgRequired(arg)
+                        "--gen-keep-all-file" ->
+                            ret.inputJarAsKeepAllFile.setNextStringArg()
 
-                    // Following options are for debugging.
-                    "--enable-class-checker" -> ret.enableClassChecker = true
-                    "--no-class-checker" -> ret.enableClassChecker = false
+                        // Following options are for debugging.
+                        "--enable-class-checker" -> ret.enableClassChecker.set(true)
+                        "--no-class-checker" -> ret.enableClassChecker.set(false)
 
-                    "--enable-pre-trace" -> ret.enablePreTrace = true
-                    "--no-pre-trace" -> ret.enablePreTrace = false
+                        "--enable-pre-trace" -> ret.enablePreTrace.set(true)
+                        "--no-pre-trace" -> ret.enablePreTrace.set(false)
 
-                    "--enable-post-trace" -> ret.enablePostTrace = true
-                    "--no-post-trace" -> ret.enablePostTrace = false
+                        "--enable-post-trace" -> ret.enablePostTrace.set(true)
+                        "--no-post-trace" -> ret.enablePostTrace.set(false)
 
-                    "--enable-non-stub-method-check" -> ret.enableNonStubMethodCallDetection = true
-                    "--no-non-stub-method-check" -> ret.enableNonStubMethodCallDetection = false
+                        "--enable-non-stub-method-check" ->
+                            ret.enableNonStubMethodCallDetection.set(true)
 
-                    "--gen-input-dump-file" -> ret.inputJarDumpFile = ai.nextArgRequired(arg)
+                        "--no-non-stub-method-check" ->
+                            ret.enableNonStubMethodCallDetection.set(false)
 
-                    else -> throw ArgumentsException("Unknown option: $arg")
+                        "--gen-input-dump-file" -> ret.inputJarDumpFile.setNextStringArg()
+
+                        "--verbose-log" -> setLogFile(LogLevel.Verbose, nextArg())
+                        "--debug-log" -> setLogFile(LogLevel.Debug, nextArg())
+
+                        else -> throw ArgumentsException("Unknown option: $arg")
+                    }
+                } catch (e: SetOnce.SetMoreThanOnceException) {
+                    throw ArgumentsException("Duplicate or conflicting argument found: $arg")
                 }
             }
-            if (ret.inJar.isEmpty()) {
+
+            if (!ret.inJar.isSet) {
                 throw ArgumentsException("Required option missing: --in-jar")
             }
-            if (ret.outStubJar == null && ret.outImplJar == null) {
+            if (!ret.outStubJar.isSet && !ret.outImplJar.isSet) {
                 log.w("Neither --out-stub-jar nor --out-impl-jar is set." +
                         " $COMMAND_NAME will not generate jar files.")
             }
 
-            if (ret.enableNonStubMethodCallDetection) {
+            if (ret.enableNonStubMethodCallDetection.get) {
                 log.w("--enable-non-stub-method-check is not fully implemented yet." +
                     " See the todo in doesMethodNeedNonStubCallCheck().")
             }
@@ -329,8 +382,6 @@
               intersectStubJars=$intersectStubJars,
               policyOverrideFile=$policyOverrideFile,
               defaultPolicy=$defaultPolicy,
-              keepAllClasses=$keepAllClasses,
-              logLevel=$logLevel,
               cleanUpOnError=$cleanUpOnError,
               enableClassChecker=$enableClassChecker,
               enablePreTrace=$enablePreTrace,
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Main.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Main.kt
index 0321d9d..4882c00 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Main.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Main.kt
@@ -17,6 +17,8 @@
 
 package com.android.hoststubgen
 
+import java.io.PrintWriter
+
 const val COMMAND_NAME = "HostStubGen"
 
 /**
@@ -25,12 +27,11 @@
 fun main(args: Array<String>) {
     var success = false
     var clanupOnError = false
+
     try {
         // Parse the command line arguments.
         val options = HostStubGenOptions.parseArgs(args)
-        clanupOnError = options.cleanUpOnError
-
-        log.level = options.logLevel
+        clanupOnError = options.cleanUpOnError.get
 
         log.v("HostStubGen started")
         log.v("Options: $options")
@@ -39,17 +40,18 @@
         HostStubGen(options).run()
 
         success = true
-    } catch (e: Exception) {
+    } catch (e: Throwable) {
         log.e("$COMMAND_NAME: Error: ${e.message}")
         if (e !is UserErrorException) {
-            e.printStackTrace(log.getErrorPrintStream())
+            e.printStackTrace(PrintWriter(log.getWriter(LogLevel.Error)))
         }
         if (clanupOnError) {
-            TODO("clanupOnError is not implemented yet")
+            TODO("Remove output jars here")
         }
+    } finally {
+        log.i("$COMMAND_NAME finished")
+        log.flush()
     }
 
-    log.v("HostStubGen finished")
-
     System.exit(if (success) 0 else 1 )
 }
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
index 356e1fa..8354d98 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
@@ -39,5 +39,5 @@
 private fun ClassNodes.isAidlClass(className: String): Boolean {
     return hasClass(className) &&
             hasClass("$className\$Stub") &&
-            hasClass("$className\$Proxy")
+            hasClass("$className\$Stub\$Proxy")
 }
\ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
index 45f61c5..cdd24e8 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
@@ -19,7 +19,7 @@
  * Base class for an [OutputFilter] that uses another filter as a fallback.
  */
 abstract class DelegatingFilter(
-        // fallback shouldn't be used by subclasses, so make it private.
+        // fallback shouldn't be used by subclasses directly, so make it private.
         // They should instead be calling into `super` or `outermostFilter`.
         private val fallback: OutputFilter
 ) : OutputFilter() {
@@ -27,11 +27,21 @@
         fallback.outermostFilter = this
     }
 
+    /**
+     * Returns the outermost filter in a filter chain.
+     *
+     * When methods in a subclass needs to refer to a policy on an item (class, fields, methods)
+     * that are not the "subject" item -- e.g.
+     * in [ClassWidePolicyPropagatingFilter.getPolicyForField], when it checks the
+     * class policy -- [outermostFilter] must be used, rather than the super's method.
+     * The former will always return the correct policy, but the later won't consult outer
+     * filters than the current filter.
+     */
     override var outermostFilter: OutputFilter = this
         get() = field
         set(value) {
             field = value
-            // Propagate the inner filters.
+            // Propagate to the inner filters.
             fallback.outermostFilter = value
         }
 
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
index 84856ac..ea7d1d0 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
@@ -149,7 +149,7 @@
         val fallback = super.getPolicyForField(className, fieldName)
 
         val cn = classes.getClass(className)
-        val classPolicy = super.getPolicyForClass(className)
+        val classPolicy = outermostFilter.getPolicyForClass(className)
 
         log.d("Class ${cn.name} Class policy: $classPolicy")
         if (classPolicy.policy.needsInImpl) {
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/KeepAllClassesFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/KeepAllClassesFilter.kt
deleted file mode 100644
index 45dd38d1..0000000
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/KeepAllClassesFilter.kt
+++ /dev/null
@@ -1,30 +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.hoststubgen.filters
-
-/**
- * An [OutputFilter] that keeps all classes by default. (but none of its members)
- *
- * We're not currently using it, but using it *might* make certain things easier. For example, with
- * this, all classes would at least be loadable.
- */
-class KeepAllClassesFilter(fallback: OutputFilter) : DelegatingFilter(fallback) {
-    override fun getPolicyForClass(className: String): FilterPolicyWithReason {
-        // If the default visibility wouldn't keep it, change it to "keep".
-        val f = super.getPolicyForClass(className)
-        return f.promoteToKeep("keep-all-classes")
-    }
-}
\ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt
index f25e862..96e4a3f 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt
@@ -16,6 +16,7 @@
 package com.android.hoststubgen.visitors
 
 import com.android.hoststubgen.HostStubGenErrors
+import com.android.hoststubgen.LogLevel
 import com.android.hoststubgen.asm.ClassNodes
 import com.android.hoststubgen.asm.getPackageNameFromClassName
 import com.android.hoststubgen.asm.resolveClassName
@@ -229,7 +230,7 @@
         ): ClassVisitor {
             var next = nextVisitor
 
-            val verbosePrinter = PrintWriter(log.getVerbosePrintStream())
+            val verbosePrinter = PrintWriter(log.getWriter(LogLevel.Verbose))
 
             // Inject TraceClassVisitor for debugging.
             if (options.enablePostTrace) {
diff --git a/tools/hoststubgen/hoststubgen/test-framework/README.md b/tools/hoststubgen/hoststubgen/test-framework/README.md
index f616ad6..26a9ad1 100644
--- a/tools/hoststubgen/hoststubgen/test-framework/README.md
+++ b/tools/hoststubgen/hoststubgen/test-framework/README.md
@@ -1,20 +1,21 @@
-# HostStubGen: real framework test
+# HostStubGen: (obsolete) real framework test
 
 This directory contains tests against the actual framework.jar code. The tests were
 copied from somewhere else in the android tree. We use this directory to quickly run existing
 tests.
 
+This directory was used during the prototype phase, but now that we have real ravenwood tests,
+this directory is obsolete and should be deleted.
+
 ## How to run
 
 - With `atest`. This is the proper way to run it, but it may fail due to atest's known problems.
 
-  See the top level README.md on why `--no-bazel-mode` is needed (for now).
-
 ```
-$ atest --no-bazel-mode HostStubGenTest-framework-test-host-test
+$ atest HostStubGenTest-framework-all-test-host-test
 ```
 
-- Advanced option: `run-test-without-atest.sh` runs the test without using `atest` or `run-ravenwood-test`
+- Advanced option: `run-test-without-atest.sh` runs the test without using `atest`
 
 ```
 $ ./run-test-without-atest.sh
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/README.md b/tools/hoststubgen/hoststubgen/test-tiny-framework/README.md
index 3bfad9b..344b4e9 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/README.md
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/README.md
@@ -2,7 +2,7 @@
 
 This directory contains a small classes that "simulates" framework.jar, and tests against it.
 
-This test doesn't use the actual android framework code.
+This test is agnostic to Android, and it doesn't use any android framework code or knowledge.
 
 ## How to run
 
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
index 214de59..3956893 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
@@ -223,16 +223,16 @@
     java.lang.annotation.Target(
       value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD]
     )
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
   Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
   minor version: 0
   major version: 61
   flags: (0x0021) ACC_PUBLIC, ACC_SUPER
-  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
   super_class: #x                         // java/lang/Object
   interfaces: 0, fields: 0, methods: 2, attributes: 3
-  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
     descriptor: ()V
     flags: (0x0001) ACC_PUBLIC
     Code:
@@ -243,7 +243,7 @@
       LineNumberTable:
       LocalVariableTable:
         Start  Length  Slot  Name   Signature
-            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy;
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy;
 
   public static int addTwo(int);
     descriptor: (I)I
@@ -262,7 +262,8 @@
 SourceFile: "IPretendingAidl.java"
 NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
 InnerClasses:
-  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;          // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 ## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub.class
   Compiled from "IPretendingAidl.java"
 public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
@@ -303,6 +304,7 @@
 NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
 InnerClasses:
   public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 ## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl.class
   Compiled from "IPretendingAidl.java"
 public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
@@ -315,11 +317,11 @@
 }
 SourceFile: "IPretendingAidl.java"
 NestMembers:
-  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
   com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
 InnerClasses:
-  public static #x= #x of #x;            // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
-  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;            // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
   Compiled from "TinyFrameworkCallerCheck.java"
 class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
index 9031228..9349355 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
@@ -1,13 +1,13 @@
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
   Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
   minor version: 0
   major version: 61
   flags: (0x0021) ACC_PUBLIC, ACC_SUPER
-  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
   super_class: #x                         // java/lang/Object
   interfaces: 0, fields: 0, methods: 2, attributes: 4
-  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
     descriptor: ()V
     flags: (0x0001) ACC_PUBLIC
     Code:
@@ -30,7 +30,8 @@
          x: athrow
 }
 InnerClasses:
-  public static #x= #x of #x;            // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -71,6 +72,7 @@
 }
 InnerClasses:
   public static #x= #x of #x;            // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -89,8 +91,8 @@
   interfaces: 0, fields: 0, methods: 0, attributes: 4
 }
 InnerClasses:
-  public static #x= #x of #x;            // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
-  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;            // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -98,8 +100,8 @@
   x: #x()
     com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
 NestMembers:
-  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
   com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
 ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
   Compiled from "TinyFrameworkCallerCheck.java"
 class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
index e01f49b..4f8c408e 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
@@ -205,16 +205,16 @@
     java.lang.annotation.Retention(
       value=Ljava/lang/annotation/RetentionPolicy;.CLASS
     )
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
   Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
   minor version: 0
   major version: 61
   flags: (0x0021) ACC_PUBLIC, ACC_SUPER
-  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
   super_class: #x                         // java/lang/Object
   interfaces: 0, fields: 0, methods: 2, attributes: 4
-  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
     descriptor: ()V
     flags: (0x0001) ACC_PUBLIC
     Code:
@@ -225,7 +225,7 @@
       LineNumberTable:
       LocalVariableTable:
         Start  Length  Slot  Name   Signature
-            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy;
+            0       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy;
 
   public static int addTwo(int);
     descriptor: (I)I
@@ -242,7 +242,8 @@
             0       4     0     a   I
 }
 InnerClasses:
-  public static #x= #x of #x;            // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -288,6 +289,7 @@
 }
 InnerClasses:
   public static #x= #x of #x;            // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -306,8 +308,8 @@
   interfaces: 0, fields: 0, methods: 0, attributes: 4
 }
 InnerClasses:
-  public static #x= #x of #x;            // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
-  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;            // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -315,8 +317,8 @@
   x: #x()
     com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
 NestMembers:
-  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
   com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
 ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
   Compiled from "TinyFrameworkCallerCheck.java"
 class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
index 9031228..9349355 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
@@ -1,13 +1,13 @@
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
   Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
   minor version: 0
   major version: 61
   flags: (0x0021) ACC_PUBLIC, ACC_SUPER
-  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
   super_class: #x                         // java/lang/Object
   interfaces: 0, fields: 0, methods: 2, attributes: 4
-  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
     descriptor: ()V
     flags: (0x0001) ACC_PUBLIC
     Code:
@@ -30,7 +30,8 @@
          x: athrow
 }
 InnerClasses:
-  public static #x= #x of #x;            // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -71,6 +72,7 @@
 }
 InnerClasses:
   public static #x= #x of #x;            // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -89,8 +91,8 @@
   interfaces: 0, fields: 0, methods: 0, attributes: 4
 }
 InnerClasses:
-  public static #x= #x of #x;            // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
-  public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;            // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -98,8 +100,8 @@
   x: #x()
     com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
 NestMembers:
-  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
   com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
 ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
   Compiled from "TinyFrameworkCallerCheck.java"
 class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
index 5246355..5ff3cde 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
@@ -289,13 +289,13 @@
     java.lang.annotation.Retention(
       value=Ljava/lang/annotation/RetentionPolicy;.CLASS
     )
-## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy.class
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
   Compiled from "IPretendingAidl.java"
-public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
   minor version: 0
   major version: 61
   flags: (0x0021) ACC_PUBLIC, ACC_SUPER
-  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+  this_class: #x                          // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
   super_class: #x                         // java/lang/Object
   interfaces: 0, fields: 0, methods: 3, attributes: 4
   private static {};
@@ -303,17 +303,17 @@
     flags: (0x000a) ACC_PRIVATE, ACC_STATIC
     Code:
       stack=2, locals=0, args_size=0
-         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
          x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
          x: invokestatic  #x                 // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
          x: return
 
-  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Proxy();
+  public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
     descriptor: ()V
     flags: (0x0001) ACC_PUBLIC
     Code:
       stack=4, locals=1, args_size=1
-         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
          x: ldc           #x                 // String <init>
          x: ldc           #x                 // String ()V
          x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
@@ -324,14 +324,14 @@
       LineNumberTable:
       LocalVariableTable:
         Start  Length  Slot  Name   Signature
-           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy;
+           11       5     0  this   Lcom/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy;
 
   public static int addTwo(int);
     descriptor: (I)I
     flags: (0x0009) ACC_PUBLIC, ACC_STATIC
     Code:
       stack=4, locals=1, args_size=1
-         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
+         x: ldc           #x                  // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
          x: ldc           #x                 // String addTwo
          x: ldc           #x                 // String (I)I
          x: ldc           #x                 // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
@@ -346,7 +346,8 @@
            11       4     0     a   I
 }
 InnerClasses:
-  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;          // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -412,6 +413,7 @@
 }
 InnerClasses:
   public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -439,8 +441,8 @@
          x: return
 }
 InnerClasses:
-  public static #x= #x of #x;           // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
   public static #x= #x of #x;           // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+  public static #x= #x of #x;          // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
 SourceFile: "IPretendingAidl.java"
 RuntimeVisibleAnnotations:
   x: #x()
@@ -448,8 +450,8 @@
   x: #x()
     com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
 NestMembers:
-  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Proxy
   com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+  com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
 ## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
   Compiled from "TinyFrameworkCallerCheck.java"
 class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/IPretendingAidl.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/IPretendingAidl.java
index 583e13c..0a07c2b 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/IPretendingAidl.java
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/IPretendingAidl.java
@@ -25,11 +25,12 @@
         public static int addOne(int a) {
             return a + 1;
         }
-    }
 
-    public static class Proxy {
-        public static int addTwo(int a) {
-            return a + 2;
+        public static class Proxy {
+            public static int addTwo(int a) {
+                return a + 2;
+            }
         }
     }
+
 }
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
index 0d52791..d350105 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
@@ -289,6 +289,6 @@
     @Test
     public void testAidlHeuristics() {
         assertThat(IPretendingAidl.Stub.addOne(1)).isEqualTo(2);
-        assertThat(IPretendingAidl.Proxy.addTwo(1)).isEqualTo(3);
+        assertThat(IPretendingAidl.Stub.Proxy.addTwo(1)).isEqualTo(3);
     }
 }
diff --git a/tools/hoststubgen/scripts/run-all-tests.sh b/tools/hoststubgen/scripts/run-all-tests.sh
index 82faa91..4ea501e 100755
--- a/tools/hoststubgen/scripts/run-all-tests.sh
+++ b/tools/hoststubgen/scripts/run-all-tests.sh
@@ -53,4 +53,4 @@
 # These tests should all pass.
 run atest ${READY_TEST_MODULES[*]}
 
-echo ""${0##*/}" finished, with no unexpected failures. Ready to submit!"
\ No newline at end of file
+echo ""${0##*/}" finished, with no failures. Ready to submit!"
\ No newline at end of file